Skip to content

Commit 0e2607c

Browse files
authored
Merge pull request #39 from clue-labs/residual-parallel
Fix option to merge parallel edges when creating residual graph
2 parents 8846e11 + d797842 commit 0e2607c

File tree

2 files changed

+90
-17
lines changed

2 files changed

+90
-17
lines changed

src/ResidualGraph.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
namespace Graphp\Algorithms;
44

5-
use Graphp\Algorithms\BaseGraph;
6-
use Fhaculty\Graph\Exception\UnexpectedValueException;
7-
8-
use Fhaculty\Graph\Graph;
95
use Fhaculty\Graph\Edge\Base as Edge;
106
use Fhaculty\Graph\Edge\Directed as EdgeDirected;
7+
use Fhaculty\Graph\Exception\UnexpectedValueException;
8+
use Fhaculty\Graph\Graph;
119

1210
class ResidualGraph extends BaseGraph
1311
{
@@ -90,20 +88,22 @@ public function createGraph()
9088
*/
9189
private function mergeParallelEdges(Edge $newEdge)
9290
{
93-
$parallelEdges = $newEdge->getEdgesParallel();
94-
if ($parallelEdges) {
91+
$alg = new Parallel($this->graph);
92+
$parallelEdges = $alg->getEdgesParallelEdge($newEdge)->getVector();
9593

96-
$mergedCapacity = 0;
94+
if (!$parallelEdges) {
95+
return;
96+
}
9797

98-
foreach ($parallelEdges as $parallelEdge) {
99-
$mergedCapacity += $parallelEdge->getCapacity();
100-
}
98+
$mergedCapacity = 0;
99+
foreach ($parallelEdges as $parallelEdge) {
100+
$mergedCapacity += $parallelEdge->getCapacity();
101+
}
101102

102-
$newEdge->setCapacity($newEdge->getCapacity() + $mergedCapacity);
103+
$newEdge->setCapacity($newEdge->getCapacity() + $mergedCapacity);
103104

104-
foreach ($parallelEdges as $parallelEdge) {
105-
$parallelEdge->destroy();
106-
}
105+
foreach ($parallelEdges as $parallelEdge) {
106+
$parallelEdge->destroy();
107107
}
108108
}
109109
}

tests/ResidualGraphTest.php

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
<?php
22

3-
use Fhaculty\Graph\Exception\UnexpectedValueException;
4-
use Fhaculty\Graph\Edge\Base as Edge;
5-
use Graphp\Algorithms\ResidualGraph;
63
use Fhaculty\Graph\Graph;
4+
use Graphp\Algorithms\ResidualGraph;
75

86
class ResidualGraphTest extends TestCase
97
{
@@ -87,6 +85,81 @@ public function testEdgePartial()
8785
$this->assertGraphEquals($expected, $residual);
8886
}
8987

88+
public function testResidualGraphCanOptionallyKeepNullCapacityForEdgeWithZeroFlow()
89+
{
90+
// 1 -[0/2]-> 2
91+
$graph = new Graph();
92+
$v1 = $graph->createVertex(1);
93+
$v2 = $graph->createVertex(2);
94+
$v1->createEdgeTo($v2)->setFlow(0)->setCapacity(2);
95+
96+
// 1 -[0/2]-> 2
97+
// ^ |
98+
// \--[0/0]---/
99+
$expected = new Graph();
100+
$v1 = $expected->createVertex(1);
101+
$v2 = $expected->createVertex(2);
102+
$v1->createEdgeTo($v2)->setFlow(0)->setCapacity(2);
103+
$v2->createEdgeTo($v1)->setFlow(0)->setCapacity(0);
104+
105+
$alg = new ResidualGraph($graph);
106+
$alg->setKeepNullCapacity(true);
107+
$residual = $alg->createGraph();
108+
109+
$this->assertGraphEquals($expected, $residual);
110+
}
111+
112+
public function testResidualGraphCanOptionallyKeepNullCapacityForEdgeWithZeroCapacityRemaining()
113+
{
114+
// 1 -[2/2]-> 2
115+
$graph = new Graph();
116+
$v1 = $graph->createVertex(1);
117+
$v2 = $graph->createVertex(2);
118+
$v1->createEdgeTo($v2)->setFlow(2)->setCapacity(2);
119+
120+
// 1 -[0/0]-> 2
121+
// ^ |
122+
// \--[0/2]---/
123+
$expected = new Graph();
124+
$v1 = $expected->createVertex(1);
125+
$v2 = $expected->createVertex(2);
126+
$v1->createEdgeTo($v2)->setFlow(0)->setCapacity(0);
127+
$v2->createEdgeTo($v1)->setFlow(0)->setCapacity(2);
128+
129+
$alg = new ResidualGraph($graph);
130+
$alg->setKeepNullCapacity(true);
131+
$residual = $alg->createGraph();
132+
133+
$this->assertGraphEquals($expected, $residual);
134+
}
135+
136+
public function testParallelEdgesCanBeMerged()
137+
{
138+
// 1 -[1/2]-> 2
139+
// | ^
140+
// \--[2/3]---/
141+
$graph = new Graph();
142+
$v1 = $graph->createVertex(1);
143+
$v2 = $graph->createVertex(2);
144+
$v1->createEdgeTo($v2)->setFlow(1)->setCapacity(2);
145+
$v1->createEdgeTo($v2)->setFlow(2)->setCapacity(3);
146+
147+
// 1 -[0/2]-> 2
148+
// ^ |
149+
// \--[0/3]---/
150+
$expected = new Graph();
151+
$v1 = $expected->createVertex(1);
152+
$v2 = $expected->createVertex(2);
153+
$v1->createEdgeTo($v2)->setFlow(0)->setCapacity(2);
154+
$v2->createEdgeTo($v1)->setFlow(0)->setCapacity(3);
155+
156+
$alg = new ResidualGraph($graph);
157+
$alg->setMergeParallelEdges(true);
158+
$residual = $alg->createGraph();
159+
160+
$this->assertGraphEquals($expected, $residual);
161+
}
162+
90163
/**
91164
* expect exception for undirected edges
92165
* @expectedException UnexpectedValueException

0 commit comments

Comments
 (0)