106 FlowMap, Tolerance> OutResGraph; |
110 FlowMap, Tolerance> OutResGraph; |
107 typedef typename OutResGraph::Edge OutResEdge; |
111 typedef typename OutResGraph::Edge OutResEdge; |
108 |
112 |
109 OutResGraph* _out_res_graph; |
113 OutResGraph* _out_res_graph; |
110 |
114 |
111 typedef typename Graph::template NodeMap<OutResEdge> OutCurrentEdgeMap; |
|
112 OutCurrentEdgeMap* _out_current_edge; |
|
113 |
|
114 typedef RevGraphAdaptor<const Graph> RevGraph; |
115 typedef RevGraphAdaptor<const Graph> RevGraph; |
115 RevGraph* _rev_graph; |
116 RevGraph* _rev_graph; |
116 |
117 |
117 typedef ResGraphAdaptor<const RevGraph, Value, CapacityMap, |
118 typedef ResGraphAdaptor<const RevGraph, Value, CapacityMap, |
118 FlowMap, Tolerance> InResGraph; |
119 FlowMap, Tolerance> InResGraph; |
119 typedef typename InResGraph::Edge InResEdge; |
120 typedef typename InResGraph::Edge InResEdge; |
120 |
121 |
121 InResGraph* _in_res_graph; |
122 InResGraph* _in_res_graph; |
122 |
|
123 typedef typename Graph::template NodeMap<InResEdge> InCurrentEdgeMap; |
|
124 InCurrentEdgeMap* _in_current_edge; |
|
125 |
|
126 |
123 |
127 typedef IterableBoolMap<Graph, Node> WakeMap; |
124 typedef IterableBoolMap<Graph, Node> WakeMap; |
128 WakeMap* _wake; |
125 WakeMap* _wake; |
129 |
126 |
130 typedef typename Graph::template NodeMap<int> DistMap; |
127 typedef typename Graph::template NodeMap<int> DistMap; |
159 /// Constructor of the algorithm class. |
156 /// Constructor of the algorithm class. |
160 HaoOrlin(const Graph& graph, const CapacityMap& capacity, |
157 HaoOrlin(const Graph& graph, const CapacityMap& capacity, |
161 const Tolerance& tolerance = Tolerance()) : |
158 const Tolerance& tolerance = Tolerance()) : |
162 _graph(&graph), _capacity(&capacity), |
159 _graph(&graph), _capacity(&capacity), |
163 _preflow(0), _source(), _target(), |
160 _preflow(0), _source(), _target(), |
164 _out_res_graph(0), _out_current_edge(0), |
161 _out_res_graph(0), _rev_graph(0), _in_res_graph(0), |
165 _rev_graph(0), _in_res_graph(0), _in_current_edge(0), |
|
166 _wake(0),_dist(0), _excess(0), _source_set(0), |
162 _wake(0),_dist(0), _excess(0), _source_set(0), |
167 _highest_active(), _active_nodes(), _dormant_max(), _dormant(), |
163 _highest_active(), _active_nodes(), _dormant_max(), _dormant(), |
168 _min_cut(), _min_cut_map(0), _tolerance(tolerance) {} |
164 _min_cut(), _min_cut_map(0), _tolerance(tolerance) {} |
169 |
165 |
170 ~HaoOrlin() { |
166 ~HaoOrlin() { |
171 if (_min_cut_map) { |
167 if (_min_cut_map) { |
172 delete _min_cut_map; |
168 delete _min_cut_map; |
173 } |
169 } |
174 if (_in_current_edge) { |
|
175 delete _in_current_edge; |
|
176 } |
|
177 if (_in_res_graph) { |
170 if (_in_res_graph) { |
178 delete _in_res_graph; |
171 delete _in_res_graph; |
179 } |
172 } |
180 if (_rev_graph) { |
173 if (_rev_graph) { |
181 delete _rev_graph; |
174 delete _rev_graph; |
182 } |
175 } |
183 if (_out_current_edge) { |
|
184 delete _out_current_edge; |
|
185 } |
|
186 if (_out_res_graph) { |
176 if (_out_res_graph) { |
187 delete _out_res_graph; |
177 delete _out_res_graph; |
188 } |
178 } |
189 if (_source_set) { |
179 if (_source_set) { |
190 delete _source_set; |
180 delete _source_set; |
217 for (NodeIt it(*_graph); it != INVALID; ++it) { |
207 for (NodeIt it(*_graph); it != INVALID; ++it) { |
218 (*_wake)[it] = true; |
208 (*_wake)[it] = true; |
219 (*_dist)[it] = 1; |
209 (*_dist)[it] = 1; |
220 (*_excess)[it] = 0; |
210 (*_excess)[it] = 0; |
221 (*_source_set)[it] = false; |
211 (*_source_set)[it] = false; |
222 |
212 } |
223 res_graph.firstOut(current_edge[it], it); |
213 |
224 } |
214 _dormant[0].push_front(_source); |
|
215 (*_source_set)[_source] = true; |
|
216 _dormant_max = 0; |
|
217 (*_wake)[_source] = false; |
|
218 |
|
219 _level_size[0] = 1; |
|
220 _level_size[1] = _node_num - 1; |
225 |
221 |
226 _target = target; |
222 _target = target; |
227 (*_dist)[target] = 0; |
223 (*_dist)[target] = 0; |
228 |
224 |
229 for (ResOutEdgeIt it(res_graph, _source); it != INVALID; ++it) { |
225 for (ResOutEdgeIt it(res_graph, _source); it != INVALID; ++it) { |
230 Value delta = res_graph.rescap(it); |
226 Value delta = res_graph.rescap(it); |
231 if (!_tolerance.positive(delta)) continue; |
227 (*_excess)[_source] -= delta; |
232 |
|
233 (*_excess)[res_graph.source(it)] -= delta; |
|
234 res_graph.augment(it, delta); |
228 res_graph.augment(it, delta); |
235 Node a = res_graph.target(it); |
229 Node a = res_graph.target(it); |
236 if (!_tolerance.positive((*_excess)[a]) && |
230 if ((*_excess)[a] == 0 && (*_wake)[a] && a != _target) { |
237 (*_wake)[a] && a != _target) { |
|
238 _active_nodes[(*_dist)[a]].push_front(a); |
231 _active_nodes[(*_dist)[a]].push_front(a); |
239 if (_highest_active < (*_dist)[a]) { |
232 if (_highest_active < (*_dist)[a]) { |
240 _highest_active = (*_dist)[a]; |
233 _highest_active = (*_dist)[a]; |
241 } |
234 } |
242 } |
235 } |
243 (*_excess)[a] += delta; |
236 (*_excess)[a] += delta; |
244 } |
237 } |
245 |
238 |
246 _dormant[0].push_front(_source); |
|
247 (*_source_set)[_source] = true; |
|
248 _dormant_max = 0; |
|
249 (*_wake)[_source] = false; |
|
250 |
|
251 _level_size[0] = 1; |
|
252 _level_size[1] = _node_num - 1; |
|
253 |
239 |
254 do { |
240 do { |
255 Node n; |
241 Node n; |
256 while ((n = findActiveNode()) != INVALID) { |
242 while ((n = findActiveNode()) != INVALID) { |
257 ResEdge e; |
243 for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e) { |
258 while (_tolerance.positive((*_excess)[n]) && |
244 Node a = res_graph.target(e); |
259 (e = findAdmissibleEdge(n, res_graph, current_edge)) |
245 if ((*_dist)[a] >= (*_dist)[n] || !(*_wake)[a]) continue; |
260 != INVALID){ |
246 Value delta = res_graph.rescap(e); |
261 Value delta; |
247 if (_tolerance.positive((*_excess)[n] - delta)) { |
262 if ((*_excess)[n] < res_graph.rescap(e)) { |
248 (*_excess)[n] -= delta; |
|
249 } else { |
263 delta = (*_excess)[n]; |
250 delta = (*_excess)[n]; |
264 } else { |
251 (*_excess)[n] = 0; |
265 delta = res_graph.rescap(e); |
|
266 res_graph.nextOut(current_edge[n]); |
|
267 } |
252 } |
268 if (!_tolerance.positive(delta)) continue; |
|
269 res_graph.augment(e, delta); |
253 res_graph.augment(e, delta); |
270 (*_excess)[res_graph.source(e)] -= delta; |
254 if ((*_excess)[a] == 0 && a != _target) { |
271 Node a = res_graph.target(e); |
|
272 if (!_tolerance.positive((*_excess)[a]) && a != _target) { |
|
273 _active_nodes[(*_dist)[a]].push_front(a); |
255 _active_nodes[(*_dist)[a]].push_front(a); |
274 } |
256 } |
275 (*_excess)[a] += delta; |
257 (*_excess)[a] += delta; |
|
258 if ((*_excess)[n] == 0) break; |
276 } |
259 } |
277 if (_tolerance.positive((*_excess)[n])) { |
260 if ((*_excess)[n] != 0) { |
278 relabel(n, res_graph, current_edge); |
261 relabel(n, res_graph); |
279 } |
262 } |
280 } |
263 } |
281 |
264 |
282 Value current_value = cutValue(out); |
265 Value current_value = cutValue(out); |
283 if (_min_cut > current_value){ |
266 if (_min_cut > current_value){ |
370 } |
352 } |
371 } |
353 } |
372 |
354 |
373 if (wake_was_empty){ |
355 if (wake_was_empty){ |
374 for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) { |
356 for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) { |
375 if (_tolerance.positive((*_excess)[it])) { |
357 if ((*_excess)[it] != 0 && it != _target) { |
376 if ((*_wake)[it] && it != _target) { |
358 _active_nodes[(*_dist)[it]].push_front(it); |
377 _active_nodes[(*_dist)[it]].push_front(it); |
359 if (_highest_active < (*_dist)[it]) { |
378 } |
360 _highest_active = (*_dist)[it]; |
379 if (_highest_active < (*_dist)[it]) { |
|
380 _highest_active = (*_dist)[it]; |
|
381 } |
361 } |
382 } |
362 } |
383 } |
363 } |
384 } |
364 } |
385 |
365 |
386 for (ResOutEdgeIt e(res_graph, old_target); e!=INVALID; ++e){ |
366 Node n = old_target; |
387 if (!(*_source_set)[res_graph.target(e)]) { |
367 for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e){ |
388 Value delta = res_graph.rescap(e); |
368 Node a = res_graph.target(e); |
389 if (!_tolerance.positive(delta)) continue; |
369 if (!(*_wake)[a]) continue; |
390 res_graph.augment(e, delta); |
370 Value delta = res_graph.rescap(e); |
391 (*_excess)[res_graph.source(e)] -= delta; |
371 res_graph.augment(e, delta); |
392 Node a = res_graph.target(e); |
372 (*_excess)[n] -= delta; |
393 if (!_tolerance.positive((*_excess)[a]) && |
373 if ((*_excess)[a] == 0 && (*_wake)[a] && a != _target) { |
394 (*_wake)[a] && a != _target) { |
374 _active_nodes[(*_dist)[a]].push_front(a); |
395 _active_nodes[(*_dist)[a]].push_front(a); |
375 if (_highest_active < (*_dist)[a]) { |
396 if (_highest_active < (*_dist)[a]) { |
376 _highest_active = (*_dist)[a]; |
397 _highest_active = (*_dist)[a]; |
|
398 } |
|
399 } |
377 } |
400 (*_excess)[a] += delta; |
378 } |
401 } |
379 (*_excess)[a] += delta; |
402 } |
380 } |
403 |
381 |
404 return true; |
382 return true; |
405 } |
383 } |
406 |
384 |
407 Node findActiveNode() { |
385 Node findActiveNode() { |
408 while (_highest_active > 0 && _active_nodes[_highest_active].empty()){ |
386 while (_highest_active > 0 && _active_nodes[_highest_active].empty()){ |
409 --_highest_active; |
387 --_highest_active; |
410 } |
388 } |
411 if( _highest_active > 0) { |
389 if( _highest_active > 0) { |
412 Node n = _active_nodes[_highest_active].front(); |
390 Node n = _active_nodes[_highest_active].front(); |
413 _active_nodes[_highest_active].pop_front(); |
391 _active_nodes[_highest_active].pop_front(); |
414 return n; |
392 return n; |
415 } else { |
|
416 return INVALID; |
|
417 } |
|
418 } |
|
419 |
|
420 template <typename ResGraph, typename EdgeMap> |
|
421 typename ResGraph::Edge findAdmissibleEdge(const Node& n, |
|
422 ResGraph& res_graph, |
|
423 EdgeMap& current_edge) { |
|
424 typedef typename ResGraph::Edge ResEdge; |
|
425 ResEdge e = current_edge[n]; |
|
426 while (e != INVALID && |
|
427 ((*_dist)[n] <= (*_dist)[res_graph.target(e)] || |
|
428 !(*_wake)[res_graph.target(e)])) { |
|
429 res_graph.nextOut(e); |
|
430 } |
|
431 if (e != INVALID) { |
|
432 current_edge[n] = e; |
|
433 return e; |
|
434 } else { |
393 } else { |
435 return INVALID; |
394 return INVALID; |
436 } |
395 } |
437 } |
396 } |
438 |
397 |
510 _source_set = new SourceSetMap(*_graph); |
469 _source_set = new SourceSetMap(*_graph); |
511 } |
470 } |
512 if (!_out_res_graph) { |
471 if (!_out_res_graph) { |
513 _out_res_graph = new OutResGraph(*_graph, *_capacity, *_preflow); |
472 _out_res_graph = new OutResGraph(*_graph, *_capacity, *_preflow); |
514 } |
473 } |
515 if (!_out_current_edge) { |
|
516 _out_current_edge = new OutCurrentEdgeMap(*_graph); |
|
517 } |
|
518 if (!_rev_graph) { |
474 if (!_rev_graph) { |
519 _rev_graph = new RevGraph(*_graph); |
475 _rev_graph = new RevGraph(*_graph); |
520 } |
476 } |
521 if (!_in_res_graph) { |
477 if (!_in_res_graph) { |
522 _in_res_graph = new InResGraph(*_rev_graph, *_capacity, *_preflow); |
478 _in_res_graph = new InResGraph(*_rev_graph, *_capacity, *_preflow); |
523 } |
|
524 if (!_in_current_edge) { |
|
525 _in_current_edge = new InCurrentEdgeMap(*_graph); |
|
526 } |
479 } |
527 if (!_min_cut_map) { |
480 if (!_min_cut_map) { |
528 _min_cut_map = new MinCutMap(*_graph); |
481 _min_cut_map = new MinCutMap(*_graph); |
529 } |
482 } |
530 |
483 |
553 /// \brief Calculates a minimum cut with \f$ source \f$ on the |
506 /// \brief Calculates a minimum cut with \f$ source \f$ on the |
554 /// source-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source \in X \f$ |
507 /// source-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source \in X \f$ |
555 /// and minimal out-degree). The \c target is the initial target |
508 /// and minimal out-degree). The \c target is the initial target |
556 /// for the push-relabel algorithm. |
509 /// for the push-relabel algorithm. |
557 void calculateOut(const Node& target) { |
510 void calculateOut(const Node& target) { |
558 findMinCut(target, true, *_out_res_graph, *_out_current_edge); |
511 findMinCut(target, true, *_out_res_graph); |
559 } |
512 } |
560 |
513 |
561 /// \brief Calculates a minimum cut with \f$ source \f$ on the |
514 /// \brief Calculates a minimum cut with \f$ source \f$ on the |
562 /// sink-side. |
515 /// sink-side. |
563 /// |
516 /// |
581 /// sink-side (i.e. a set \f$ X\subsetneq V |
534 /// sink-side (i.e. a set \f$ X\subsetneq V |
582 /// \f$ with \f$ source \notin X \f$ and minimal out-degree). |
535 /// \f$ with \f$ source \notin X \f$ and minimal out-degree). |
583 /// The \c target is the initial |
536 /// The \c target is the initial |
584 /// target for the push-relabel algorithm. |
537 /// target for the push-relabel algorithm. |
585 void calculateIn(const Node& target) { |
538 void calculateIn(const Node& target) { |
586 findMinCut(target, false, *_in_res_graph, *_in_current_edge); |
539 findMinCut(target, false, *_in_res_graph); |
587 } |
540 } |
588 |
541 |
589 /// \brief Runs the algorithm. |
542 /// \brief Runs the algorithm. |
590 /// |
543 /// |
591 /// Runs the algorithm. It finds nodes \c source and \c target |
544 /// Runs the algorithm. It finds nodes \c source and \c target |