"Bidirectional Dijkstra" 来自 NetworkX
"Bidirectional Dijkstra" by NetworkX
我刚刚阅读了使用双向搜索的最短路径 Dijkstra 算法的 NetworkX 实现(在 this)。这个方法的终点是什么?
我将以 networkx 的实现为基础。
双向 Dijkstra 在两个方向遇到同一个节点时停止 - 但它 return 在该点的路径可能不通过该节点。它正在进行额外的计算以跟踪最短路径的最佳候选者。
我将根据您的评论(在 this answer 上)进行解释
Consider this simple graph (with nodes A,B,C,D,E). The edges of this graph and their weights are: "A->B:1","A->C:6","A->D:4","A->E:10","D->C:3","C->E:1". when I use Dijkstra algorithm for this graph in both sides: in forward it finds B after A and then D, in backward it finds C after E and then D. in this point, both sets have same vertex and an intersection. Does this is the termination point or It must be continued? because this answer (A->D->C->E) is incorrect.
供参考,下面是图表:
当我 运行 在反例中的(无向)网络上使用 networkx 的双向 dijkstra 时,您声称评论:"A->B:1","A->C:6","A->D:4","A->E:10","D->C:3","C->E:1"
:它给了我:(7, ['A', 'C', 'E'])
,而不是 A-D-C-E
.
问题是在 它停止之前误解了它在做什么。它在查找节点方面完全符合您的预期,但在执行此操作时,会进行额外的处理以找到最短路径。当它从两个方向到达 D
时,它已经收集了其他一些可能更短的 "candidate" 路径。不能保证仅仅因为节点 D
从两个方向到达最终成为最短路径的一部分。相反,在从两个方向到达节点时,当前候选最短路径比它继续 运行ning.
时会找到的任何候选路径都短。
算法从两个空簇开始,每个簇与 A
或 E
相关联
{} {}
它会在每个周围建立 "clusters"。它首先将 A
放入与 A
关联的集群中
{A:0} {}
现在它检查 A
是否已经在 E
周围的集群中(当前为空)。它不是。接下来,它查看 A
的每个邻居并检查它们是否在 E
周围的集群中。他们不是。然后,它会将所有这些邻居放入 A
的即将到来的邻居的堆(如有序列表)中,这些邻居按路径长度从 A
排序。称其为 A
的 'fringe'
clusters ..... fringes
{A:0} {} ..... A:[(B,1), (D,4), (C,6), (E,10)]
E:[]
现在它检查 E
。对于 E
它做对称的事情。将 E
放入其簇中。检查 E
是否不在 A
周围的集群中。然后检查它的所有邻居,看看是否有 A
周围的集群(它们不是)。然后创建 E
.
的边缘
clusters fringes
{A:0} {E:0} ..... A:[(B,1), (D,4), (C,6), (E,10)]
E:[(C,1), (A,10)]
现在又回到了 A
。它从列表中取出 B
,并将其添加到 A
周围的集群中。它检查 B
的任何邻居是否在 E
周围的集群中(没有要考虑的邻居)。所以我们有:
clusters fringes
{A:0, B:1} {E:0} ..... A:[(D,4), (C,6), (E,10)]
E:[(C,1), (A,10)]
回到E
:我们将C
添加到E
的集群中,并检查C
的任何邻居是否在A
的集群中.你知道什么,有A
。所以我们有一个 候选 最短路径 A-C-E,距离为 7。我们会坚持下去。我们添加 D
以添加到 E
的边缘(距离为 4,因为它是 1+3)。我们有:
clusters fringes
{A:0, B:1} {E:0, C:1} ..... A:[(D,4), (C,6), (E,10)]
E:[(D,4), (A,10)]
candidate path: A-C-E, length 7
回到A
:我们从它的边缘得到下一个东西,D
。我们将它添加到关于 A
的集群中,并注意到它的邻居 C
在关于 E
的集群中。所以我们有一个新的候选路径,A-D-C-E
,但是它的长度大于 7,所以我们丢弃它。
clusters fringes
{A:0, B:1, D:4} {E:0, C:1} ..... A:[(C,6), (E,10)]
E:[(D,4), (A,10)]
candidate path: A-C-E, length 7
现在我们回到E
。我们看D
。它位于 A
周围的集群中。我们可以确定,我们将遇到的任何未来候选路径的长度至少与我们刚刚追踪到的 A-D-C-E
路径一样长(这种说法不一定显而易见,但它是这种方法的关键) .所以我们可以停下来。我们return之前找到的候选路径
我刚刚阅读了使用双向搜索的最短路径 Dijkstra 算法的 NetworkX 实现(在 this)。这个方法的终点是什么?
我将以 networkx 的实现为基础。
双向 Dijkstra 在两个方向遇到同一个节点时停止 - 但它 return 在该点的路径可能不通过该节点。它正在进行额外的计算以跟踪最短路径的最佳候选者。
我将根据您的评论(在 this answer 上)进行解释
Consider this simple graph (with nodes A,B,C,D,E). The edges of this graph and their weights are: "A->B:1","A->C:6","A->D:4","A->E:10","D->C:3","C->E:1". when I use Dijkstra algorithm for this graph in both sides: in forward it finds B after A and then D, in backward it finds C after E and then D. in this point, both sets have same vertex and an intersection. Does this is the termination point or It must be continued? because this answer (A->D->C->E) is incorrect.
供参考,下面是图表:
当我 运行 在反例中的(无向)网络上使用 networkx 的双向 dijkstra 时,您声称评论:"A->B:1","A->C:6","A->D:4","A->E:10","D->C:3","C->E:1"
:它给了我:(7, ['A', 'C', 'E'])
,而不是 A-D-C-E
.
问题是在 它停止之前误解了它在做什么。它在查找节点方面完全符合您的预期,但在执行此操作时,会进行额外的处理以找到最短路径。当它从两个方向到达 D
时,它已经收集了其他一些可能更短的 "candidate" 路径。不能保证仅仅因为节点 D
从两个方向到达最终成为最短路径的一部分。相反,在从两个方向到达节点时,当前候选最短路径比它继续 运行ning.
算法从两个空簇开始,每个簇与 A
或 E
{} {}
它会在每个周围建立 "clusters"。它首先将 A
放入与 A
{A:0} {}
现在它检查 A
是否已经在 E
周围的集群中(当前为空)。它不是。接下来,它查看 A
的每个邻居并检查它们是否在 E
周围的集群中。他们不是。然后,它会将所有这些邻居放入 A
的即将到来的邻居的堆(如有序列表)中,这些邻居按路径长度从 A
排序。称其为 A
clusters ..... fringes
{A:0} {} ..... A:[(B,1), (D,4), (C,6), (E,10)]
E:[]
现在它检查 E
。对于 E
它做对称的事情。将 E
放入其簇中。检查 E
是否不在 A
周围的集群中。然后检查它的所有邻居,看看是否有 A
周围的集群(它们不是)。然后创建 E
.
clusters fringes
{A:0} {E:0} ..... A:[(B,1), (D,4), (C,6), (E,10)]
E:[(C,1), (A,10)]
现在又回到了 A
。它从列表中取出 B
,并将其添加到 A
周围的集群中。它检查 B
的任何邻居是否在 E
周围的集群中(没有要考虑的邻居)。所以我们有:
clusters fringes
{A:0, B:1} {E:0} ..... A:[(D,4), (C,6), (E,10)]
E:[(C,1), (A,10)]
回到E
:我们将C
添加到E
的集群中,并检查C
的任何邻居是否在A
的集群中.你知道什么,有A
。所以我们有一个 候选 最短路径 A-C-E,距离为 7。我们会坚持下去。我们添加 D
以添加到 E
的边缘(距离为 4,因为它是 1+3)。我们有:
clusters fringes
{A:0, B:1} {E:0, C:1} ..... A:[(D,4), (C,6), (E,10)]
E:[(D,4), (A,10)]
candidate path: A-C-E, length 7
回到A
:我们从它的边缘得到下一个东西,D
。我们将它添加到关于 A
的集群中,并注意到它的邻居 C
在关于 E
的集群中。所以我们有一个新的候选路径,A-D-C-E
,但是它的长度大于 7,所以我们丢弃它。
clusters fringes
{A:0, B:1, D:4} {E:0, C:1} ..... A:[(C,6), (E,10)]
E:[(D,4), (A,10)]
candidate path: A-C-E, length 7
现在我们回到E
。我们看D
。它位于 A
周围的集群中。我们可以确定,我们将遇到的任何未来候选路径的长度至少与我们刚刚追踪到的 A-D-C-E
路径一样长(这种说法不一定显而易见,但它是这种方法的关键) .所以我们可以停下来。我们return之前找到的候选路径