/** * {@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; }
$pq->insert(1, 'one'); echo "done."; $pq->renderInternalRepresentation(); echo "<br>"; echo "Insert (2, 'two') into pq, "; $pq->insert(2, 'two'); echo "done."; $pq->renderInternalRepresentation(); echo "<br>"; echo "Insert (0, 'zero') into pq, "; $pq->insert(0, 'zero'); echo "done."; $pq->renderInternalRepresentation(); echo "<br>"; echo "Top of pq: "; var_dump($pq->top()); $pq->renderInternalRepresentation(); echo "<br>"; echo "Pop pq: "; var_dump($pq->pop()); $pq->renderInternalRepresentation(); echo "<br>"; echo "Pop pq: "; var_dump($pq->pop()); $pq->renderInternalRepresentation(); echo "<br>"; echo "Pop pq: "; var_dump($pq->pop()); $pq->renderInternalRepresentation(); echo "<br>"; echo "Pop pq: ";