diff --git a/lib/Fhaculty/Graph/Algorithm/CycleFinder.php b/lib/Fhaculty/Graph/Algorithm/CycleFinder.php new file mode 100644 index 00000000..77395a65 --- /dev/null +++ b/lib/Fhaculty/Graph/Algorithm/CycleFinder.php @@ -0,0 +1,57 @@ +graph->getVertices()->getVector(); + + // Compute distance map + foreach($vertices as $u){ + foreach($vertices as $v){ + if($u === $v){ + continue; + } + if(isset($walkMap[$u->getId()][$v->getId()])){ + continue; + } + $distUV = new Dijkstra($u); + $walkMap[$u->getId()][$v->getId()] = $distUV->getWalkTo($v); + } + } + + // The eulerian path is the shortest + $minimum = count($this->graph->getEdges()) + 1; + $walk = null; + + // Find shortest + foreach($vertices as $u){ + foreach($vertices as $v){ + if($u === $v){ + continue; + } + $walkU = $walkMap[$u->getId()][$v->getId()]; + $walkV = $walkMap[$v->getId()][$u->getId()]; + $length = count($walkU->getEdges()) + count($walkV->getEdges()); + if($length < $minimum){ + $minimum = $length; + $walk = $walkU->append($walkV); + } + } + } + + return $walk; + } +} \ No newline at end of file diff --git a/tests/Fhaculty/Graph/Algorithm/CycleFinderTest.php b/tests/Fhaculty/Graph/Algorithm/CycleFinderTest.php new file mode 100644 index 00000000..f6382500 --- /dev/null +++ b/tests/Fhaculty/Graph/Algorithm/CycleFinderTest.php @@ -0,0 +1,35 @@ +createVertex("A"); + $B = $graph->createVertex("B"); + $C = $graph->createVertex("C"); + + $A->createEdgeTo($B); + $B->createEdgeTo($C); + $C->createEdgeTo($A); + $B->createEdgeTo($A); + + // $tarjan = new Tarjan($graph); + // $componentsVertices = $tarjan->getStronglyConnected(); + // foreach($componentsVertices as $componentVertices){ + // $component = $graph->createGraphCloneVertices($componentVertices); + + $find = new CycleFinder($graph); + $shortest = $find->getShortestCycle(); + + $walk = Walk::factoryCycleFromVertices(array($A, $B, $A)); + $this->assertSame($walk->__toString(), $shortest->__toString()); + } +} \ No newline at end of file