Esempio n. 1
0
 /**
  * Check whether another node is near by the their identifier
  *
  * @param Node $otherNode
  * @return bool
  */
 public function isNear(Node $otherNode)
 {
     $otherIdentifier = $otherNode->getIdentifier();
     if ($otherIdentifier->getSize() != $this->identifier->getSize()) {
         return false;
     }
     $differences = 0;
     for ($i = 0; $i < $this->dimensions; $i++) {
         if ($otherIdentifier[$i] != $this->identifier[$i]) {
             $differences++;
         }
         if ($differences > 1) {
             return false;
         }
     }
     return true;
 }
Esempio n. 2
0
 /**
  * Recursive search step
  *
  * @param Node $currentNode
  * @param array $unavailable
  * @param array $path
  * @param WeightedNodeCollection $wNodes
  * @return array
  */
 public function step(Node $currentNode, array $unavailable, array $path, WeightedNodeCollection $wNodes = null)
 {
     $currentString = $currentNode->getStringIdentifier();
     $neighbors = $currentNode->computeNeighbors();
     $exploredPaths = array();
     $randomChoice = mt_rand(0, $this->dimensions - 1);
     $randomCount = 0;
     $randomAttempts = 0;
     $unavailable[] = $currentString;
     // Use weight information when available
     if (!is_null($wNodes) && $wNodes->hasStatisticsFor($currentString)) {
         $randomChoice = array_search($wNodes->getNode($currentString)->getBiasedNeighborChoice(), $neighbors);
     }
     foreach ($neighbors as $neighborString) {
         // Randomization
         if ($this->isRandomized()) {
             if ($randomChoice != $randomCount) {
                 $randomCount++;
                 continue;
             }
             $randomCount++;
             if (in_array($neighborString, $unavailable)) {
                 $randomChoice = mt_rand(0, $this->dimensions - 1);
                 $randomAttempts++;
                 $randomCount = 0;
                 // Give up if it is a dead end
                 if ($randomAttempts > $this->dimensions) {
                     break;
                 }
                 continue;
             }
         } elseif (in_array($neighborString, $unavailable)) {
             continue;
         }
         // Recursively navigate into the node
         $neighbor = new Node($this->dimensions, $neighborString);
         // Clone paths
         $neighborPath = array_merge($path);
         // Add path taken
         $neighborPath[] = array($currentString, $neighborString);
         // Add this node and other neighbors
         $neighborUnavailable[] = $neighbor->getStringIdentifier();
         $otherNeighbors = array_diff($neighbors, array($neighborString));
         $neighborUnavailable = array_merge($unavailable, array($currentString), $otherNeighbors);
         $newPath = $this->step($neighbor, $neighborUnavailable, $neighborPath);
         $exploredPaths[] = $newPath;
     }
     /*echo "\nExplored: " . count($exploredPaths) . "\n";
     
             echo "Current: " . $currentString . "\n";
     
             echo "Neighbors: \n";
             print_r($neighbors);
     
             echo "Unavailable: \n";
             print_r($unavailable);*/
     // Find largest path explored
     $largestPathLength = 0;
     $largestPath = $path;
     foreach ($exploredPaths as $exploredPath) {
         $length = count($exploredPath);
         if ($length > $largestPathLength) {
             $largestPath = $exploredPath;
             $largestPathLength = $length;
         }
     }
     return $largestPath;
 }