Пример #1
0
 /**
  *
  * @param  Vertex    $vertex          current point-of-view
  * @param  number    $totalWeight     total weight (so far)
  * @param  boolean[] $visitedVertices
  * @param  Edge[]    $visitedEdges
  * @return Edge[]
  */
 private function step(Vertex $vertex, $totalWeight, array $visitedVertices, array $visitedEdges)
 {
     // stop recursion if best result is exceeded (branch and bound)
     if ($this->branchAndBound && $this->bestWeight !== NULL && $totalWeight >= $this->bestWeight) {
         return NULL;
     }
     // kreis geschlossen am Ende
     if ($vertex === $this->startVertex && count($visitedEdges) === $this->numEdges) {
         // new best result
         $this->bestWeight = $totalWeight;
         return $visitedEdges;
     }
     // only visit each vertex once
     if (isset($visitedVertices[$vertex->getId()])) {
         return NULL;
     }
     $visitedVertices[$vertex->getId()] = true;
     $bestResult = NULL;
     // weiter verzweigen in alle vertices
     foreach ($vertex->getEdgesOut() as $edge) {
         // get target vertex of this edge
         $target = $edge->getVertexToFrom($vertex);
         $weight = $edge->getWeight();
         if ($weight < 0) {
             throw new UnexpectedValueException('Edge with negative weight "' . $weight . '" not supported');
         }
         $result = $this->step($target, $totalWeight + $weight, $visitedVertices, array_merge($visitedEdges, array($edge)));
         // new result found
         if ($result !== NULL) {
             // branch and bound enabled (default): returned result MUST be the new best result
             if ($this->branchAndBound || $bestResult === NULL || $this->sumEdges($result) < $this->sumEdges($bestResult)) {
                 $bestResult = $result;
             }
         }
     }
     return $bestResult;
 }