/**
  *
  * @return Edges
  */
 public function getEdges()
 {
     $returnEdges = array();
     // Create minimum spanning tree
     $minimumSpanningTreeAlgorithm = new MstKruskal($this->graph);
     $minimumSpanningTree = $minimumSpanningTreeAlgorithm->createGraph();
     $alg = new SearchDepthFirst($minimumSpanningTree->getVertices()->getVertexFirst());
     // Depth first search in minmum spanning tree (for the eulerian path)
     $startVertex = NULL;
     $oldVertex = NULL;
     // connect vertices in order of the depth first search
     foreach ($alg->getVertices() as $vertex) {
         // get vertex from the original graph (not from the depth first search)
         $vertex = $this->graph->getVertex($vertex->getId());
         // need to clone the edge from the original graph, therefore i need the original edge
         if ($startVertex === NULL) {
             $startVertex = $vertex;
         } else {
             // get edge(s) to clone, multiple edges are possible (returns an array if undirected edge)
             $returnEdges[] = $oldVertex->getEdgesTo($vertex)->getEdgeFirst();
         }
         $oldVertex = $vertex;
     }
     // connect last vertex with start vertex
     // multiple edges are possible (returns an array if undirected edge)
     $returnEdges[] = $oldVertex->getEdgesTo($startVertex)->getEdgeFirst();
     return new Edges($returnEdges);
 }
Example #2
0
 /**
  * The function finds out the lowest common ancestor(LCA) of two nodes.
  *              1
  *            /  \
  *           2    5
  *         /  \    \
  *        3    4    6
  *  For example: LCA of (3,4) would be 2
  *  LCA of (3,6) would be 1.
  * @param Vertex $local
  * @param Vertex $remote
  * @return Lowest common ancestor from the graph.
  */
 public function find(Vertex $local, Vertex $remote)
 {
     // Traverse in reverse order starting from $local to the root.
     $direction = BreadthFirst::DIRECTION_REVERSE;
     // Use BFS algorithm to get all vertices starting with $local to the root.
     $bfs_local = new BreadthFirst($local);
     $vertices_local = $bfs_local->setDirection($direction)->getVertices();
     // Use BFS algorithm to get all vertices starting with $remote to the root.
     $bfs_remote = new BreadthFirst($remote);
     $vertices_remote = $bfs_remote->setDirection($direction)->getVertices();
     // Intersect the $vertices_local and $vertices_remote to get all common
     // ancestors for $local and $remote. If the $vertices_intersection array is
     // not empty then first value should be our solution - the LCA.
     $vertices_intersection = $vertices_local->getVerticesIntersection($vertices_remote)->getMap();
     if ($lca = reset($vertices_intersection)) {
         return $lca;
     } else {
         throw new LcaException("No common ancestor found");
     }
 }
 /**
  *
  *
  * @param  Vertex    $source
  * @throws Exception if there is no reachable sink vertex
  *
  * @return Vertex a sink-vertex that is reachable from the source
  * @uses BreadthFirst::getVertices()
  */
 private function getVertexSink(Vertex $source)
 {
     // search for reachable Vertices
     $algBFS = new SearchBreadthFirst($source);
     foreach ($algBFS->getVertices()->getMap() as $vid => $vertex) {
         if ($this->graph->getVertex($vid)->getBalance() - $vertex->getBalance() < 0) {
             return $vertex;
         }
     }
     throw new UnderflowException('No sink vertex connected to given source vertex found');
 }
 /**
  *
  * @param Vertex $vertex
  * @return SearchBreadthFirst
  */
 private function createSearch(Vertex $vertex)
 {
     $alg = new SearchBreadthFirst($vertex);
     // follow into both directions (loosely connected)
     return $alg->setDirection(SearchBreadthFirst::DIRECTION_BOTH);
 }