【问题标题】:Finding the shortest distance between two nodes寻找两个节点之间的最短距离
【发布时间】:2019-03-11 09:33:51
【问题描述】:

我发现 Dijkstra 的算法并将其实现到我创建的图表中 - 它显示了我当地的地图

代码工作正常,但我希望它显示它访问的所有节点,以便从源节点到达位置节点。例如:如果我将源节点设置为 1(Banstead),将位置节点设置为 4(Whteleafe) - 我希望它可能将它访问的节点存储在一个数组中,如 Array = {1,2,4} Any想法?我想把它放在一个 FXML 文件中,并将节点作为椭圆并用线连接它们 - 但为了做到这一点,我需要存储访问过的节点的值。

package dijkstras;

public class Dijkstras {

    static class createGraph{
        int vertices;
        int matrix[][];

        public createGraph(int vertex){

            this.vertices = vertex;
            matrix = new int[vertex][vertex];
        }

        public void edge(int source, int destination, int weight){

            matrix[source][destination] = weight;
            matrix[destination][source] = weight;
        }

        int getMinVertex(boolean [] mst, int [] key){
            int minKey = Integer.MAX_VALUE;
            int vertex = -1;
            for (int i = 1; i < vertices; i++) {
                if(mst[i]==false && minKey>key[i]){
                    minKey = key[i];
                    vertex =i;
                }
            }

            return vertex;  
        }

        public void dijkstras(int sourceVertex){
            boolean[] spt = new boolean[vertices];
            int [] distance = new int[vertices];
            int infinity = Integer.MAX_VALUE;

            //setting all distances to infinity
            for(int i=1; i<vertices; i++){
                distance[i] = infinity;
            }

            //test for starting vertext = 1
            distance[sourceVertex] = 1;

            //create tree
            for(int i=1; i<vertices; i++){

                int vertexU = getMinVertex(spt, distance);

                spt[vertexU] = true;   
                //go through all possible paths adjacent to vertex
                for(int vertexV=1; vertexV<vertices; vertexV++){
                    //check if edge between Vu and Vv exists
                    if(matrix[vertexU][vertexV]>0){

                        //checks vertexV exists and if distance is not infinite
                        if(spt[vertexV]==false && matrix[vertexU][vertexV]!=infinity){

                            int newKey = matrix[vertexU][vertexV] + distance[vertexU];
                            if(newKey<distance[vertexV])
                                distance[vertexV] = newKey;
                        }
                    }
                }
            }

            System.out.println();      
            printDijkstras(sourceVertex, distance);
        }

        public void printDijkstras(int sourceVertex, int [] key){
            System.out.println("Dijkstra Algorithm:");
            int LocationOfChosenUser = 10;  
            System.out.println("Source Vertex: "+ sourceVertex + " to " +
              LocationOfChosenUser + " distance: " + (key[LocationOfChosenUser]-1));
        }
    }

    public static void graph() {
       int vertices = 18;
       createGraph graph = new createGraph(vertices);
       int sourceVertex = 8;
       //adding all nodes
       graph.edge(1,2,4);   graph.edge(1,17,3); 
       graph.edge(2,1,4);   graph.edge(2,4,4);   graph.edge(2,10,5); 
       graph.edge(3,4,1);   graph.edge(3,6,5);   graph.edge(3,5,2);
       graph.edge(4,2,4);   graph.edge(4,3,1);   graph.edge(4,5,2); 
       graph.edge(5,4,2);   graph.edge(5,3,2);   graph.edge(5,6,3);  graph.edge(5,9,4);  graph.edge(5,10,5); 
       graph.edge(6,3,5);   graph.edge(6,5,3);   graph.edge(6,7,2);  graph.edge(6,9,2);
       graph.edge(7,6,2);   graph.edge(7,8,5);   
       graph.edge(8,7,5);   graph.edge(8,9,4);   graph.edge(8,12,5);
       graph.edge(9,5,4);   graph.edge(9,8,4);   graph.edge(9,11,5); graph.edge(9,6,2); 
       graph.edge(10,2,5);  graph.edge(10,5,5);  graph.edge(10,13,1);graph.edge(10,14,3); graph.edge(10,17,6);
       graph.edge(11,9,5);  graph.edge(11,12,3); graph.edge(11,13,3);
       graph.edge(12,8,5);  graph.edge(12,11,3); graph.edge(12,15,4);
       graph.edge(13,11,3); graph.edge(13,10,1); graph.edge(13,14,2);
       graph.edge(14,10,3); graph.edge(14,13,2); graph.edge(14,16,6); graph.edge(14,15,6);
       graph.edge(15,12,4); graph.edge(15,14,5); graph.edge(15,16,9); 
       graph.edge(16,15,9); graph.edge(16,17,1); graph.edge(16,14,6);
       graph.edge(17,1,3);  graph.edge(17,16,1);

       graph.dijkstras(sourceVertex);
    }
    public static void main(String[] args){
        graph();
    }
}

如您所见,我将 sourceVertex 设置为 8,将 LocationVertex (LocationOfChosenUser) 设置为 10。输出如下所示:

 Dijkstra Algorithm:
Source Vertex: 8 to 10 distance: 12

【问题讨论】:

    标签: java matrix dijkstra


    【解决方案1】:

    最简单的方法是跟踪每个节点的前任。当您到达末端节点时,您可以回溯以找出您来自哪里。

    添加初始化

    int [] comeFrom = new int[vertices];
    

    改变

    if(newKey<distance[vertexV])
        distance[vertexV] = newKey;
    

    if(newKey<distance[vertexV]) {
        distance[vertexV] = newKey;
        comeFrom[vertexV] = vertexU;
    }
    

    打印出来的时候

    List<Integer> path = new ArrayList();
    int pos = LocationOfChosenUser;
    
    while(pos != sourceVertex) {
       path.add(pos);
       pos = comeFrom[pos];
    }
    
    for (int i=path.size()-1; i>=0; i--) {
       System.out.print(path.get(i));
       if (i > 0) System.out.print(" -> ");
    }
    

    【讨论】:

      【解决方案2】:

      每次更新距离数组时,都需要跟踪到达节点的路径。这可以通过多种方式完成,我推荐一个数组,用于存储距离数组中为实现距离所采取的步骤。

      distance[vertexV] = newKey;
      lastStep[vertexV] = vertexU;
      

      算法完成后,您可以遍历从目的地返回起点的路径。基本上,你这样做:

      int location = LocationOfChosenUser;
      System.out.print(LocationOfChosenUser);
      while (location != sourceVertex) {
          location = lastStep[LocationOfChosenUser];
          System.out.print(" <- " + location);
      }
      System.out.println();
      

      此顺序为您提供相反的顺序(因此,&lt;- 箭头)。您将如何存储数字并将其反转留给您作为练习。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-09-18
        • 2018-03-01
        • 1970-01-01
        • 2021-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多