最短路径问题—Dijkstra算法及其实现

《最短路径问题—Dijkstra算法及其实现》

《最短路径问题—Dijkstra算法及其实现》

shortPath数组和DistantanceParent类。
最短路径算法的关键数据结构是一个数组,它保持了从原点到其他顶点(终点的最短路径)。在算法的执行过程中这个距离是变化的,直到最后,它存储了从原点开始真正的最短距离,在程序中,这个数组叫做shortPath[]. 也就是最短路径

不仅应该记录从原点到终点的最短路径,还应该记录走过的路径。幸运的是,不必要明确记录整个路径,只需要记录终点的父节点。父节点就是达到终点前的节点。有几种方法保存父节点顶点的信息,本程序选用了把父节点和距离放在一起的方法,并把结果的对象放在shortPath[]数组中。这个对象类叫做DistanceParent (距离-父节点)。


class DistanceParent  //distance and parent
{
    public  int  distance ;//distance from start to this vertex
    public  int parentVert; // current parent of this vertex

    //.............................
    public  DistanceParent(int pv, int d)
    {
        distance = d;
        parentVert = pv;
    }

}

//.............................................
class Vertex
{
    public  char  label; // label,like 'A'
    public  boolean  isInTree;
    //...............................

    public  Vertex(char  lab)
    {
        label = lab;
        isInTree = false;
    }
}

//.....................................
class Graph
{
    private  final  int  MAX_VERTS = 20;
    private  final  int INFINITY = 10000000; //用一个很大的数代表无穷大
    private Vertex vertexList[] ; //list of vertices
    private  int  adjMat[][] ; // 邻接矩阵
    private  int  nVerts;  //当前节点数
    private  int  nTree ; //number of verts in tree
    private  DistanceParent   shortPath[] ;  //保存最短路径的数组
    private  int  currentVert ; //当前顶点
    private  int  startToCurrent ;//到当前顶点的距离

    //.......................................................

    public  Graph()
    {
        vertexList  = new  Vertex[MAX_VERTS];
        adjMat = new int[MAX_VERTS][MAX_VERTS];
        nVerts = 0;
        nTree = 0;
        for(int j = 0;j<MAX_VERTS;j++)
            for(int k=0;k<MAX_VERTS;k++)
                adjMat[j][k] = INFINITY;
        shortPath = new DistanceParent[MAX_VERTS];

    }
    //.............................................

    public void addVertex(char  lab)
    {
        vertexList[nVerts++] = new Vertex(lab);
    }

    //......................................
    public  void addEdge(int  start,int  end,int  weight)
    {
        adjMat[start][end]  = weight;
    }

    //.........................
    public  void  path()
    {
        int  startTree = 0;  //从第0格节点开始
        vertexList[startTree].isInTree = true;  // put int tree
        nTree = 1;

        for(int  j = 0;j<nVerts;j++)
        {
            int  tempDistance = adjMat[startTree][j];
            shortPath[j] = new DistanceParent(startTree, tempDistance);
            //until all vertices are in the tree
        }
        /* * 1.选择shortPath[] 数组中的最小距离 * 2.把对于的顶点放入树中,这个点变成当前顶点 ,currentVert * 3.根据currentVert的变化,更新所有的shortPath[]数组内容 */

        while(nTree <nVerts)
        {
            int indexMin  = getMin();//从shortPath【】数组中获得最短路径
            int  minDintance = shortPath[indexMin].distance;

            if(minDintance == INFINITY)
            {
                System.out.println("节点不可到达");
                break;
            }
            else
            {  // reset currentVert
                currentVert = indexMin;   //to closest vert
                startToCurrent =shortPath[indexMin].distance;

            }
            //put current vertex in tree
            vertexList[currentVert].isInTree= true;
            nTree++;
            adjust_shortPath();  //更新最短路径数组
        }
        displayPaths(); //显示最短路径数组内容

            nTree = 0; // clear tree
            for (int i = 0; i < nVerts; i++)
            vertexList[i].isInTree = false;
    }

    //........................................
    public  int  getMin()
    {
        int minDistance = INFINITY;
        int  indexMin = 0;
        for(int j = 1;j<nVerts;j++)
        {
            if(!vertexList[j].isInTree &&shortPath[j].distance <minDistance)
            {
                minDistance = shortPath[j].distance;
                indexMin = j;
            }
        }
        return indexMin;
    }

    /* * adjust_shortPath()方法更新shortPath[]数组 * 当程序被调用时,currentVert刚被放入树中, * startToCurrent时shortPath[]数组的当前项。adjust_shortPath()方法检查shortPath[] * 中的每一项,它使用循环计数器column依次指向每个顶点。 * 对于shortPath[]数组的每一个项,如果对应顶点不在树中,它做三件事: * 1.把到当前顶点的距离(存在startToCurrent变量中)加到从currentVert顶点到column顶点的距离上 * 结果叫做startToFringe * 2.把startToFringe与shortPath[]数组的当前项进行比较 * 3.如果startToFringe更小,就替换当前项 * * 这就是Dijkstra算法的核心,它让shortPath[]数组总是存储从原点到所有已知顶点的最短路径。 */
    public  void  adjust_shortPath()
    {
        // adjust values in shortest-path array shortPath
        int colunm = 1; //skip starting vertex
        while(colunm < nVerts)
        {
            //if this column vertex already in tree skip it
            if(vertexList[colunm].isInTree)
            {
                colunm++;
                continue;
            }
            //calculate distance for one shortPath entry
            //get edge from currentVert to column
            int currentToFringe = adjMat[currentVert][colunm];
            //add distance from start
            int  startToFringe =startToCurrent +currentToFringe;
            //get distance of current shortPath entry
            int shortPathDistance = shortPath[colunm].distance;

            //compare distance from start with shortPath entry
            if(startToFringe  <shortPathDistance)  //update 
            {
                shortPath[colunm].parentVert = currentVert;
                shortPath[colunm].distance = startToFringe;
            }
            colunm++;
        }
    }

    //..........................
    public  void  displayPaths()
    {
        for(int j = 0;j<nVerts;j++)
        {
            System.out.print(vertexList[j].label + "=");
            if(shortPath[j].distance == INFINITY)
                System.out.print("inf");
            else
                System.out.print(shortPath[j].distance);
            char  parent = vertexList[shortPath[j].parentVert].label;
            System.out.print(" ("+parent +") ");
        }
        System.out.println(" ");
    }
}


////////////////////////////////////////////
class  PathApp
{
    public static void main(String[] args)
    {
        Graph   theGraph = new Graph();

        theGraph.addVertex('A'); //0
        theGraph.addVertex('B'); //1
        theGraph.addVertex('C'); //2
        theGraph.addVertex('D');  //3
        theGraph.addVertex('E'); //4

        theGraph.addEdge(0, 1, 50);
        theGraph.addEdge(0, 3, 80);
        theGraph.addEdge(1, 2, 60);
        theGraph.addEdge(1, 3, 90);
        theGraph.addEdge(2, 4, 40);
        theGraph.addEdge(3, 2, 20);
        theGraph.addEdge(3, 4, 70);
        theGraph.addEdge(4, 1, 50);

        System.out.println("最短路径:");
        theGraph.path();
        System.out.println();
    }
}







    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/zlz18225318697/article/details/53422848
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞