Entendendo um algoritmo para o problema do posto de gasolina


11

No problema do posto de gasolina, temos n cidades {0,,n1} e estradas entre elas. Cada estrada tem extensão e cada cidade define o preço do combustível. Uma unidade de estrada custa uma unidade de combustível. Nosso objetivo é ir de uma fonte a um destino da maneira mais barata possível. Nosso tanque é limitado por algum valor.

Eu tento entender o algoritmo , então escrevi manualmente as etapas para calcular a solução. Infelizmente fiquei preso - em algum momento não há arestas a serem consideradas, não sei por que, talvez esteja perdendo alguma coisa.

Exemplo:
estrada:
0 ----------- 1 ------------ 2 -------------- 3
(não tem que ser tão simples, pode ser qualquer gráfico, ou seja, pode haver estradas entre 0-> 2, 0-> 3, 1-> 3 etc.)

Fonte: 0, Destino: 3, Tanque: 10 unidades
Preços de combustível: 0 : 10 unidades, 1 : 10 unidades, 2 : 20 unidades, 3 : 12 unidades
Comprimentos: 0-> 1 : 9 unidades, 1-> 2 : 1 unidade, 2-> 3 : 7 unidades
Solução ideal: preencha 9 unidades em 0 e 8 unidades em 1. O custo total será de 170 unidades (9 * 10 + 8 * 10).

Então, tentei calculá-lo como mostrado aqui (parágrafo 2.2)

GV[u] is defined as:
GV[u] = { TankCapacity - length[w][u] | w in Cities and fuelPrice[w] < fuelPrice[v] and length[w][u] <= TankCapacity } U {0}

so in my case:
GV[0] = {0}
GV[1] = {0}
GV[2] = {0, 3, 9}
GV[3] = {0}

D(u,g) - minimum cost to get from u to t starting with g units of fuel in tank:
D(t,0) = 0, otherwise:
D(u,g) = min (foreach length[u][v] <= TankCapacity)
         { 
           D(v,0) + (length[u][v] - g) * fuelPrice[u]                             : if  fuelPrice[v] <= fuelPrice[u] and g <= length[u][v]
           D(v, TankCapacity - length[u][v]) + (TankCapacity - g) * fuelPrice[u]  : if  fuelPrice[v] > fuelPrice[u]
         }

so in my case:
D(0,0) = min { D(1,0) + 9*10 }  - D(0,0) should contain minimum cost from 0->3
D(1,0) = min { D(2,9) + 10*10 } - in OPT we should tank here only 8 units :(
D(2,9) = min { ??? - no edges which follows the condition from the reccurence 

Nevertheless D(0,0) = 90 + 100 + smth, so it's already too much.

To achieve the optimal solution algorithm should calculate D(2,7) because the optimal route is:   
(0,0) -> (1,0) -> (2, 7) -> (3, 0) [(v, g): v - city, g - fuel in tank]. 
If we look at G[2] there is no "7", so algorithm doesn't even assume to calculate D(2,7), 
so how can it return optimal solutions?

A recorrência do documento não parece funcionar ou o que é mais provável que eu faça algo errado.

Alguém poderia me ajudar com isso?

Respostas:


7

O problema está na condição do primeiro argumento min()da Equação (4) na p. 7. Atualmente

c(v) <= c(u) and g < d[u][v]

mas deveria ser

(c(v) <= c(u) or v = t) and g < d[u][v]

para forçar a chegada em t para não ter mais gás. (Assim como na minha explicação abaixo para o bug no Fill-Row (u, q), nunca estamos interessados ​​no custo do gás em t. E, como lá, outra maneira de corrigir o problema seria sobrescrever c (t ) com 0 no início do algoritmo.)

Corrigir esse erro (no algoritmo publicado), combinado com adicionar as arestas ausentes, como descrevo abaixo (seu erro :-P), deve ser suficiente para fazer tudo funcionar.


Uma coisa que você está perdendo é que o gráfico G deve estar completo (primeira frase da seção 2, p. 4) - e se não estiver completo, quaisquer arestas ausentes deverão ser adicionadas, com os pesos encontrados, levando-se os comprimentos mínimos de caminho em o gráfico. Então, por exemplo, no seu exemplo de gráfico, deve haver (entre outros) uma aresta de 1 a 3 com peso 8 (correspondente ao caminho via 2), para que, de fato, GV [3] = {0, 2}.

Não tenho certeza se isso resolverá completamente o problema para você, mas deve ajudar.

Separadamente, acho que há um erro no algoritmo Fill-Row (u, q) na p. 6: esse algoritmo deve tratar o caso q = 1 especialmente, mas não o faz. Eu acredito que poderia ser corrigido mudando

if c(v) <= c(u)

na linha 3 a

if c(v) <= c(u) or q = 1

para forçar qualquer perna final a chegar ao destino vazia. (Intuitivamente, devemos sempre desconsiderar o preço do gás no destino final, t.) Outra maneira de contornar isso seria sobrescrever c (t) por 0 no início.


q=1c(v)>c(u)

2

Usando a solução @j_random_hacker, precisamos transformar nosso gráfico em um gráfico completo e alterar a condição da equação (4) para:

(c(v) <= c(u) or v = t) and g < d[u][v]     

O gráfico completo deve ficar assim:

insira a descrição da imagem aqui

e cálculos finais:

GV[0] = {0}, GV[1] = {0}, GV[2] = {0, 3, 9}, GV[3] = {0, 2}

D(0,0) = min { D(1,0) + 9 * 10 }
D(1,0) = min { D(2,9) + 10 * 10, D(3,0) + 8*10 }
D(3,0) = 0
... etc

so D(0,0) = 170

Caminho através de 0 -> 1 -> 3 [custo total 170 $] é a solução. É o que esperávamos :-). Se precisarmos de uma rota, poderemos transformar essas arestas extras da solução nas arestas especificadas no início (não deve ser muita dificuldade).

Só me pergunto como devemos evitar impasses nessa recorrência. Por exemplo, pode haver deadloop entre 0 <-> 1, porque c (0) <= c (1) ec (1) <= c (0).


Para referência futura, consulte este meta post :-)
Juho

1

A idéia é obter o combustível conforme necessário na tarifa mais barata onde quer que você esteja (paradigma de algoritmo ganancioso)

Veja alguns exemplos. no seu exemplo

Fonte: 0, Destino: 3, Tanque: 10 unidades Preços de combustível: 0: 10 unidades, 1: 10 unidades, 2: 20 unidades, 3: 12 unidades Comprimentos: 0-> 1: 9 unidades, 1-> 2: 1 unidade, 2-> 3: 7 unidades

Eu tenho que viajar 9 unidades no começo, então eu preciso encher meu tanque em 0 com> = 9 unidades (capacidade> = 9). Agora, vejo em 1,2,3 que a taxa de combustível é> = taxa de combustível em 0. Como eu quero comprar o combustível necessário na taxa mais barata, tentarei encher 9 + 1 + 7 = 17 unidades em somente cidade 0. Mas, a capacidade do tanque pode ser <17, digamos 10. Então, vou encher até 10. Então, em 1, tenho 1 unidade de combustível restante e tenho que percorrer 8 unidades a mais, então em 1 encher 7 unidades mais. Não consigo preencher 2, porque a taxa seria maior. Meu, custo total = 10 * 10 + 7 * 10 = 170.

Cidijij

i) cheio = 0

i=0n1liCi>Clll=n1dllk=i+1ldk,k+1mindltotal, capacidade} combustível unitário na cidade . cheio = { cheio, capacidade}. Defina .imindli=l


Obrigado pela sua resposta! Infelizmente, não me especifiquei com clareza suficiente. Você assumido, que o gráfico vai ser tão simples como o meu exemplo, mas pode ser qualquer gráfico ou seja, pode haver também estradas 0-> 2, 1-> 3 etc.
Wojciech Kulik

Sim, como você não mencionou isso antes, eu assumi que todas as cidades estão conectadas de maneira linear (o gráfico é um caminho simples).
Sayan Bandyapadhyay
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.