package graphtea.extensions.algorithms; import graphtea.graph.GraphUtils; import graphtea.graph.graph.Edge; import graphtea.graph.graph.GraphModel; import graphtea.graph.graph.Vertex; import graphtea.platform.core.BlackBoard; import graphtea.plugins.algorithmanimator.core.GraphAlgorithm; import graphtea.plugins.algorithmanimator.extension.AlgorithmExtension; import java.util.*; /** * Created by rostam on 06.03.15. * @author M. Ali Rostami */ public class DijkstraAlgorithm extends GraphAlgorithm implements AlgorithmExtension { public DijkstraAlgorithm(BlackBoard blackBoard) { super(blackBoard); } @Override public void doAlgorithm() { step("Start of the algorithm.") ; GraphModel graph = graphData.getGraph(); Vertex startVertex = requestVertex(graph,"Select a starting vertex."); startVertex.setColor(6); Vertex targetVertex = requestVertex(graph,"Select a target vertex."); targetVertex.setColor(4); step("<br/>"); step("We are searching now for the minimum path from the starting " + "vertex to the target vertex. The red vertex is the current vertex"); step("---------------------------------------------------------------------<br/>"); final int dist[] = new int[graph.getVerticesCount()]; //the edge connected to i'th vertex final HashMap<Vertex, Edge> edges = new HashMap<>(); HashMap<Vertex, Vertex> prev = new HashMap<>(); for (int i = 0; i < dist.length; i++) dist[i] = Integer.MAX_VALUE; dist[startVertex.getId()] = 0; class VertexComparator implements Comparator<Vertex> { public int compare(Vertex o1, Vertex o2) { if (dist[o1.getId()] < dist[o2.getId()]) return -1; if (dist[o1.getId()] == dist[o2.getId()]) return 0; else return 1; } } VertexComparator vComp = new VertexComparator(); //selected vertices HashSet<Vertex> selectedVertices = new HashSet<>(); PriorityQueue<Vertex> Q = new PriorityQueue<>(1, vComp); Q.add(startVertex); startVertex.setMark(true); while (!Q.isEmpty()) { Vertex vMin = Q.poll(); vMin.setMark(true); Edge edg = edges.get(vMin); if (edg != null) edg.setMark(true); if(vMin.getId() != startVertex.getId()) vMin.setColor(2); selectedVertices.add(vMin); Iterator<Edge> iet = graph.edgeIterator(vMin); //step("Consider the neighbour vertex with the minimum weight."); //step(""); step("Compute the distance from the starting node until the neighbours" + " of the node " + vMin.getLabel() + " ."); step(""); GraphUtils gu = new GraphUtils(); while ((iet.hasNext())) { Edge edge = iet.next(); Vertex target = vMin == edge.source ? edge.target : edge.source; int tmp = dist[vMin.getId()] + edge.getWeight(); if (!selectedVertices.contains(target)) { gu.setMessage("Currently computed distnace:" + tmp, graphData.getBlackboard(), true); step("<br/>"); if (dist[target.getId()] > dist[vMin.getId()] + edge.getWeight()) { dist[target.getId()] = dist[vMin.getId()] + edge.getWeight(); edge.setMark(true); edge.setColor(3); if(prev.containsKey(target)) graph.getEdge(target,prev.get(target)).setColor(8); edges.put(target, edge); target.setMark(true); if(target.getId() != targetVertex.getId()) target.setColor(5); Q.add(target); prev.put(edge.target, edge.source); } } if(edge.target.getId() == targetVertex.getId() || edge.source.getId() == targetVertex.getId()) { gu.setMessage("The minimum path is found: " + dist[targetVertex.getId()], graphData.getBlackboard(),true); step("The minimum path is found: " + dist[targetVertex.getId()]); Q.clear(); break; } } } step(""); step(""); step(""); step("End of the algorithm.") ; } @Override public String getName() { return "Dijkstra"; } @Override public String getDescription() { return "Dijkstra Algorithm"; } }