📜  为什么 Dijkstra 算法在负权重上失败?

📅  最后修改于: 2021-10-25 03:16:07             🧑  作者: Mango

Dijkstra 算法它是一种图搜索算法,它使用贪心方法找到从源节点到所有其他剩余节点的最短路径。它解决了加权图的单源最短路径问题。该算法跟踪边的权重以找到使总距离最小的路径。

时间复杂度: O(V + E*log(V)),当使用优先队列时(其中 V 是节点,E 是边)

Dijkstra算法的局限性对于这个算法函数:

  • 该图应该是加权和有方向的。
  • 权重应该是非负的。

Dijkstra 算法的优点

  • 它具有线性时间复杂度,因此可以轻松用于解决大型问题。
  • 它在寻找最短距离方面很有用,因此也用于谷歌地图和计算流量。

Dijkstra 算法的缺点

  • 它无法处理负权重。
  • 它遵循一种盲目的方法,因此浪费了时间。

为什么 Dijkstra 算法在负权重上失败?

让我们举一个简单的例子来更好地理解为什么Dijkstra 算法对负权重失败。

考虑具有节点A、BC 的循环有向图,这些节点由边连接,边的权重表示使用此边的成本。以下是上图中提到的权重:

A –>B = 5,A –>C = 6,C –>B = -3 。这里一个权重C -> B是负数。

  • 将节点A视为源节点,任务是找到从源节点A到图中存在的所有其他节点(即节点BC )的最短距离。

  • 因此,首先将节点A处的距离标记为0 (因为从AA的距离为0 ),然后将此节点标记为已访问,这意味着它已包含在最短路径中。
  • 由于一开始,源节点到所有其他节点的距离是未知的,因此将其初始化为infinity 。如果发现任何小于无穷大的距离,则更新此距离(这基本上是贪婪的方法)

  • 然后,将源节点AB的距离更新为连接它与A的边的权重为5 (因为 5 < 无穷大)。
    以类似的方式,还将从AC的距离(之前为无穷大)更新为6 (如 6 < 无穷大)。
  • 现在检查与源节点A的最短距离,因为 5 是从AB的最小距离,因此将节点B标记为“已访问”。
    同样,下一个最短的是6,因此也将节点C标记为已访问。此时,图的所有三个节点都被访问了。
  • 现在最重要的一步出现在这里,因为可以看出,按照这个算法,从A –> B的最短距离是5但如果通过节点C行进的距离是路径A –> C –> B距离将是3 (因为 A–>C = 6 和 C–>B = -3 ),所以 6 + (-3) = 3。因为3小于5 ,但 Dijkstra 的算法给出了错误的答案5 ,即不是最短距离。因此, Dijkstra 算法在否定情况下失败。

结论:

  • 由于 Dijkstra 遵循贪婪方法,一旦节点被标记为已访问,即使存在另一条成本或距离较小的路径,也无法重新考虑它。仅当图中存在负权重或边时才会出现此问题。
  • 因此,该算法无法在负权重的情况下找到最小距离,因此使用替代的 Bellman-Ford 算法在负权重的情况下找到最短距离,因为它会在遇到负循环时停止循环。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程