33namespace Fhaculty \Graph \Algorithm \MinimumCostFlow ;
44
55use Fhaculty \Graph \Exception \DomainException ;
6-
76use Fhaculty \Graph \Exception \UnderflowException ;
8-
97use Fhaculty \Graph \Exception \UnexpectedValueException ;
10-
118use Fhaculty \Graph \Graph ;
129use Fhaculty \Graph \Vertex ;
1310use Fhaculty \Graph \Edge \Base as Edge ;
@@ -21,10 +18,9 @@ class SuccessiveShortestPath extends Base
2118{
2219 /**
2320 * @uses Graph::createGraphClone()
24- * @uses AlgorithmResidualGraph::createGraph()
25- * @uses AlgorithmSpMooreBellmanFord::getEdgesTo(Vertex $targetVertex)
26- *
27- * @see AlgorithmMCF::createGraph()
21+ * @uses ResidualGraph::createGraph()
22+ * @uses SpMooreBellmanFord::getEdgesTo(Vertex $targetVertex)
23+ * @see Base::createGraph()
2824 */
2925 public function createGraph ()
3026 {
@@ -40,29 +36,29 @@ public function createGraph()
4036 // initial flow of edges
4137 $ edges = $ resultGraph ->getEdges ();
4238 foreach ($ edges as $ edge ) {
43- // 0 if weight of edge is positiv
39+ if (!($ edge instanceof EdgeDirected)) {
40+ throw new UnexpectedValueException ('Undirected edges are not supported for SuccessiveShortestPath ' );
41+ }
42+
43+ // 0 if weight of edge is positive
4444 $ flow = 0 ;
4545
4646 // maximal flow if weight of edge is negative
4747 if ($ edge ->getWeight () < 0 ) {
4848 $ flow = $ edge ->getCapacity ();
4949
50- if ($ edge instanceof EdgeDirected) {
51- $ startVertex = $ edge ->getVertexStart ();
52- $ endVertex = $ edge ->getVertexEnd ();
50+ $ startVertex = $ edge ->getVertexStart ();
51+ $ endVertex = $ edge ->getVertexEnd ();
5352
54- // add balance to start- and end-vertex
55- $ this ->addBalance ($ startVertex , $ flow );
56- $ this ->addBalance ($ endVertex , - $ flow );
57- } else {
58- throw new UnexpectedValueException ('Undirected Edges not suported ' );
59- }
53+ // add balance to start- and end-vertex
54+ $ this ->addBalance ($ startVertex , $ flow );
55+ $ this ->addBalance ($ endVertex , - $ flow );
6056 }
6157
6258 $ edge ->setFlow ($ flow );
6359 }
6460
65- // return or Exception insite this while
61+ // return or Exception inside this while
6662 while (true ) {
6763 // create residual graph
6864 $ algRG = new ResidualGraph ($ resultGraph );
@@ -71,25 +67,25 @@ public function createGraph()
7167 // search for a source
7268 try {
7369 $ sourceVertex = $ this ->getVertexSource ($ residualGraph );
74- // if no source is found the minimum-cost flow is found
7570 } catch (UnderflowException $ ignore ) {
71+ // no source is found => minimum-cost flow is found
7672 break ;
7773 }
7874
79- // search for reachble sink from this source
75+ // search for reachable target sink from this source
8076 try {
8177 $ targetVertex = $ this ->getVertexSink ($ sourceVertex );
82- // if no target is found the network has not enough capacity
83- } catch ( UnderflowException $ ignore ) {
84- throw new UnexpectedValueException ('The graph has not enough capacity for the minimum-cost flow ' );
78+ } catch ( UnderflowException $ e ) {
79+ // no target found => network does not have enough capacity
80+ throw new UnexpectedValueException ('The graph has not enough capacity for the minimum-cost flow ' , 0 , $ e );
8581 }
8682
8783 // calculate shortest path between source- and target-vertex
8884 $ algSP = new SpMooreBellmanFord ($ sourceVertex );
8985 $ edgesOnFlow = $ algSP ->getEdgesTo ($ targetVertex );
9086
9187 // calculate the maximal possible flow
92- // new flow is the maximal possible flow for this path
88+ // new flow is the maximal possible flow for this path
9389 $ newflow = $ this ->graph ->getVertex ($ sourceVertex ->getId ())->getBalance () - $ sourceVertex ->getBalance ();
9490 $ targetFlow = - ($ this ->graph ->getVertex ($ targetVertex ->getId ())->getBalance () - $ targetVertex ->getBalance ());
9591
@@ -107,7 +103,7 @@ public function createGraph()
107103 // add the new flow to the path
108104 $ this ->addFlow ($ resultGraph , $ edgesOnFlow , $ newflow );
109105
110- // add balance to source and remove for the sink
106+ // add balance to source and remove for the target sink
111107 $ oriSourceVertex = $ resultGraph ->getVertex ($ sourceVertex ->getId ());
112108 $ oriTargetVertex = $ resultGraph ->getVertex ($ targetVertex ->getId ());
113109
@@ -118,29 +114,6 @@ public function createGraph()
118114 return $ resultGraph ;
119115 }
120116
121- /**
122- * check if balance on each vertex of the given graph matches the original graph's
123- *
124- * @param Graph $graph
125- * @return boolean
126- * @throws Exception if given graph is not a clone of the original graph (each vertex has to be present in both graphs)
127- * @uses Graph::getBalanace()
128- * @uses Graph::getVertex()
129- */
130- private function isBalanceReached (Graph $ graph )
131- {
132- if (count ($ graph ->getVertices ()) !== count ($ this ->graph ->getVertices ())) {
133- throw new DomainException ('Given graph does not appear to be a clone of input graph ' );
134- }
135- foreach ($ this ->graph ->getVertices ()->getMap () as $ vid => $ vertex ) {
136- if ($ vertex ->getBalance () !== $ graph ->getVertex ($ vid )->getBalance ()) {
137- return false ;
138- }
139- }
140-
141- return true ;
142- }
143-
144117 /**
145118 *
146119 *
0 commit comments