A vertex (B) is a successor to another vertex (A) if an arc points from
A to B. In such an arc, A is considered the 'tail', B is considered the
'head', as it would be visually represented with an arrow:
A -> B
Note that, in set terms,
g.adjacentTo(x) == g.successorsOf(x) ∪ g.predecessorsOf(x)
public successorsOf ( object $vertex ) : Generator | ||
$vertex | object | The vertex whose successor vertices should be enumerated. |
Результат | Generator | A generator that yields successor vertices as values. |
/** * Finds connected components in the provided directed graph. * * @param Digraph $graph * The Digraph to search for connected components. * @param TarjanSCCVisitor $visitor * The visitor that will collect and store the connected components. One * will be created if not provided. * * @return TarjanSCCVisitor * The finalized visitor. */ public static function tarjan_scc(Digraph $graph, TarjanSCCVisitor $visitor = NULL) { $visitor = $visitor ?: new TarjanSCCVisitor(); $counter = 0; $stack = array(); $indices = new \SplObjectStorage(); $lowlimits = new \SplObjectStorage(); $visit = function ($vertex) use(&$visit, &$counter, $graph, &$stack, $indices, $lowlimits, $visitor) { $indices->attach($vertex, $counter); $lowlimits->attach($vertex, $counter); $stack[] = $vertex; $counter++; foreach ($graph->successorsOf($vertex) as $head) { if (!$indices->contains($head)) { $visit($head); $lowlimits[$vertex] = min($lowlimits[$vertex], $lowlimits[$head]); } else { if (in_array($head, $stack, TRUE)) { $lowlimits[$vertex] = min($lowlimits[$vertex], $indices[$head]); } } } if ($lowlimits[$vertex] === $indices[$vertex]) { $visitor->newComponent(); do { $other = array_pop($stack); $visitor->addToCurrentComponent($other); } while ($other != $vertex); } }; foreach ($graph->vertices() as $v) { if (!$indices->contains($v)) { $visit($v); } } return $visitor; }
public static function isLiveVar(Variable $var, Vertex $vtx, Digraph $graph) { static $seen = []; if (in_array($vtx, $seen, true)) { return false; } elseif (in_array($var, $vtx->getVariables(), true)) { return true; } $seen[] = $vtx; foreach ($graph->successorsOf($vtx) as $sub) { if (self::isLiveVar($var, $sub, $graph)) { array_pop($seen); return true; } } array_pop($seen); return false; }