简体   繁体   English

Python Dijkstra算法内存错误?

[英]Python Dijkstra Algorithm Memory Error?

I have copied and pasted this answer for Dijkstra Algorithm to my project. 我已将Dijkstra算法的答案复制并粘贴到我的项目中。 It seemed ok after several simple tests. 经过几次简单的测试后,看起来还可以。

In my specific implementation, I need the algorithm to return a list of nodes. 在我的特定实现中,我需要算法来返回节点列表 So I have to modify the original code so that it always returns a list. 因此,我必须修改原始代码,以便它始终返回一个列表。 More specifically, I removed all the return "string" lines there . 更具体地说, 我在那里删除了所有的return "string" The modified code by me is as follows: 我修改的代码如下:

## 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]

Then when I run it, I end up with the following error: 然后,当我运行它时,出现以下错误:

>>> Traceback (most recent call last):
  File "C:\Users\...\simulation.py", line 162, in choosePath
    rpath.append(temp)
MemoryError

Obviously, it is because I have removed the return "string" lines. 显然,这是因为我删除了返回的“字符串”行。 However, I failed to find out which deletion makes it die. 但是,我无法找出导致它删除的删除。 Why is it so? 为什么会这样呢?

How may I make it work again AND always returns a list instead of a string as I wish? 如何使它再次工作,并且总是返回列表,而不是我希望的字符串?

I suspect your problem is that you're passing the wrong arguments to the function. 我怀疑您的问题是您将错误的参数传递给该函数。 You want to call choosePath('0', '9') . 您要调用choosePath('0', '9') Strings. 字符串。 Not integers. 不是整数。

What's comical is that if ANY of the parts of the program you removed were still there, it would have caught this and stopped the program. 可笑的是,如果您删除的程序的任何部分仍在那儿,它会抓住并停止程序。 With this part, it catches if your input is wrong. 通过这一部分,它可以捕获您的输入是否错误。

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) + "."

With this part, it catches if it never reaches a solution. 有了这一部分,它就可以解决从未解决的问题。

else: return "There is no path from " + str(s) + " to " + str(t) + "."

The sanity checks are not strictly necessary, since as you mentioned a path is assured in your net. 严格来说,健全性检查不是必需的,因为正如您提到的,可以确保网络中有一条路径。 Still the checks are nice because if you ever do choose to change things around you'll know the computer will call you out on obvious mistakes. 仍然进行检查很不错,因为如果您确实选择更改周围的事物,您将知道计算机会在出现明显错误时将您召唤出去。 One option is to replace them with exceptions, since none of these messages should really come up unless something has gone horribly wrong. 一种选择是用异常替换它们,因为除非出现严重错误,否则这些消息都不应该真正出现。 That's what I opted for in the following code. 这就是我在以下代码中选择的内容。

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

Testing 测试中

a = choosePath('3', '9')
print(a)
['3', '4', '5', '6', '7', '8', '9']

Is this the output you're looking for? 这是您要找的输出吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM