Version: 1.1
Type: Full Script
Category: Algorithms
License: GNU General Public License
Description: This function allows to trace the shortest path beetwen nodes and traces the route, for example on a map. I found on a forum and i think its very good, altougth i think it doesnt works properly on >PHP 4.0.
> I'm wondering has anyone made a some kind of "program" (with PHP) which finds the shortest way between
two nodes in a node network? The program could also tell the nodes by shortest route and distance.
>
> I have heard something about Dijkstra's algorithm...
>
> Can anyone help me? or the best, can anyone send sources?
The following should work I think, let me show an example:
B-------C
/ \ 1 \
2 / \ \5
/ \ \
A \4 F G
\ \ /
3 \ \ /1
\ \ /
D-------E
2
This graph can be represented by listing the neighbors for each
vertex, like below, and then calling the function dijkstra.
NOTE: this version DOES work for PHP 5.
<?php
/* the neighbors array */
$neighbors['A'] = array('B' => 2, 'D' => 3);
$neighbors['B'] = array('A' => 2, 'C' => 1, 'E' => 4);
$neighbors['C'] = array('B' => 1, 'F' => 5);
$neighbors['D'] = array('A' => 3, 'E' => 2);
$neighbors['E'] = array('D' => 2, 'B' => 4, 'F' => 1);
$neighbors['F'] = array('C' => 5, 'E' => 1);
function dijkstra($neighbors, $start) {
$closest = $start;
while (isset($closest)) {
$marked[$closest] = 1;
/* loop through each neighbor for this $closest node and
* and store the distance and route in an array */
foreach ($neighbors[$closest] as $vertex => $distance) {
/* if we already have the route and distance, skip */
if (isset($marked[$vertex]))
continue;
/* distance from $closest to $vertex */
$dist = (isset($paths[$closest][0]) ? $paths[$closest][0] : 0) + $distance;
/* if we dont have a path to $vertex yet, create it.
* If this distance is shorter, override the existing one */
if (!isset($paths[$vertex]) || ($dist < $paths[$vertex][0])) {
if (isset($paths[$closest])) {
$paths[$vertex]= $paths[$closest];
}
$paths[$vertex][] = $closest;
$paths[$vertex][0] = $dist;
}
}
unset($closest);
/* Find the next node we should create a path for */
foreach ($paths as $vertex => $path) {
if (isset($marked[$vertex]))
continue;
$distance = $path[0];
if ((!isset($min) || $distance < $min) || !isset($closest)) {
$min = $distance;
$closest = $vertex;
}
}
}
return $paths;
}
$paths = dijkstra($neighbors, 'A');
print_r($paths);
?>
If you run this, you get this:
Array
(
[B] => Array
(
[0] => 2
)
[D] => Array
(
[0] => 3
)
[C] => Array
(
[0] => 3
[1] => B
)
[E] => Array
(
[0] => 5
[1] => D
)
[F] => Array
(
[0] => 6
[1] => D
[2] => E
)
)