[英]Dijkstra's weighted shortest path in Python
我正在嘗試解決來自 PepCoding、Graph Foundation 1、Shortest Path In Weights 的問題,並將解決方案從 Java 復制到 Python。
問題:
1. You are given a graph and a source vertex. The vertices represent cities and the edges represent
distance in kms.
2. You are required to find the shortest path to each city (in terms of kms) from the source city along
with the total distance on path from source to destinations.
Note -> For output, check the sample output and question video.
示例輸入:
7
9
0 1 10
1 2 10
2 3 10
0 3 40
3 4 2
4 5 3
5 6 3
4 6 8
2 5 5
0
Output:
0 via 0 @ 0
1 via 01 @ 10
2 via 012 @ 20
5 via 0125 @ 25
4 via 01254 @ 28
6 via 01256 @ 28
3 via 012543 @ 30
我實現了一個列表而不是 PriorityQueue,並嘗試使用__lt__
和__ge__
等運算符對 class 中的Pair
元素進行排序。 但是,除了0
和3
之間的最短路徑不正確之外,我得到的所有結果都是正確的。
這是我的 output:
0 via 0 @ 0
1 via 01 @ 10
2 via 012 @ 20
5 via 0125 @ 25
4 via 01254 @ 28
6 via 01256 @ 28
3 via 0123 @ 30 <-- This differ should be: 3 via 012543 @ 30
Loop: [(28, 6, '01256'), (30, 3, '0123'), (40, 3, '03'), (30, 3, '012543')]
Loop: [(28, 6, '01256'), (30, 3, '0123'), (40, 3, '03'), (30, 3, '012543'), (36, 6, '012546')]
POP: (28, 6, '01256')
6 via 01256 @ 28
POP: (30, 3, '0123') <-- *This is getting pop instead of, POP: (30, 3, '012543')
3 via 0123 @ 30
POP: (30, 3, '012543')
POP: (36, 6, '012546')
POP: (40, 3, '03')
實現compareTo的 Java 中的這段代碼正在發揮作用。
static class Pair implements Comparable<Pair> {
int v;
String psf;
int wsf;
Pair(int v, String psf, int wsf){
this.v = v;
this.psf = psf;
this.wsf = wsf;
}
public int compareTo(Pair o){
return this.wsf - o.wsf;
}
}
這是 Python 中的代碼:
class Edge:
def __init__(self, src, nbr, wt):
self.src = src
self.nbr = nbr
self.wt = wt
def __repr__(self):
return repr(self.__dict__)
class Pair:
def __init__(self, wsf, v, psf):
self.wsf = wsf
self.v = v
self.psf = psf
def __repr__(self):
return repr((self.wsf, self.v, self.psf))
def __lt__(self, o):
return self.wsf < o.wsf
def __ge__(self, o):
return len(self.psf) < len(o.psf)
def main():
vtces = int(input())
edges = int(input())
graph = {}
for i in range(vtces):
graph[i] = []
for i in range(edges):
lines = input().split(" ")
v1 = int(lines[0])
v2 = int(lines[1])
wt = int(lines[2])
e1 = Edge(v1, v2, wt)
e2 = Edge(v2, v1, wt)
graph[e1.src].append(e1)
graph[e2.src].append(e2)
src = int(input())
# print(type(graph))
# for i in graph:
# for j in graph[i]:
# print(i, j)
# Write your code here
pq = []
pq.append(Pair(0, src, str(src) + ""))
# print("\nStart: ",pq)
visited = [False] * vtces
while len(pq) > 0:
pq.sort()
rem = pq.pop(0)
# print("POP: ", rem)
if visited[rem.v] == True:
continue
visited[rem.v] = True
print(rem.v, " via ", rem.psf, "@", rem.wsf)
for e in graph[rem.v]:
if visited[e.nbr] == False:
pq.append(Pair(rem.wsf + e.wt, e.nbr, str(rem.psf) + str(e.nbr)))
# print("Loop: ",pq)
# print(pq)
if __name__ == "__main__":
main()
PS:初來乍到,盡力而為,如有打字或解釋不當請見諒。
查看您的代碼后,我認為排序function 將返回距離最短且跳數(頂點)最少的路徑。
在嘗試了多個 class 比較器或此處提到的 Java 的“compareTo()”之后。 最后,我在這里遇到了“Java 的 compareTo() 的 Python 等價物”,並在Pair
class 中做了以下修改,它3 via 012543 @ 30
的路徑 [Previous error was 30, 3, '0123'
]。
class Pair():
def __init__(self, wsf, v, psf):
self.wsf = wsf
self.v = v
self.psf = psf
def __repr__(self):
return repr((self.wsf, self.v, self.psf))
def __lt__(self, other):
if self.wsf == other.wsf:
return len(self.psf) > len(other.psf)
return self.wsf < other.wsf
def __gt__(self, other):
return other.__lt__(self)
我使用list
實現了上面的內容,但在測試期間我嘗試了heapq
,但沒有解決太多問題。 也許我不確定有什么更好的方法。
while len(pq) > 0:
pq.sort()
# print("sLoop: ", pq)
rem = pq.pop(0)
# print("POP: ", rem)
if visited[rem.v] == True:
continue
visited[rem.v] = True
print(rem.v, "via", rem.psf, "@", rem.wsf)
for e in graph[rem.v]:
if visited[e.nbr] == False:
pq.append(Pair(rem.wsf + e.wt, e.nbr, str(rem.psf) + str(e.nbr)))
# print("Loop: ", pq)
因此,歡迎提出任何改進上述代碼的建議。
另外,下面的測試用例失敗了,我不確定測試用例中的預期輸出/輸入是什么(因為可能有多個邊):
2 via 2 @ 0
5 via 25 @ 5
4 via 254 @ 8
6 via 256 @ 8
3 via 2543 @ 10
1 via 21 @ 10
0 via 210 @ 20
但我仍然對我的結果感到滿意。 謝謝大家。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.