两者在负权问题上不是很好,最好只处理正值,Dijkstra算法对负权毫无办法,但是Floyd算法不能处理出现负环的东西。。。
Dijkstra算法的话,为了方便,我认为从i到i点不可达;百部百科解释挺好,那个堆优化挺好的
Floyd算法百部百科也不错,都是老算法了,哪都有资料
博客园这位筒子的写得很好 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html
Mathematica下的代码【我也觉得mathematica写很诡异。。。】
(*Dijkstra算法,其思想和Prim有点像,输出的是每个点的前向节点*) Dijkstra[tu_, dian_, point_] := Module[ {dis = tu[[point]], pre = Table[point, {i, 1, dian}], diannum = dian, visin = Table[False, {i, 1, dian}], k, lval, mindis, flag = True}, visin[[point]] = True; k = point; While[diannum != 0, mindis = Infinity; Do[ If[visin[[i]] == False && dis[[i]] < mindis, mindis = dis[[i]]; k = i] , {i, 1, dian}]; If[mindis == Infinity, flag = True; Break[]]; diannum--; visin[[k]] = True; Do[ If[visin[[j]], Continue[]]; lval = tu[[k]][[j]] + dis[[k]]; If[lval < dis[[j]], dis[[j]] = lval; pre[[j]] = k] , {j, 1, dian}] ]; pre ]
Input: tuer = {{INF, 7, INF, 5, INF, INF, INF}, {7, INF, 8, 9, 7, INF, INF}, {INF, 8, INF, INF, 5, INF, INF}, {5, 9, INF, INF, 15, 6, INF}, {INF, 7, 5, 15, INF, 8, 9}, {INF, INF, INF, 6, 8, INF, 11}, {INF, INF, INF, INF, 9, 11, INF}} Dijkstra[tuer, 7, 1] Out: {1, 1, 2, 1, 2, 4, 6}
(*Floyd算法,打印输出了长度,函数输出前节点*) Floyd[tu_, dian_] := Module[ {path = Table[-1, {i, 1, dian}, {j, 1, dian}], Dis = tu, lenn}, Do[ Do[ Do[ lenn = Dis[[i, k]] + Dis[[k, j]]; If[Dis[[i, j]] > lenn, path[[i, j]] = k; Dis[[i, j]] = lenn] , {k, 1, dian}] , {j, 1, dian}] , {i, 1, dian}]; Print[Dis]; path ]
Input: tuer = {{INF, 7, INF, 5, INF, INF, INF}, {7, INF, 8, 9, 7, INF, INF}, {INF, 8, INF, INF, 5, INF, INF}, {5, 9, INF, INF, 15, 6, INF}, {INF, 7, 5, 15, INF, 8, 9}, {INF, INF, INF, 6, 8, INF, 11}, {INF, INF, INF, INF, 9, 11, INF}} Floyd[tuer, 7] During evaluation of Input: {{0,7,15,5,14,11,22},{7,0,8,9,7,15,16},{15,8,0,17,5,13,14},{5,9,17,0,14,6,17},{14,7,5,14,0,8,9},{11,15,13,6,8,0,11},{22,16,14,17,9,11,0}} Out: {{-1, -1, 2, -1, 2, 4, 6}, {-1, -1, -1, -1, -1, 4, 5}, {2, -1, -1, 2, -1, 5, 5}, {-1, -1, 2, -1, 6, -1, 6}, {2, -1, -1, 6, -1, -1, -1}, {4, 4, 5, -1, -1, -1, -1}, {6, 5, 5, 6, -1, -1, -1}}