弗洛伊德算法求图的最短路径 JavaScript实现
核心思想我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j)
【实现】
// 打印矩阵
function print(v) {
for (var i = 0, l1 = v.length; i < l1; i++) {
var str = "";
for (var j = 0, l2 = v[i].length; j < l2; j++) {
str += (v[i][j] == Infinity ? ' ' + '∞' : v[i][j] < 10 ? " " + v[i][j] : v[i][j]) + "(" + i + "," + j + ") ";
}
console.log(str);
}
printSep();
}
function printSep() {
console.log("-------------------------");
}
// 输出信息:最短距离+详细路径
function getInfo(i, j) {
var p = n[i][j];
var path = i;
while (p != j) {
path += "→" + p;
p = n[p][j];
}
path += "→" + j;
console.log("最短距离:" + v[i][j]);
console.log("路径:" + path);
}
// 录入的信息,值为权值
var m = Infinity;
var v = [
[0, 12, m, m, m, 16, 14],
[12, 0, 10, m, m, 7, m],
[m, 10, 0, 3, 5, 6, m],
[m, m, 3, 0, 4, m, m],
[m, m, 5, 4, 0, 2, 8],
[16, 7, 6, m, 2, 0, 9],
[14, m, m, m, 8, 9, 0]
];
var l = v.length;
// 中转点矩阵
var n = [];
// 初始化中转点矩阵。
for (var i = 0; i < l; i++) {
n[i] = [];
for (var j = 0; j < l; j++) {
n[i][j] = j;
}
}
// 核心算法 三层循环
for (k = 0; k < l; k++) { // 中间点
for (s = 0; s < l; s++) { // 起点
for (e = 0; e < l; e++) { // 终点
if (v[s][e] > v[s][k] + v[k][e]) {
v[s][e] = v[s][k] + v[k][e];
n[s][e] = n[s][k];
}
}
}
}
print(v);
print(n);
getInfo(0, 3);