Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3f1d2b9

Browse files
Added Dijkstra Algorithm
1 parent 226b281 commit 3f1d2b9

File tree

2 files changed

+280
-0
lines changed

2 files changed

+280
-0
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
import java.util.ArrayList;
2+
import java.util.*;
3+
4+
public class Dijkstra {
5+
// VERTEX
6+
public static class Vertex {
7+
8+
private String data;
9+
private ArrayList<Edge> edges;
10+
11+
public Vertex(String inputData) {
12+
this.data = inputData;
13+
this.edges = new ArrayList<Edge>();
14+
}
15+
16+
public String getData() {
17+
return this.data;
18+
}
19+
20+
public ArrayList<Edge> getEdges(){
21+
return this.edges;
22+
}
23+
24+
public void addEdge(Vertex v, int weight) {
25+
this.edges.add(new Edge(this, v, weight));
26+
}
27+
28+
public void removeEdge(Vertex v) {
29+
//I don't love this solution, we don't teach removeIf
30+
this.edges.removeIf(e -> e.getEnd().equals(v));
31+
}
32+
33+
public void print() {
34+
String message = "";
35+
36+
if(this.edges.size() == 0) {
37+
System.out.println(this.data + " -->");
38+
return;
39+
}
40+
41+
for(int i = 0; i < this.edges.size(); i++) {
42+
if(i == 0) {
43+
message += this.edges.get(i).getStart().data + " --> ";
44+
}
45+
message += this.edges.get(i).getEnd().data + " (" + this.edges.get(i).getWeight() + ")";
46+
if (i != this.edges.size() - 1) {
47+
message += ", ";
48+
}
49+
}
50+
System.out.println(message);
51+
}
52+
}
53+
54+
// EDGE
55+
public static class Edge {
56+
private Vertex start;
57+
private Vertex end;
58+
private int weight;
59+
60+
public Edge(Vertex startV, Vertex endV, int inputWeight) {
61+
this.start = startV;
62+
this.end = endV;
63+
this.weight = inputWeight;
64+
}
65+
66+
public Vertex getStart() {
67+
return this.start;
68+
}
69+
70+
public Vertex getEnd() {
71+
return this.end;
72+
}
73+
74+
public int getWeight() {
75+
return this.weight;
76+
}
77+
78+
}
79+
80+
// GRAPH
81+
public static class Graph {
82+
private ArrayList<Vertex> vertices;
83+
private boolean isDirected;
84+
private boolean isWeighted;
85+
86+
public Graph(boolean inputIsWeighted, boolean inputIsDirected) {
87+
this.vertices = new ArrayList<Vertex>();
88+
this.isWeighted = inputIsWeighted;
89+
this.isDirected = inputIsDirected;
90+
}
91+
92+
public ArrayList<Vertex> getVertices(){
93+
return this.vertices;
94+
}
95+
96+
public Vertex addVertex(String data) {
97+
Vertex newVertex = new Vertex(data);
98+
this.vertices.add(newVertex);
99+
return newVertex;
100+
}
101+
102+
public void removeVertex(Vertex v){
103+
this.vertices.remove(v);
104+
}
105+
106+
public void addEdge(Vertex v1, Vertex v2, int weight) {
107+
if (!isWeighted) {
108+
weight = 0;
109+
}
110+
v1.addEdge(v2, weight);
111+
if(!this.isDirected) {
112+
v2.addEdge(v1, weight);
113+
}
114+
}
115+
116+
public void removeEdge(Vertex v1, Vertex v2) {
117+
v1.removeEdge(v2);
118+
if(!this.isDirected) {
119+
v2.removeEdge(v1);
120+
}
121+
}
122+
123+
public Vertex getVertexByValue(String value) {
124+
//This is weird as well. Not sure what we should do if the vertex doesn't exist in the graph
125+
for(Vertex v: this.vertices) {
126+
if (v.getData() == value) {
127+
return v;
128+
}
129+
}
130+
return new Vertex("");
131+
}
132+
133+
public void print() {
134+
for(Vertex v: this.vertices) {
135+
v.print();
136+
}
137+
}
138+
}
139+
140+
// QUEUE OBJECT
141+
public static class QueueObject implements Comparable<QueueObject> {
142+
public Vertex vertex;
143+
public int priority;
144+
145+
public QueueObject(Vertex v, int p){
146+
this.vertex = v;
147+
this.priority = p;
148+
}
149+
150+
@Override
151+
public int compareTo(QueueObject o) {
152+
if (this.priority == o.priority){
153+
return 0;
154+
}
155+
else if (this.priority > o.priority){
156+
return 1;
157+
}
158+
else{
159+
return -1;
160+
}
161+
}
162+
}
163+
164+
// DIJKSTRA IMPLEMENTATION
165+
public static Dictionary[] dijkstra (Graph g, Vertex startingVertex){
166+
Dictionary<String, Integer> distances = new Hashtable<>();
167+
Dictionary<String, Vertex> previous = new Hashtable<>();
168+
PriorityQueue<QueueObject> queue = new PriorityQueue<QueueObject>();
169+
170+
queue.add(new QueueObject(startingVertex, 0));
171+
172+
for (Vertex v: g.getVertices()) {
173+
if(v != startingVertex){
174+
distances.put(v.getData(), Integer.MAX_VALUE);
175+
}
176+
previous.put(v.getData(), new Vertex("Null"));
177+
}
178+
179+
distances.put(startingVertex.getData(), 0);
180+
181+
182+
while(queue.size() != 0){
183+
Vertex current = queue.poll().vertex;
184+
for (Edge e: current.getEdges()) {
185+
Integer alternate = distances.get(current.getData()) + e.getWeight();
186+
String neighborValue = e.getEnd().getData();
187+
if (alternate < distances.get(neighborValue)){
188+
distances.put(neighborValue, alternate);
189+
previous.put(neighborValue, current);
190+
queue.add(new QueueObject(e.getEnd(), distances.get(neighborValue)));
191+
}
192+
}
193+
}
194+
195+
return new Dictionary[]{distances, previous};
196+
}
197+
198+
public static void shortestPathBetween(Graph g, Vertex startingVertex, Vertex targetVertex){
199+
Dictionary[] dijkstraDicts = dijkstra(g, startingVertex);
200+
Dictionary distances = dijkstraDicts[0];
201+
Dictionary previous = dijkstraDicts[1];
202+
Integer distance = (Integer) distances.get(targetVertex.getData());
203+
System.out.println("Shortest Distance between " + startingVertex.getData() + " and " + targetVertex.getData());
204+
System.out.println(distance);
205+
206+
ArrayList<Vertex> path = new ArrayList<>();
207+
Vertex v = targetVertex;
208+
while(v.getData() != "Null"){
209+
path.add(0,v);
210+
v = (Vertex) previous.get(v.getData());
211+
}
212+
System.out.println("Shortest Path");
213+
for (Vertex pathVertex: path){
214+
System.out.println(pathVertex.getData());
215+
}
216+
}
217+
218+
public static void dijkstraResultPrinter(Dictionary[] d){
219+
System.out.println("Distances:\n");
220+
for (Enumeration keys = d[0].keys(); keys.hasMoreElements();){
221+
String nextKey = keys.nextElement().toString();
222+
System.out.println(nextKey + ": " + d[0].get(nextKey));
223+
}
224+
System.out.println("\nPrevious:\n");
225+
for (Enumeration keys = d[1].keys(); keys.hasMoreElements();) {
226+
String nextKey = keys.nextElement().toString();
227+
Vertex nextVertex = (Vertex) d[1].get(nextKey);
228+
System.out.println(nextKey + ": " + nextVertex.getData());
229+
}
230+
}
231+
232+
public static void main(String[] args){
233+
Graph testGraph = new Graph(true, true);
234+
Vertex a = testGraph.addVertex("A");
235+
Vertex b = testGraph.addVertex("B");
236+
Vertex c = testGraph.addVertex("C");
237+
Vertex d = testGraph.addVertex("D");
238+
Vertex e = testGraph.addVertex("E");
239+
Vertex f = testGraph.addVertex("F");
240+
Vertex g = testGraph.addVertex("G");
241+
242+
testGraph.addEdge(a, c, 100);
243+
testGraph.addEdge(a, b, 3);
244+
testGraph.addEdge(a, d, 4);
245+
testGraph.addEdge(d, c, 3);
246+
testGraph.addEdge(d, e, 8);
247+
testGraph.addEdge(e, b, -2);
248+
testGraph.addEdge(e, f, 10);
249+
testGraph.addEdge(b, g, 9);
250+
testGraph.addEdge(e, g, -50);
251+
252+
dijkstraResultPrinter(dijkstra(testGraph, a));
253+
shortestPathBetween(testGraph, a, g);
254+
}
255+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Dijkstra's Algorithm
2+
3+
One of the most common applications of graph searches is to find the shortest distance between vertices.
4+
5+
Finding this distance has a variety of applications such as finding the optimal route to a destination or transferring data in a computer network.
6+
7+
It computes the shortest distance from a given vertex to the rest of the vertices in a graph
8+
9+
**Dijkstra’s Algorithm works like the following:**
10+
11+
1. Instantiate a dictionary that will eventually map vertices to their distance from the start vertex
12+
2. Assign the start vertex a distance of 0 in a min heap
13+
3. Assign every other vertex a distance of infinity in a min heap
14+
4. Remove the vertex with the smallest distance from the min heap and set that to the current vertex
15+
5. For the current vertex, consider all of its adjacent vertices and calculate the distance to them as (distance to the current vertex) + (edge weight of current vertex to adjacent vertex).
16+
6. If this new distance is less than the current distance, replace the current distance.
17+
7. Repeat 4 and 5 until the heap is empty
18+
8. After the heap is empty, return the distances
19+
20+
## Runtime
21+
Just like breadth-first search and depth-first search, to search through an entire graph, in the worst case, we would go through all of the edges and all of the vertices resulting in a runtime of O(E + V).
22+
23+
For Dijkstra’s, we use a min-heap to keep track of all the distances. Searching through and updating a min-heap with V nodes takes O(log V) because in each layer of the min-heap, we reduce the number of nodes we are looking at by a factor of 2.
24+
25+
In the worst case, we would update the min-heap every iteration. Since there are at most E + V iterations of Dijkstra’s and it takes log V to update a min-heap in the worst case, then the runtime of Dijkstra’s is **O((E+V)log V)**.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /