1. 程式人生 > >JS實現最短路徑之弗洛伊德(Floyd)算法

JS實現最短路徑之弗洛伊德(Floyd)算法

arc 技術 func tst rap 分享圖片 char 參考文獻 med

弗洛伊德算法是實現最小生成樹的一個很精妙的算法,也是求所有頂點至所有頂點的最短路徑問題的不二之選。時間復雜度為O(n3),n為頂點數。

  精妙之處在於:一個二重初始化,加一個三重循環權值修正,完成了所有頂點至所有頂點的的最短路徑計算,代碼及其簡潔

JS實現:

//定義鄰接矩陣
let Arr2 = [
    [0, 1, 5, 65535, 65535, 65535, 65535, 65535, 65535],
    [1, 0, 3, 7, 5, 65535, 65535, 65535, 65535],
    [5, 3, 0, 65535, 1, 7, 65535, 65535, 65535],
    [
65535, 7, 65535, 0, 2, 65535, 3, 65535, 65535], [65535, 5, 1, 2, 0, 3, 6, 9, 65535], [65535, 65535, 7, 65535, 3, 0, 65535, 5, 65535], [65535, 65535, 65535, 3, 6, 65535, 0, 2, 7], [65535, 65535, 65535, 65535, 9, 5, 2, 0, 4], [65535, 65535, 65535, 65535, 65535, 65535, 7, 4, 0], ] let numVertexes
= 9, //定義頂點數 numEdges = 15; //定義邊數 // 定義圖結構 function MGraph() { this.vexs = []; //頂點表 this.arc = []; // 鄰接矩陣,可看作邊表 this.numVertexes = null; //圖中當前的頂點數 this.numEdges = null; //圖中當前的邊數 } let G = new MGraph(); //創建圖使用 //創建圖 function createMGraph() { G.numVertexes = numVertexes; //設置頂點數 G.numEdges = numEdges; //
設置邊數 //錄入頂點信息 for (let i = 0; i < G.numVertexes; i++) { G.vexs[i] = ‘V‘ + i; //scanf(‘%s‘); //ascii碼轉字符 //String.fromCharCode(i + 65); } console.log(G.vexs) //打印頂點 //鄰接矩陣初始化 for (let i = 0; i < G.numVertexes; i++) { G.arc[i] = []; for (j = 0; j < G.numVertexes; j++) { G.arc[i][j] = Arr2[i][j]; //INFINITY; } } console.log(G.arc); //打印鄰接矩陣 } let Pathmatirx = []; //二維數組 表示頂點到頂點的最短路徑權值和的矩陣 let ShortPathTable = []; //二維數組 表示對應頂點的最小路徑的前驅矩陣 function Floyd() { let w, k; for (let v = 0; v < G.numVertexes; ++v) { //初始化 Pathmatirx ShortPathTable Pathmatirx[v] = []; ShortPathTable[v] = []; for (let w = 0; w < G.numVertexes; ++w) { ShortPathTable[v][w] = G.arc[v][w]; Pathmatirx[v][w] = w; } } for (let k = 0; k < G.numVertexes; ++k) { for (let v = 0; v < G.numVertexes; ++v) { for (let w = 0; w < G.numVertexes; ++w) { if (ShortPathTable[v][w] > (ShortPathTable[v][k] + ShortPathTable[k][w])) { //如果經過下標為k頂點路徑比原兩點間路徑更短,當前兩點間權值設為更小的一個 ShortPathTable[v][w] = ShortPathTable[v][k] + ShortPathTable[k][w]; Pathmatirx[v][w] = Pathmatirx[v][k]; //路徑設置經過下標為k的頂點 } } } } } function PrintAll() { for (let v = 0; v < G.numVertexes; ++v) { for (let w = v + 1; w < G.numVertexes; w++) { console.log(‘V%d-V%d weight: %d‘, v, w, ShortPathTable[v][w]); k = Pathmatirx[v][w]; console.log(‘ Path: %d‘, v); while (k != w) { console.log(‘ -> %d‘, k); k = Pathmatirx[k][w]; } console.log(‘ -> %d‘, w); } } } createMGraph(); Floyd(); PrintAll();

運行結果:(結果太長只截取不分)

技術分享圖片

求最短路徑的兩個算法(迪傑斯特拉算法和弗洛伊德算法),對有向圖依然有效,因為者的差異僅僅是鄰接矩陣是否對稱而已

參考文獻: 程傑 《大話設計模式》

JS實現最短路徑之弗洛伊德(Floyd)算法