A
download ShortestPathDijkstraAlgorithm.java
Language: Java
LOC: 95
Project Info
OpenJGraph
Server: SourceForge
Type: cvs
...alvo\jesus\graph\algorithm\
   BreadthFirstTraversal.java
   ...DetectionAlgorithm.java
   ...ectionAlgorithmDFS.java
   ...ctedGraphTraversal.java
   ...irstGraphTraversal.java
   EulerCircleFinder.java
   ...ntractionAlgorithm.java
   GraphTraversal.java
   GraphUnionAlgorithm.java
   ...nningTreeAlgorithm.java
   ...eeKruskalAlgorithm.java
   ShortestPathAlgorithm.java
   ...hDijkstraAlgorithm.java
   TopologicalSorting.java

package salvo.jesus.graph.algorithm;

import salvo.jesus.graph.*;
import salvo.jesus.util.*;
import java.util.*;

/**
 * A concrete implementation of ShortestPathAlgorithm using Dijkstra's method.
 *
 * @author  Jesus M. Salvo Jr.
 */

public class ShortestPathDijkstraAlgorithm extends ShortestPathAlgorithm {
  /**
   * List of vertices that has been added to the tree
   */
  private List  visited;

  /**
   * Heap of FringeObjects that are to be processed.
   */
  private Heap  fringe;

  /**
   * Subgraph forming the shortest spanning tree.
   */
  private WeightedGraph shortestpathtree;

  /**
   * Comparator used to be compare priorities in the fringe.
   */
  private HeapNodeComparator  comparator;

  /**
   * Creates an instance of ShortestPathDijkstraAlgorithm.
   *
   * @param wgraph  The WeightedGraph where a shortest path spanning tree will be determined.
   * @param comparator  The HeapNodeComparator to be used to compare priorities of objects in the fringe/heap.
   */
  public ShortestPathDijkstraAlgorithm( WeightedGraph wgraph, HeapNodeComparator comparator ) {
    super( wgraph );
    this.visited = new ArrayList( 10 );
    this.comparator = comparator;
    this.fringe = new Heap( new HeapNodeComparator( 1 ));
  }

  /**
   * Determines the shortest path from a given vertex to all other vertices
   * that are in the same connected set as the given vertex in the weighted graph
   * using Dijkstra's algorithm.
   *
   * @return  A WeightedGraph comprising of the shortest path spanning tree.
   * @param from  The Vertex from where we want to obtain the shortest path
   * to all other vertices.
   */
  public WeightedGraph shortestPath( Vertex from ) {
    // clear the graph.
    // this.shortestpathtree.clear();
    this.shortestpathtree = new WeightedGraphImpl();

    // Now add the vertex we are interested in to the fringe.
    this.fringe.insert( new HeapNode( new FringeObject( from, null ), 0.0 ));

    // Continually process while there are vertices in the heap.
    while( !this.fringe.isEmpty() ) {

      // Moves the highest priority node from the heap to the tree.
      this.moveToVisited();
    }

    // Clear the vectors
    this.visited.clear();
    this.fringe.clear();

    return shortestpathtree;
  }

  /**
   * Moves the vertex that has the highest priority in the heap
   * from the fringe to the tree,
   */
  private void moveToVisited() {
    HeapNode  prioritynode;

    // Remove the node with highest priority from the fringe ...
    prioritynode = this.fringe.remove( );

    FringeObject  fringeobject = (FringeObject) prioritynode.getObject();
    Vertex    priorityvertex = fringeobject.vertex;

    // ... and add it to the tree.
    this.visited.add( priorityvertex );
    if( fringeobject.edge != null ) {
        try {
            this.shortestpathtree.addEdge( fringeobject.edge );
        }
        catch( Exception ex ) {
            ex.printStackTrace();
        }
    }

    // ... then move all the adjacent vertices of the vertex
    // we just moved to the tree and put them in the fringe.
    this.moveAdjacentVerticesToFringe( prioritynode );
  }

  /**
   * Gets all the adjacent vertices from unseen to the fringe.
   * The parameter vertex must be a vertex that is being moved
   * from the fringe to the tree. This method must only be called
   * by the method moveToVisited().
   *
   * @param vertex  The vertex that is being moved from the fringe to the tree
   * and whose adjacent vertices we want added to the fringe.
   */
  private void moveAdjacentVerticesToFringe( HeapNode prioritynode ) {
    // Get the vertex encapsulated by the heap node
    Vertex    priorityvertex = ((FringeObject) prioritynode.getObject()).vertex;

    // Then get the edges of the vertex
    // We cant use wgraph.getAdjacentVertices() as that will
    // not tell us what edge to use.
    List    incidentedges = this.wgraph.getEdges( priorityvertex );

    // Get the priority of the heap node
    double    priority = prioritynode.getPriority();

    // We need to iterate through the edges
    Iterator  iterator = incidentedges.iterator();

    // Because we are using HeapNodes in the fringe,
    // we need a way to compare the object (a Vertex) encapsulated in a HeapNode in the
    // fringe and a Vertex
    HeapNodeObjectComparator  heapnodeobjectcomparator = new HeapNodeObjectComparator();

    // The current incident edge iterated
    WeightedEdge  incidentedge;

    // The current adjacent vertex within the iteration
    Vertex    adjacentvertex;

    // Either an existing HeapNode or an exsting one in the fringe
    HeapNode  heapnode;

    // The new priority of a heapnode
    double    fringepriority;

    // For each edge of the vertex ...
    while( iterator.hasNext() ) {
      incidentedge = (WeightedEdge) iterator.next();

      // ... get the vertex opposite to the priority vertex
      // meaning get the adjacent vertex
      adjacentvertex = incidentedge.getOppositeVertex( priorityvertex );

      // ... check if the adjacent vertex has been visited
      // If it has been visited, then proceed with the next edge
      if( this.visited.contains( adjacentvertex )) continue;

      // ... check if the adjacent vertex is already in the fringe
      heapnode = (HeapNode) this.fringe.contains( adjacentvertex, heapnodeobjectcomparator );

      // ... if it is not yet on the fringe, add it to the fringe
      if( heapnode == null ) {
        fringepriority = priority + incidentedge.getWeight();
        heapnode = new HeapNode( new FringeObject( adjacentvertex, incidentedge ), fringepriority );
        this.fringe.insert( heapnode );
      }
      // If it is already the fringe, reassign its priority,
      // only if it will give it a "higher" priority.
      // Use the HeapNodeComparator to determine which is "higher".
      else {
        fringepriority = priority + incidentedge.getWeight();
        if( this.comparator.compare( new HeapNode( adjacentvertex, fringepriority), heapnode ) < 0 ) {
          this.fringe.setPriority( heapnode, fringepriority );
          // Also reassign the edge that is used to get the shortest path
          FringeObject   fobject = (FringeObject) heapnode.getObject();
          fobject.edge = incidentedge;
        }
      }

    }
  }

}

/**
 * A Comparator for comparing the Vertex in the FringObject of the HeapNode
 * against another Vertex.
 */
class HeapNodeObjectComparator implements Comparator {

  /**
   * Compare a Vertex against the Vertex in the FringeObject of a HeapNode.
   * The comparison is made using the == operator to compare the actual instance.
   *
   * @return  Returns 0 if they are the same object. Returns -1 otherwise.
   */
  public int compare( Object vertex, Object hnode ) {
    Vertex    compareTo = (Vertex) vertex;
    HeapNode  heapnode = (HeapNode) hnode;
    FringeObject  fringeobject = (FringeObject) heapnode.getObject();
    Vertex    heapobject = (Vertex) fringeobject.vertex;

    if( compareTo == heapobject )
      return 0;
    else
      return -1;
  }
}

/**
 * An Object encapsulated in a HeapNode, which in turn is added to the fringe.
 * The classical algorithm only mentions of storing vertices in the fringe, but
 * it is programatically difficult to determine what edge to add to the
 * shortest path spanning tree when moving a vertex from the fringe to the tree.
 * It is therefore easier to store the edge along with the vertex in the fringe.
 *
 * The edge stored along with the vertex in the fringe is the
 * edge connecting the vertex that has been moved from the fringe to the tree
 * and the vertex adjacent to the vertex that has been moved from the fringe
 * and being added to the fringe. Got that?
 *
 */
class FringeObject {
  Vertex        vertex;
  WeightedEdge  edge;

  public FringeObject( Vertex vertex, WeightedEdge edge ) {
    this.vertex = vertex;
    this.edge = edge;
  }

  public String toString() {
    return "Vertex: " + vertex + "; Edge: " + edge;
  }
}

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us