3

This is the implementation of Djikstra algorithm in java i have followed from book Introduction to Algorithms.But the results are not accurate in some cases.For the graph below,the output is showing the minimum distance of vertex F from source vertex A as 16,which actually is 12.I am fairly new in algorithm,so any suggestions in improvement in code is welcome. enter image description here Graph

The code of program is:

Graph.Java

package Djikstra;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import Djikstra.Vertex;


public class Graph {
  Vertex[] vertexes;


  public Graph(String file) throws FileNotFoundException{
      Scanner sc = new Scanner(new File(file));
      vertexes=new Vertex[sc.nextInt()];

      for (int v = 0; v < vertexes.length; v++){
        vertexes[v] = new Vertex(sc.next());
      }

        while (sc.hasNext()) {
        int v1= indexForName(sc.next());     //read source vertex
        String destination=sc.next();        //read destination vertex 

        int w=sc.nextInt();                  //read weight of the edge


        vertexes[v1].neighbours.put(destination, w);   //put the edge adjacent to source vertex
        }
        sc.close();
  }

  public int indexForName(String name) {
    for (int v = 0; v < vertexes.length; v++) {
        if (vertexes[v].id.equals(name))
            return v;
    }
    return -1;
}

}

Dijkstra.java

package Djikstra;
import Djikstra.Graph;
import java.io.FileNotFoundException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;

public class Dijkstra {

   Graph graph;;

    public Dijkstra(String file) throws FileNotFoundException{
        graph = new Graph(file);
    }

    public void initialiseSingleSource(Graph G,int s){  //set min distance    of all vertex to infinite and parent to null
         for(Vertex v:G.vertexes){
             v.d=1000;
             v.p=null;
         }
         G.vertexes[s].d=0;   //set min distance of source to 0
     }

    public void relax(Vertex u,Vertex v,int weight){  
        if(v.d>(u.d + weight)){
            v.d=u.d+weight;
            v.p=u;
        }
    }

    public int weightFunc(Graph G,Vertex u,Vertex v){   //to get weight of an edge from vertex u to v
        int weight=u.neighbours.get(v.id);
        return weight;
    }

    public class VertexComparator implements Comparator<Vertex>{    //min priority queue keyed by their d(min distance from source) values

        @Override
        public int compare(Vertex v1, Vertex v2) {
        return (v1.d-v2.d);
        }
    }

    public int indexForName(Graph G,String name) {      //to get index from the id of vertex
        for (int v = 0; v < G.vertexes.length; v++) {
            if (G.vertexes[v].id.equals(name))
                return v;
        }
        return -1;
    }

    public Set<Vertex> dijkstraAlgo(Graph G,int s){
        initialiseSingleSource(G,s);
        Set<Vertex> set=new HashSet<Vertex>();   //intitially empty set of vertexes

        Queue<Vertex> Q=new PriorityQueue<Vertex>(10,new VertexComparator());   //min priority queue

        for(Vertex v:G.vertexes)            //add all vertexes to priority queue
             Q.add(v);

        while(Q.size()!=0){
            Vertex u=Q.poll();        //extract vertex which have min  distance in priority queue
            set.add(u);               //add that vertex to set
            for(String vertexId:u.neighbours.keySet()){     //see neighbours of vertex extracted
                int vertexNum=indexForName(G,vertexId);      //get index for neighbour vertex in vertexes array
                Vertex v=G.vertexes[vertexNum];               
                int w=weightFunc(G,u,v);                //get weight of edge from Vertex u to v
                relax(u,v,w);
            }
       }

       return set;

    }

    public static void main(String[] args) throws FileNotFoundException{
        String fileName = "C:/Users/Dell PC/Algorithm_Workspace/Graph_CLRS/src/Djikstra/dijkstraGraph.txt";
        Dijkstra dijkstra=new Dijkstra(fileName);

        Set<Vertex> vertexInfo=dijkstra.dijkstraAlgo(dijkstra.graph, 0);
        System.out.println("Printing min distance of all vertexes from source vertex A ");
        for(Vertex v:vertexInfo){
            System.out.println("Id: " + v.id + " distance: " + v.d);
        }
    }
}

class Vertex{
   String id;    
   int d;        //to store min distance from source
   Vertex p;     //to store last vertex from which min distance is reached
   Map<String,Integer> neighbours;   //to store edges of adjacent to the vertex

   public Vertex(String id){
     this.id=id;
     neighbours=new HashMap<String,Integer>();
}

}

The input file dijkstraGraph.txt

7
A
B
C
D
E
F
G
A B 5
A C 10
B E 3
B D 6
D F 6
E C 2
E G 2
E D 2
G F 2

Output:

Printing min distance of all vertexes from source vertex A
Id: A distance: 0 
Id: G distance: 10
Id: F distance: 16
Id: E distance: 8
Id: C distance: 10
Id: D distance: 10
Id: B distance: 5
2
  • 1
    Could you add a Desired Output section showing us what is off? Commented Feb 22, 2016 at 5:09
  • @mech Minimum distance of F from A is 12 as can be seen in graph image.But the output is showing it as 16.All other minimun distances are correct.Please see the graph image above. Commented Feb 22, 2016 at 5:19

1 Answer 1

4

Instead of initializing the queue Q with all nodes, just initialize it with the source node.

    for (Vertex v : G.vertexes){ // add source to priority queue
        Q.add(G.vertexes[s]);
    }

and then when you iterate over the neighbors, add them to Q

    for (String vertexId : u.neighbours.keySet()) { // see neighbours of
                                                        // vertex extracted
        int vertexNum = indexForName(G, vertexId);

        Vertex v = G.vertexes[vertexNum];
        int w = weightFunc(G, u, v);

        relax(u, v, w);
        Q.add(v);
    }

New output:

Printing min distance of all vertexes from source vertex A 
Id: C distance: 10
Id: A distance: 0
Id: F distance: 12
Id: G distance: 10
Id: B distance: 5
Id: E distance: 8
Id: D distance: 10
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you very much.I understood the mistake.Please,can you suggest if any improvement in code is required or if we can do a better implementation than this.
Well a few small things: 1. Set<Vertex> set why do you store the path in a set? Use a list to preserve the order. Map<String, Integer> neighbours; why do you store the neighbors as Integers and not as just the Vertex object itself? The rest looks kinda ok :)
More on a higher level: If you want to do really fast and efficient graph processing, consider changing your graph representation. The CSR representation is pretty popular for that.
Thank you very much for your suggestions.
Or use a graph DSL with a framework (like Green-Marl that is available in PGX ) Ok enough spamming from my side ^^ Glad I could help you :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.