SEO知识:福特算法

如何证明Ford-Fulkerson网络流算法的正确性

如题,谁知道呀。

Bellman-Ford算法的算法流程

如题,谁知道呀。


算法大致流程是用一个队列来进行维护。 初始时将源加入队列。 每次从队列中取出一个元素,并对所有与他相邻的点进行松弛,若某个相邻的点松弛成功,则将其入队。 直到队列为空时算法结束。 分析 Bellman-Ford算法,不难看出,外层循环(迭代次数)|v|-1实际上取得是上限。由上面对算法正确性的证明可知,需要的迭代遍数等于最短路径树的高度。如果不存在负权回路,平均情况下的最短路径树的高度应该远远小于 |v|-1,在此情况下,多余最短路径树高的迭代遍数就是时间上的浪费,由此,可以依次来实施优化。
从细节上分析,如果在某一遍迭代中,算法描述中第7行的松弛操作未执行,说明该遍迭代所有的边都没有被松弛。可以证明(怎么证明?):至此后,边集中所有的边都不需要再被松弛,从而可以提前结束迭代过程。这样,优化的措施就非常简单了。
设定一个布尔型标志变量 relaxed,初值为false。在内层循环中,仅当有边被成功松弛时,将 relaxed 设置为true。如果没有边被松弛,则提前结束外层循环。这一改进可以极大的减少外层循环的迭代次数。优化后的 bellman-ford函数如下。 functionbellmanford(s:longint):boolean;beginfori:=1tonvdod[i]:=max;d[s]:=0;fori:=1tonv-1dobeginrelaxed:=false;forj:=1TOnedoif(d[edges[j].s]<>max)and(d[edges[j].e]>d[edges[j].s]+edges[j].w)thenbegind[edges[j].e]:=d[edges[j].s]+edges[j].w;relaxed:=true;end;ifnotrelaxedthenbreak;end;fori:=1tonedoifd[edges[j].e]>d[edges[j].s]+edges[j].wthenexit(false);exit(true);end;这样看似平凡的优化,会有怎样的效果呢?有研究表明,对于随机生成数据的平均情况,时间复杂度的估算公式为
1.13|E| if |E|<|V|
0.95*|E|*lg|V| if |E|>|V|
优化后的算法在处理有负权回路的测试数据时,由于每次都会有边被松弛,所以relaxed每次都会被置为true,因而不可能提前终止外层循环。这对应了最坏情况,其时间复杂度仍旧为O(VE)。
优化后的算法的时间复杂度已经和用二叉堆优化的Dijkstra算法相近了,而编码的复杂程度远比后者低。加之Bellman-Ford算法能处理各种边值权情况下的最短路径问题,因而还是非常优秀的。

文章发布时间与标签:

更新时间:2022-05-24 17:12:33
标签: bellman ford算法图解 贝尔曼福特算法图解 福特富尔克森算法百度百科 最短路ford算法过程图解 贝尔曼福特算法 bellmanford算法

推荐的SEO知识: