Skip to content

Instantly share code, notes, and snippets.

@heiba
Last active October 3, 2015 19:10
Show Gist options
  • Save heiba/2169798a467fefd55307 to your computer and use it in GitHub Desktop.
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
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