⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shortestpathdijkstraalgorithm.java

📁 OpenJGraph是一个开源的Java库
💻 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;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -