/** * @param Digraph $graph * @param int $vertex */ private function depthSearch(Digraph $graph, int $vertex) { $this->onStack[$vertex] = true; $this->marked[$vertex] = true; foreach ($graph->adjacent($vertex) as $item) { if ($this->hasCircle()) { return; } else { if (!isset($this->marked[$item])) { $this->edgeTo[$item] = $vertex; $this->depthSearch($graph, $item); } else { if ($this->onStack[$item]) { $this->circle = new Stack(); for ($x = $vertex; $x !== $item; $x = $this->edgeTo[$x]) { $this->circle->add($x); } $this->circle->add($vertex); $this->circle->add($item); } } } } $this->onStack[$vertex] = false; }
/** * @return Digraph */ public function reverse() : Digraph { $graph = new Digraph($this->vertices); foreach ($this->adj as $index => $bag) { foreach ($bag as $item) { $graph->addEdge($item, $index); } } return $graph; }
<?php use Graph\Digraph; use Graph\DirectDepthFirstSearch; use Graph\DirectedCircle; spl_autoload_register(function ($class) { $file = str_replace('\\', '/', $class); require "../{$file}.php"; }); $edges = [[0, 5], [4, 3], [0, 1], [9, 12], [6, 4], [5, 4], [0, 2], [11, 12], [9, 10], [0, 6], [7, 8], [9, 11], [5, 3], [3, 0]]; $graph = new Digraph(count($edges)); foreach ($edges as $edge) { $graph->addEdge($edge[0], $edge[1]); } echo "edges: {$graph->edges()}\n"; echo "vertexes: {$graph->vertices()}\n"; echo "graph:\n{$graph}"; $dfs = new DirectDepthFirstSearch($graph, 0); echo "0 -> 7 ? {$dfs->marked(7)}\n"; echo "0 -> 6 ? {$dfs->marked(6)}\n"; $directCircle = new DirectedCircle($graph); echo "has circle: {$directCircle->hasCircle()}\n"; foreach ($directCircle->circle() as $item) { echo "{$item}\n"; }