4

I found and implemented Dijkstra's algorithm into a graph that I had created - which shows a map of my local area enter image description here

The code works fine but I want it to display all the nodes that it visited in order to get to the location Node from the source node. So for example: if I set the source node at 1 (Banstead), and the location node to 4 (Whteleafe) - I want it to perhaps store in an array the nodes it visited like Array = {1,2,4} Any ideas? I want to put this on an FXML file and have the nodes as ellipses and connecting them with lines - but in order to do so I need to store that values of the nodes visited.

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();
    }
}

As you can see I set the sourceVertex to 8 and the LocationVertex (LocationOfChosenUser) to 10. and the output looks something like this:

 Dijkstra Algorithm:
Source Vertex: 8 to 10 distance: 12
kleopatra
  • 51,061
  • 28
  • 99
  • 211

2 Answers2

1

Easiest way of doing this is to just keep track of the predecessors of each node. When you've reached the end node you can then backtrack to find out where you came from.

Add initialization

int [] comeFrom = new int[vertices];

Change

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

to

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

and when printing out

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(" -> ");
}
David Narum
  • 312
  • 2
  • 3
0

Every time you update your distance array, you need to keep track of what path was taken to reach the node. This can be done several ways, and I recommend an array that stores which step was taken to achieve the distance in the distance array.

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

When the algorithm is done, you can then traverse the path from the destination back to the start. Basically, you do this:

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

This order gives you the reverse order (therefore, the <- arrow). How you would store the numbers and reverse it is left as an exercise for you.

T Tse
  • 786
  • 7
  • 19