Last active
October 3, 2015 19:10
-
-
Save heiba/2169798a467fefd55307 to your computer and use it in GitHub Desktop.
This is my implementation of Dijkstra's algorithm. Implementation works for single-directional vectors by default. For bi-directional vectors, the vector needs to be associated with both nodes. Feedback is welcome. Special thanks to Nathaniel Fan. https://www.youtube.com/watch?v=gdmfOwyQlcI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.Collections; | |
/** | |
* Created by Mohamed Heiba on 01/10/2015. | |
* <p> | |
* Implementation of Dijkstra's algorithm. | |
* <p> | |
* Implementation works for single-directional vectors by default. | |
* For bi-directional vectors, vectors needs to be associated to both nodes concerned. | |
* | |
* Special thanks to Nathaniel Fan https://www.youtube.com/watch?v=gdmfOwyQlcI | |
*/ | |
public class HeibaDijkstra | |
{ | |
public static Graph graph; | |
class Graph | |
{ | |
ArrayList<Node> nodes; | |
ArrayList<Node> shortestPath; | |
Node getNode(String id) | |
{ | |
for (Node node : graph.nodes) | |
if (node.id.equals(id)) | |
return node; | |
return null; | |
} | |
void calculateShortestPath() | |
{ | |
Node currentNode = getStartNode(); | |
while (!currentNode.isGoal) | |
{ | |
currentNode.updateUnvisitedNodesCost(); | |
sortNodes(); | |
Node lowestUnvisited = getLowestUnvisitedNode(); | |
assert lowestUnvisited != null; | |
lowestUnvisited.isVisited = true; | |
currentNode = lowestUnvisited; | |
} | |
shortestPath = new ArrayList<>(); | |
Node currentNodeShortestPath = getGoalNode(); | |
shortestPath.add(currentNodeShortestPath); | |
while (!currentNodeShortestPath.isStart) | |
{ | |
currentNodeShortestPath = currentNodeShortestPath.previousNode; | |
shortestPath.add(currentNodeShortestPath); | |
} | |
Collections.reverse(shortestPath); | |
} | |
private void printShortestPath() | |
{ | |
for (Node node : shortestPath) | |
System.out.println(node.id); | |
} | |
private void printShortestPathCost() | |
{ | |
System.out.println(getGoalNode().costFromStart); | |
} | |
private void sortNodes() | |
{ | |
Collections.sort(graph.nodes, (o1, o2) -> ((Integer) o1.costFromStart).compareTo((Integer) o2.costFromStart)); | |
} | |
private Node getLowestUnvisitedNode() | |
{ | |
for (Node node : graph.nodes) | |
if (!node.isVisited) | |
return node; | |
return null; | |
} | |
Node getStartNode() | |
{ | |
for (Node node : graph.nodes) | |
if (node.isStart) | |
return node; | |
throw new IllegalStateException(); | |
} | |
Node getGoalNode() | |
{ | |
for (Node node : graph.nodes) | |
if (node.isGoal) | |
return node; | |
throw new IllegalStateException(); | |
} | |
} | |
class Node | |
{ | |
String id; | |
boolean isStart; | |
boolean isGoal; | |
boolean isVisited; | |
int costFromStart; | |
Node previousNode; | |
ArrayList<Vector> vectors; | |
public Node(String id) | |
{ | |
this.id = id; | |
isStart = false; | |
isGoal = false; | |
isVisited = false; | |
costFromStart = Integer.MAX_VALUE; | |
previousNode = null; | |
vectors = new ArrayList<>(); | |
} | |
public boolean equals(Node node) | |
{ | |
return this.id.equals(node.id); | |
} | |
public void updateUnvisitedNodesCost() | |
{ | |
for (Vector vector : vectors) | |
{ | |
Node otherNode = vector.getOtherNode(this); | |
if (otherNode.isVisited) | |
continue; | |
int testCost = costFromStart + vector.cost; | |
if (otherNode.costFromStart > testCost) | |
{ | |
otherNode.costFromStart = testCost; | |
otherNode.previousNode = this; | |
} | |
} | |
} | |
} | |
class Vector | |
{ | |
Node oneNode; | |
Node anotherNode; | |
final int cost; | |
public Vector(Node oneNode, Node anotherNode, final int cost) | |
{ | |
this.oneNode = oneNode; | |
this.anotherNode = anotherNode; | |
this.cost = cost; | |
} | |
Node getOtherNode(Node node) | |
{ | |
if (oneNode.equals(node)) | |
return anotherNode; | |
else if (anotherNode.equals(node)) | |
return oneNode; | |
else | |
return null; | |
} | |
} | |
void initializeGraph() | |
{ | |
graph = new Graph(); | |
graph.nodes = new ArrayList<>(); | |
Node aNode = new Node("A"); | |
Node bNode = new Node("B"); | |
Node cNode = new Node("C"); | |
Node dNode = new Node("D"); | |
Node eNode = new Node("E"); | |
Node fNode = new Node("F"); | |
Node gNode = new Node("G"); | |
graph.nodes.add(aNode); | |
graph.nodes.add(bNode); | |
graph.nodes.add(cNode); | |
graph.nodes.add(dNode); | |
graph.nodes.add(eNode); | |
graph.nodes.add(fNode); | |
graph.nodes.add(gNode); | |
graph.getNode("A").isStart = true; | |
graph.getNode("A").isVisited = true; | |
graph.getNode("A").costFromStart = 0; | |
graph.getNode("F").isGoal = true; | |
Vector abVector = new Vector(aNode, bNode, 4); | |
Vector acVector = new Vector(aNode, cNode, 3); | |
Vector aeVector = new Vector(aNode, eNode, 7); | |
Vector bcVector = new Vector(bNode, cNode, 6); | |
Vector bdVector = new Vector(bNode, dNode, 5); | |
Vector cdVector = new Vector(cNode, dNode, 11); | |
Vector ceVector = new Vector(cNode, eNode, 8); | |
Vector dfVector = new Vector(dNode, fNode, 2); | |
Vector dgVector = new Vector(dNode, gNode, 10); | |
Vector deVector = new Vector(dNode, eNode, 2); | |
Vector fgVector = new Vector(fNode, gNode, 3); | |
Vector egVector = new Vector(eNode, gNode, 5); | |
aNode.vectors.add(abVector); | |
bNode.vectors.add(abVector); | |
aNode.vectors.add(acVector); | |
cNode.vectors.add(acVector); | |
aNode.vectors.add(aeVector); | |
eNode.vectors.add(aeVector); | |
bNode.vectors.add(bcVector); | |
cNode.vectors.add(bcVector); | |
bNode.vectors.add(bdVector); | |
dNode.vectors.add(bdVector); | |
cNode.vectors.add(cdVector); | |
dNode.vectors.add(cdVector); | |
cNode.vectors.add(ceVector); | |
eNode.vectors.add(ceVector); | |
dNode.vectors.add(dfVector); | |
fNode.vectors.add(dfVector); | |
dNode.vectors.add(dgVector); | |
gNode.vectors.add(dgVector); | |
dNode.vectors.add(deVector); | |
eNode.vectors.add(deVector); | |
fNode.vectors.add(fgVector); | |
gNode.vectors.add(fgVector); | |
eNode.vectors.add(egVector); | |
gNode.vectors.add(egVector); | |
} | |
public static void main(String args[]) | |
{ | |
new HeibaDijkstra().initializeGraph(); | |
graph.calculateShortestPath(); | |
graph.printShortestPath(); | |
graph.printShortestPathCost(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment