File indexing completed on 2025-07-09 08:12:53
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GRAPH_R_C_SHORTEST_PATHS_HPP
0009 #define BOOST_GRAPH_R_C_SHORTEST_PATHS_HPP
0010
0011 #include <map>
0012 #include <queue>
0013 #include <vector>
0014 #include <list>
0015
0016 #include <boost/make_shared.hpp>
0017 #include <boost/enable_shared_from_this.hpp>
0018 #include <boost/graph/graph_traits.hpp>
0019 #include <boost/graph/iteration_macros.hpp>
0020 #include <boost/property_map/property_map.hpp>
0021
0022 namespace boost
0023 {
0024
0025
0026 template < class Graph, class Resource_Container >
0027 struct r_c_shortest_paths_label
0028 : public boost::enable_shared_from_this<
0029 r_c_shortest_paths_label< Graph, Resource_Container > >
0030 {
0031 r_c_shortest_paths_label(const unsigned long n,
0032 const Resource_Container& rc = Resource_Container(),
0033 const boost::shared_ptr<
0034 r_c_shortest_paths_label< Graph, Resource_Container > >
0035 pl
0036 = boost::shared_ptr<
0037 r_c_shortest_paths_label< Graph, Resource_Container > >(),
0038 const typename graph_traits< Graph >::edge_descriptor& ed
0039 = graph_traits< Graph >::edge_descriptor(),
0040 const typename graph_traits< Graph >::vertex_descriptor& vd
0041 = graph_traits< Graph >::vertex_descriptor())
0042 : num(n)
0043 , cumulated_resource_consumption(rc)
0044 , p_pred_label(pl)
0045 , pred_edge(ed)
0046 , resident_vertex(vd)
0047 , b_is_dominated(false)
0048 , b_is_processed(false)
0049 {
0050 }
0051
0052 r_c_shortest_paths_label& operator=(const r_c_shortest_paths_label& other)
0053 {
0054 if (this == &other)
0055 return *this;
0056 this->~r_c_shortest_paths_label();
0057 new (this) r_c_shortest_paths_label(other);
0058 return *this;
0059 }
0060 const unsigned long num;
0061 Resource_Container cumulated_resource_consumption;
0062 const boost::shared_ptr<
0063 r_c_shortest_paths_label< Graph, Resource_Container > >
0064 p_pred_label;
0065 const typename graph_traits< Graph >::edge_descriptor pred_edge;
0066 const typename graph_traits< Graph >::vertex_descriptor resident_vertex;
0067 bool b_is_dominated;
0068 bool b_is_processed;
0069 };
0070
0071 template < class Graph, class Resource_Container >
0072 inline bool operator==(
0073 const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
0074 const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
0075 {
0076 return l1.cumulated_resource_consumption
0077 == l2.cumulated_resource_consumption;
0078 }
0079
0080 template < class Graph, class Resource_Container >
0081 inline bool operator!=(
0082 const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
0083 const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
0084 {
0085 return !(l1 == l2);
0086 }
0087
0088 template < class Graph, class Resource_Container >
0089 inline bool operator<(
0090 const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
0091 const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
0092 {
0093 return l1.cumulated_resource_consumption
0094 < l2.cumulated_resource_consumption;
0095 }
0096
0097 template < class Graph, class Resource_Container >
0098 inline bool operator>(
0099 const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
0100 const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
0101 {
0102 return l2.cumulated_resource_consumption
0103 < l1.cumulated_resource_consumption;
0104 }
0105
0106 template < class Graph, class Resource_Container >
0107 inline bool operator<=(
0108 const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
0109 const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
0110 {
0111 return l1 < l2 || l1 == l2;
0112 }
0113
0114 template < class Graph, class Resource_Container >
0115 inline bool operator>=(
0116 const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
0117 const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
0118 {
0119 return l2 < l1 || l1 == l2;
0120 }
0121
0122 template < typename Graph, typename Resource_Container >
0123 inline bool operator<(
0124 const boost::shared_ptr<
0125 r_c_shortest_paths_label< Graph, Resource_Container > >& t,
0126 const boost::shared_ptr<
0127 r_c_shortest_paths_label< Graph, Resource_Container > >& u)
0128 {
0129 return *t < *u;
0130 }
0131
0132 template < typename Graph, typename Resource_Container >
0133 inline bool operator<=(
0134 const boost::shared_ptr<
0135 r_c_shortest_paths_label< Graph, Resource_Container > >& t,
0136 const boost::shared_ptr<
0137 r_c_shortest_paths_label< Graph, Resource_Container > >& u)
0138 {
0139 return *t <= *u;
0140 }
0141
0142 template < typename Graph, typename Resource_Container >
0143 inline bool operator>(
0144 const boost::shared_ptr<
0145 r_c_shortest_paths_label< Graph, Resource_Container > >& t,
0146 const boost::shared_ptr<
0147 r_c_shortest_paths_label< Graph, Resource_Container > >& u)
0148 {
0149 return *t > *u;
0150 }
0151
0152 template < typename Graph, typename Resource_Container >
0153 inline bool operator>=(
0154 const boost::shared_ptr<
0155 r_c_shortest_paths_label< Graph, Resource_Container > >& t,
0156 const boost::shared_ptr<
0157 r_c_shortest_paths_label< Graph, Resource_Container > >& u)
0158 {
0159 return *t >= *u;
0160 }
0161
0162 namespace detail
0163 {
0164
0165
0166 template < class Graph, class VertexIndexMap, class EdgeIndexMap,
0167 class Resource_Container, class Resource_Extension_Function,
0168 class Dominance_Function, class Label_Allocator, class Visitor >
0169 void r_c_shortest_paths_dispatch(const Graph& g,
0170 const VertexIndexMap& vertex_index_map,
0171 const EdgeIndexMap& ,
0172 typename graph_traits< Graph >::vertex_descriptor s,
0173 typename graph_traits< Graph >::vertex_descriptor t,
0174
0175 std::vector<
0176 std::vector< typename graph_traits< Graph >::edge_descriptor > >&
0177 pareto_optimal_solutions,
0178 std::vector< Resource_Container >& pareto_optimal_resource_containers,
0179 bool b_all_pareto_optimal_solutions,
0180
0181
0182 const Resource_Container& rc, Resource_Extension_Function& ref,
0183 Dominance_Function& dominance,
0184
0185 Label_Allocator , Visitor vis)
0186 {
0187 pareto_optimal_resource_containers.clear();
0188 pareto_optimal_solutions.clear();
0189
0190 size_t i_label_num = 0;
0191 #if defined(BOOST_NO_CXX11_ALLOCATOR)
0192 typedef typename Label_Allocator::template rebind<
0193 r_c_shortest_paths_label< Graph, Resource_Container > >::other
0194 LAlloc;
0195 #else
0196 typedef typename std::allocator_traits< Label_Allocator >::
0197 template rebind_alloc<
0198 r_c_shortest_paths_label< Graph, Resource_Container > >
0199 LAlloc;
0200 typedef std::allocator_traits< LAlloc > LTraits;
0201 #endif
0202 LAlloc l_alloc;
0203 typedef boost::shared_ptr<
0204 r_c_shortest_paths_label< Graph, Resource_Container > >
0205 Splabel;
0206 std::priority_queue< Splabel, std::vector< Splabel >,
0207 std::greater< Splabel > >
0208 unprocessed_labels;
0209
0210 bool b_feasible = true;
0211 Splabel splabel_first_label = boost::allocate_shared<
0212 r_c_shortest_paths_label< Graph, Resource_Container > >(l_alloc,
0213 i_label_num++, rc,
0214 boost::shared_ptr<
0215 r_c_shortest_paths_label< Graph, Resource_Container > >(),
0216 typename graph_traits< Graph >::edge_descriptor(), s);
0217
0218 unprocessed_labels.push(splabel_first_label);
0219 std::vector< std::list< Splabel > > vec_vertex_labels_data(
0220 num_vertices(g));
0221 iterator_property_map<
0222 typename std::vector< std::list< Splabel > >::iterator,
0223 VertexIndexMap >
0224 vec_vertex_labels(vec_vertex_labels_data.begin(), vertex_index_map);
0225 vec_vertex_labels[s].push_back(splabel_first_label);
0226 typedef std::vector< typename std::list< Splabel >::iterator >
0227 vec_last_valid_positions_for_dominance_data_type;
0228 vec_last_valid_positions_for_dominance_data_type
0229 vec_last_valid_positions_for_dominance_data(num_vertices(g));
0230 iterator_property_map<
0231 typename vec_last_valid_positions_for_dominance_data_type::iterator,
0232 VertexIndexMap >
0233 vec_last_valid_positions_for_dominance(
0234 vec_last_valid_positions_for_dominance_data.begin(),
0235 vertex_index_map);
0236 BGL_FORALL_VERTICES_T(v, g, Graph)
0237 {
0238 put(vec_last_valid_positions_for_dominance, v,
0239 vec_vertex_labels[v].begin());
0240 }
0241 std::vector< size_t > vec_last_valid_index_for_dominance_data(
0242 num_vertices(g), 0);
0243 iterator_property_map< std::vector< size_t >::iterator, VertexIndexMap >
0244 vec_last_valid_index_for_dominance(
0245 vec_last_valid_index_for_dominance_data.begin(),
0246 vertex_index_map);
0247 std::vector< bool > b_vec_vertex_already_checked_for_dominance_data(
0248 num_vertices(g), false);
0249 iterator_property_map< std::vector< bool >::iterator, VertexIndexMap >
0250 b_vec_vertex_already_checked_for_dominance(
0251 b_vec_vertex_already_checked_for_dominance_data.begin(),
0252 vertex_index_map);
0253
0254 while (!unprocessed_labels.empty()
0255 && vis.on_enter_loop(unprocessed_labels, g))
0256 {
0257 Splabel cur_label = unprocessed_labels.top();
0258 unprocessed_labels.pop();
0259 vis.on_label_popped(*cur_label, g);
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272 if (!cur_label->b_is_dominated)
0273 {
0274 typename boost::graph_traits< Graph >::vertex_descriptor
0275 i_cur_resident_vertex
0276 = cur_label->resident_vertex;
0277 std::list< Splabel >& list_labels_cur_vertex
0278 = get(vec_vertex_labels, i_cur_resident_vertex);
0279 if (list_labels_cur_vertex.size() >= 2
0280 && vec_last_valid_index_for_dominance[i_cur_resident_vertex]
0281 < list_labels_cur_vertex.size())
0282 {
0283 typename std::list< Splabel >::iterator outer_iter
0284 = list_labels_cur_vertex.begin();
0285 bool b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
0286 = false;
0287 while (outer_iter != list_labels_cur_vertex.end())
0288 {
0289 Splabel cur_outer_splabel = *outer_iter;
0290 typename std::list< Splabel >::iterator inner_iter
0291 = outer_iter;
0292 if (!b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
0293 && outer_iter
0294 == get(vec_last_valid_positions_for_dominance,
0295 i_cur_resident_vertex))
0296 b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
0297 = true;
0298 if (!get(b_vec_vertex_already_checked_for_dominance,
0299 i_cur_resident_vertex)
0300 || b_outer_iter_at_or_beyond_last_valid_pos_for_dominance)
0301 {
0302 ++inner_iter;
0303 }
0304 else
0305 {
0306 inner_iter
0307 = get(vec_last_valid_positions_for_dominance,
0308 i_cur_resident_vertex);
0309 ++inner_iter;
0310 }
0311 bool b_outer_iter_erased = false;
0312 while (inner_iter != list_labels_cur_vertex.end())
0313 {
0314 Splabel cur_inner_splabel = *inner_iter;
0315 if (dominance(cur_outer_splabel
0316 ->cumulated_resource_consumption,
0317 cur_inner_splabel
0318 ->cumulated_resource_consumption))
0319 {
0320 typename std::list< Splabel >::iterator buf
0321 = inner_iter;
0322 ++inner_iter;
0323 list_labels_cur_vertex.erase(buf);
0324 if (cur_inner_splabel->b_is_processed)
0325 {
0326 cur_inner_splabel.reset();
0327 }
0328 else
0329 cur_inner_splabel->b_is_dominated = true;
0330 continue;
0331 }
0332 else
0333 ++inner_iter;
0334 if (dominance(cur_inner_splabel
0335 ->cumulated_resource_consumption,
0336 cur_outer_splabel
0337 ->cumulated_resource_consumption))
0338 {
0339 typename std::list< Splabel >::iterator buf
0340 = outer_iter;
0341 ++outer_iter;
0342 list_labels_cur_vertex.erase(buf);
0343 b_outer_iter_erased = true;
0344 if (cur_outer_splabel->b_is_processed)
0345 {
0346 cur_outer_splabel.reset();
0347 }
0348 else
0349 cur_outer_splabel->b_is_dominated = true;
0350 break;
0351 }
0352 }
0353 if (!b_outer_iter_erased)
0354 ++outer_iter;
0355 }
0356 if (list_labels_cur_vertex.size() > 1)
0357 put(vec_last_valid_positions_for_dominance,
0358 i_cur_resident_vertex,
0359 (--(list_labels_cur_vertex.end())));
0360 else
0361 put(vec_last_valid_positions_for_dominance,
0362 i_cur_resident_vertex,
0363 list_labels_cur_vertex.begin());
0364 put(b_vec_vertex_already_checked_for_dominance,
0365 i_cur_resident_vertex, true);
0366 put(vec_last_valid_index_for_dominance,
0367 i_cur_resident_vertex,
0368 list_labels_cur_vertex.size() - 1);
0369 }
0370 }
0371 if (!b_all_pareto_optimal_solutions
0372 && cur_label->resident_vertex == t)
0373 {
0374
0375 if (cur_label->b_is_dominated)
0376 {
0377 cur_label.reset();
0378 }
0379 while (unprocessed_labels.size())
0380 {
0381 Splabel l = unprocessed_labels.top();
0382 unprocessed_labels.pop();
0383
0384
0385 if (l->b_is_dominated)
0386 {
0387 l.reset();
0388 }
0389 }
0390 break;
0391 }
0392 if (!cur_label->b_is_dominated)
0393 {
0394 cur_label->b_is_processed = true;
0395 vis.on_label_not_dominated(*cur_label, g);
0396 typename graph_traits< Graph >::vertex_descriptor cur_vertex
0397 = cur_label->resident_vertex;
0398 typename graph_traits< Graph >::out_edge_iterator oei, oei_end;
0399 for (boost::tie(oei, oei_end) = out_edges(cur_vertex, g);
0400 oei != oei_end; ++oei)
0401 {
0402 b_feasible = true;
0403 Splabel new_label = boost::allocate_shared<
0404 r_c_shortest_paths_label< Graph, Resource_Container > >(
0405 l_alloc, i_label_num++,
0406 cur_label->cumulated_resource_consumption, cur_label,
0407 *oei, target(*oei, g));
0408 b_feasible = ref(g,
0409 new_label->cumulated_resource_consumption,
0410 new_label->p_pred_label->cumulated_resource_consumption,
0411 new_label->pred_edge);
0412
0413 if (!b_feasible)
0414 {
0415 vis.on_label_not_feasible(*new_label, g);
0416 new_label.reset();
0417 }
0418 else
0419 {
0420 vis.on_label_feasible(*new_label, g);
0421 vec_vertex_labels[new_label->resident_vertex].push_back(
0422 new_label);
0423 unprocessed_labels.push(new_label);
0424 }
0425 }
0426 }
0427 else
0428 {
0429 vis.on_label_dominated(*cur_label, g);
0430 cur_label.reset();
0431 }
0432 }
0433 std::list< Splabel > dsplabels = get(vec_vertex_labels, t);
0434 if(!b_all_pareto_optimal_solutions)
0435 {
0436 dsplabels.sort();
0437 }
0438 typename std::list< Splabel >::const_iterator csi = dsplabels.begin();
0439 typename std::list< Splabel >::const_iterator csi_end = dsplabels.end();
0440
0441 if (!dsplabels.empty())
0442 {
0443 for (; csi != csi_end; ++csi)
0444 {
0445 std::vector< typename graph_traits< Graph >::edge_descriptor >
0446 cur_pareto_optimal_path;
0447 boost::shared_ptr<
0448 r_c_shortest_paths_label< Graph, Resource_Container > >
0449 p_cur_label = *csi;
0450 pareto_optimal_resource_containers.push_back(
0451 p_cur_label->cumulated_resource_consumption);
0452 while (p_cur_label->num != 0)
0453 {
0454 cur_pareto_optimal_path.push_back(p_cur_label->pred_edge);
0455 p_cur_label = p_cur_label->p_pred_label;
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474 }
0475 pareto_optimal_solutions.push_back(cur_pareto_optimal_path);
0476 if (!b_all_pareto_optimal_solutions)
0477 break;
0478 }
0479 }
0480
0481 BGL_FORALL_VERTICES_T(i, g, Graph)
0482 {
0483 std::list< Splabel >& list_labels_cur_vertex = vec_vertex_labels[i];
0484 typename std::list< Splabel >::iterator si
0485 = list_labels_cur_vertex.begin();
0486 const typename std::list< Splabel >::iterator si_end
0487 = list_labels_cur_vertex.end();
0488 for (; si != si_end; ++si)
0489 {
0490 (*si).reset();
0491 }
0492 }
0493 }
0494
0495 }
0496
0497
0498 struct default_r_c_shortest_paths_visitor
0499 {
0500 template < class Label, class Graph >
0501 void on_label_popped(const Label&, const Graph&)
0502 {
0503 }
0504 template < class Label, class Graph >
0505 void on_label_feasible(const Label&, const Graph&)
0506 {
0507 }
0508 template < class Label, class Graph >
0509 void on_label_not_feasible(const Label&, const Graph&)
0510 {
0511 }
0512 template < class Label, class Graph >
0513 void on_label_dominated(const Label&, const Graph&)
0514 {
0515 }
0516 template < class Label, class Graph >
0517 void on_label_not_dominated(const Label&, const Graph&)
0518 {
0519 }
0520 template < class Queue, class Graph >
0521 bool on_enter_loop(const Queue& queue, const Graph& graph)
0522 {
0523 return true;
0524 }
0525 };
0526
0527
0528 typedef std::allocator< int > default_r_c_shortest_paths_allocator;
0529
0530
0531
0532
0533
0534
0535 template < class Graph, class VertexIndexMap, class EdgeIndexMap,
0536 class Resource_Container, class Resource_Extension_Function,
0537 class Dominance_Function, class Label_Allocator, class Visitor >
0538 void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
0539 const EdgeIndexMap& edge_index_map,
0540 typename graph_traits< Graph >::vertex_descriptor s,
0541 typename graph_traits< Graph >::vertex_descriptor t,
0542
0543 std::vector<
0544 std::vector< typename graph_traits< Graph >::edge_descriptor > >&
0545 pareto_optimal_solutions,
0546 std::vector< Resource_Container >& pareto_optimal_resource_containers,
0547
0548
0549 const Resource_Container& rc, const Resource_Extension_Function& ref,
0550 const Dominance_Function& dominance,
0551
0552 Label_Allocator la, Visitor vis)
0553 {
0554 r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
0555 pareto_optimal_solutions, pareto_optimal_resource_containers, true, rc,
0556 ref, dominance, la, vis);
0557 }
0558
0559
0560
0561
0562 template < class Graph, class VertexIndexMap, class EdgeIndexMap,
0563 class Resource_Container, class Resource_Extension_Function,
0564 class Dominance_Function, class Label_Allocator, class Visitor >
0565 void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
0566 const EdgeIndexMap& edge_index_map,
0567 typename graph_traits< Graph >::vertex_descriptor s,
0568 typename graph_traits< Graph >::vertex_descriptor t,
0569 std::vector< typename graph_traits< Graph >::edge_descriptor >&
0570 pareto_optimal_solution,
0571 Resource_Container& pareto_optimal_resource_container,
0572
0573
0574 const Resource_Container& rc, const Resource_Extension_Function& ref,
0575 const Dominance_Function& dominance,
0576
0577 Label_Allocator la, Visitor vis)
0578 {
0579
0580 std::vector<
0581 std::vector< typename graph_traits< Graph >::edge_descriptor > >
0582 pareto_optimal_solutions;
0583 std::vector< Resource_Container > pareto_optimal_resource_containers;
0584 r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
0585 pareto_optimal_solutions, pareto_optimal_resource_containers, false, rc,
0586 ref, dominance, la, vis);
0587 if (!pareto_optimal_solutions.empty())
0588 {
0589 pareto_optimal_solution = pareto_optimal_solutions[0];
0590 pareto_optimal_resource_container
0591 = pareto_optimal_resource_containers[0];
0592 }
0593 }
0594
0595
0596
0597
0598 template < class Graph, class VertexIndexMap, class EdgeIndexMap,
0599 class Resource_Container, class Resource_Extension_Function,
0600 class Dominance_Function >
0601 void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
0602 const EdgeIndexMap& edge_index_map,
0603 typename graph_traits< Graph >::vertex_descriptor s,
0604 typename graph_traits< Graph >::vertex_descriptor t,
0605
0606 std::vector<
0607 std::vector< typename graph_traits< Graph >::edge_descriptor > >&
0608 pareto_optimal_solutions,
0609 std::vector< Resource_Container >& pareto_optimal_resource_containers,
0610
0611
0612 const Resource_Container& rc, const Resource_Extension_Function& ref,
0613 const Dominance_Function& dominance)
0614 {
0615 r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
0616 pareto_optimal_solutions, pareto_optimal_resource_containers, true, rc,
0617 ref, dominance, default_r_c_shortest_paths_allocator(),
0618 default_r_c_shortest_paths_visitor());
0619 }
0620
0621
0622
0623
0624 template < class Graph, class VertexIndexMap, class EdgeIndexMap,
0625 class Resource_Container, class Resource_Extension_Function,
0626 class Dominance_Function >
0627 void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
0628 const EdgeIndexMap& edge_index_map,
0629 typename graph_traits< Graph >::vertex_descriptor s,
0630 typename graph_traits< Graph >::vertex_descriptor t,
0631 std::vector< typename graph_traits< Graph >::edge_descriptor >&
0632 pareto_optimal_solution,
0633 Resource_Container& pareto_optimal_resource_container,
0634
0635
0636 const Resource_Container& rc, const Resource_Extension_Function& ref,
0637 const Dominance_Function& dominance)
0638 {
0639
0640 std::vector<
0641 std::vector< typename graph_traits< Graph >::edge_descriptor > >
0642 pareto_optimal_solutions;
0643 std::vector< Resource_Container > pareto_optimal_resource_containers;
0644 r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
0645 pareto_optimal_solutions, pareto_optimal_resource_containers, false, rc,
0646 ref, dominance, default_r_c_shortest_paths_allocator(),
0647 default_r_c_shortest_paths_visitor());
0648 if (!pareto_optimal_solutions.empty())
0649 {
0650 pareto_optimal_solution = pareto_optimal_solutions[0];
0651 pareto_optimal_resource_container
0652 = pareto_optimal_resource_containers[0];
0653 }
0654 }
0655
0656
0657
0658 template < class Graph, class Resource_Container,
0659 class Resource_Extension_Function >
0660 void check_r_c_path(const Graph& g,
0661 const std::vector< typename graph_traits< Graph >::edge_descriptor >&
0662 ed_vec_path,
0663 const Resource_Container& initial_resource_levels,
0664
0665
0666
0667
0668 bool b_result_must_be_equal_to_desired_final_resource_levels,
0669 const Resource_Container& desired_final_resource_levels,
0670 Resource_Container& actual_final_resource_levels,
0671 const Resource_Extension_Function& ref, bool& b_is_a_path_at_all,
0672 bool& b_feasible, bool& b_correctly_extended,
0673 typename graph_traits< Graph >::edge_descriptor& ed_last_extended_arc)
0674 {
0675 size_t i_size_ed_vec_path = ed_vec_path.size();
0676 std::vector< typename graph_traits< Graph >::edge_descriptor > buf_path;
0677 if (i_size_ed_vec_path == 0)
0678 b_feasible = true;
0679 else
0680 {
0681 if (i_size_ed_vec_path == 1
0682 || target(ed_vec_path[0], g) == source(ed_vec_path[1], g))
0683 buf_path = ed_vec_path;
0684 else
0685 for (size_t i = i_size_ed_vec_path; i > 0; --i)
0686 buf_path.push_back(ed_vec_path[i - 1]);
0687 for (size_t i = 0; i < i_size_ed_vec_path - 1; ++i)
0688 {
0689 if (target(buf_path[i], g) != source(buf_path[i + 1], g))
0690 {
0691 b_is_a_path_at_all = false;
0692 b_feasible = false;
0693 b_correctly_extended = false;
0694 return;
0695 }
0696 }
0697 }
0698 b_is_a_path_at_all = true;
0699 b_feasible = true;
0700 b_correctly_extended = false;
0701 Resource_Container current_resource_levels = initial_resource_levels;
0702 actual_final_resource_levels = current_resource_levels;
0703 for (size_t i = 0; i < i_size_ed_vec_path; ++i)
0704 {
0705 ed_last_extended_arc = buf_path[i];
0706 b_feasible = ref(g, actual_final_resource_levels,
0707 current_resource_levels, buf_path[i]);
0708 current_resource_levels = actual_final_resource_levels;
0709 if (!b_feasible)
0710 return;
0711 }
0712 if (b_result_must_be_equal_to_desired_final_resource_levels)
0713 b_correctly_extended
0714 = actual_final_resource_levels == desired_final_resource_levels
0715 ? true
0716 : false;
0717 else
0718 {
0719 if (actual_final_resource_levels < desired_final_resource_levels
0720 || actual_final_resource_levels == desired_final_resource_levels)
0721 b_correctly_extended = true;
0722 }
0723 }
0724
0725 }
0726
0727 #endif