예제 #1
0
 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;
 }
예제 #2
0
파일: Flow.php 프로젝트: feffi/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);
 }
예제 #3
0
파일: GroupsTest.php 프로젝트: feffi/graph
 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());
 }
예제 #4
0
파일: Bipartit.php 프로젝트: feffi/graph
 /**
  * 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();
 }