File indexing completed on 2025-01-18 09:37:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #ifndef BOOST_BOYKOV_KOLMOGOROV_MAX_FLOW_HPP
0033 #define BOOST_BOYKOV_KOLMOGOROV_MAX_FLOW_HPP
0034
0035 #include <boost/config.hpp>
0036 #include <boost/assert.hpp>
0037 #include <vector>
0038 #include <list>
0039 #include <utility>
0040 #include <iosfwd>
0041 #include <algorithm> // for std::min and std::max
0042
0043 #include <boost/pending/queue.hpp>
0044 #include <boost/limits.hpp>
0045 #include <boost/property_map/property_map.hpp>
0046 #include <boost/none_t.hpp>
0047 #include <boost/graph/graph_concepts.hpp>
0048 #include <boost/graph/named_function_params.hpp>
0049 #include <boost/graph/lookup_edge.hpp>
0050 #include <boost/concept/assert.hpp>
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 namespace boost
0065 {
0066
0067 namespace detail
0068 {
0069
0070 template < class Graph, class EdgeCapacityMap,
0071 class ResidualCapacityEdgeMap, class ReverseEdgeMap,
0072 class PredecessorMap, class ColorMap, class DistanceMap,
0073 class IndexMap >
0074 class bk_max_flow
0075 {
0076 typedef
0077 typename property_traits< EdgeCapacityMap >::value_type tEdgeVal;
0078 typedef graph_traits< Graph > tGraphTraits;
0079 typedef typename tGraphTraits::vertex_iterator vertex_iterator;
0080 typedef typename tGraphTraits::vertex_descriptor vertex_descriptor;
0081 typedef typename tGraphTraits::edge_descriptor edge_descriptor;
0082 typedef typename tGraphTraits::edge_iterator edge_iterator;
0083 typedef typename tGraphTraits::out_edge_iterator out_edge_iterator;
0084 typedef boost::queue< vertex_descriptor >
0085 tQueue;
0086 typedef typename property_traits< ColorMap >::value_type tColorValue;
0087 typedef color_traits< tColorValue > tColorTraits;
0088 typedef
0089 typename property_traits< DistanceMap >::value_type tDistanceVal;
0090
0091 public:
0092 bk_max_flow(Graph& g, EdgeCapacityMap cap, ResidualCapacityEdgeMap res,
0093 ReverseEdgeMap rev, PredecessorMap pre, ColorMap color,
0094 DistanceMap dist, IndexMap idx, vertex_descriptor src,
0095 vertex_descriptor sink)
0096 : m_g(g)
0097 , m_index_map(idx)
0098 , m_cap_map(cap)
0099 , m_res_cap_map(res)
0100 , m_rev_edge_map(rev)
0101 , m_pre_map(pre)
0102 , m_tree_map(color)
0103 , m_dist_map(dist)
0104 , m_source(src)
0105 , m_sink(sink)
0106 , m_active_nodes()
0107 , m_in_active_list_vec(num_vertices(g), false)
0108 , m_in_active_list_map(make_iterator_property_map(
0109 m_in_active_list_vec.begin(), m_index_map))
0110 , m_has_parent_vec(num_vertices(g), false)
0111 , m_has_parent_map(
0112 make_iterator_property_map(m_has_parent_vec.begin(), m_index_map))
0113 , m_time_vec(num_vertices(g), 0)
0114 , m_time_map(
0115 make_iterator_property_map(m_time_vec.begin(), m_index_map))
0116 , m_flow(0)
0117 , m_time(1)
0118 , m_last_grow_vertex(graph_traits< Graph >::null_vertex())
0119 {
0120
0121 vertex_iterator vi, v_end;
0122 for (boost::tie(vi, v_end) = vertices(m_g); vi != v_end; ++vi)
0123 {
0124 set_tree(*vi, tColorTraits::gray());
0125 }
0126
0127
0128 edge_iterator ei, e_end;
0129 for (boost::tie(ei, e_end) = edges(m_g); ei != e_end; ++ei)
0130 {
0131 put(m_res_cap_map, *ei, get(m_cap_map, *ei));
0132 BOOST_ASSERT(get(m_rev_edge_map, get(m_rev_edge_map, *ei))
0133 == *ei);
0134
0135 }
0136
0137 set_tree(m_source, tColorTraits::black());
0138 set_tree(m_sink, tColorTraits::white());
0139 put(m_time_map, m_source, 1);
0140 put(m_time_map, m_sink, 1);
0141 }
0142
0143 tEdgeVal max_flow()
0144 {
0145
0146 augment_direct_paths();
0147
0148 while (true)
0149 {
0150 bool path_found;
0151 edge_descriptor connecting_edge;
0152 boost::tie(connecting_edge, path_found)
0153 = grow();
0154 if (!path_found)
0155 {
0156
0157 break;
0158 }
0159 ++m_time;
0160 augment(connecting_edge);
0161 adopt();
0162 }
0163 return m_flow;
0164 }
0165
0166
0167
0168 protected:
0169 void augment_direct_paths()
0170 {
0171
0172
0173
0174
0175
0176 out_edge_iterator ei, e_end;
0177 for (boost::tie(ei, e_end) = out_edges(m_source, m_g); ei != e_end;
0178 ++ei)
0179 {
0180 edge_descriptor from_source = *ei;
0181 vertex_descriptor current_node = target(from_source, m_g);
0182 if (current_node == m_sink)
0183 {
0184 tEdgeVal cap = get(m_res_cap_map, from_source);
0185 put(m_res_cap_map, from_source, 0);
0186 m_flow += cap;
0187 continue;
0188 }
0189 edge_descriptor to_sink;
0190 bool is_there;
0191 boost::tie(to_sink, is_there)
0192 = lookup_edge(current_node, m_sink, m_g);
0193 if (is_there)
0194 {
0195 tEdgeVal cap_from_source = get(m_res_cap_map, from_source);
0196 tEdgeVal cap_to_sink = get(m_res_cap_map, to_sink);
0197 if (cap_from_source > cap_to_sink)
0198 {
0199 set_tree(current_node, tColorTraits::black());
0200 add_active_node(current_node);
0201 set_edge_to_parent(current_node, from_source);
0202 put(m_dist_map, current_node, 1);
0203 put(m_time_map, current_node, 1);
0204
0205
0206
0207 put(m_res_cap_map, from_source,
0208 get(m_res_cap_map, from_source) - cap_to_sink);
0209 put(m_res_cap_map, to_sink, 0);
0210 m_flow += cap_to_sink;
0211 }
0212 else if (cap_to_sink > 0)
0213 {
0214 set_tree(current_node, tColorTraits::white());
0215 add_active_node(current_node);
0216 set_edge_to_parent(current_node, to_sink);
0217 put(m_dist_map, current_node, 1);
0218 put(m_time_map, current_node, 1);
0219
0220
0221
0222 put(m_res_cap_map, to_sink,
0223 get(m_res_cap_map, to_sink) - cap_from_source);
0224 put(m_res_cap_map, from_source, 0);
0225 m_flow += cap_from_source;
0226 }
0227 }
0228 else if (get(m_res_cap_map, from_source))
0229 {
0230
0231
0232
0233 set_tree(current_node, tColorTraits::black());
0234 set_edge_to_parent(current_node, from_source);
0235 put(m_dist_map, current_node, 1);
0236 put(m_time_map, current_node, 1);
0237 add_active_node(current_node);
0238 }
0239 }
0240 for (boost::tie(ei, e_end) = out_edges(m_sink, m_g); ei != e_end;
0241 ++ei)
0242 {
0243 edge_descriptor to_sink = get(m_rev_edge_map, *ei);
0244 vertex_descriptor current_node = source(to_sink, m_g);
0245 if (get(m_res_cap_map, to_sink))
0246 {
0247 set_tree(current_node, tColorTraits::white());
0248 set_edge_to_parent(current_node, to_sink);
0249 put(m_dist_map, current_node, 1);
0250 put(m_time_map, current_node, 1);
0251 add_active_node(current_node);
0252 }
0253 }
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263 std::pair< edge_descriptor, bool > grow()
0264 {
0265 BOOST_ASSERT(m_orphans.empty());
0266 vertex_descriptor current_node;
0267 while ((current_node = get_next_active_node())
0268 != graph_traits< Graph >::null_vertex())
0269 {
0270 BOOST_ASSERT(get_tree(current_node) != tColorTraits::gray()
0271 && (has_parent(current_node) || current_node == m_source
0272 || current_node == m_sink));
0273
0274 if (get_tree(current_node) == tColorTraits::black())
0275 {
0276
0277 out_edge_iterator ei, e_end;
0278 if (current_node != m_last_grow_vertex)
0279 {
0280 m_last_grow_vertex = current_node;
0281 boost::tie(m_last_grow_edge_it, m_last_grow_edge_end)
0282 = out_edges(current_node, m_g);
0283 }
0284 for (; m_last_grow_edge_it != m_last_grow_edge_end;
0285 ++m_last_grow_edge_it)
0286 {
0287 edge_descriptor out_edge = *m_last_grow_edge_it;
0288 if (get(m_res_cap_map, out_edge) > 0)
0289 {
0290 vertex_descriptor other_node
0291 = target(out_edge, m_g);
0292 if (get_tree(other_node) == tColorTraits::gray())
0293 {
0294 set_tree(other_node,
0295 tColorTraits::black());
0296
0297
0298 set_edge_to_parent(
0299 other_node, out_edge);
0300 put(m_dist_map, other_node,
0301 get(m_dist_map, current_node)
0302 + 1);
0303
0304 put(m_time_map, other_node,
0305 get(m_time_map, current_node));
0306 add_active_node(other_node);
0307 }
0308 else if (get_tree(other_node)
0309 == tColorTraits::black())
0310 {
0311
0312
0313 if (is_closer_to_terminal(
0314 current_node, other_node))
0315 {
0316 set_edge_to_parent(other_node, out_edge);
0317 put(m_dist_map, other_node,
0318 get(m_dist_map, current_node) + 1);
0319 put(m_time_map, other_node,
0320 get(m_time_map, current_node));
0321 }
0322 }
0323 else
0324 {
0325 BOOST_ASSERT(get_tree(other_node)
0326 == tColorTraits::white());
0327
0328
0329
0330 return std::make_pair(out_edge, true);
0331 }
0332 }
0333 }
0334 }
0335 else
0336 {
0337 BOOST_ASSERT(
0338 get_tree(current_node) == tColorTraits::white());
0339 out_edge_iterator ei, e_end;
0340 if (current_node != m_last_grow_vertex)
0341 {
0342 m_last_grow_vertex = current_node;
0343 boost::tie(m_last_grow_edge_it, m_last_grow_edge_end)
0344 = out_edges(current_node, m_g);
0345 }
0346 for (; m_last_grow_edge_it != m_last_grow_edge_end;
0347 ++m_last_grow_edge_it)
0348 {
0349 edge_descriptor in_edge
0350 = get(m_rev_edge_map, *m_last_grow_edge_it);
0351 if (get(m_res_cap_map, in_edge) > 0)
0352 {
0353 vertex_descriptor other_node = source(in_edge, m_g);
0354 if (get_tree(other_node) == tColorTraits::gray())
0355 {
0356 set_tree(other_node,
0357 tColorTraits::white());
0358
0359
0360 set_edge_to_parent(
0361 other_node, in_edge);
0362 add_active_node(
0363 other_node);
0364 put(m_dist_map, other_node,
0365 get(m_dist_map, current_node)
0366 + 1);
0367 put(m_time_map, other_node,
0368 get(m_time_map, current_node));
0369 }
0370 else if (get_tree(other_node)
0371 == tColorTraits::white())
0372 {
0373 if (is_closer_to_terminal(
0374 current_node, other_node))
0375 {
0376
0377
0378 set_edge_to_parent(other_node, in_edge);
0379 put(m_dist_map, other_node,
0380 get(m_dist_map, current_node) + 1);
0381 put(m_time_map, other_node,
0382 get(m_time_map, current_node));
0383 }
0384 }
0385 else
0386 {
0387 BOOST_ASSERT(get_tree(other_node)
0388 == tColorTraits::black());
0389
0390
0391
0392 return std::make_pair(in_edge, true);
0393 }
0394 }
0395 }
0396 }
0397
0398
0399
0400
0401 finish_node(current_node);
0402 }
0403
0404
0405 return std::make_pair(edge_descriptor(), false);
0406 }
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420 void augment(edge_descriptor e)
0421 {
0422 BOOST_ASSERT(get_tree(target(e, m_g)) == tColorTraits::white());
0423 BOOST_ASSERT(get_tree(source(e, m_g)) == tColorTraits::black());
0424 BOOST_ASSERT(m_orphans.empty());
0425
0426 const tEdgeVal bottleneck = find_bottleneck(e);
0427
0428
0429
0430
0431 put(m_res_cap_map, e, get(m_res_cap_map, e) - bottleneck);
0432 BOOST_ASSERT(get(m_res_cap_map, e) >= 0);
0433 put(m_res_cap_map, get(m_rev_edge_map, e),
0434 get(m_res_cap_map, get(m_rev_edge_map, e)) + bottleneck);
0435
0436
0437 vertex_descriptor current_node = source(e, m_g);
0438 while (current_node != m_source)
0439 {
0440 edge_descriptor pred = get_edge_to_parent(current_node);
0441 put(m_res_cap_map, pred, get(m_res_cap_map, pred) - bottleneck);
0442 BOOST_ASSERT(get(m_res_cap_map, pred) >= 0);
0443 put(m_res_cap_map, get(m_rev_edge_map, pred),
0444 get(m_res_cap_map, get(m_rev_edge_map, pred)) + bottleneck);
0445 if (get(m_res_cap_map, pred) == 0)
0446 {
0447 set_no_parent(current_node);
0448 m_orphans.push_front(current_node);
0449 }
0450 current_node = source(pred, m_g);
0451 }
0452
0453 current_node = target(e, m_g);
0454 while (current_node != m_sink)
0455 {
0456 edge_descriptor pred = get_edge_to_parent(current_node);
0457 put(m_res_cap_map, pred, get(m_res_cap_map, pred) - bottleneck);
0458 BOOST_ASSERT(get(m_res_cap_map, pred) >= 0);
0459 put(m_res_cap_map, get(m_rev_edge_map, pred),
0460 get(m_res_cap_map, get(m_rev_edge_map, pred)) + bottleneck);
0461 if (get(m_res_cap_map, pred) == 0)
0462 {
0463 set_no_parent(current_node);
0464 m_orphans.push_front(current_node);
0465 }
0466 current_node = target(pred, m_g);
0467 }
0468
0469 m_flow += bottleneck;
0470 }
0471
0472
0473
0474
0475
0476 inline tEdgeVal find_bottleneck(edge_descriptor e)
0477 {
0478 BOOST_USING_STD_MIN();
0479 tEdgeVal minimum_cap = get(m_res_cap_map, e);
0480 vertex_descriptor current_node = source(e, m_g);
0481
0482 while (current_node != m_source)
0483 {
0484 edge_descriptor pred = get_edge_to_parent(current_node);
0485 minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION(
0486 minimum_cap, get(m_res_cap_map, pred));
0487 current_node = source(pred, m_g);
0488 }
0489
0490 current_node = target(e, m_g);
0491 while (current_node != m_sink)
0492 {
0493 edge_descriptor pred = get_edge_to_parent(current_node);
0494 minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION(
0495 minimum_cap, get(m_res_cap_map, pred));
0496 current_node = target(pred, m_g);
0497 }
0498 return minimum_cap;
0499 }
0500
0501
0502
0503
0504
0505
0506 void adopt()
0507 {
0508 while (!m_orphans.empty() || !m_child_orphans.empty())
0509 {
0510 vertex_descriptor current_node;
0511 if (m_child_orphans.empty())
0512 {
0513
0514 current_node = m_orphans.front();
0515 m_orphans.pop_front();
0516 }
0517 else
0518 {
0519 current_node = m_child_orphans.front();
0520 m_child_orphans.pop();
0521 }
0522 if (get_tree(current_node) == tColorTraits::black())
0523 {
0524
0525 tDistanceVal min_distance
0526 = (std::numeric_limits< tDistanceVal >::max)();
0527 edge_descriptor new_parent_edge;
0528 out_edge_iterator ei, e_end;
0529 for (boost::tie(ei, e_end) = out_edges(current_node, m_g);
0530 ei != e_end; ++ei)
0531 {
0532 const edge_descriptor in_edge
0533 = get(m_rev_edge_map, *ei);
0534 BOOST_ASSERT(target(in_edge, m_g)
0535 == current_node);
0536
0537 if (get(m_res_cap_map, in_edge) > 0)
0538 {
0539 vertex_descriptor other_node = source(in_edge, m_g);
0540 if (get_tree(other_node) == tColorTraits::black()
0541 && has_source_connect(other_node))
0542 {
0543 if (get(m_dist_map, other_node) < min_distance)
0544 {
0545 min_distance = get(m_dist_map, other_node);
0546 new_parent_edge = in_edge;
0547 }
0548 }
0549 }
0550 }
0551 if (min_distance
0552 != (std::numeric_limits< tDistanceVal >::max)())
0553 {
0554 set_edge_to_parent(current_node, new_parent_edge);
0555 put(m_dist_map, current_node, min_distance + 1);
0556 put(m_time_map, current_node, m_time);
0557 }
0558 else
0559 {
0560 put(m_time_map, current_node, 0);
0561 for (boost::tie(ei, e_end)
0562 = out_edges(current_node, m_g);
0563 ei != e_end; ++ei)
0564 {
0565 edge_descriptor in_edge = get(m_rev_edge_map, *ei);
0566 vertex_descriptor other_node = source(in_edge, m_g);
0567 if (get_tree(other_node) == tColorTraits::black()
0568 && other_node != m_source)
0569 {
0570 if (get(m_res_cap_map, in_edge) > 0)
0571 {
0572 add_active_node(other_node);
0573 }
0574 if (has_parent(other_node)
0575 && source(
0576 get_edge_to_parent(other_node), m_g)
0577 == current_node)
0578 {
0579
0580
0581 set_no_parent(other_node);
0582 m_child_orphans.push(other_node);
0583 }
0584 }
0585 }
0586 set_tree(current_node, tColorTraits::gray());
0587 }
0588 }
0589 else
0590 {
0591
0592 BOOST_ASSERT(
0593 get_tree(current_node) == tColorTraits::white());
0594 out_edge_iterator ei, e_end;
0595 edge_descriptor new_parent_edge;
0596 tDistanceVal min_distance
0597 = (std::numeric_limits< tDistanceVal >::max)();
0598 for (boost::tie(ei, e_end) = out_edges(current_node, m_g);
0599 ei != e_end; ++ei)
0600 {
0601 const edge_descriptor out_edge = *ei;
0602 if (get(m_res_cap_map, out_edge) > 0)
0603 {
0604 const vertex_descriptor other_node
0605 = target(out_edge, m_g);
0606 if (get_tree(other_node) == tColorTraits::white()
0607 && has_sink_connect(other_node))
0608 if (get(m_dist_map, other_node) < min_distance)
0609 {
0610 min_distance = get(m_dist_map, other_node);
0611 new_parent_edge = out_edge;
0612 }
0613 }
0614 }
0615 if (min_distance
0616 != (std::numeric_limits< tDistanceVal >::max)())
0617 {
0618 set_edge_to_parent(current_node, new_parent_edge);
0619 put(m_dist_map, current_node, min_distance + 1);
0620 put(m_time_map, current_node, m_time);
0621 }
0622 else
0623 {
0624 put(m_time_map, current_node, 0);
0625 for (boost::tie(ei, e_end)
0626 = out_edges(current_node, m_g);
0627 ei != e_end; ++ei)
0628 {
0629 const edge_descriptor out_edge = *ei;
0630 const vertex_descriptor other_node
0631 = target(out_edge, m_g);
0632 if (get_tree(other_node) == tColorTraits::white()
0633 && other_node != m_sink)
0634 {
0635 if (get(m_res_cap_map, out_edge) > 0)
0636 {
0637 add_active_node(other_node);
0638 }
0639 if (has_parent(other_node)
0640 && target(
0641 get_edge_to_parent(other_node), m_g)
0642 == current_node)
0643 {
0644
0645
0646 set_no_parent(other_node);
0647 m_child_orphans.push(other_node);
0648 }
0649 }
0650 }
0651 set_tree(current_node, tColorTraits::gray());
0652 }
0653 }
0654 }
0655 }
0656
0657
0658
0659
0660 inline vertex_descriptor get_next_active_node()
0661 {
0662 while (true)
0663 {
0664 if (m_active_nodes.empty())
0665 return graph_traits< Graph >::null_vertex();
0666 vertex_descriptor v = m_active_nodes.front();
0667
0668
0669
0670 if (!has_parent(v) && v != m_source && v != m_sink)
0671 {
0672 m_active_nodes.pop();
0673 put(m_in_active_list_map, v, false);
0674 }
0675 else
0676 {
0677 BOOST_ASSERT(get_tree(v) == tColorTraits::black()
0678 || get_tree(v) == tColorTraits::white());
0679 return v;
0680 }
0681 }
0682 }
0683
0684
0685
0686
0687 inline void add_active_node(vertex_descriptor v)
0688 {
0689 BOOST_ASSERT(get_tree(v) != tColorTraits::gray());
0690 if (get(m_in_active_list_map, v))
0691 {
0692 if (m_last_grow_vertex == v)
0693 {
0694 m_last_grow_vertex = graph_traits< Graph >::null_vertex();
0695 }
0696 return;
0697 }
0698 else
0699 {
0700 put(m_in_active_list_map, v, true);
0701 m_active_nodes.push(v);
0702 }
0703 }
0704
0705
0706
0707
0708
0709 inline void finish_node(vertex_descriptor v)
0710 {
0711 BOOST_ASSERT(m_active_nodes.front() == v);
0712 m_active_nodes.pop();
0713 put(m_in_active_list_map, v, false);
0714 m_last_grow_vertex = graph_traits< Graph >::null_vertex();
0715 }
0716
0717
0718
0719
0720
0721
0722 inline void remove_active_node(vertex_descriptor v)
0723 {
0724 BOOST_ASSERT(!has_parent(v));
0725 }
0726
0727
0728
0729
0730
0731 inline tColorValue get_tree(vertex_descriptor v) const
0732 {
0733 return get(m_tree_map, v);
0734 }
0735
0736
0737
0738
0739
0740 inline void set_tree(vertex_descriptor v, tColorValue t)
0741 {
0742 put(m_tree_map, v, t);
0743 }
0744
0745
0746
0747
0748 inline edge_descriptor get_edge_to_parent(vertex_descriptor v) const
0749 {
0750 return get(m_pre_map, v);
0751 }
0752
0753
0754
0755
0756 inline bool has_parent(vertex_descriptor v) const
0757 {
0758 return get(m_has_parent_map, v);
0759 }
0760
0761
0762
0763
0764 inline void set_edge_to_parent(
0765 vertex_descriptor v, edge_descriptor f_edge_to_parent)
0766 {
0767 BOOST_ASSERT(get(m_res_cap_map, f_edge_to_parent) > 0);
0768 put(m_pre_map, v, f_edge_to_parent);
0769 put(m_has_parent_map, v, true);
0770 }
0771
0772
0773
0774
0775
0776 inline void set_no_parent(vertex_descriptor v)
0777 {
0778 put(m_has_parent_map, v, false);
0779 }
0780
0781
0782
0783
0784
0785
0786 inline bool has_sink_connect(vertex_descriptor v)
0787 {
0788 tDistanceVal current_distance = 0;
0789 vertex_descriptor current_vertex = v;
0790 while (true)
0791 {
0792 if (get(m_time_map, current_vertex) == m_time)
0793 {
0794
0795
0796 current_distance += get(m_dist_map, current_vertex);
0797 break;
0798 }
0799 if (current_vertex == m_sink)
0800 {
0801 put(m_time_map, m_sink, m_time);
0802 break;
0803 }
0804 if (has_parent(current_vertex))
0805 {
0806
0807 current_vertex
0808 = target(get_edge_to_parent(current_vertex), m_g);
0809 ++current_distance;
0810 }
0811 else
0812 {
0813
0814 return false;
0815 }
0816 }
0817 current_vertex = v;
0818 while (get(m_time_map, current_vertex) != m_time)
0819 {
0820 put(m_dist_map, current_vertex, current_distance);
0821 --current_distance;
0822 put(m_time_map, current_vertex, m_time);
0823 current_vertex
0824 = target(get_edge_to_parent(current_vertex), m_g);
0825 }
0826 return true;
0827 }
0828
0829
0830
0831
0832
0833
0834 inline bool has_source_connect(vertex_descriptor v)
0835 {
0836 tDistanceVal current_distance = 0;
0837 vertex_descriptor current_vertex = v;
0838 while (true)
0839 {
0840 if (get(m_time_map, current_vertex) == m_time)
0841 {
0842
0843
0844 current_distance += get(m_dist_map, current_vertex);
0845 break;
0846 }
0847 if (current_vertex == m_source)
0848 {
0849 put(m_time_map, m_source, m_time);
0850 break;
0851 }
0852 if (has_parent(current_vertex))
0853 {
0854
0855 current_vertex
0856 = source(get_edge_to_parent(current_vertex), m_g);
0857 ++current_distance;
0858 }
0859 else
0860 {
0861
0862 return false;
0863 }
0864 }
0865 current_vertex = v;
0866 while (get(m_time_map, current_vertex) != m_time)
0867 {
0868 put(m_dist_map, current_vertex, current_distance);
0869 --current_distance;
0870 put(m_time_map, current_vertex, m_time);
0871 current_vertex
0872 = source(get_edge_to_parent(current_vertex), m_g);
0873 }
0874 return true;
0875 }
0876
0877
0878
0879
0880 inline bool is_closer_to_terminal(
0881 vertex_descriptor p, vertex_descriptor q)
0882 {
0883
0884
0885 return (get(m_time_map, q) <= get(m_time_map, p)
0886 && get(m_dist_map, q) > get(m_dist_map, p) + 1);
0887 }
0888
0889
0890
0891
0892 Graph& m_g;
0893 IndexMap m_index_map;
0894 EdgeCapacityMap m_cap_map;
0895 ResidualCapacityEdgeMap m_res_cap_map;
0896 ReverseEdgeMap m_rev_edge_map;
0897 PredecessorMap m_pre_map;
0898 ColorMap m_tree_map;
0899
0900 DistanceMap m_dist_map;
0901 vertex_descriptor m_source;
0902 vertex_descriptor m_sink;
0903
0904 tQueue m_active_nodes;
0905 std::vector< bool > m_in_active_list_vec;
0906 iterator_property_map< std::vector< bool >::iterator, IndexMap >
0907 m_in_active_list_map;
0908
0909 std::list< vertex_descriptor > m_orphans;
0910 tQueue m_child_orphans;
0911
0912
0913 std::vector< bool > m_has_parent_vec;
0914 iterator_property_map< std::vector< bool >::iterator, IndexMap >
0915 m_has_parent_map;
0916
0917 std::vector< long > m_time_vec;
0918
0919 iterator_property_map< std::vector< long >::iterator, IndexMap >
0920 m_time_map;
0921 tEdgeVal m_flow;
0922 long m_time;
0923 vertex_descriptor m_last_grow_vertex;
0924 out_edge_iterator m_last_grow_edge_it;
0925 out_edge_iterator m_last_grow_edge_end;
0926 };
0927
0928 }
0929
0930
0931
0932
0933
0934 template < class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap,
0935 class ReverseEdgeMap, class PredecessorMap, class ColorMap,
0936 class DistanceMap, class IndexMap >
0937 typename property_traits< CapacityEdgeMap >::value_type
0938 boykov_kolmogorov_max_flow(Graph& g, CapacityEdgeMap cap,
0939 ResidualCapacityEdgeMap res_cap, ReverseEdgeMap rev_map,
0940 PredecessorMap pre_map, ColorMap color, DistanceMap dist, IndexMap idx,
0941 typename graph_traits< Graph >::vertex_descriptor src,
0942 typename graph_traits< Graph >::vertex_descriptor sink)
0943 {
0944 typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor;
0945 typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor;
0946
0947
0948
0949 BOOST_CONCEPT_ASSERT(
0950 (VertexListGraphConcept< Graph >));
0951
0952 BOOST_CONCEPT_ASSERT((EdgeListGraphConcept< Graph >));
0953 BOOST_CONCEPT_ASSERT(
0954 (IncidenceGraphConcept< Graph >));
0955
0956 BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< CapacityEdgeMap,
0957 edge_descriptor >));
0958 BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< ResidualCapacityEdgeMap,
0959 edge_descriptor >));
0960 BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< ReverseEdgeMap,
0961 edge_descriptor >));
0962 BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< PredecessorMap,
0963 vertex_descriptor >));
0964 BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< ColorMap,
0965 vertex_descriptor >));
0966 BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< DistanceMap,
0967 vertex_descriptor >));
0968 BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< IndexMap,
0969 vertex_descriptor >));
0970 BOOST_ASSERT(num_vertices(g) >= 2 && src != sink);
0971
0972 detail::bk_max_flow< Graph, CapacityEdgeMap, ResidualCapacityEdgeMap,
0973 ReverseEdgeMap, PredecessorMap, ColorMap, DistanceMap, IndexMap >
0974 algo(g, cap, res_cap, rev_map, pre_map, color, dist, idx, src, sink);
0975
0976 return algo.max_flow();
0977 }
0978
0979
0980
0981
0982
0983 template < class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap,
0984 class ReverseEdgeMap, class IndexMap >
0985 typename property_traits< CapacityEdgeMap >::value_type
0986 boykov_kolmogorov_max_flow(Graph& g, CapacityEdgeMap cap,
0987 ResidualCapacityEdgeMap res_cap, ReverseEdgeMap rev, IndexMap idx,
0988 typename graph_traits< Graph >::vertex_descriptor src,
0989 typename graph_traits< Graph >::vertex_descriptor sink)
0990 {
0991 typename graph_traits< Graph >::vertices_size_type n_verts
0992 = num_vertices(g);
0993 std::vector< typename graph_traits< Graph >::edge_descriptor >
0994 predecessor_vec(n_verts);
0995 std::vector< default_color_type > color_vec(n_verts);
0996 std::vector< typename graph_traits< Graph >::vertices_size_type >
0997 distance_vec(n_verts);
0998 return boykov_kolmogorov_max_flow(g, cap, res_cap, rev,
0999 make_iterator_property_map(predecessor_vec.begin(), idx),
1000 make_iterator_property_map(color_vec.begin(), idx),
1001 make_iterator_property_map(distance_vec.begin(), idx), idx, src, sink);
1002 }
1003
1004
1005
1006
1007
1008
1009 template < class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap,
1010 class ReverseEdgeMap, class ColorMap, class IndexMap >
1011 typename property_traits< CapacityEdgeMap >::value_type
1012 boykov_kolmogorov_max_flow(Graph& g, CapacityEdgeMap cap,
1013 ResidualCapacityEdgeMap res_cap, ReverseEdgeMap rev, ColorMap color,
1014 IndexMap idx, typename graph_traits< Graph >::vertex_descriptor src,
1015 typename graph_traits< Graph >::vertex_descriptor sink)
1016 {
1017 typename graph_traits< Graph >::vertices_size_type n_verts
1018 = num_vertices(g);
1019 std::vector< typename graph_traits< Graph >::edge_descriptor >
1020 predecessor_vec(n_verts);
1021 std::vector< typename graph_traits< Graph >::vertices_size_type >
1022 distance_vec(n_verts);
1023 return boykov_kolmogorov_max_flow(g, cap, res_cap, rev,
1024 make_iterator_property_map(predecessor_vec.begin(), idx), color,
1025 make_iterator_property_map(distance_vec.begin(), idx), idx, src, sink);
1026 }
1027
1028
1029
1030
1031 template < class Graph, class P, class T, class R >
1032 typename detail::edge_capacity_value< Graph, P, T, R >::type
1033 boykov_kolmogorov_max_flow(Graph& g,
1034 typename graph_traits< Graph >::vertex_descriptor src,
1035 typename graph_traits< Graph >::vertex_descriptor sink,
1036 const bgl_named_params< P, T, R >& params)
1037 {
1038 return boykov_kolmogorov_max_flow(g,
1039 choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
1040 choose_pmap(get_param(params, edge_residual_capacity), g,
1041 edge_residual_capacity),
1042 choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
1043 choose_pmap(
1044 get_param(params, vertex_predecessor), g, vertex_predecessor),
1045 choose_pmap(get_param(params, vertex_color), g, vertex_color),
1046 choose_pmap(get_param(params, vertex_distance), g, vertex_distance),
1047 choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
1048 src, sink);
1049 }
1050
1051
1052
1053
1054 template < class Graph >
1055 typename property_traits<
1056 typename property_map< Graph, edge_capacity_t >::const_type >::value_type
1057 boykov_kolmogorov_max_flow(Graph& g,
1058 typename graph_traits< Graph >::vertex_descriptor src,
1059 typename graph_traits< Graph >::vertex_descriptor sink)
1060 {
1061 bgl_named_params< int, buffer_param_t > params(0);
1062 return boykov_kolmogorov_max_flow(g, src, sink, params);
1063 }
1064
1065 }
1066
1067 #endif