/** * Main program. * * @param array $args Command-line arguments. * @return integer Zero on success; non-zero on failure. */ public static function main($args) { printf("Application program number 11.\n"); $status = 0; $g = new GraphAsMatrix(32); Application11::weightedGraphTest($g); $g = new GraphAsLists(32); Application11::weightedGraphTest($g); $g = new DigraphAsMatrix(32); Application11::weightedDigraphTest($g); $g = new DigraphAsLists(32); Application11::weightedDigraphTest($g); printf("Critical path analysis.\n"); $g = new DigraphAsMatrix(10); for ($v = 0; $v < 10; ++$v) { $g->addVertex($v); } $g->addEdge(0, 1, box(3)); $g->addEdge(1, 2, box(1)); $g->addEdge(1, 3, box(4)); $g->addEdge(2, 4, box(0)); $g->addEdge(3, 4, box(0)); $g->addEdge(4, 5, box(1)); $g->addEdge(5, 6, box(9)); $g->addEdge(5, 7, box(5)); $g->addEdge(6, 8, box(0)); $g->addEdge(7, 8, box(0)); $g->addEdge(8, 9, box(2)); printf("%s\n", str($g)); $g2 = Algorithms::criticalPathAnalysis($g); printf("%s\n", str($g2)); return $status; }
/** * Floyd's algorithm to solve the all-pairs, shortest path problem * for the given edge-weighted, directed graph. * * @param object IDigraph $g An edge-weighted, directed graph. * It is assumed that the edge weights are BoxedIntegers. * @return object IDigraph An edge-weighted, directed graph. * There is an edge in the result for each pair of vertices * if a path that connects those vertices exists. * The weight on the edge is the length of the shortest path * between the two vertices it connects. */ public static function floydsAlgorithm(IDigraph $g) { $n = $g->getNumberOfVertices(); $distance = new DenseMatrix($n, $n); for ($v = 0; $v < $n; ++$v) { for ($w = 0; $w < $n; ++$w) { $distance[array($v, $w)] = Limits::MAXINT; } } foreach ($g->getEdges() as $edge) { $wt = $edge->getWeight(); $distance[array($edge->getV0()->getNumber(), $edge->getV1()->getNumber())] = unbox($wt); } for ($i = 0; $i < $n; ++$i) { for ($v = 0; $v < $n; ++$v) { for ($w = 0; $w < $n; ++$w) { if ($distance[array($v, $i)] != Limits::MAXINT && $distance[array($i, $w)] != Limits::MAXINT) { $d = $distance[array($v, $i)] + $distance[array($i, $w)]; if ($distance[array($v, $w)] > $d) { $distance[array($v, $w)] = $d; } } } } } $result = new DigraphAsMatrix($n); for ($v = 0; $v < $n; ++$v) { $result->addVertex($v); } for ($v = 0; $v < $n; ++$v) { for ($w = 0; $w < $n; ++$w) { if ($distance[array($v, $w)] != limits::MAXINT) { $result->addEdge($v, $w, box($distance[array($v, $w)])); } } } return $result; }