Dijkstra 算法:它是一种图搜索算法,它使用贪婪方法来查找从源节点到所有其他剩余节点的最短路径。它解决了加权图的单源最短路径问题。该算法跟踪边的权重以找到使总距离最小的路径。
时间复杂度: O(V + E*log(V)),当使用优先队列时(其中 V 是节点,E 是边)
Dijkstra算法的局限性:对于这个算法函数:
- 该图应该是加权和有方向的。
- 权重应该是非负的。
Dijkstra 算法的优点:
- 它具有线性时间复杂度,因此可以轻松用于解决大型问题。
- 它在寻找最短距离方面很有用,因此也用于谷歌地图和计算流量。
Dijkstra 算法的缺点:
- 它无法处理负权重。
- 它遵循一种盲目的方法,因此浪费了时间。
为什么 Dijkstra 算法在负权重上失败?
让我们举一个简单的例子来更好地理解为什么Dijkstra 算法对负权重失败。
考虑具有节点A、B和C 的循环有向图,这些节点由边连接,边的权重表示使用此边的成本。以下是上图中提到的权重:
A –>B = 5,A –>C = 6,C –>B = -3 。这里一个权重C -> B是负数。
- 将节点A视为源节点,任务是找到从源节点A到图中存在的所有其他节点(即节点B和C )的最短距离。
- 因此,首先将节点A处的距离标记为0 (因为从A到A的距离为0 ),然后将此节点标记为已访问,这意味着它已包含在最短路径中。
- 由于一开始,源节点到所有其他节点的距离是未知的,因此将其初始化为infinity 。如果发现任何小于无穷大的距离,则更新此距离(这基本上是贪婪的方法)
- 然后,将源节点A到B的距离更新为连接它与A的边的权重为5 (因为 5 < 无穷大)。
以类似的方式,还将从A到C的距离(之前为无穷大)更新为6 (如 6 < 无穷大)。 - 现在检查与源节点A的最短距离,因为 5 是从A到B的最小距离,因此将节点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 现场工作专业课程和学生竞争性编程现场课程。