javascript实现有向无环图中任意两点最短路径的dijistra算法

有向无环图

一个无环的有向图称做有向无环图(directed acycline praph)。简称DAG 图。DAG 图是一类较有向树更一般的特殊有向图,

dijistra算法

摘自 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

1.定义概览

Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。注意该算法要求图中不存在负权边。

问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径。(单源最短路径)

javascript实现

<html>
<body>
<script>

//有向无环图
var pages = []

//开始结点有两个后继
pages["welecome"] = [];
pages["welecome"]["nextNode"] = [];
pages["welecome"]["nextNode"][0] = "workmode"

//一个后继又有两个后继
pages["workmode"] = [];
pages["workmode"]["nextNode"] = [];
pages["workmode"]["nextNode"][0] = "WAN"
pages["workmode"]["nextNode"][1] = "WLAN"

//WAN的后继为WLAN
pages["WAN"] = [];
pages["WAN"]["nextNode"] = [];
pages["WAN"]["nextNode"][0] = "WLAN"

//WLAN的后继为终点
pages["WLAN"] = [];
pages["WLAN"]["nextNode"] = [];
pages["WLAN"]["nextNode"][0] = "OVER"

//终点
pages["OVER"] = [];
pages["OVER"]["nextNode"] = [];

/* 计算有向无环图中,指定两点之间的最短路径 */
function ComputeShortPath(map, startName, endName)
{
    //判断两个节点是否有前后继关系,第一个为前,后一个为后
    function IsSuccessor(nodeNameA, nodeNameB)
    {
        var page = pages[nodeNameA];
        var nextNodes = page["nextNode"];
        for ( var index in nextNodes )
        {
            var nextNode = nextNodes[index];
            if ( nextNode == nodeNameB )
            {
                return true;
            }
        }
        
        return false;
    }

    /* 生成权重矩阵 */
    function GenerateEdgeWeight(map)
    {
        document.write("---- Generate edgeWeightMatrix ----
") /* 记录图中各个点之间有向边的权重 */ var edgeWeightMatrix = []; for ( var nodeNameA in map ) { edgeWeightMatrix[nodeNameA] = []; for ( var nodeNameB in map ) { var isSucc = IsSuccessor(nodeNameA, nodeNameB); var weight; if ( true == isSucc ) { /* 有前后继的关系,权重设置为1 */ weight = 1; } else { /* 没有前后继的关系,权重设置为正无穷 */ weight = Number.POSITIVE_INFINITY; } edgeWeightMatrix[nodeNameA][nodeNameB] = weight; document.write("edgeWeightMatrix["+nodeNameA+"]["+nodeNameB+"]="+edgeWeightMatrix[nodeNameA][nodeNameB]+"
") } } return edgeWeightMatrix; } /* 产生Dijistra运算的数据结构 */ function GenerateDijistraDataStruct(map, startName, edgeWeightMatrix) { var dijistraJSON = { /* 已经知道最短路径集合 */ knownSet:[], /* 未知最短路径集合 */ unKnownSet:[], /* 最短特殊路径长度 */ distanceSP:[], }; /* 初始化,出发点添加到已知集合,其他添加到未知集合 */ for ( var nodeName in map ) { if ( nodeName == startName ) { dijistraJSON.knownSet.push(startName); } else { dijistraJSON.unKnownSet.push(nodeName); } } /* 初始化最短特殊路径 */ document.write("---- Generate distanceSP with startName = "+startName+" ----
") for ( var index in dijistraJSON.unKnownSet ) { var nodeName = dijistraJSON.unKnownSet[index]; dijistraJSON.distanceSP[nodeName] = edgeWeightMatrix[startName][nodeName]; document.write("distanceSP["+nodeName+"]="+dijistraJSON.distanceSP[nodeName]+"
"); } return dijistraJSON; } /* 运行最短路计算逻辑 */ function DoDijistraComputing(dijistraJSON, edgeWeightMatrix) { /* dijstra */ var loopNum = dijistraJSON.unKnownSet.length; for ( var i=0; i<loopNum; i++ ) { /* 找unKnownSet中最短特殊路径顶点 */ var minDistName = dijistraJSON.unKnownSet[0]; var minDistIndex = 0; var minDist = dijistraJSON.distanceSP[minDistName]; for ( var index in dijistraJSON.unKnownSet ) { var nodeName = dijistraJSON.unKnownSet[index]; var dist = dijistraJSON.distanceSP[nodeName]; if ( dist < minDist ) { minDist = dist; minDistName = nodeName; minDistIndex = index; } } /* 将最短特殊路径顶点,从unkownSet中删除,加入knownSet */ dijistraJSON.unKnownSet.splice(minDistIndex, 1); dijistraJSON.knownSet.push(minDistName); /* 更新 unKnownSet 中元素的 distanceSP 值 */ for ( var index in dijistraJSON.unKnownSet ) { var nodeName = dijistraJSON.unKnownSet[index]; var oldDist = dijistraJSON.distanceSP[nodeName]; var weight = edgeWeightMatrix[minDistName][nodeName]; var newDist = minDist + weight; if ( newDist < oldDist ) { dijistraJSON.distanceSP[nodeName] = newDist; } } } /* 输出看打印结果 */ document.write("---- Complete distanceSP with startName = "+startName+" ----
") for ( var index in dijistraJSON.knownSet ) { var nodeName = dijistraJSON.knownSet[index]; document.write("distanceSP["+nodeName+"]="+dijistraJSON.distanceSP[nodeName]+"
"); } return dijistraJSON; } /* 获取最短路径 */ function GetShortPath(dijistraJSON, endName) { return dijistraJSON.distanceSP[endName]; } var edgeWeightMatrix = GenerateEdgeWeight(map); var dijistraJSON = GenerateDijistraDataStruct(map, startName, edgeWeightMatrix); dijistraJSON = DoDijistraComputing(dijistraJSON, edgeWeightMatrix); var shortPath = GetShortPath(dijistraJSON, endName); document.write("---- Complete shortpath between "+startName+" and "+endName+" = "+shortPath+"----
") } ComputeShortPath(pages, "welecome", "OVER"); script> body> html>

 

计算结果截图:

最后计算结果, 中distanceSP中每一个定点的值,都是开始结点 welecome到此结点的 最短距离。

 

你可能感兴趣的:(javascript,数据结构与算法,ViewUI)