当前位置: 首页 > 知识库问答 >
问题:

使用优先级队列使用Dijkstra查找所有相等的最短路径

徐德海
2023-03-14

我想实现dijkstra的算法,在两个节点之间的图中找到最便宜的路径。权重是节点之间的距离,单位为X,Y。我知道如何实现dijkstra,但我需要找到最短的所有路径。所以如果两条路径是相同的长度,我希望他们两个。

我也在谷歌和堆栈溢出上到处找。但是我真的不能理解给出的一些答案。也没有人使用优先级队列。我在考虑标记我们已经访问过的节点,但这不会切断路径吗?

这是我要实现的来自维基百科的伪代码。

1  function Dijkstra(Graph, source):
2      dist[source] ← 0                           // Initialization
3
4      create vertex priority queue Q
5
6      for each vertex v in Graph:           
7          if v ≠ source
8              dist[v] ← INFINITY                 // Unknown distance from source to v
9          prev[v] ← UNDEFINED                    // Predecessor of v
10
11         Q.add_with_priority(v, dist[v])
12
13
14     while Q is not empty:                      // The main loop
15         u ← Q.extract_min()                    // Remove and return best vertex
16         for each neighbor v of u:              // only v that are still in Q
17             alt ← dist[u] + length(u, v) 
18             if alt < dist[v]
19                 dist[v] ← alt
20                 prev[v] ← u
21                 Q.decrease_priority(v, alt)
22
23     return dist, prev

如果有人有建议,或者如果优先队列不是最好的方式,请让我知道。非常感谢。

共有1个答案

谷梁英毅
2023-03-14

如果prev[]不是一个顶点而是一个顶点列表,您可能会得到想要的结果。在第20行中,您创建了一个只包含u的新列表。另外(可能在17到18之间),如果alt==dist[v],您将u添加到prev[v]。由于此伪代码在v==target时不会停止,因此您应该找到所有最短路径。

关于优先级队列,有一个问题,你可以通过在Q中添加一个v来获得时间,但是如果你改变了一个v,你必须在Q的中间找到它(慢),把它移走(慢),然后添加改变的版本。有一些数据结构可以更快地处理这个问题。我使用优先级队列,但我不删除更改的顶点。我添加更改的顶点而不删除它们的旧版本。如果我选择了一个好的比较器,具有较短路径的版本(或者,如果相等,较长的先前列表)将首先被拉动。所以我必须测试Q中的所有u是否被访问;如果是,我可以把你扔掉。在结束时Q...顶点u必须被标记访问。

 类似资料:
  • 我正在使用优先级队列实现Dijkstra的算法,我想要一个函数从堆中删除一个元素,但我只能从Dijkstra的主节点索引中向它发送顶点索引,我找不到它在堆上的位置,我负担不起进行二进制搜索。有什么想法吗?

  • 我需要使用Java中的优先级队列实现Dijkstra的算法。这是我到目前为止的代码: 我需要填写最短路径方法并返回节点数组。但是,我不确定如何做到这一点。我知道我需要在某个时候进行优先排队,但有人可以向我解释一下如何吗?我已经制作了startNode,我知道我需要为它分配一个距离值0,其余节点的距离值为无穷大。另外,可比性从何而来?

  • 我的问题是:每个节点的优先级是什么?我认为它是最小值的传入边缘的权重,但我不确定。这是真的吗? 第二个问题,当我提取队列的根时,如果这个节点不与任何一个被访问的节点邻接,它将如何工作?

  • 我一直在努力实现Dijkstra的算法;更具体地,具有优先级队列的部分。将顶点添加到数据结构中,并使用迭代器遍历所有顶点并找到最小距离;这很容易,但这次是。 我想要的是: < li >能够将顶点插入数据结构中 < li >提取(返回并移除)距离dist[v]最小的顶点v 我相信为了让Dijkstra的算法正常工作,你应该能够在恒定时间内插入顶点并在log(n)时间内提取它们;有人建议可以使用优先级

  • 我正在为Dikjstra算法做一个优先级队列。我目前在插入方法上有麻烦。我包含了整个类的代码,以防你需要更好地了解我想完成的事情。我将堆索引放在一个数组列表(heapIndex)中,堆放在另一个数组列表中。 那是我运行程序后的输出(值,优先级,堆索引)。*(-1)表示heapIndex中的空单元格。

  • 我曾尝试在循环加权图上使用Djikstra的算法,而不使用优先级队列(堆),结果成功了。 Wikipedia指出,该算法的原始实现不使用优先级队列,而是在O(V2)时间内运行。 现在,如果我们只删除优先级队列并使用普通队列,则运行时间是线性的,即O(ve)。 有人能解释一下为什么我们需要优先队列吗?