解析Bellman-Ford算法求最短路径


上一篇博文已经说了用dijkstra算法来求图(有向图和无向图)的最短路径了,那么怎么还需要使用Bellman-Ford算法来求解最短路径问题呢?其实这两个算法有各自求解的限制条件:dijkstra算法不能求解包含负权的图;但是用矩阵来存储图的话,那么Bellman-Ford算法时间复杂度达O(n3),所以这也是一个限制。但是还有一个改良的Bellman-Ford算法,其时间复杂度只为O(n2),这个算法到后面再给出。

        下面说明下dijkstra算法和Bellman-Ford算法的求解,而dijkstra算法无法求解负权图的原因吧!请看下图(本图片来自百度文库 用户:1107905594


          我可以从这个图中及其求解过程及其结果看到,dijkstra算法在求解带负权的图的最短路径是不合理的,因为它需要找的下一个点都必须是与自己相邻的并且路径最短的一个点,所以逐步迭代下去,最终他会忽略权为负值得边,比如图中的E(v0,v1)=7>E(v0,v2),因此,根据该算法的选边原则,它将会选择边E(v0,v1),所以就导致忽略了后面的E(v1,v2)=-2的边,这样一来就误求了v0->v2的最短路径,因为min(v0->v2)=2。到目前你也许明白了为什么dijkstra算法不适用求带负权的图了。
          现在就说下Bellman-Ford算法的基本步骤和基本思想。
  • 下Bellman-Ford算法基本思想
  •  Bellman-Ford算法的基本步骤

            1、首先将所求起点s到图中的各点距离用数组dist[n]存储起来,如果两边可达,则dist[i]=Edge[s][i],否则则灵dist[i]=maxm,(maxm为一个无穷大值,根据需要设定数值),(注意:这里假设不允许顶点自身可达)。

            2、然后通过通过循环n-2次找出含有最多含有n-1条边的路径的最小路径数组path[u]=v,这个数组也是通过保存当前顶点v的最短路径前缀u。最后也是通过读取前缀得出一条路径。由于第一步将第一条边已经保存下来,所以这里只须循环n-2次就可以了。这一步很关键,因为这一步是说怎么去找出每个节点的最短路径的呢?然而,在n-2次循环中,每循环一次,他都将保存好当前节点v离始点的最短距离的前缀u,所以一维数组path[n]保存了图中所有可达节点到节点v的最短路径前缀。最后就得到结果path[n]。

           代码的编写就不写了,借别人的用一下。





本博文翻译于一百度文库用户,有侵权之处请见谅,通知本人删除。

阅读更多

没有更多推荐了,返回首页