예제 #1
0
 public function computePath(Node $source, Node $target)
 {
     if (!$this->grid instanceof NodeGrid) {
         throw new \RuntimeException('Invalid Grid');
     }
     $priorityQueue = new NodePriorityQueueMin();
     $distanceMap = new NodeMap();
     $previousMap = new NodeMap();
     $priorityQueue->insert($source, 0);
     $distanceMap->insert($source, 0);
     while (!$priorityQueue->isEmpty()) {
         $node = $priorityQueue->extract();
         if ($node->getId() === $target->getId()) {
             return new NodePath($previousMap->lookupFrom($node));
         }
         $neighbors = $this->grid->getWalkableNeighbors($node);
         foreach ($neighbors as $neighbor) {
             $alternativeDistance = $distanceMap->lookup($node) + $this->distance->compute($node, $neighbor);
             if (!$distanceMap->exists($neighbor) || $alternativeDistance < $distanceMap->lookup($neighbor)) {
                 $priorityQueue->insert($neighbor, $alternativeDistance);
                 $distanceMap->insert($neighbor, $alternativeDistance);
                 $previousMap->insert($neighbor, $node);
             }
         }
     }
     return array();
     // no path found
 }
예제 #2
0
 public function computeRoute()
 {
     if (!$this->graph instanceof NodeGraph) {
         throw new \RuntimeException('Invalid Graph');
     }
     $vertexes = $this->graph->getVertexes();
     if (count($vertexes) <= 2) {
         return new NodePath($vertexes);
     }
     $vertexFrom = array_shift($vertexes);
     $vertexTo = null;
     $pathMap = new NodeMap();
     $pathMap->insert($vertexFrom, $vertexTo);
     while (!empty($vertexes)) {
         $minimalVertexTo = null;
         $minimalEdge = INF;
         $edges = $this->graph->getEdgesFrom($vertexFrom);
         foreach ($edges as $vertexToId => $edge) {
             $vertexTo = $this->graph->getVertex($vertexToId);
             if (!$pathMap->exists($vertexTo) && $edge < $minimalEdge) {
                 $minimalVertexTo = $vertexTo;
                 $minimalEdge = $edge;
             }
         }
         $pathMap->insert($minimalVertexTo, $vertexFrom);
         unset($vertexes[$minimalVertexTo->getId()]);
         $vertexFrom = $minimalVertexTo;
     }
     return new NodePath($pathMap->lookupFrom($vertexFrom));
 }
예제 #3
0
 public function computePath(Node $source, Node $target)
 {
     if (!$this->grid instanceof NodeGrid) {
         throw new \RuntimeException('Invalid Grid');
     }
     $fScorePriorityQueue = new NodePriorityQueueMin();
     $gScoreMap = new NodeMap();
     $openedMap = new NodeMap();
     $closedMap = new NodeMap();
     $previousMap = new NodeMap();
     $fScorePriorityQueue->insert($source, 0);
     $gScoreMap->insert($source, 0);
     $openedMap->insert($source);
     while (!$fScorePriorityQueue->isEmpty()) {
         $node = $fScorePriorityQueue->extract();
         $closedMap->insert($node);
         if ($node->getId() === $target->getId()) {
             return new NodePath($previousMap->lookupFrom($node));
         }
         $neighbors = $this->grid->getWalkableNeighbors($node);
         foreach ($neighbors as $neighbor) {
             if ($closedMap->exists($neighbor)) {
                 continue;
             }
             $gScore = $gScoreMap->lookup($node) + $this->distance->compute($node, $neighbor);
             if (!$openedMap->exists($neighbor) || $gScore < $gScoreMap->lookup($neighbor)) {
                 $fScore = $gScore + $this->heuristic->compute($node, $target);
                 $fScorePriorityQueue->insert($neighbor, $fScore);
                 $gScoreMap->insert($neighbor, $gScore);
                 $openedMap->insert($neighbor);
                 $previousMap->insert($neighbor, $node);
             }
         }
     }
     // no path found
     return array();
 }
예제 #4
0
 public function testMap()
 {
     $map = new NodeMap();
     $node = new Node(1, 1);
     $aNode = new Node(2, 1);
     $bNode = new Node(2, 2);
     $cNode = new Node(2, 3);
     $dNode = new Node(3, 1);
     $eNode = new Node(3, 2);
     $fNode = new Node(3, 3);
     $map->insert($node, 10);
     $this->assertTrue($map->exists($node));
     $this->assertSame($map->lookup($node), 10);
     $this->assertSame($map->delete($node), 10);
     $this->assertTrue($map->isEmpty());
     $this->assertFalse($map->exists($node));
     $map->insert($aNode, 'a');
     $map->insert($bNode, 'c');
     $map->insert($cNode, 'b');
     $this->assertSame($map->lookup($aNode), 'a');
     $this->assertSame($map->lookup($bNode), 'c');
     $this->assertSame($map->lookup($cNode), 'b');
     $map->insert($bNode, 'b');
     $map->insert($cNode, 'c');
     $this->assertSame($map->lookup($aNode), 'a');
     $this->assertSame($map->lookup($bNode), 'b');
     $this->assertSame($map->lookup($cNode), 'c');
     $map->insert(new Node(2, 2), 'b_');
     $map->insert(new Node(2, 3), 'c_');
     $this->assertSame($map->delete($aNode), 'a');
     $this->assertSame($map->delete($bNode), 'b_');
     $this->assertSame($map->delete($cNode), 'c_');
     $this->assertTrue($map->isEmpty());
     $map->insert($fNode, $eNode);
     $map->insert($eNode, $dNode);
     $map->insert($dNode, $cNode);
     $map->insert($cNode, $bNode);
     $map->insert($bNode, $aNode);
     $this->assertSamePath(array($aNode, $bNode, $cNode, $dNode, $eNode, $fNode), $map->lookupFrom($fNode));
     $this->assertSamePath(array($aNode, $bNode, $cNode, $dNode), $map->lookupFrom($dNode));
     $map->insert($bNode, $aNode);
     $map->insert($cNode, $bNode);
     $map->insert($dNode, $cNode);
     $map->insert($eNode, $dNode);
     $map->insert($fNode, $eNode);
     $this->assertSamePath(array($aNode, $bNode, $cNode, $dNode, $eNode, $fNode), $map->lookupFrom($fNode));
     $this->assertSamePath(array($aNode, $bNode, $cNode, $dNode), $map->lookupFrom($dNode));
     $map->insert($eNode, $fNode);
     $map->insert($fNode, $eNode);
     $this->assertSamePath(array($eNode, $fNode), $map->lookupFrom($fNode));
     $this->assertSamePath(array($fNode, $eNode), $map->lookupFrom($eNode));
     $map->insert($eNode, $eNode);
     $this->assertSamePath(array($eNode), $map->lookupFrom($eNode));
 }