-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFloyd_Warshall.php
71 lines (61 loc) · 2.08 KB
/
Floyd_Warshall.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?php
ob_start(); // for removing the printf from other files
include 'Graph.php';
ob_end_clean();
/**
* Floyd Warshall
* finding shortest paths in a weighted graph
* with positive or negative edge weights (but with no negative cycles).
*
* Time Complexity: O(V^3)
*/
function floydWarshall(&$graph) {
sort($graph->nodes); // for easy representation of distance arr
$distance = [];
foreach ($graph->nodes as $key1 => $node1) {
$distance[ $node1 ] = [];
foreach ($graph->nodes as $key2 => $node2) {
if ($node1 === $node2) {
$distance[ $node1 ][ $node2 ] = 0;
} elseif (
isset($graph->adjacencyList[ $node1 ]) &&
isset($graph->adjacencyList[ $node1 ][ $node2 ]) &&
$graph->adjacencyList[ $node1 ][ $node2 ]
) {
$distance[ $node1 ][ $node2 ] = $graph->adjacencyList[ $node1 ][ $node2 ];
} else {
$distance[ $node1 ][ $node2 ] = INF;
}
}
}
foreach ($graph->nodes as $key1 => $node1) {
foreach ($graph->nodes as $key2 => $node2) {
foreach ($graph->nodes as $key3 => $node3) {
$distance[ $node1 ][ $node2 ] = min(
$distance[ $node1 ][ $node2 ], $distance[ $node1 ][ $node3 ] + $distance[ $node3 ][ $node2 ]
);
}
}
}
return $distance;
}
// ----------------
// --- Examples ---
// ----------------
define("NL", PHP_SAPI === 'cli' ? "\n" : "<br />"); // define new line feed based on web/cli
$graph = new Graph(false, true); // direcred & weighted
$graph->addEdge(1, 2, 5);
$graph->addEdge(1, 4, 9);
$graph->addEdge(1, 5, 1);
$graph->addEdge(2, 3, 2);
$graph->addEdge(2, 4, 1);
$graph->addEdge(3, 5, 5);
$graph->addEdge(4, 3, 7);
$graph->addEdge(4, 5, 2);
$graph->addEdge(5, 2, 4);
$floydWarshall = floydWarshall($graph);
foreach ($graph->nodes as $key1 => $node1) {
foreach ($graph->nodes as $key2 => $node2) {
printf("Path from %s to %s is %s" . NL, $node1, $node2, $floydWarshall[ $node1 ][ $node2 ]);
}
}