-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDijkstra.java
More file actions
161 lines (128 loc) · 6.67 KB
/
Dijkstra.java
File metadata and controls
161 lines (128 loc) · 6.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import java.util.*;
// A weighted Graph Node
// The GraphNode is implementing Comparable interface because we are going to use minheap(Priority Queue) for dijkstra
// In PriorityQueue all the elements are ordered using their "natural ordering" and we will be supplying GraphNode to priority queue
// Hence, we need to implement comparable interface to determine the "ordering".
class GraphNode implements Comparable<GraphNode>{
String name;
ArrayList<GraphNode> neighbours;
GraphNode parent;
// following used in Dijkstra's Algo
int distance;
// weightmap is used to store weight of edges to adjacent nodes
HashMap<GraphNode, Integer> weightMap;
// constructor
GraphNode(String name){
this.name = name;
this.neighbours = new ArrayList<>();
this.parent = null;
// we set distance of each node except source node to Infinity
// Here setting max value for all nodes, will be changing distance for source node later.
this.distance = Integer.MAX_VALUE;
this.weightMap = new HashMap<>();
}
// ONE MORE THING IS REMAINING
// whenever we use comparable interface, we need to override the compareTo method
// This is done to provide the comparable interface the knowledge about how to compare two GraphNodes
// and finally store it in priority queue or minheap as per the ordering determined by this override method.
@Override
public int compareTo(GraphNode node) {
// compares the current node's distance (this.distance) with other node's distance in minheap or priority queue (node.distance).
// if positive no. is returned -> greater
// if negative is returned -> smaller
// if zero is returned -> equal
return this.distance - node.distance;
}
}
public class Dijkstra {
// to store all nodes of directed weighted graph
ArrayList<GraphNode> nodeList;
// constructor
Dijkstra(){
this.nodeList = new ArrayList<>();
}
// function to add an edge from i -> j and add a weight 'weight' to the edge
public void addDirectedWeightedEdge(int i, int j, int weight){
GraphNode source = this.nodeList.get(i-1);
GraphNode dest = this.nodeList.get(j-1);
source.neighbours.add(dest);
source.weightMap.put(dest,weight);
}
// function to find shortest path from source node to every other node using Dijkstra's algorithm.
//Time Complexity: O(v^2), Space Complexity: O(V)
public void dijkstra(GraphNode source){
// using minheap to store distance of all nodes
PriorityQueue<GraphNode> minHeap = new PriorityQueue<>();
// setting distance of source node as 0
// Also, we have already set the distance of all other nodes in GraphNode constructor
source.distance=0;
// adding all nodes distance to minheap
minHeap.addAll(this.nodeList);
while(!minHeap.isEmpty()){
GraphNode currNode = minHeap.poll();
for(GraphNode neighbour : currNode.neighbours){
// if neighbour is yet to be processed finally
if(minHeap.contains(neighbour)){
// if (source distance + weight of edge to neighbour node) is less than neighbour distance, we update the neighbour distance
// and set neighbour's parent to current node
if((currNode.distance + currNode.weightMap.get(neighbour)) < neighbour.distance){
neighbour.distance = currNode.distance + currNode.weightMap.get(neighbour);
neighbour.parent = currNode;
// refreshing the minheap as we have updated neighbour details
minHeap.remove(neighbour);
minHeap.add(neighbour);
}
}
}
}
// printing shortest path for all nodes from the given source node
for(int i=0;i<this.nodeList.size();i++){
System.out.println("Printing Shortest path from source node: "+source.name+" to node : "+this.nodeList.get(i).name);
System.out.print(" Total distance: "+this.nodeList.get(i).distance+" Shortest path: ");
printPath(this.nodeList.get(i));
System.out.println();
System.out.println();
}
}
// A helper function to print the path from source node to the given node
private void printPath(GraphNode node){
if(node.parent!=null){
printPath(node.parent);
}
System.out.print(node.name+" ");
}
public static void main(String[] args) throws Exception {
Dijkstra graph = new Dijkstra();
// adding 5 nodes V1-V5 to nodeList
for(int i=1;i<=5;i++){
graph.nodeList.add(new GraphNode("V"+i));
}
// Now adding directed weighted edges between nodes
// Diagram for the graph used can be found on the top of this post: https://theheapspace.blogspot.com/2020/05/single-source-shortest-path-dijkstras.html
graph.addDirectedWeightedEdge(1,3,6); //Add V1 -> V3 , weight 6
graph.addDirectedWeightedEdge(1,4,6); //Add V1 -> V4 , weight 6
graph.addDirectedWeightedEdge(2,1,3); //Add V2 -> V1 , weight 3
graph.addDirectedWeightedEdge(3,4,2); //Add V3 -> V4 , weight 2
graph.addDirectedWeightedEdge(4,3,1); //Add V4 -> V3 , weight 1
graph.addDirectedWeightedEdge(4,2,1); //Add V4 -> V2 , weight 1
graph.addDirectedWeightedEdge(5,2,4); //Add V5 -> V2 , weight 4
graph.addDirectedWeightedEdge(5,4,2); //Add V5 -> V4 , weight 2
// Now we have added all nodes and directed weighted edges to it, we can now use Dijkstra algo
System.out.println("Printing Shortest Path from source V5 to all other nodes using Dijkstra: ");
System.out.println();
graph.dijkstra(graph.nodeList.get(4));
}
}
/*============================================OUTPUT==============================================
Printing Shortest Path from source V5 to all other nodes using Dijkstra:
Printing Shortest path from source node: V5 to node : V1
Total distance: 6 Shortest path: V5 V4 V2 V1
Printing Shortest path from source node: V5 to node : V2
Total distance: 3 Shortest path: V5 V4 V2
Printing Shortest path from source node: V5 to node : V3
Total distance: 3 Shortest path: V5 V4 V3
Printing Shortest path from source node: V5 to node : V4
Total distance: 2 Shortest path: V5 V4
Printing Shortest path from source node: V5 to node : V5
Total distance: 0 Shortest path: V5
====================================================================================================*/