Otimização de Rotas de Veículos com Janelas de Tempo e Restrições Múltiplas em MATLAB

A otimização de rotas de veículos é um desafio central na logística moderna, especialmente quando lidamos com variantes complexas como o Problema de Roteamento de Veículos com Janelas de Tempo (VRPTW), Roteamento de Veículos Elétricos (EVRP) e o Problema de Roteamento e Localização (LRP). A implementação eficiente dessas restrições em MATLAB requer abordagens algorítmicas robustas, como Algoritmos Genéticos, Colônia de Formigas e Têmpera Simulada.

No contexto do VRPTW, especialmente em cenários de logística de cadeia de frio, o tratamento das janelas de tempo como restrições rígidas frequentemente inviabiliza a busca por soluções. Uma abordagem mais eficaz utiliza restrições flexíveis, incorporando penalidades diretamente na função de aptidão do Algoritmo Genético. O código abaixo demonstra essa estratégia, aplciando pesos distintos para atrasos e esperas excessivas:

function custo_total = avaliar_solucao(caminhos, janelas_tempo, velocidade)
    penalidade_tempo = 0;
    num_caminhos = length(caminhos);
    
    for idx_caminho = 1:num_caminhos
        tempo_atual = 0;
        sequencia = caminhos{idx_caminho};
        
        for idx_no = 2:length(sequencia)
            no_anterior = sequencia(idx_no - 1);
            no_atual = sequencia(idx_no);
            
            duracao_viagem = calcular_distancia(no_anterior, no_atual) / velocidade;
            tempo_chegada = tempo_atual + duracao_viagem;
            
            inicio_janela = janelas_tempo(no_atual, 1);
            fim_janela = janelas_tempo(no_atual, 2);
            
            tempo_atual = max(tempo_chegada, inicio_janela);
            
            if tempo_atual > fim_janela
                penalidade_tempo = penalidade_tempo + 150 * (tempo_atual - fim_janela);
            elseif tempo_chegada < inicio_janela
                penalidade_tempo = penalidade_tempo + 30 * (inicio_janela - tempo_chegada);
            end
        end
    end
    
    distancia_total = somar_distancias(caminhos);
    custo_total = distancia_total + penalidade_tempo;
end

Para o EVRP, a limitação da autonomia da bateria exige a integração de pontos de recarga na rota. Em vez de fixar estações previamente, uma mutação dinâmica pode inserir pontos de recarga estrategicamente quando a distância acumulada excede a capacidade do veículo. Isso é particularmente útil em áreas urbanas com alta densidade de infraestrutura de recarga:

function rota_atualizada = inserir_recarga(rota_original, pontos_recarga, autonomia_max)
    distancia_acumulada = 0;
    indices_insercao = [];
    num_nos = length(rota_original);
    
    for i = 2:num_nos
        no_origem = rota_original(i-1);
        no_destino = rota_original(i);
        trecho_dist = calcular_distancia(no_origem, no_destino);
        distancia_acumulada = distancia_acumulada + trecho_dist;
        
        if distancia_acumulada > autonomia_max
            estacao_vizinha = buscar_estacao_proxima(no_destino, pontos_recarga);
            indices_insercao = [indices_insercao; i, estacao_vizinha];
            distancia_acumulada = 0; 
        end
    end
    
    rota_atualizada = aplicar_insercoes(rota_original, indices_insercao);
end

Em cenários LRP com múltiplos centros de distribuição, a qualidade da população inicial impacta diretamente a convergência. A alocação de clientes aos depósitos mais próximos utilizando vetorialização de distâncias reduz o custo computacional e melhora a distribuição geográfica inicial, mitigando efeitos de fronteira em regiões com depósitos assimétricos:

function grupos_clientes = alocar_depositos(matriz_clientes, matriz_depositos)
    num_depositos = size(matriz_depositos, 1);
    grupos_clientes = cell(num_depositos, 1);
    
    for idx_cliente = 1:size(matriz_clientes, 1)
        coords_cliente = matriz_clientes(idx_cliente, :);
        distancias = sqrt(sum((matriz_depositos - coords_cliente).^2, 2));
        
        [~, indice_melhor] = min(distancias);
        grupos_clientes{indice_melhor} = [grupos_clientes{indice_melhor}; coords_cliente];
    end
end

Quando a escala do problema aumenta significativamente, o Algoritmo de Colônia de Formigas (ACO) torna-se mais adequado. Para otimizar o atendimento a pedidos urgentes, a matriz de feromônio pode ser ajustada dinamicamente, reforçando as rotas que atendem a janelas de tempo estritas. Isso acelera a convergência para soluções viáveis em cenários críticos:

matriz_feromonio = (1 - taxa_evaporacao) .* matriz_feromonio;

largura_janela = janelas_tempo(:, 2) - janelas_tempo(:, 1);
mask_critico = largura_janela < 1.5; 

for i = 1:size(matriz_feromonio, 1)
    if mask_critico(i)
        delta_feromonio(i, :) = delta_feromonio(i, :) * 1.8;
    end
end

matriz_feromonio = matriz_feromonio + delta_feromonio;

Por fim, a Têmpera Simulada (Simulated Annealing) pode ser aprimorada com um mecanismo de resfriamento adaptativo. Ajustar a taxa de decaimento da temperatura com base na aceitação de soluções piores permite um equilíbrio entre a exploração global e a refinação local, sendo altamente eficaz para escapar de ótimos locais em espaços de busca altamente restritos:

if solucao_pior_aceita
    taxa_resfriamento = 0.92; 
else
    taxa_resfriamento = 0.98; 
end

temperatura_atual = temperatura_atual * taxa_resfriamento;

Tags: MATLAB VRPTW EVRP LRP Algoritmos-Geneticos

Publicado em 9-9 01:23