ทำความเข้าใจเกี่ยวกับอัลกอริทึมสำหรับปัญหาปั้มน้ำมัน


11

ในปัญหาปั้มน้ำมันเราได้รับเมืองnเมือง{0,,n1}และถนนระหว่างทั้งสอง ถนนแต่ละสายมีความยาวและแต่ละเมืองกำหนดราคาน้ำมัน ถนนหนึ่งหน่วยมีราคาน้ำมันหนึ่งหน่วย เป้าหมายของเราคือไปจากแหล่งต้นทางไปยังปลายทางด้วยวิธีที่ถูกที่สุด รถถังของเราถูก จำกัด ด้วยค่าบางอย่าง

ฉันพยายามเข้าใจอัลกอริธึมดังนั้นฉันจึงจดขั้นตอนเพื่อคำนวณวิธีแก้ปัญหาด้วยตนเอง น่าเสียดายที่ฉันติดอยู่ - ในบางจุดไม่มีขอบที่ต้องพิจารณาฉันไม่รู้ว่าทำไม

ตัวอย่าง:
ถนน:
0 ----------- 1 ------------ 2 -------------- 3
(ไม่ได้ ต้องง่ายขนาดนั้นมันอาจเป็นกราฟใดก็ได้เช่นอาจมีถนนระหว่าง 0-> 2, 0-> 3, 1-> 3 เป็นต้น)

ที่มา: 0, ปลายทาง: 3, รถถัง: 10 หน่วย
ราคาน้ำมัน: 0 : 10 หน่วย, 1 : 10 หน่วย, 2 : 20 หน่วย, 3 : 12 หน่วย
ความยาว: 0-> 1 : 9 หน่วย, 1-> 2 : 1 หน่วย2-> 3 : 7 หน่วย
ทางออกที่ดีที่สุด:เติม 9 หน่วยที่ 0 และ 8 หน่วยที่ 1 ราคารวมแล้วเป็น 170 หน่วย (9 * 10 + 8 * 10)

ดังนั้นฉันจึงพยายามคำนวณตามที่แสดงที่นี่ (ย่อหน้า 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?

การเกิดซ้ำจากเอกสารดูเหมือนจะไม่ทำงานหรือมีแนวโน้มที่ฉันจะทำอะไรผิด

มีใครช่วยฉันได้บ้างไหม

คำตอบ:


7

ปัญหาอยู่ในเงื่อนไขสำหรับอาร์กิวเมนต์แรกไปยังmin()ในสมการ (4) บน p 7. ปัจจุบัน

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

แต่มันควรจะเป็น

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

เพื่อบังคับให้มาถึงที่ t เพื่อไม่ให้มีก๊าซเหลือ (เช่นเดียวกับคำอธิบายของฉันด้านล่างสำหรับข้อผิดพลาดใน Fill-Row (u, q) เราไม่เคยสนใจค่าใช้จ่ายของก๊าซที่ t และเช่นเดียวกับที่นั่นอีกวิธีหนึ่งในการแก้ไขปัญหาคือการเขียนทับ c (t ) ด้วย 0 ที่จุดเริ่มต้นของอัลกอริทึม)

แก้ไขข้อผิดพลาดนี้ (ในอัลกอริทึมที่เผยแพร่) รวมกับการเพิ่มในขอบที่หายไปตามที่ฉันอธิบายด้านล่าง (ความผิดพลาดของคุณ :-P) ควรเพียงพอที่จะทำให้ทุกอย่างทำงานได้


สิ่งหนึ่งที่คุณขาดหายไปคือกราฟ G ต้องสมบูรณ์ (ประโยคแรกของส่วนที่ 2, หน้า 4) - และหากยังไม่สมบูรณ์จะต้องเพิ่มขอบที่ขาดหายไปด้วยน้ำหนักที่พบโดยใช้ความยาวเส้นทางขั้นต่ำใน กราฟ ดังนั้นในกราฟตัวอย่างของคุณควรมีขอบตั้งแต่ 1 ถึง 3 พร้อมน้ำหนัก 8 (ตรงกับเส้นทางผ่าน 2) ดังนั้นในความเป็นจริง GV [3] = {0, 2}

ฉันไม่แน่ใจว่าจะช่วยแก้ปัญหาให้คุณได้หรือไม่ แต่น่าจะช่วยได้

ฉันคิดว่ามีข้อผิดพลาดในอัลกอริทึม Fill-Row (u, q) ในหน้า p 6: อัลกอริทึมนี้ควรปฏิบัติต่อเคส q = 1 เป็นพิเศษ แต่ก็ไม่เป็นเช่นนั้น ฉันเชื่อว่าสามารถแก้ไขได้โดยการเปลี่ยน

if c(v) <= c(u)

ในบรรทัดที่ 3 ถึง

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

เพื่อบังคับให้ขาสุดท้ายไปถึงที่ว่างเปล่า (โดยสังหรณ์ใจเราควรมองข้ามราคาก๊าซที่ปลายทางสุดท้าย, t.) อีกวิธีหนึ่งคือเขียนทับ c (t) ด้วย 0 เมื่อเริ่มต้น


Q=1(โวลต์)>(ยู)

2

การใช้โซลูชัน @j_random_hacker เราต้องเปลี่ยนกราฟเป็นกราฟสมบูรณ์และเปลี่ยนเงื่อนไขจากสมการ (4) เป็น:

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

กราฟที่สมบูรณ์ควรมีลักษณะดังนี้:

ป้อนคำอธิบายรูปภาพที่นี่

และการคำนวณขั้นสุดท้าย:

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

เส้นทางผ่าน 0 -> 1 -> 3 [ราคารวม 170 $] เป็นทางออก นั่นคือสิ่งที่เราคาดไว้ :-) หากเราต้องการเส้นทางเราควรจะสามารถแปลงขอบพิเศษเหล่านั้นจากโซลูชันเป็นขอบที่กำหนดไว้ในตอนเริ่มต้น (มันไม่ควรลำบากมาก)

ฉันแค่สงสัยว่าเราควรหลีกเลี่ยง deadloops ในการเกิดซ้ำนี้ได้อย่างไร ตัวอย่างเช่นสามารถมี deadloop ระหว่าง 0 <-> 1 เนื่องจาก c (0) <= c (1) และ c (1) <= c (0)


สำหรับการอ้างอิงในอนาคตโปรดดูเมตาโพสต์นี้ :-)
Juho

1

ความคิดคือการได้รับเชื้อเพลิงตามที่ต้องการในอัตราที่ถูกที่สุดไม่ว่าคุณจะได้รับจากที่ใด

นำตัวอย่างบางส่วน ในตัวอย่างของคุณ

ที่มา: 0, ปลายทาง: 3, รถถัง: 10 หน่วยราคาน้ำมัน: 0: 10 หน่วย, 1: 10 หน่วย, 2: 20 หน่วย, 3: 12 หน่วยความยาว: 0-> 1: 9 หน่วย, 1-> 2: 1 หน่วย 2-> 3: 7 หน่วย

ตอนแรกฉันต้องเดินทาง 9 หน่วยดังนั้นฉันต้องเติมถังของฉันที่ 0 ด้วย> = 9 หน่วย (ความจุ> = 9) ตอนนี้ฉันสามารถดูได้ที่ 1,2,3 อัตราเชื้อเพลิงคือ> = อัตราเชื้อเพลิงที่ 0 ขณะที่ฉันต้องการซื้อเชื้อเพลิงที่ต้องการในอัตราที่ถูกที่สุดฉันจะพยายามเติม 9 + 1 + 7 = 17 หน่วยที่ เมือง 0 เท่านั้น แต่ความจุของรถถังอาจเท่ากับ <17, บอกว่า 10 ดังนั้นฉันจะเติมจนครบ 10 แล้วที่ 1 ฉันเหลือเชื้อเพลิง 1 หน่วยและฉันต้องเคลื่อนที่ 8 หน่วยขึ้นไปดังนั้นที่ 1 ฉันจะเติม 7 หน่วยเพิ่มเติม ฉันไม่สามารถเติมเต็มได้ที่ 2 เพราะอัตราจะสูงขึ้น ของฉันค่าใช้จ่ายทั้งหมด = 10 * 10 + 7 * 10 = 170

ผมdผมJผมJ

i) เต็ม = 0

ผม=0n-1ล.ผมผม>ล.ล.ล.=n-1dล.ล.Σk=ผม+1ล.dk,k+1นาทีdล.-ผมนาทีdล.-ผม=ล.


ขอบคุณสำหรับคำตอบ! น่าเสียดายที่ฉันไม่ได้ระบุตัวเองชัดเจนเพียงพอ คุณสันนิษฐานว่ากราฟนั้นจะง่ายอย่างที่เป็นตัวอย่างของฉัน แต่มันอาจเป็นกราฟใดก็ได้เช่นสามารถมีถนน 0-> 2, 1 -> 3 เป็นต้น
Wojciech Kulik

Ya อย่างที่คุณไม่ได้พูดถึงก่อนที่ฉันจะสันนิษฐานว่าทุกเมืองมีการเชื่อมต่อในลักษณะเชิงเส้น (กราฟเป็นเส้นทางที่เรียบง่าย)
Sayan Bandyapadhyay
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.