public function createGraph() { $graph = new Graph(); $file = $this->getLines(); $countOfAllVertices = $this->readInt($file[0]); $countOfVerticesInA = $this->readInt($file[1]); if ($countOfVerticesInA > $countOfAllVertices || $countOfVerticesInA < 0) { throw new UnexpectedValueException('Invalid value for number of vertices in group 0'); } $graph->createVertices($countOfAllVertices); for ($i = 0; $i < $countOfVerticesInA; ++$i) { $graph->getVertex($i)->setGroup(0); } for ($k = $countOfVerticesInA; $k < $countOfAllVertices; ++$k) { $graph->getVertex($k)->setGroup(1); } unset($file[0]); unset($file[1]); foreach ($file as $zeile) { $parts = $this->readLine($zeile, array('vertex', 'vertex'), $graph); if ($this->directedEdges) { $edge = $parts[0]->createEdgeTo($parts[1]); } else { $edge = $parts[0]->createEdge($parts[1]); } } $alg = new AlgorithmGroups($graph); if (!$alg->isBipartit()) { throw new UnexpectedValueException('Graph read from file does not form a valid bipartit graph'); } return $graph; }
public function getEdges() { $alg = new Directed($this->graph); if ($alg->hasDirected()) { throw new UnexpectedValueException('Input graph contains directed edges'); } $alg = new Groups($this->graph); if (!$alg->isBipartit()) { throw new UnexpectedValueException('Input graph does not have bipartit groups assigned to each vertex. Consider Using "AlgorithmBipartit::createGraph()" first'); } // create temporary flow graph with supersource and supersink $graphFlow = $this->graph->createGraphCloneEdgeless(); $superSource = $graphFlow->createVertex()->setLayoutAttribute('label', 's*'); $superSink = $graphFlow->createVertex()->setLayoutAttribute('label', 't*'); $groups = $alg->getGroups(); $groupA = $groups[0]; $groupB = $groups[1]; // connect supersource s* to set A and supersink t* to set B foreach ($graphFlow->getVertices() as $vertex) { // we want to skip over supersource & supersink as they do not have a partition assigned if ($vertex === $superSource || $vertex === $superSink) { continue; } $group = $vertex->getGroup(); // source if ($group === $groupA) { $superSource->createEdgeTo($vertex)->setCapacity(1)->setFlow(0); // temporarily create edges from A->B for flow graph $originalVertex = $this->graph->getVertex($vertex->getId()); foreach ($originalVertex->getVerticesEdgeTo() as $vertexTarget) { $vertex->createEdgeTo($graphFlow->getVertex($vertexTarget->getId()))->setCapacity(1)->setFlow(0); } // sink } elseif ($group === $groupB) { $vertex->createEdgeTo($superSink)->setCapacity(1)->setFlow(0); } else { // @codeCoverageIgnoreStart throw new LogicException('Should not happen. Unknown set: ' + $belongingSet); // @codeCoverageIgnoreEnd } } // visualize($resultGraph); // calculate (s*, t*)-flow $algMaxFlow = new MaxFlowEdmondsKarp($superSource, $superSink); $resultGraph = $algMaxFlow->createGraph(); // destroy temporary supersource and supersink again $resultGraph->getVertex($superSink->getId())->destroy(); $resultGraph->getVertex($superSource->getId())->destroy(); $returnEdges = array(); foreach ($resultGraph->getEdges() as $edge) { // only keep matched edges if ($edge->getFlow() > 0) { $originalEdge = $this->graph->getEdgeClone($edge); $returnEdges[] = $originalEdge; } } return new Edges($returnEdges); }
public function testGraphTriangleCycleIsNotBipartit() { // 1 -> 2 -> 3 -> 1 $graph = new Graph(); $v1 = $graph->createVertex(1)->setGroup(1); $v2 = $graph->createVertex(2)->setGroup(2); $v3 = $graph->createVertex(3)->setGroup(1); $v1->createEdgeTo($v2); $v2->createEdgeTo($v3); $v3->createEdgeTo($v1); $alg = new AlgorithmGroups($graph); $this->assertEquals(array(1, 2), $alg->getGroups()); $this->assertEquals(2, $alg->getNumberOfGroups()); $this->assertTrue($alg->getVerticesGroup(123)->isEmpty()); $this->assertEquals(array(1 => $v1, 3 => $v3), $alg->getVerticesGroup(1)->getMap()); $this->assertFalse($alg->isBipartit()); }
/** * checks whether the input graph's vertex groups are a valid bipartition * * @return boolean * @uses AlgorithmGroups::isBipartit() */ public function isBipartitGroups() { $alg = new Groups($this->graph); return $alg->isBipartit(); }