Dijkstra's pyghorm在蟒蛇中的奇怪行为

时间:2016-04-16 17:57:29

标签: python graph dijkstra

我正在尝试在python中实现dijkstra的alghoritm。我想知道节点的长度"你"到所有其他节点。

def Dijkstr():
    listOfProcessingNodes = listOfNodes
    for i in listOfNodes:
        if i.name == "You":
            i.lastNode = None
            i.length = 0
            i.resolved = True
            lastProcessNode = i

    listOfProcessingNodes.sort(key=lambda x: x.length, reverse=True)

    while len(listOfProcessingNodes):
        processNode = listOfProcessingNodes.pop()
        for i in processNode.adjencyList:
            for k in listOfEdges:
                if (k.inNode == i.name and k.outNode == processNode.name and i.resolved == False) or (k.inNode == processNode.name and k.outNode == i.name and i.resolved == False):
                    i.length = processNode.length + int(float(k.cost))
                    i.lastNode = processNode
                    i.resolved = True
        listOfProcessingNodes.sort(key=lambda x: x.length, reverse=True)
        lastProcessNode = processNode
        print processNode.name,":", processNode.length

以下是Node和Edge类的定义:

class Node():
    def __init__(self, name):
        self.name=name
        self.adjencyList=[]
        self.resolved = False
        self.lastNode = None
        self.length = float("inf")

class Edge():
    def __init__(self, inNode, outNode, cost):
        self.inNode=inNode
        self.outNode=outNode
        self.cost=cost

我的输入

You - A: 3
You - B: 2
A - C: 4
A - D: 4
B - D: 1
B - E: 2
C - F: 1
D - F: 2
D - G: 4
E - G: 2
F - G: 2

我得到了这个输出

You : 0
B : 2
A : 3
D : 3
E : 4
F : 5
C : 7
G : 7

而不是

You : 0
B : 2
A : 3
D : 3
E : 4
F : 5
C : 6
G : 6

我真的很困惑,如果它不适用于所有节点,那么我会犯错误,但如果它不适用于最后2个节点?谢谢你的帮助

1 个答案:

答案 0 :(得分:0)

似乎你对Dijkstra算法的一个关键部分有误解。

随着算法的进行,如果算法找到到那个“更便宜”的节点的路由,节点的“长度”(即来自“你”节点的最小总成本')可能会减少比之前找到的还要多。您的代码假定一旦访问了一个节点,则其长度将被修复。这是不正确的。

您的图表包含一种发生这种情况的情况。当访问节点D,长度为3时,你给F一个长度为5,G给长度为7.但是,当访问节点E,长度为4时,你需要将G的长度减少到6,因为E有长度4和E到G的边缘成本为2.

不要过滤掉resolved设置为True的任何节点,而是检查processNode的长度加上边k的成本是否小于i节点i的当前已知长度。如果是这样,您为节点i找到了新的较低长度,因此您应该更新节点{{1}}及其上一个节点的长度。

顺便提一下,节点C的长度应该是7,而不是你声称的6。