Gliph\Algorithm\ConnectedComponent::tarjan_scc PHP Method

tarjan_scc() public static method

Finds connected components in the provided directed graph.
public static tarjan_scc ( Gliph\Graph\Digraph $graph, Gliph\Visitor\TarjanSCCVisitor $visitor = NULL ) : Gliph\Visitor\TarjanSCCVisitor
$graph Gliph\Graph\Digraph The Digraph to search for connected components.
$visitor Gliph\Visitor\TarjanSCCVisitor The visitor that will collect and store the connected components. One will be created if not provided.
return Gliph\Visitor\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;
    }

Usage Example

 /**
  * @covers \Gliph\Algorithm\ConnectedComponent::tarjan_scc()
  */
 public function testTarjanScc()
 {
     $a = new TestVertex('a');
     $b = new TestVertex('b');
     $c = new TestVertex('c');
     $d = new TestVertex('d');
     $e = new TestVertex('e');
     $f = new TestVertex('f');
     $g = new TestVertex('g');
     $h = new TestVertex('h');
     $graph = new DirectedAdjacencyList();
     $graph->addDirectedEdge($a, $d);
     $graph->addDirectedEdge($a, $b);
     $graph->addDirectedEdge($b, $c);
     $graph->addDirectedEdge($c, $d);
     $graph->addDirectedEdge($d, $a);
     $graph->addDirectedEdge($e, $d);
     $graph->addDirectedEdge($f, $g);
     $graph->addDirectedEdge($g, $h);
     $graph->addDirectedEdge($h, $f);
     $visitor = ConnectedComponent::tarjan_scc($graph);
     $expected_full = array(array($c, $b, $d, $a), array($e), array($h, $g, $f));
     $this->assertEquals($expected_full, $visitor->getComponents());
     $expected_full = array(array($c, $b, $d, $a), array($h, $g, $f));
     $this->assertEquals($expected_full, $visitor->getConnectedComponents());
 }
All Usage Examples Of Gliph\Algorithm\ConnectedComponent::tarjan_scc
ConnectedComponent