II. ĐSTĐNAFIN LEH VE ALEYHĐNE ĐLERĐ SÜRÜLEN GÖRÜŞLER
1. Đstinaf Yolunun Lehine Olan Görüşler
Durante a construção ou na alteração de uma solução de um problema de roteamento de veículos com serviços de coleta e entrega é necessário verificar a viabilidade desta solução. A restrição do problema referente a capacidade máxima do veículo deve ser verificada sempre que um consumidor é inserido em alguma rota, uma vez que as demandas de coleta e entrega desta rota não devem extrapolar a capacidade máxima do veículo.
Dada a rota na qual um consumidor será inserido, uma implementação simples para este procedimento consiste em calcular a carga do veículo após o atendimento de cada demanda dos consumidores desta rota, verificando, assim, se a capacidade do veículo não será extrapolada com a inserção das demandas de entrega e coleta do novo consumidor. O algoritmo 5.1 apresenta o pseudocódigo para este procedimento. No algoritmo a seguinte notação é utilizada:
Rota 1: [0 - 4 - 1 - 8 - 9 - 0] Rota 2: [0 - 5 - 7 - 6 - 2 - 3 - 0]
Estado Coleta: [1 - 1 - 0 - 1 - 0 - 0 - 1 - 1 - 1]
Figura 5.3: Representação de uma solução para o problema de roteamento de veículos multiobjetivo com coleta opcional: os dois primeiros vetores representam as rotas que compõem a solução, indicando a ordem em que os consumidores devem ser visitados, sempre começando e terminado no depósito, representado pelo número 0. O último vetor informa quais deles terão a demanda de coleta atendida, representada pelo valor 1, ou 0 caso contrário. A primeira posição se refere ao consumidor 1, a segunda posição ao consumidor 2, e assim sucessivamente.
• rj: consumidor pertencente a rota R, tal que j = {v0, r1, r2, r3, ..., v0}. O primeiro e o último consumidor representa o depósito (v0) e os demais elementos estão associados a um determinado consumidor vi ∈ V
• |R|: o comprimento da rota, que é o número de consumidores presentes nela. Sendo as posições da rota numeradas a partir do zero, então, para uma rota com |R| = 7, as suas posições variam no intervalo [0 − 6].
• vnew: novo consumidor a ser inserido na rota R, tal que vnew∈ V .
• p: a posição na rota R em que o consumidor vnew será inserido, tal que 0 < p < |R|. • E[i]: a demanda de entrega do consumidor vi ∈ V .
• C[i]: a demanda de coleta do consumidor vi ∈ V . • Q: a capacidade máxima do veículo.
• SomaEntregas[j]: é a soma das demandas de entrega do j-ésimo consumidor (rj), exclusive, até o último consumidor presente na rota (v0). Por exemplo, dada uma rota com 7 consumidores, se SomaEntregas[3] é igual a 50, significa que a soma das demandas de entrega dos consumidores presentes no intervalo (3 − 0] da rota é igual a 50.
• SomaColetas[j]: é a soma das demandas de coleta do primeiro consumidor (v0) até o j-ésimo consumidor (rj), inclusive, presente na rota. Por exemplo, dada uma rota com
7 consumidores, se SomaColetas[4] é igual a 74, significa que a soma das demandas de coleta dos consumidores presentes no intervalo [0 − 4] da rota é igual a 74.
A verificação de viabilidade referente a capacidade máxima do veículo deve ser feita tanto no depósito, considerando as demandas de entregas dos consumidores que partem do depósito e as demandas de coleta dos consumidores que retornam ao depósito, e em cada consumidor considerando a demanda líquida (demanda de coleta - demanda de entrega) dos consumidores acrescida a carga do veículo.
Algoritmo 5.1 Verificar a viabilidade de inserção de um consumidor em uma rota
1: {Verifica a carga do veículo ao partir e retornar ao depósito} 2: se (SomaEntregas[0] + E[vnew]) > Q então
3: retornar falso; 4: fim se
5: se (SomaColetas[|R| − 1] + C[vnew]) > Q então 6: retornar falso;
7: fim se
{Inicia a verificação ponto a ponto}
8: carga ← (somaEntregas[0] + E[vnew]); 9: para j = 0 até p − 1 faça
10: demanda liquida ← (C[rj] − E[rj]); 11: se (carga + demanda liquida) > Q então
12: retornar falso; 13: fim se
14: carga ← (carga + demanda liquida); 15: fim para
16: demanda liquida ← (C[vnew] − E[vnew]); 17: se (carga + demanda liquida) > Q então
18: retornar falso; 19: fim se
20: carga ← (carga + demanda liquida); 21: para j = p até |R| − 1 faça
22: demanda liquida ← (C[rj] − E[rj]); 23: se (carga + demanda liquida) > Q então
24: retornar falso; 25: fim se
26: carga ← (carga + demanda liquida); 27: fim para
{Então satisfaz a restrição de capacidade máxima do veículo}
28: retornar verdadeiro;
O algoritmo 5.1 inicialmente confirma se o somatório das demandas de entrega e coletas dos consumidores rj ∈ R acrescido da demanda de entrega E[vnew] e coleta C[vnew] do consumidor vnew a ser inserido em R não extrapola a capacidade Q do veículo (linhas 1–7) . Na etapa seguinte, verifica-se a viabilidade em cada consumidor rj ∈ R até o ponto p de inserção do
novo consumidor vnew, calculando a carga atual do veículo acrescido da demanda líquida em cada consumidor rj (linhas 8–15). No ponto p de inserção do novo consumidor vnew, faz-se a mesma verificação, calculando a carga do veículo (carga atual + demanda liquida) caso vnew seja inserido na posição p (linhas 16–19). Seguindo esta mesma ideia, a viabilidade é analisada nos consumidores rj seguintes da rota R até o retorno ao depósito v0 (linhas 20–27). Se, em nenhum dos pontos da rota a restrição de capacidade máxima do veículo é violada, então é retornado verdadeiro, indicando que a inserção do consumidor vnew na posição p da rota é viável.
Apesar de sua fácil implementação, este algoritmo tem uma complexidade computacional O(|R|). Como a avaliação da viabilidade é realizada inúmeras vezes, qualquer otimização realizada melhora o desempenho dos algoritmos que o utilizam. Assim, é proposto o ar- mazenamento de algumas informações adicionais sobre a carga do veículo ao longo da rota, tornando mais eficiente esta análise de viabilidade.
As informações que devem ser armazenadas são: um vetor infoCarga que indica a carga presente no veículo em cada posição da rota e uma variável maxP osicao que indica em qual ponto da rota o veículo apresenta a maior carga. Com estas informações, o algoritmo 5.2 apresenta o pseudo-código de como pode ser feito a verificação de viabilidade das rotas.
Inicialmente o algoritmo 5.2 analisa se a carga do veículo não extrapola a capacidade máxima quando o veículo parte do depósito e quando ele retorna ao depósito (linhas 2–7). Em seguida, verifica se a posição onde o veículo apresenta maior carga está antes ou depois da posição que se deseja inserir o consumidor (linha 9).
Caso o consumidor seja inserido antes da posição na qual o veículo atinge o ponto de maior carga, então a carga máxima do veículo será acrescida apenas da demanda de coleta do consumidor. Assim sendo, apenas esta averiguação será efetuada (linha 10) uma vez que não será preciso calcular a carga do veículo em todas as posições após p, pois se a capacidade máxima do veículo não for extrapolada no ponto em que o veículo apresenta a maior carga transportada, ela não será extrapolada nas demais posições após p. A carga do veículo no interior da rota só será calculada se a demanda de entrega do consumidor vnew a ser inserido for maior que a sua demanda de coleta (linha 13). Caso isso ocorra, será necessário calcular a carga do veículo nas posições anteriores a posição p onde ocorrerá a inserção do consumidor (linhas 14–18). Neste caso, não se pode prever se em algum ponto intermediário entre o depósito e o ponto p de inserção do consumidor vnew haverá alguma inviabilidade.
Quando p estiver após o ponto de maior carga, o procedimento é análogo (linhas 20–32). No fim, se o veículo não extrapola sua capacidade máxima, então é retornado verdadeiro, indicando que a inserção do consumidor na posição p é viável (linha 33).
Algoritmo 5.2 Verificar a viabilidade de inserção de um consumidor em uma rota (otimizado)
1: {Verifica a carga do veículo ao partir e retornar ao depósito} 2: se (SomaEntregas[0] + E[vnew]) > Q então
3: retornar falso; 4: fim se
5: se (SomaColetas[|R| − 1] + C[vnew]) > Q então 6: retornar falso;
7: fim se
8: {Verifica se o local onde o consumidor será inserido está antes do ponto de maior
carga}
9: se p ≤ maxP osicao então
10: se (inf oCarga[maxP osicao] + C[vnew]) > Q então 11: retornar falso;
12: fim se
13: se E[vnew] > C[vnew] então 14: para j = 0 até p − 1 faça
15: se (inf oCarga[rj] + E[vnew]) > Q então 16: retornar falso;
17: fim se
18: fim para
19: fim se
20: senão
21: {Consumidor será inserido depois do ponto de maior carga} 22: se (inf oCarga[maxP osicao] + E[vnew]) > Q então
23: retornar falso; 24: fim se
25: se E[vnew] < C[vnew] então 26: para j = p até |R| − 1 faça
27: se (inf oCarga[rj] + C[vnew]) > Q então 28: retornar falso; 29: fim se 30: fim para 31: fim se 32: fim se 33: retornar verdadeiro;
e C[vnew] ≤ E[vnew], tem-se o melhor caso, com complexidade O(1), pois ele não executa nenhum bloco de repetição. Apenas no pior caso o algoritmo 5.2 apresenta complexidade O(|R|).
O pior caso ocorre em duas situações: (i) quando se trata da inserção de um consumidor vnew imediatamente anterior à posição de maior carga, e a posição de maior carga ocorre no final da rota, e a demanda de entrega do consumidor vnew é maior que a demanda de coleta vnew; (ii) quando ocorre a inserção de um consumidor vnewlogo após a posição de maior carga, e a posição de maior carga ocorre no início da rota, e a demanda de coleta do consumidor vnew é maior que a demanda de coleta de x. Em ambos casos, as linhas 14–18 ou 26–30 serão executadas aproximadamente |R| vezes.
A análise de viabilidade é ilustrada na figura 5.4. Neste exemplo, é avaliado se a inserção do consumidor vnew = 6 entre os consumidores 7 e 2 (p = 3), considerando que o veículo para o transporte tem uma capacidade máxima de Q = 15. Primeiramente, foi verificado se a capacidade do veículo é extrapolada considerando o somatório das demandas de entrega que partem do depósito e o somatório das demandas de coleta que retornam ao depósito. Em seguida, verifica-se a carga do veículo no ponto de maior carga, indicado por maxP osicao. Este é o ponto mais crítico da rota e onde geralmente ocorrem as inviabilidades. Como a inserção do consumidor 6 é realizada após este ponto, então a carga do veículo (9) é acrescida apenas da demanda de entrega do consumidor 6 (E[6] = 3). Assim, esta soma (9 + 3 = 12) é inferior a capacidade máxima do veículo (Q = 15), garantindo a viabilidade da rota até o ponto de inserção do consumidor. No restante da rota, a carga do veículo será acrescida apenas da demanda de coleta do consumidor 6 (C[6] = 2). Sendo a demanda de coleta (C[6] = 2) menor que a demanda de entrega (E[6] = 3), então garante-se a viabiliade no restante da rota. Em outras palavras, se no ponto de maior carga for acrescido um valor maior que nos demais pontos da rota, então certamente a carga do veículo nos demais pontos será inferior a este valor calculado.