Python Dijkstra算法内存错误?
我已复制并粘贴到我的项目中。经过几次简单的测试,它看起来还可以 在我的具体实现中,我需要算法返回节点列表。因此,我必须修改原始代码,使其始终返回一个列表。更具体地说,我删除了那里的所有Python Dijkstra算法内存错误?,python,Python,我已复制并粘贴到我的项目中。经过几次简单的测试,它看起来还可以 在我的具体实现中,我需要算法返回节点列表。因此,我必须修改原始代码,使其始终返回一个列表。更具体地说,我删除了那里的所有返回“string”行。我修改的代码如下: ## using Dijkstra Algorithm ## def choosePath(s, t): net = {'0':{'1':138, '9':150}, '1':{'0':138, '2':178, '8':194}, '
返回“string”
行。我修改的代码如下:
## using Dijkstra Algorithm ##
def choosePath(s, t):
net = {'0':{'1':138, '9':150},
'1':{'0':138, '2':178, '8':194},
'2':{'1':178, '3':47.5},
'3':{'2':47.5, '4':70},
'4':{'3':70, '5':70},
'5':{'4':70, '6':36},
'6':{'5':36, '7':50},
'7':{'6':50, '8':81},
'8':{'7':81, '9':138, '1':194},
'9':{'8':138, '0':150}}
# sanity check
if s == t:
return []
# create a labels dictionary
labels={}
# record whether a label was updated
order={}
# populate an initial labels dictionary
for i in net.keys():
if i == s: labels[i] = 0 # shortest distance form s to s is 0
else: labels[i] = float("inf") # initial labels are infinity
from copy import copy
drop1 = copy(labels) # used for looping
## begin algorithm
while len(drop1) > 0:
# find the key with the lowest label
minNode = min(drop1, key = drop1.get) #minNode is the node with the smallest label
# update labels for nodes that are connected to minNode
for i in net[minNode]:
if labels[i] > (labels[minNode] + net[minNode][i]):
labels[i] = labels[minNode] + net[minNode][i]
drop1[i] = labels[minNode] + net[minNode][i]
order[i] = minNode
del drop1[minNode] # once a node has been visited, it's excluded from drop1
## end algorithm
# print shortest path
temp = copy(t)
rpath = []
path = []
while 1:
rpath.append(temp)
if order.has_key(temp):
temp = order[temp]
if temp == s:
rpath.append(temp)
break
for j in range(len(rpath)-1,-1,-1):
path.append(rpath[j])
return [junctions[int(elem)] for elem in path]
然后当我运行它时,我会出现以下错误:
>>> Traceback (most recent call last):
File "C:\Users\...\simulation.py", line 162, in choosePath
rpath.append(temp)
MemoryError
显然,这是因为我删除了返回“string”行。然而,我没能找出是哪个删除导致它死亡。为什么会这样
如何使它再次工作,并始终返回列表而不是我希望的字符串?我怀疑您的问题在于向函数传递了错误的参数。您想调用
choosePath('0','9')
。串。不是整数
有趣的是,如果你删除的程序的任何部分仍然存在,它就会捕捉到这一点并停止程序。有了这一部分,它会捕捉到您的输入是否错误
if net.has_key(s)==False:
return "There is no start node called " + str(s) + "."
if net.has_key(t)==False:
return "There is no terminal node called " + str(t) + "."
有了这一部分,如果永远无法找到解决方案,它就会被捕获
else: return "There is no path from " + str(s) + " to " + str(t) + "."
健全性检查并不是绝对必要的,因为正如您所提到的,在您的网络中有一条路径是有保证的。尽管如此,检查还是很好的,因为如果你真的选择改变周围的事情,你就会知道电脑会在明显的错误上提醒你。一种选择是用异常替换它们,因为除非出现了严重错误,否则这些消息都不应该出现。这就是我在下面代码中选择的
class NoPathException(Exception):
pass
def choosePath(s, t):
net = {'0':{'1':138, '9':150},
'1':{'0':138, '2':178, '8':194},
'2':{'1':178, '3':47.5},
'3':{'2':47.5, '4':70},
'4':{'3':70, '5':70},
'5':{'4':70, '6':36},
'6':{'5':36, '7':50},
'7':{'6':50, '8':81},
'8':{'7':81, '9':138, '1':194},
'9':{'8':138, '0':150}}
# sanity check
if s == t:
return []
if not net.has_key(s):
raise ValueError("start node argument not in net")
if not net.has_key(t):
raise ValueError("end node argument not in net")
# create a labels dictionary
labels={}
# record whether a label was updated
order={}
# populate an initial labels dictionary
for i in net.keys():
if i == s: labels[i] = 0 # shortest distance form s to s is 0
else: labels[i] = float("inf") # initial labels are infinity
from copy import copy
drop1 = copy(labels) # used for looping
## begin algorithm
while len(drop1) > 0:
# find the key with the lowest label
minNode = min(drop1, key = drop1.get) #minNode is the nod2 with the smallest label
# update labels for nodes that are connected to minNode
for i in net[minNode]:
if labels[i] > (labels[minNode] + net[minNode][i]):
labels[i] = labels[minNode] + net[minNode][i]
drop1[i] = labels[minNode] + net[minNode][i]
order[i] = minNode
del drop1[minNode] # once a node has been visited, it's excluded from drop1
## end algorithm
# print shortest path
temp = copy(t)
rpath = []
path = []
while 1:
rpath.append(temp)
if order.has_key(temp):
temp = order[temp]
else:
raise NoPathException("no path to solution")
if temp == s:
rpath.append(temp)
break
for j in range(len(rpath)-1,-1,-1):
path.append(rpath[j])
return path
测试
a = choosePath('3', '9')
print(a)
['3', '4', '5', '6', '7', '8', '9']
这就是您要查找的输出吗?它听起来确实像是在向
rpath
添加节点,直到内存耗尽为止。我不知道为什么会发生这种情况,但是如果发生异常,您可以添加代码来捕获异常,并打印出rpath
和order
字典?这会让你很好地了解出了什么问题。这三行代码正是我删除的。但实际上,用字符串调用choosPath('0','9')。另外,我认为我可以安全地删除else子句的原因是,在我的问题中,路径始终确保存在。因此,我感到困惑,为什么这仍然出现。但无论如何,你给了我很好的建议。我将尝试异常捕获。或者我可以简单地用print替换return,对吗?@perfectionm1ng我已经更新了答案。同样,用打印替换退货也不是最好的,原因之一是它没有离开函数。回报和例外情况都可以纾困。