最短路径

package org.exam.ch14.path;

/**
 * Created by xin on 15.10.22.
 */
class DistPar {             // distance and parent.items stored in sPath array
    public int distance;   // distance from start to this vertex
    public int parentVert; // current parent of this vertex

    public DistPar(int pv, int d) {
        distance = d;
        parentVert = pv;
    }
}
class Vertex {
    public char label;        // label (e.g. 'A')
    public boolean isInTree;

    public Vertex(char lab) {
        label = lab;
        isInTree = false;
    }
}
class Graph {
    private final int MAX_VERTS = 20;
    private final int INFINITY = 1000000;//足够大的值模拟看作无穷大
    private Vertex vertexList[]; // list of vertices
    private int adjMat[][];      // adjacency matrix
    private int nVerts;          // current number of vertices
    private int nTree;           // number of verts in tree
    private DistPar[] sPath;     // array for shortest-path data
    private int currentVert;     // current vertex
    private int startToCurrent;  // distance to currentVert

    public Graph() {
        vertexList = new Vertex[MAX_VERTS];
        // adjacency matrix
        adjMat = new int[MAX_VERTS][MAX_VERTS];

        for (int j = 0; j < MAX_VERTS; j++) {     //初始化邻接距离
            for (int k = 0; k < MAX_VERTS; k++) {  //
                adjMat[j][k] = INFINITY;     //都设为无穷大
            }
        }
        sPath = new DistPar[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) {// find all shortest paths
        vertexList[startTree].isInTree = true;从顶点startTree开始,并将顶点加入到树中
        nTree = 1;                     //树中顶点的个数

        for(int j=0; j<nVerts; j++){//transfer row of distances from adjMat to sPath
            int tempDist = adjMat[startTree][j];
            sPath[j] = new DistPar(startTree, tempDist);
        }

        while (nTree < nVerts) {//直到所有顶点都已放入树
            int indexMin = getMin();    //从当前顶点到各顶点获取最小路径,将这个顶点的索引返回
            int minDist = sPath[indexMin].distance;//获取当前顶点到此顶点的距离
            if (minDist == INFINITY) {//if all infinite or in tree,
                //System.out.println("There are unreachable vertices");
                break;                   // sPath is complete
            } else {                     //将此顶点置为当前顶点
                currentVert = indexMin;  // to closest vert
                startToCurrent = minDist;// minimum distance from startTree is to currentVert, and is startToCurrent
            }
            //将当前顶点放入树中
            vertexList[currentVert].isInTree = true;
            nTree++;
            //将此顶点置为当前顶点后,调校最小距离,完成一次循环
            adjust_sPath();
        }
        displayPaths();                //打印显示最终结果

        nTree = 0;                     //重置。清除树
        for(int j=0; j<nVerts; j++) {
            vertexList[j].isInTree = false;
        }
    }

    private void displayPaths() {//显示格式如:   A=inf(A) B=50(A) C=100(D) D=80(A) E=140(C)
        for (int j = 0; j < nVerts; j++){
            System.out.print(vertexList[j].label + "=");
            if (sPath[j].distance == INFINITY) {
                System.out.print("inf");
            } else {
                System.out.print(sPath[j].distance);
            }
            char parent = vertexList[sPath[j].parentVert].label;
            System.out.print("(" + parent + ") ");
        }
        System.out.println("");
    }

    private void adjust_sPath() { // adjust values in shortest-path array sPath
        int column = 1;                //跳过起点(这个column可看作表14。2的列,而每一步可看作是表的行),column是从0开始的
        while (column < nVerts) {        //一个一个顶点去迭代
            if (vertexList[column].isInTree) {//如果此顶点已在树中,跳过
                column++;
                continue;
            }
            int currentToFringe = adjMat[currentVert][column];//计算currentVert顶点到column顶点的距离
            int startToFringe = startToCurrent + currentToFringe;//从起点到column顶点的距离
            int sPathDist = sPath[column].distance;//从sPath数组获取对应起点到column顶点的距离
            if (startToFringe < sPathDist) {    // 如果startToFringe距离是更小,重新保存到sPath数组
                sPath[column].parentVert = currentVert;
                sPath[column].distance = startToFringe;
            }
            column++;//迭代下一个顶点,看一下是否有必要调整
        }
    }

    private int getMin() {//get entry from sPath with minimum distance
        int minDist = INFINITY;        //assume minimum
        int indexMin = 0;
        for (int j = 1; j < nVerts; j++) {   // 对于每个顶点,它不在树中,并且与前一个顶点的距离比较都还要小,就更新下最小值
            if (!vertexList[j].isInTree && sPath[j].distance < minDist) {
                minDist = sPath[j].distance;
                indexMin = j;
            }
        }
        return indexMin;//返回最小距离顶点的索引
    }
}
public class App {
    public static void main(String[] args) {
        Graph theGraph = new Graph();
        theGraph.addVertex('A');     // 0  (start)
        theGraph.addVertex('B');     // 1
        theGraph.addVertex('C');     // 2
        theGraph.addVertex('D');     // 3
        theGraph.addVertex('E');     // 4

        theGraph.addEdge(0, 1, 50);  // AB 50
        theGraph.addEdge(0, 3, 80);  // AD 80
        theGraph.addEdge(1, 2, 60);  // BC 60
        theGraph.addEdge(1, 3, 90);  // BD 90
        theGraph.addEdge(2, 4, 40);  // CE 40
        theGraph.addEdge(3, 2, 20);  // DC 20
        theGraph.addEdge(3, 4, 70);  // DE 70
        theGraph.addEdge(4, 1, 50);  // EB 50

        System.out.println("Shortest paths");
        for (int i = 0; i < 5; i++) {
            System.out.print(i+":");
            theGraph.path(i);
        }
        System.out.println();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值