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;