Dijkstra(迪杰斯特拉)算法-js实现

实现代码如下:

 var n = 3;
    var dis = [0];
    var mark = [];
    var arr = [];
    var inf = 9999;
    var i, j, k;
    //init
    for (i = 0; i < n; i++) {
        mark.push(1);
        arr[i] = [];
        for (j = 0; j < n; j++) {
            arr[i][j] = inf;//i->j,init 9999
        }
    }

    arr[0][1] = 3;
    arr[1][2] = -2;
    arr[0][2] = 6;

    //init dis

    dis[0] = 0;
    for (j = 1; j < arr.length; j++) {
        dis[j] = arr[0][j];
    }

    mark[0] = 0;
    for (i = 0; i < arr.length - 1; i++) {//去除源点自身,从剩下的点中选出离源点距离最小的点,因此只需进行n-1轮查找
        var min = [0, 0, inf];//src,dis,weight
        for (j = 0; j < arr.length; j++) {
            //找出最小值
            if (mark[j]) {
                if (arr[i][j] < min[2]) {
                    min = [i, j, arr[i][j]];
                }
            }
        }
        mark[min[1]] = 0;//将dis最小的点min[1]标记为选中

        for (k = 0; k < arr.length; k++) {//比较 min[1]->k + 源点到min[1]的距离dis[[min[1]]],是否比dis[k]的距离要小
            if (arr[min[1]][k] + dis[min[1]] < dis[k]) {
                dis[k] = arr[min[1]][k] + dis[min[1]];//松弛
            }

        }
    }

    console.log(dis);

迪杰斯特拉算法是求单源最短路径,思路是用一个dis数组保存源点到各点的距离(源点到自身的距离记为0),然后每次取距离最小的点,对这个点的所有出边进行松弛。
所谓松弛(relaxation),比如1->3=10,1->2->3=5,那么1->3实际上可缩短为5,这就叫做对边1->3进行了一轮松弛操作。
最近在看《啊哈!算法》,书上说迪杰斯特拉算法不能有负权边,我用js写的这个,试了一下负权边好像是可以的,只是不能有负权回路,然后看了书上的Bellman-ford算法,我觉得除了加上了负权回路的判断好像和迪杰斯特拉算法没什么区别。。。嗯,应该是我没看懂= =
我用js实现了负权回路的判断,代码如下:

var n = 3;
    var dis = [0];
    var mark = [];
    var arr = [];
    var inf = 9999;
    var i, j, k;
    //init
    for (i = 0; i < n; i++) {
        mark.push(1);
        arr[i] = [];
        for (j = 0; j < n; j++) {
            arr[i][j] = inf;//i->j,init 9999
        }
    }

    arr[0][1] = 3;
    arr[1][2] = 2;
    arr[0][2] = 6;
    arr[2][0] = -1;

    //init dis

    dis[0] = 0;
    for (j = 1; j < arr.length; j++) {
        dis[j] = arr[0][j];
    }

    mark[0] = 0;
    for (i = 0; i < arr.length - 1; i++) {//去除源点自身,从剩下的点中选出离源点距离最小的点,因此只需进行n-1轮查找
        var min = [0, 0, inf];//src,dis,weight
        for (j = 0; j < arr.length; j++) {
            //找出最小值
            if (mark[j]) {
                if (arr[i][j] < min[2]) {
                    min = [i, j, arr[i][j]];
                }
            }
        }
        mark[min[1]] = 0;//将dis最小的点min[1]标记为选中

        for (k = 0; k < arr.length; k++) {//比较 min[1]->k + 源点到min[1]的距离dis[[min[1]]],是否比dis[k]的距离要小
            if (arr[min[1]][k] + dis[min[1]] < dis[k]) {
                dis[k] = arr[min[1]][k] + dis[min[1]];//松弛
                arr[0][k] = dis[k];//同时修改数组值,用于判断是否有负权回路
            }

        }
    }

    console.log(dis);

    /*检测是否有负权回路*/
    for (i = 0; i < arr.length; i++) {
        for (j = 0; j < arr.length; j++) {
            if (arr[0][j] > dis[i] + arr[i][j]) {
                console.log("有负权回路", "0->", i, "->", j);
                break;
            }
        }
    }
    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/qq_24734285/article/details/52918714
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞