在图类中,我制作了一个vertList字典,用于存储顶点名称和顶点类对象,该字典在调用Dijkstra函数时会在Relax函数中抛出键错误0。
我尝试使用get函数,而不是直接从字典本身进行调用。
from collections import defaultdict
import math
import heapq
class PriorityQueue:
def __init__(self):
self.is_empty = True
self.length = 0
self.pqueue = []
def makePQueue(self, l):
self.pqueue = l.copy()
heapq.heapify(self.pqueue)
if(len(l) > 0):
self.length = len(l)
self.is_empty = False
def addElement(self, element):
heapq.heappush(self.pqueue, element)
self.length = self.length+1
def removeElement(self):
if(self.length > 0):
element = heapq.heappop(self.pqueue)
self.length = self.length-1
if(self.length == 0):
self.is_empty = True
return element
else:
return None
# vertex class
class Vertex:
def __init__(self, key):
self.id = key
self.parent = None
self.distFromSource = math.inf
def getId(self):
return self.id
def getParent(self):
return self.parent
def addParent(self, p):
self.parent = p
def getDistSource(self):
return self.distFromSource
def setDistFromSource(self, d):
self.distFromSource = d
# Graph class
class Graph:
def __init__(self):
self.graph = defaultdict(list)
self.soruce = None
self.vertList = {}
def addVertex(self, v):
if(v not in list(self.vertList.keys())):
ver = Vertex(v)
self.vertList[v] = ver
def addEdge(self, u, v, c):
if(u not in list(self.vertList.keys())):
ver = Vertex(u)
self.vertList[u] = ver
if(v not in list(self.vertList.keys())):
ver = Vertex(v)
self.vertList[v] = ver
self.graph[u].append((v, c))
def getWeight(self, u, v):
# binary search can be implemented for speed
for i in self.graph[u]:
if(i[0] == v):
return i[1]
def setSource(self, s):
if(s not in list(self.vertList.keys())):
ver = Vertex(s)
self.vertList[s] = ver
self.vertList[s].setDistFromSource(0)
self.source = self.vertList[s]
self.source.setDistFromSource(0)
def getSource(self):
return self.source.getId()
def getDistList(self):
l = [(self.vertList[i].getDistSource(), str(i))
for i in list(self.vertList.keys())]
return l
# def costArray(self):
# l = [i.]
# implementation of edge array of cost
def relax(self, u, v, c):
if(self.vertList[v].getDistSource() > self.vertList[u].getDistSource()+c):
self.vertList[v].setDistFromSource(
self.vertList[u].getDistSource()+c)
self.vertList[v].addParent(self.vertList[u])
def dijkstra(graph):
ss = []
l = graph.getDistList()
pq = PriorityQueue()
pq.makePQueue(l)
# print(pq.pqueue)
while(pq.is_empty == False):
(cost, u) = pq.removeElement()
# in priority queue on the basis of cost
if int(u) not in ss:
ss = ss.append(int(u))
for (i, c) in graph.graph[int(u)]:
graph.relax(u, i, c)
```
g = Graph()
g.addEdge(0, 1, 3)
g.addEdge(0, 2, 2)
g.addEdge(0, 3, 5)
g.addEdge(1, 0, 3)
g.addEdge(1, 4, 3)
g.addEdge(4, 1, 3)
g.addEdge(4, 2, 1)
g.addEdge(4, 6, 4)
g.addEdge(2, 0, 2)
g.addEdge(2, 4, 1)
g.addEdge(2, 5, 6)
g.addEdge(3, 0, 5)
g.addEdge(3, 5, 2)
g.addEdge(5, 2, 6)
g.addEdge(5, 3, 2)
g.addEdge(5, 6, 1)
g.addEdge(5, 7, 4)
g.addEdge(6, 4, 4)
g.addEdge(6, 5, 1)
g.addEdge(6, 7, 2)
g.addEdge(7, 5, 4)
g.addEdge(7, 6, 2)
g.setSource(0)
dijkstra(g)
例外
python graph.py
Traceback (most recent call last):
File "graph.py", line 155, in <module>
dijkstra(g)
File "graph.py", line 126, in dijkstra
graph.relax(u, i, c)
File "graph.py", line 108, in relax
if(self.vertList[v].getDistSource() >
self.vertList[u].getDistSource()+c):
KeyError: '0'
答案 0 :(得分:2)
调用relax()
方法时,u
是一个字符串,而不是整数!
这就是为什么出现KeyError的原因:确实有一个0
键,但是没有'0'
。
定义优先级队列时,将显式存储字符串:
def getDistList(self):
l = [(self.vertList[i].getDistSource(), str(i))
for i in list(self.vertList.keys())]
return l
然后,在您的dijkstra
方法中,将该字符串转换为if
语句中的int,但之后不进行graph.relax()
调用中的转换:
if int(u) not in ss:
ss = ss.append(int(u))
for (i, c) in graph.graph[int(u)]:
graph.relax(u, i, c)
答案 1 :(得分:0)
在进行进一步调试之前,我将检查Graph类的属性 soruce ,我认为它是 source ,并且您输入了错误的代码,作为函数定义在类图形中 getSource 返回 self.source.getId()