function calcShortestPaths(vertex $start, &$adjLists) { // define an empty queue $q = new PriorityQueue(); // push the starting vertex into the queue $q->insert($start, 0); $q->rewind(); // mark the distance to it 0 $start->distance = 0; // the path to the starting vertex $start->path = array($start->key); while ($q->valid()) { $vertex = $q->extract(); $vertex->visited = 1; $list = $adjLists[$vertex->key]; while ($list->valid()) { $item = $list->current(); if (!$item['vertex']->visited) { if ($item['vertex']->distance > $vertex->distance + $item['distance']) { $item['vertex']->distance = $vertex->distance + $item['distance']; $item['vertex']->parent = $vertex; } $item['vertex']->path = array_merge($vertex->path, array($item['vertex']->key)); $q->insert($item["vertex"], $item["vertex"]->distance); } $list->next(); } $q->recoverFromCorruption(); $q->rewind(); } }
/** * {@inheritdoc} */ public function calculate($start, $finish) { // check if the nodes exist if (!isset($this->nodes[$start])) { throw new \InvalidArgumentException("The starting node '" . $start . "' is not found"); } if (!isset($this->nodes[$finish])) { throw new \InvalidArgumentException("The ending node '" . $finish . "' is not found"); } $distances = []; $distances[$start] = 0; $visited = []; $previous = []; $queue = new PriorityQueue(); $queue->insert($start, $distances[$start]); $queue->top(); while ($queue->valid()) { $smallest = $queue->current(); if ($smallest == $finish) { // trying to make path $path = array(); while (isset($previous[$smallest])) { $path[] = $smallest; $smallest = $previous[$smallest]; } $path[] = $start; return ['distance' => $distances[$finish], 'path' => array_reverse($path)]; } if (isset($visited[$smallest])) { $queue->next(); continue; } $visited[$smallest] = true; foreach ($this->nodes[$smallest] as $neighbor => $weight) { if (isset($visited[$neighbor])) { continue; } $alt = $distances[$smallest] + $weight; if (!isset($distances[$neighbor]) || $alt < $distances[$neighbor]) { $distances[$neighbor] = $alt; $previous[$neighbor] = $smallest; $queue->insert($neighbor, $alt); } } $queue->next(); } // there is no available path if the graph is unconnected return null; }
public function shortest_path($start, $finish) { $distances = array(); $previous = array(); $nodes = new PriorityQueue(); foreach ($this->verticies as $vertex => $value) { if ($vertex === $start) { $distances[$vertex] = 0; $nodes->insert($vertex, 0); } else { $distances[$vertex] = PHP_INT_MAX; $nodes->insert($vertex, PHP_INT_MAX); } $previous[$vertex] = null; } $nodes->top(); while ($nodes->valid()) { $smallest = $nodes->current(); if ($smallest === $finish) { $path = array(); while ($previous[$smallest]) { $path[] = $smallest; $smallest = $previous[$smallest]; } $path[] = $start; $alt = $distances[$finish]; $path['Разстояние'] = $alt; return array_reverse($path); } if ($smallest === null || $distances[$smallest] === PHP_INT_MAX) { break; } foreach ($this->verticies[$smallest] as $neighbor => $value) { $alt = $distances[$smallest] + $this->verticies[$smallest][$neighbor]; if ($alt < $distances[$neighbor]) { $distances[$neighbor] = $alt; $previous[$neighbor] = $smallest; $nodes->insert($neighbor, $alt); } } $nodes->next(); } return $distances; }
function calcDistances($start) { // define an empty queue $q = new PriorityQueue(); // push the starting vertex into the queue $q->insert($start, 0); $q->rewind(); // mark the distance to it 0 $start->distance = 0; while ($q->valid()) { $t = $q->extract(); $t->visited = 1; foreach ($t->getRelations() as $key => $relation) { foreach ($relation as $object) { if (!$object->visited) { if ($object->distance > $t->distance + 1) { $object->distance = $t->distance + 1; $object->parent = $t; } $q->insert($object, $object->distance); } } } $q->recoverFromCorruption(); $q->rewind(); } }