Verständnis eines Algorithmus für das Tankstellenproblem


11

Im Tankstellenproblem erhalten wir n Städte {0,,n1}} und Straßen zwischen ihnen. Jede Straße hat eine Länge und jede Stadt definiert den Preis des Kraftstoffs. Eine Straßeneinheit kostet eine Kraftstoffeinheit. Unser Ziel ist es, auf möglichst günstige Weise von einer Quelle zu einem Ziel zu gelangen. Unser Tank ist durch einen gewissen Wert begrenzt.

Ich versuche, den Algorithmus zu verstehen , also habe ich die Schritte zur Berechnung der Lösung manuell aufgeschrieben. Leider blieb ich stecken - irgendwann gibt es keine Kanten mehr zu berücksichtigen, ich weiß nicht warum, vielleicht fehlt mir etwas.

Beispiel:
Straße:
0 ----------- 1 ------------ 2 -------------- 3
(nicht) muss so einfach sein, es könnte jeder Graph sein, dh es könnte Straßen zwischen 0-> 2, 0-> 3, 1-> 3 usw. geben)

Quelle: 0, Ziel: 3, Tank: 10 Einheiten
Kraftstoffpreise: 0 : 10 Einheiten, 1 : 10 Einheiten, 2 : 20 Einheiten, 3 : 12 Einheiten
Längen: 0-> 1 : 9 Einheiten, 1-> 2 : 1 Einheit, 2-> 3 : 7 Einheiten
Optimale Lösung: 9 Einheiten zu 0 und 8 Einheiten zu 1 füllen. Die Gesamtkosten betragen dann 170 Einheiten (9 * 10 + 8 * 10).

Also habe ich versucht, es wie hier gezeigt zu berechnen (Absatz 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?

Die Wiederholung aus dem Dokument scheint nicht zu funktionieren oder was wahrscheinlicher ist, dass ich etwas falsch mache.

Könnte mir jemand dabei helfen?

Antworten:


7

Das Problem liegt in der Bedingung für das erste Argument min()in Gleichung (4) auf S. 7. Es ist derzeit

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

aber es sollte sein

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

die Ankunft bei t zu erzwingen, um kein Gas mehr zu haben. (Genau wie bei meiner Erklärung unten für den Fehler in Fill-Row (u, q) sind wir nie an den Gaskosten bei t interessiert. Und wie bei dort wäre eine andere Möglichkeit, das Problem zu beheben, c (t zu überschreiben ) mit 0 am Anfang des Algorithmus.)

Das Beheben dieses Fehlers (im veröffentlichten Algorithmus) und das Hinzufügen der fehlenden Kanten, wie unten beschrieben (Ihr Fehler :-P), sollten ausreichen, um alles zum Laufen zu bringen.


Eine Sache, die Sie vermissen, ist, dass der Graph G vollständig sein muss (erster Satz von Abschnitt 2, S. 4) - und wenn er nicht vollständig ist, müssen fehlende Kanten hinzugefügt werden, wobei die Gewichte ermittelt werden, indem minimale Pfadlängen in übernommen werden der Graph. So sollte beispielsweise in Ihrem Beispieldiagramm (unter anderem) eine Kante von 1 bis 3 mit dem Gewicht 8 (entsprechend dem Pfad über 2) vorhanden sein, so dass tatsächlich GV [3] = {0, 2} ist.

Ich bin nicht sicher, ob das das Problem für Sie vollständig lösen wird, aber es sollte helfen.

Unabhängig davon denke ich, dass es einen Fehler im Fill-Row (u, q) -Algorithmus auf S. 22 gibt. 6: Dieser Algorithmus sollte den Fall q = 1 speziell behandeln, tut es aber nicht. Ich glaube, es könnte durch Änderung behoben werden

if c(v) <= c(u)

in Zeile 3 bis

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

um eine letzte Etappe zu zwingen, leer am Ziel anzukommen. (Intuitiv sollten wir den Gaspreis am endgültigen Bestimmungsort t immer außer Acht lassen.) Ein anderer Weg, dies zu umgehen, wäre, c (t) zu Beginn mit 0 zu überschreiben.


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

2

Mit der @ j_random_hacker-Lösung müssen wir unseren Graphen in einen vollständigen Graphen umwandeln und die Bedingung von Gleichung (4) in Folgendes ändern:

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

Das vollständige Diagramm sollte folgendermaßen aussehen:

Geben Sie hier die Bildbeschreibung ein

und endgültige Berechnungen:

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

Pfad durch 0 -> 1 -> 3 [Gesamtkosten 170 $] ist die Lösung. Das haben wir erwartet :-). Wenn wir eine Route benötigen, sollten wir in der Lage sein, diese zusätzlichen Kanten von der Lösung zu Beginn in die angegebenen Kanten umzuwandeln (dies sollte keine große Schwierigkeit sein).

Ich frage mich nur, wie wir bei dieser Wiederholung Deadloops vermeiden sollten. Zum Beispiel kann es einen Deadloop zwischen 0 - 1 geben, weil c (0) <= c (1) und c (1) <= c (0).


Für zukünftige Referenz, sehen Sie diesen Meta-Beitrag :-)
Juho

1

Die Idee ist, den Kraftstoff nach Bedarf zum günstigsten Preis zu erhalten, wo immer Sie ihn haben (Paradigma des gierigen Algorithmus).

Nehmen Sie einige Beispiele. in deinem Beispiel

Quelle: 0, Ziel: 3, Tank: 10 Einheiten Kraftstoffpreise: 0: 10 Einheiten, 1: 10 Einheiten, 2: 20 Einheiten, 3: 12 Einheiten Längen: 0-> 1: 9 Einheiten, 1-> 2: 1 Einheit, 2-> 3: 7 Einheiten

Ich muss zuerst 9 Einheiten fahren, also muss ich meinen Tank bei 0 mit> = 9 Einheiten füllen (Kapazität> = 9). Jetzt kann ich bei 1,2,3 sehen, dass die Kraftstoffmenge> = Kraftstoffmenge bei 0 ist. Da ich meinen benötigten Kraftstoff zum günstigsten Preis kaufen möchte, werde ich versuchen, 9 + 1 + 7 = 17 Einheiten bei zu tanken Stadt 0 nur. Aber die Kapazität des Tanks könnte <17 sein, sagen wir 10. Also werde ich bis 10 tanken. Dann habe ich bei 1 1 Einheit Kraftstoff übrig und ich muss 8 Einheiten mehr durchqueren, also fülle ich bei 1 7 Einheiten mehr. Ich kann nicht bei 2 tanken, weil die Rate höher wäre. Meine Gesamtkosten = 10 * 10 + 7 * 10 = 170.

Cidijij

i) voll = 0

i=0n1liCi>Clll=n1dllk=i+1ldk,k+1mindlimindli=l


Vielen Dank für Ihre Antwort! Leider habe ich mich nicht klar genug angegeben. Sie haben angenommen, dass der Graph so einfach sein wird wie mein Beispiel, aber es kann jeder Graph sein, dh es kann auch Straßen 0-> 2, 1-> 3 usw. geben.
Wojciech Kulik

Ja, wie Sie bereits erwähnt haben, bevor ich davon ausgegangen bin, dass alle Städte linear miteinander verbunden sind (die Grafik ist ein einfacher Pfad).
Sayan Bandyapadhyay
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.