Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 迪克斯特拉';负边有向无环图的s算法_Algorithm_Dijkstra_Directed Acyclic Graphs - Fatal编程技术网

Algorithm 迪克斯特拉';负边有向无环图的s算法

Algorithm 迪克斯特拉';负边有向无环图的s算法,algorithm,dijkstra,directed-acyclic-graphs,Algorithm,Dijkstra,Directed Acyclic Graphs,Dijkstra算法是否适用于具有负边的图,如果它是非循环的(DAG)?我认为这是因为没有循环就不可能有负循环。这个算法失败还有其他原因吗 谢谢[明天期中考试]考虑一下图表(直接1->2,2->4,4->3,1->3,3->5): 最小路径为1-2-4-3-5,成本为-3。但是,Dijkstra将在第一步中设置d[3]=2,d[2]=3,然后从其优先级队列中提取节点3,并设置d[5]=4。由于节点3是从优先级队列中提取出来的,并且Dijkstra不会多次将给定节点推送到其优先级队列,因此它将永远

Dijkstra算法是否适用于具有负边的图,如果它是非循环的(DAG)?我认为这是因为没有循环就不可能有负循环。这个算法失败还有其他原因吗

谢谢[明天期中考试]

考虑一下图表(直接
1->2,2->4,4->3,1->3,3->5
):

最小路径为
1-2-4-3-5
,成本为
-3
。但是,Dijkstra将在第一步中设置
d[3]=2,d[2]=3
,然后从其优先级队列中提取节点
3
,并设置
d[5]=4
。由于节点3是从优先级队列中提取出来的,并且Dijkstra不会多次将给定节点推送到其优先级队列,因此它将永远不会再次进入优先级队列,因此该算法将无法工作

Dijkstra的算法不适用于负边,周期。没有一个周期,什么都不会改变。贝尔曼福特是一个可以检测到负成本周期,并与负面的优势。如果你有负边缘,Dijkstra就不起作用


如果更改Dijkstra的算法,使其能够多次将节点推送到优先级队列,则该算法将在负成本边缘下工作。但是,如果新算法仍然是Dijkstra的,这是有争议的:我会说你用这种方式得到Bellman Ford,它通常是这样实现的(通常使用FIFO队列,而不是优先级队列)。

如果没有负权重,Dijkstra的算法将适用于DAG。因为Dijkstra算法不能给出负加权边图的正确答案。但有时它是基于图类型的。

只要边权重为负,Dijkstra的纯实现就会失败。以下变体仍适用于给定的问题场景

  • 每次放松一个u->v边时,将一对(从源到v的较新/较短距离)推到队列中。这会导致队列中同一顶点的多个副本与源的距离不同
  • 继续更新距离,直到队列为空
  • 即使存在负边缘,上述变体也有效。但如果存在负重量循环,则情况并非如此。DAG是非循环的,所以我们不必担心负循环


    有一种更有效的方法可以使用拓扑排序计算DAG的最短路径距离O(V+E)时间。更多详细信息请参见

    您正在寻找贝尔曼·福特·摩尔。在这种情况下,Dijkstra的算法如何(以及是否)失败取决于Dijkstra的算法在你的教科书中写得有多准确。假设在您提到的已更改的Dijkstra中,节点3再次添加到优先级提示。这不会产生访问节点2的效果。你能解释一下“不止一次推”吗?@Gerard node
    2
    仍将被访问。首先,从队列中提取节点
    1
    ,因为这是开始节点。然后更新距离:
    d[3]=2,d[2]=3
    。将节点
    3
    2
    添加到优先级队列。然后提取
    3
    ,因为这是队列中距离它最小的节点。更新
    d[4]=4,d[5]=4
    ,并将节点
    4,5
    添加到队列中。然后提取节点
    2
    ,更新d[4]=-7
    ,将
    4`添加到队列中。然后提取节点
    4
    ,更新
    d[3]=-5
    ,并将节点
    3
    再次添加到队列中,这将导致找到成本
    -3
    的最佳路径@Gerard在经典的Dijkstra算法中,不允许再次将节点
    3
    添加到优先级队列中。当它有
    d[3]=2
    时,我们提取了它之后,我们就不会再添加它了,当有负成本优势时,可能会导致错误的答案。如果我理解正确,你1)删除经典Dijkstra
    If(endnode.IsVisited)break的停止标准?然后2)你说在经典的Dijkstra中,当一个替代节点被访问时,只有在这种情况下,你才能快速地重新添加到优先级队列中?我相信这会起作用。问题很可能是,在一个大型图形中,可能需要很长时间才能重新访问具有负长度的备选路线。假设一条成功的路线在早期阶段达到-1000,其终点的总距离为+100。由于早期的-1000,可能90%的网络位于优先级队列的顶部,您必须等待,直到最后另一条路由也达到-1000并赢得总距离为+90的算法。
    
      1---(2)---3--(2)--5
      |         |
     (3)      (2)
      |         |  
      2--(-10)--4