예제 #1
0
 /**
  * Calculate the Moore-Bellman-Ford-Algorithm and get all edges on shortest path for this vertex
  *
  * @return Edges
  * @throws NegativeCycleException if there is a negative cycle
  */
 public function getEdges()
 {
     // start node distance, add placeholder weight
     $totalCostOfCheapestPathTo = array($this->vertex->getId() => INF);
     // predecessor
     $predecessorVertexOfCheapestPathTo = array($this->vertex->getId() => $this->vertex);
     // the usal algorithm says we repeat (n-1) times.
     // but because we also want to check for loop edges on the start vertex,
     // we have to add an additional step:
     $numSteps = count($this->vertex->getGraph()->getVertices());
     $edges = $this->vertex->getGraph()->getEdges();
     $changed = true;
     for ($i = 0; $i < $numSteps && $changed; ++$i) {
         $changed = $this->bigStep($edges, $totalCostOfCheapestPathTo, $predecessorVertexOfCheapestPathTo);
     }
     // no cheaper edge to start vertex found => remove placeholder weight
     if ($totalCostOfCheapestPathTo[$this->vertex->getId()] === INF) {
         unset($predecessorVertexOfCheapestPathTo[$this->vertex->getId()]);
     }
     // algorithm is done, build graph
     $returnEdges = $this->getEdgesCheapestPredecesor($predecessorVertexOfCheapestPathTo);
     // Check for negative cycles (only if last step didn't already finish anyway)
     // something is still changing...
     if ($changed && ($changed = $this->bigStep($edges, $totalCostOfCheapestPathTo, $predecessorVertexOfCheapestPathTo))) {
         $cycle = Walk::factoryCycleFromPredecessorMap($predecessorVertexOfCheapestPathTo, $changed, Edges::ORDER_WEIGHT);
         throw new NegativeCycleException('Negative cycle found', 0, NULL, $cycle);
     }
     return $returnEdges;
 }
예제 #2
0
파일: WalkTest.php 프로젝트: cmfcmf/graph
 /**
  * @expectedException InvalidArgumentException
  */
 public function testInvalidPredecessors()
 {
     $graph = new Graph();
     $v1 = $graph->createVertex(1);
     Walk::factoryCycleFromPredecessorMap(array(), $v1);
 }