r_c_shortest_paths.hpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. // r_c_shortest_paths.hpp header file
  2. // Copyright Michael Drexl 2005, 2006.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_GRAPH_R_C_SHORTEST_PATHS_HPP
  7. #define BOOST_GRAPH_R_C_SHORTEST_PATHS_HPP
  8. #include <map>
  9. #include <queue>
  10. #include <vector>
  11. #include <list>
  12. #include <boost/make_shared.hpp>
  13. #include <boost/enable_shared_from_this.hpp>
  14. #include <boost/graph/graph_traits.hpp>
  15. #include <boost/graph/iteration_macros.hpp>
  16. #include <boost/property_map/property_map.hpp>
  17. namespace boost
  18. {
  19. // r_c_shortest_paths_label struct
  20. template < class Graph, class Resource_Container >
  21. struct r_c_shortest_paths_label
  22. : public boost::enable_shared_from_this<
  23. r_c_shortest_paths_label< Graph, Resource_Container > >
  24. {
  25. r_c_shortest_paths_label(const unsigned long n,
  26. const Resource_Container& rc = Resource_Container(),
  27. const boost::shared_ptr<
  28. r_c_shortest_paths_label< Graph, Resource_Container > >
  29. pl
  30. = boost::shared_ptr<
  31. r_c_shortest_paths_label< Graph, Resource_Container > >(),
  32. const typename graph_traits< Graph >::edge_descriptor& ed
  33. = graph_traits< Graph >::edge_descriptor(),
  34. const typename graph_traits< Graph >::vertex_descriptor& vd
  35. = graph_traits< Graph >::vertex_descriptor())
  36. : num(n)
  37. , cumulated_resource_consumption(rc)
  38. , p_pred_label(pl)
  39. , pred_edge(ed)
  40. , resident_vertex(vd)
  41. , b_is_dominated(false)
  42. , b_is_processed(false)
  43. {
  44. }
  45. r_c_shortest_paths_label& operator=(const r_c_shortest_paths_label& other)
  46. {
  47. if (this == &other)
  48. return *this;
  49. this->~r_c_shortest_paths_label();
  50. new (this) r_c_shortest_paths_label(other);
  51. return *this;
  52. }
  53. const unsigned long num;
  54. Resource_Container cumulated_resource_consumption;
  55. const boost::shared_ptr<
  56. r_c_shortest_paths_label< Graph, Resource_Container > >
  57. p_pred_label;
  58. const typename graph_traits< Graph >::edge_descriptor pred_edge;
  59. const typename graph_traits< Graph >::vertex_descriptor resident_vertex;
  60. bool b_is_dominated;
  61. bool b_is_processed;
  62. }; // r_c_shortest_paths_label
  63. template < class Graph, class Resource_Container >
  64. inline bool operator==(
  65. const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
  66. const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
  67. {
  68. return l1.cumulated_resource_consumption
  69. == l2.cumulated_resource_consumption;
  70. }
  71. template < class Graph, class Resource_Container >
  72. inline bool operator!=(
  73. const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
  74. const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
  75. {
  76. return !(l1 == l2);
  77. }
  78. template < class Graph, class Resource_Container >
  79. inline bool operator<(
  80. const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
  81. const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
  82. {
  83. return l1.cumulated_resource_consumption
  84. < l2.cumulated_resource_consumption;
  85. }
  86. template < class Graph, class Resource_Container >
  87. inline bool operator>(
  88. const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
  89. const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
  90. {
  91. return l2.cumulated_resource_consumption
  92. < l1.cumulated_resource_consumption;
  93. }
  94. template < class Graph, class Resource_Container >
  95. inline bool operator<=(
  96. const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
  97. const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
  98. {
  99. return l1 < l2 || l1 == l2;
  100. }
  101. template < class Graph, class Resource_Container >
  102. inline bool operator>=(
  103. const r_c_shortest_paths_label< Graph, Resource_Container >& l1,
  104. const r_c_shortest_paths_label< Graph, Resource_Container >& l2)
  105. {
  106. return l2 < l1 || l1 == l2;
  107. }
  108. template < typename Graph, typename Resource_Container >
  109. inline bool operator<(
  110. const boost::shared_ptr<
  111. r_c_shortest_paths_label< Graph, Resource_Container > >& t,
  112. const boost::shared_ptr<
  113. r_c_shortest_paths_label< Graph, Resource_Container > >& u)
  114. {
  115. return *t < *u;
  116. }
  117. template < typename Graph, typename Resource_Container >
  118. inline bool operator<=(
  119. const boost::shared_ptr<
  120. r_c_shortest_paths_label< Graph, Resource_Container > >& t,
  121. const boost::shared_ptr<
  122. r_c_shortest_paths_label< Graph, Resource_Container > >& u)
  123. {
  124. return *t <= *u;
  125. }
  126. template < typename Graph, typename Resource_Container >
  127. inline bool operator>(
  128. const boost::shared_ptr<
  129. r_c_shortest_paths_label< Graph, Resource_Container > >& t,
  130. const boost::shared_ptr<
  131. r_c_shortest_paths_label< Graph, Resource_Container > >& u)
  132. {
  133. return *t > *u;
  134. }
  135. template < typename Graph, typename Resource_Container >
  136. inline bool operator>=(
  137. const boost::shared_ptr<
  138. r_c_shortest_paths_label< Graph, Resource_Container > >& t,
  139. const boost::shared_ptr<
  140. r_c_shortest_paths_label< Graph, Resource_Container > >& u)
  141. {
  142. return *t >= *u;
  143. }
  144. namespace detail
  145. {
  146. // r_c_shortest_paths_dispatch function (body/implementation)
  147. template < class Graph, class VertexIndexMap, class EdgeIndexMap,
  148. class Resource_Container, class Resource_Extension_Function,
  149. class Dominance_Function, class Label_Allocator, class Visitor >
  150. void r_c_shortest_paths_dispatch(const Graph& g,
  151. const VertexIndexMap& vertex_index_map,
  152. const EdgeIndexMap& /*edge_index_map*/,
  153. typename graph_traits< Graph >::vertex_descriptor s,
  154. typename graph_traits< Graph >::vertex_descriptor t,
  155. // each inner vector corresponds to a pareto-optimal path
  156. std::vector<
  157. std::vector< typename graph_traits< Graph >::edge_descriptor > >&
  158. pareto_optimal_solutions,
  159. std::vector< Resource_Container >& pareto_optimal_resource_containers,
  160. bool b_all_pareto_optimal_solutions,
  161. // to initialize the first label/resource container
  162. // and to carry the type information
  163. const Resource_Container& rc, Resource_Extension_Function& ref,
  164. Dominance_Function& dominance,
  165. // to specify the memory management strategy for the labels
  166. Label_Allocator /*la*/, Visitor vis)
  167. {
  168. pareto_optimal_resource_containers.clear();
  169. pareto_optimal_solutions.clear();
  170. size_t i_label_num = 0;
  171. #if defined(BOOST_NO_CXX11_ALLOCATOR)
  172. typedef typename Label_Allocator::template rebind<
  173. r_c_shortest_paths_label< Graph, Resource_Container > >::other
  174. LAlloc;
  175. #else
  176. typedef typename std::allocator_traits< Label_Allocator >::
  177. template rebind_alloc<
  178. r_c_shortest_paths_label< Graph, Resource_Container > >
  179. LAlloc;
  180. typedef std::allocator_traits< LAlloc > LTraits;
  181. #endif
  182. LAlloc l_alloc;
  183. typedef boost::shared_ptr<
  184. r_c_shortest_paths_label< Graph, Resource_Container > >
  185. Splabel;
  186. std::priority_queue< Splabel, std::vector< Splabel >,
  187. std::greater< Splabel > >
  188. unprocessed_labels;
  189. bool b_feasible = true;
  190. Splabel splabel_first_label = boost::allocate_shared<
  191. r_c_shortest_paths_label< Graph, Resource_Container > >(l_alloc,
  192. i_label_num++, rc,
  193. boost::shared_ptr<
  194. r_c_shortest_paths_label< Graph, Resource_Container > >(),
  195. typename graph_traits< Graph >::edge_descriptor(), s);
  196. unprocessed_labels.push(splabel_first_label);
  197. std::vector< std::list< Splabel > > vec_vertex_labels_data(
  198. num_vertices(g));
  199. iterator_property_map<
  200. typename std::vector< std::list< Splabel > >::iterator,
  201. VertexIndexMap >
  202. vec_vertex_labels(vec_vertex_labels_data.begin(), vertex_index_map);
  203. vec_vertex_labels[s].push_back(splabel_first_label);
  204. typedef std::vector< typename std::list< Splabel >::iterator >
  205. vec_last_valid_positions_for_dominance_data_type;
  206. vec_last_valid_positions_for_dominance_data_type
  207. vec_last_valid_positions_for_dominance_data(num_vertices(g));
  208. iterator_property_map<
  209. typename vec_last_valid_positions_for_dominance_data_type::iterator,
  210. VertexIndexMap >
  211. vec_last_valid_positions_for_dominance(
  212. vec_last_valid_positions_for_dominance_data.begin(),
  213. vertex_index_map);
  214. BGL_FORALL_VERTICES_T(v, g, Graph)
  215. {
  216. put(vec_last_valid_positions_for_dominance, v,
  217. vec_vertex_labels[v].begin());
  218. }
  219. std::vector< size_t > vec_last_valid_index_for_dominance_data(
  220. num_vertices(g), 0);
  221. iterator_property_map< std::vector< size_t >::iterator, VertexIndexMap >
  222. vec_last_valid_index_for_dominance(
  223. vec_last_valid_index_for_dominance_data.begin(),
  224. vertex_index_map);
  225. std::vector< bool > b_vec_vertex_already_checked_for_dominance_data(
  226. num_vertices(g), false);
  227. iterator_property_map< std::vector< bool >::iterator, VertexIndexMap >
  228. b_vec_vertex_already_checked_for_dominance(
  229. b_vec_vertex_already_checked_for_dominance_data.begin(),
  230. vertex_index_map);
  231. while (!unprocessed_labels.empty()
  232. && vis.on_enter_loop(unprocessed_labels, g))
  233. {
  234. Splabel cur_label = unprocessed_labels.top();
  235. unprocessed_labels.pop();
  236. vis.on_label_popped(*cur_label, g);
  237. // an Splabel object in unprocessed_labels and the respective
  238. // Splabel object in the respective list<Splabel> of
  239. // vec_vertex_labels share their embedded r_c_shortest_paths_label
  240. // object to avoid memory leaks, dominated r_c_shortest_paths_label
  241. // objects are marked and deleted when popped from
  242. // unprocessed_labels, as they can no longer be deleted at the end
  243. // of the function; only the Splabel object in unprocessed_labels
  244. // still references the r_c_shortest_paths_label object this is also
  245. // for efficiency, because the else branch is executed only if there
  246. // is a chance that extending the label leads to new undominated
  247. // labels, which in turn is possible only if the label to be
  248. // extended is undominated
  249. if (!cur_label->b_is_dominated)
  250. {
  251. typename boost::graph_traits< Graph >::vertex_descriptor
  252. i_cur_resident_vertex
  253. = cur_label->resident_vertex;
  254. std::list< Splabel >& list_labels_cur_vertex
  255. = get(vec_vertex_labels, i_cur_resident_vertex);
  256. if (list_labels_cur_vertex.size() >= 2
  257. && vec_last_valid_index_for_dominance[i_cur_resident_vertex]
  258. < list_labels_cur_vertex.size())
  259. {
  260. typename std::list< Splabel >::iterator outer_iter
  261. = list_labels_cur_vertex.begin();
  262. bool b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
  263. = false;
  264. while (outer_iter != list_labels_cur_vertex.end())
  265. {
  266. Splabel cur_outer_splabel = *outer_iter;
  267. typename std::list< Splabel >::iterator inner_iter
  268. = outer_iter;
  269. if (!b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
  270. && outer_iter
  271. == get(vec_last_valid_positions_for_dominance,
  272. i_cur_resident_vertex))
  273. b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
  274. = true;
  275. if (!get(b_vec_vertex_already_checked_for_dominance,
  276. i_cur_resident_vertex)
  277. || b_outer_iter_at_or_beyond_last_valid_pos_for_dominance)
  278. {
  279. ++inner_iter;
  280. }
  281. else
  282. {
  283. inner_iter
  284. = get(vec_last_valid_positions_for_dominance,
  285. i_cur_resident_vertex);
  286. ++inner_iter;
  287. }
  288. bool b_outer_iter_erased = false;
  289. while (inner_iter != list_labels_cur_vertex.end())
  290. {
  291. Splabel cur_inner_splabel = *inner_iter;
  292. if (dominance(cur_outer_splabel
  293. ->cumulated_resource_consumption,
  294. cur_inner_splabel
  295. ->cumulated_resource_consumption))
  296. {
  297. typename std::list< Splabel >::iterator buf
  298. = inner_iter;
  299. ++inner_iter;
  300. list_labels_cur_vertex.erase(buf);
  301. if (cur_inner_splabel->b_is_processed)
  302. {
  303. cur_inner_splabel.reset();
  304. }
  305. else
  306. cur_inner_splabel->b_is_dominated = true;
  307. continue;
  308. }
  309. else
  310. ++inner_iter;
  311. if (dominance(cur_inner_splabel
  312. ->cumulated_resource_consumption,
  313. cur_outer_splabel
  314. ->cumulated_resource_consumption))
  315. {
  316. typename std::list< Splabel >::iterator buf
  317. = outer_iter;
  318. ++outer_iter;
  319. list_labels_cur_vertex.erase(buf);
  320. b_outer_iter_erased = true;
  321. if (cur_outer_splabel->b_is_processed)
  322. {
  323. cur_outer_splabel.reset();
  324. }
  325. else
  326. cur_outer_splabel->b_is_dominated = true;
  327. break;
  328. }
  329. }
  330. if (!b_outer_iter_erased)
  331. ++outer_iter;
  332. }
  333. if (list_labels_cur_vertex.size() > 1)
  334. put(vec_last_valid_positions_for_dominance,
  335. i_cur_resident_vertex,
  336. (--(list_labels_cur_vertex.end())));
  337. else
  338. put(vec_last_valid_positions_for_dominance,
  339. i_cur_resident_vertex,
  340. list_labels_cur_vertex.begin());
  341. put(b_vec_vertex_already_checked_for_dominance,
  342. i_cur_resident_vertex, true);
  343. put(vec_last_valid_index_for_dominance,
  344. i_cur_resident_vertex,
  345. list_labels_cur_vertex.size() - 1);
  346. }
  347. }
  348. if (!b_all_pareto_optimal_solutions
  349. && cur_label->resident_vertex == t)
  350. {
  351. // the devil don't sleep
  352. if (cur_label->b_is_dominated)
  353. {
  354. cur_label.reset();
  355. }
  356. while (unprocessed_labels.size())
  357. {
  358. Splabel l = unprocessed_labels.top();
  359. unprocessed_labels.pop();
  360. // delete only dominated labels, because nondominated labels
  361. // are deleted at the end of the function
  362. if (l->b_is_dominated)
  363. {
  364. l.reset();
  365. }
  366. }
  367. break;
  368. }
  369. if (!cur_label->b_is_dominated)
  370. {
  371. cur_label->b_is_processed = true;
  372. vis.on_label_not_dominated(*cur_label, g);
  373. typename graph_traits< Graph >::vertex_descriptor cur_vertex
  374. = cur_label->resident_vertex;
  375. typename graph_traits< Graph >::out_edge_iterator oei, oei_end;
  376. for (boost::tie(oei, oei_end) = out_edges(cur_vertex, g);
  377. oei != oei_end; ++oei)
  378. {
  379. b_feasible = true;
  380. Splabel new_label = boost::allocate_shared<
  381. r_c_shortest_paths_label< Graph, Resource_Container > >(
  382. l_alloc, i_label_num++,
  383. cur_label->cumulated_resource_consumption, cur_label,
  384. *oei, target(*oei, g));
  385. b_feasible = ref(g,
  386. new_label->cumulated_resource_consumption,
  387. new_label->p_pred_label->cumulated_resource_consumption,
  388. new_label->pred_edge);
  389. if (!b_feasible)
  390. {
  391. vis.on_label_not_feasible(*new_label, g);
  392. new_label.reset();
  393. }
  394. else
  395. {
  396. vis.on_label_feasible(*new_label, g);
  397. vec_vertex_labels[new_label->resident_vertex].push_back(
  398. new_label);
  399. unprocessed_labels.push(new_label);
  400. }
  401. }
  402. }
  403. else
  404. {
  405. vis.on_label_dominated(*cur_label, g);
  406. cur_label.reset();
  407. }
  408. }
  409. std::list< Splabel > dsplabels = get(vec_vertex_labels, t);
  410. typename std::list< Splabel >::const_iterator csi = dsplabels.begin();
  411. typename std::list< Splabel >::const_iterator csi_end = dsplabels.end();
  412. // if d could be reached from o
  413. if (!dsplabels.empty())
  414. {
  415. for (; csi != csi_end; ++csi)
  416. {
  417. std::vector< typename graph_traits< Graph >::edge_descriptor >
  418. cur_pareto_optimal_path;
  419. boost::shared_ptr<
  420. r_c_shortest_paths_label< Graph, Resource_Container > >
  421. p_cur_label = *csi;
  422. pareto_optimal_resource_containers.push_back(
  423. p_cur_label->cumulated_resource_consumption);
  424. while (p_cur_label->num != 0)
  425. {
  426. cur_pareto_optimal_path.push_back(p_cur_label->pred_edge);
  427. p_cur_label = p_cur_label->p_pred_label;
  428. // assertion b_is_valid beyond this point is not correct if
  429. // the domination function requires resource levels to be
  430. // strictly greater than existing values
  431. //
  432. // Example
  433. // Customers
  434. // id min_arrival max_departure
  435. // 2 0 974
  436. // 3 0 972
  437. // 4 0 964
  438. // 5 678 801
  439. //
  440. // Path A: 2-3-4-5 (times: 0-16-49-84-678)
  441. // Path B: 3-2-4-5 (times: 0-18-51-62-678)
  442. // The partial path 3-2-4 dominates the other partial path
  443. // 2-3-4, though the path 3-2-4-5 does not strictly dominate
  444. // the path 2-3-4-5
  445. }
  446. pareto_optimal_solutions.push_back(cur_pareto_optimal_path);
  447. if (!b_all_pareto_optimal_solutions)
  448. break;
  449. }
  450. }
  451. BGL_FORALL_VERTICES_T(i, g, Graph)
  452. {
  453. std::list< Splabel >& list_labels_cur_vertex = vec_vertex_labels[i];
  454. typename std::list< Splabel >::iterator si
  455. = list_labels_cur_vertex.begin();
  456. const typename std::list< Splabel >::iterator si_end
  457. = list_labels_cur_vertex.end();
  458. for (; si != si_end; ++si)
  459. {
  460. (*si).reset();
  461. }
  462. }
  463. } // r_c_shortest_paths_dispatch
  464. } // detail
  465. // default_r_c_shortest_paths_visitor struct
  466. struct default_r_c_shortest_paths_visitor
  467. {
  468. template < class Label, class Graph >
  469. void on_label_popped(const Label&, const Graph&)
  470. {
  471. }
  472. template < class Label, class Graph >
  473. void on_label_feasible(const Label&, const Graph&)
  474. {
  475. }
  476. template < class Label, class Graph >
  477. void on_label_not_feasible(const Label&, const Graph&)
  478. {
  479. }
  480. template < class Label, class Graph >
  481. void on_label_dominated(const Label&, const Graph&)
  482. {
  483. }
  484. template < class Label, class Graph >
  485. void on_label_not_dominated(const Label&, const Graph&)
  486. {
  487. }
  488. template < class Queue, class Graph >
  489. bool on_enter_loop(const Queue& queue, const Graph& graph)
  490. {
  491. return true;
  492. }
  493. }; // default_r_c_shortest_paths_visitor
  494. // default_r_c_shortest_paths_allocator
  495. typedef std::allocator< int > default_r_c_shortest_paths_allocator;
  496. // default_r_c_shortest_paths_allocator
  497. // r_c_shortest_paths functions (handle/interface)
  498. // first overload:
  499. // - return all pareto-optimal solutions
  500. // - specify Label_Allocator and Visitor arguments
  501. template < class Graph, class VertexIndexMap, class EdgeIndexMap,
  502. class Resource_Container, class Resource_Extension_Function,
  503. class Dominance_Function, class Label_Allocator, class Visitor >
  504. void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
  505. const EdgeIndexMap& edge_index_map,
  506. typename graph_traits< Graph >::vertex_descriptor s,
  507. typename graph_traits< Graph >::vertex_descriptor t,
  508. // each inner vector corresponds to a pareto-optimal path
  509. std::vector<
  510. std::vector< typename graph_traits< Graph >::edge_descriptor > >&
  511. pareto_optimal_solutions,
  512. std::vector< Resource_Container >& pareto_optimal_resource_containers,
  513. // to initialize the first label/resource container
  514. // and to carry the type information
  515. const Resource_Container& rc, const Resource_Extension_Function& ref,
  516. const Dominance_Function& dominance,
  517. // to specify the memory management strategy for the labels
  518. Label_Allocator la, Visitor vis)
  519. {
  520. r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
  521. pareto_optimal_solutions, pareto_optimal_resource_containers, true, rc,
  522. ref, dominance, la, vis);
  523. }
  524. // second overload:
  525. // - return only one pareto-optimal solution
  526. // - specify Label_Allocator and Visitor arguments
  527. template < class Graph, class VertexIndexMap, class EdgeIndexMap,
  528. class Resource_Container, class Resource_Extension_Function,
  529. class Dominance_Function, class Label_Allocator, class Visitor >
  530. void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
  531. const EdgeIndexMap& edge_index_map,
  532. typename graph_traits< Graph >::vertex_descriptor s,
  533. typename graph_traits< Graph >::vertex_descriptor t,
  534. std::vector< typename graph_traits< Graph >::edge_descriptor >&
  535. pareto_optimal_solution,
  536. Resource_Container& pareto_optimal_resource_container,
  537. // to initialize the first label/resource container
  538. // and to carry the type information
  539. const Resource_Container& rc, const Resource_Extension_Function& ref,
  540. const Dominance_Function& dominance,
  541. // to specify the memory management strategy for the labels
  542. Label_Allocator la, Visitor vis)
  543. {
  544. // each inner vector corresponds to a pareto-optimal path
  545. std::vector<
  546. std::vector< typename graph_traits< Graph >::edge_descriptor > >
  547. pareto_optimal_solutions;
  548. std::vector< Resource_Container > pareto_optimal_resource_containers;
  549. r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
  550. pareto_optimal_solutions, pareto_optimal_resource_containers, false, rc,
  551. ref, dominance, la, vis);
  552. if (!pareto_optimal_solutions.empty())
  553. {
  554. pareto_optimal_solution = pareto_optimal_solutions[0];
  555. pareto_optimal_resource_container
  556. = pareto_optimal_resource_containers[0];
  557. }
  558. }
  559. // third overload:
  560. // - return all pareto-optimal solutions
  561. // - use default Label_Allocator and Visitor
  562. template < class Graph, class VertexIndexMap, class EdgeIndexMap,
  563. class Resource_Container, class Resource_Extension_Function,
  564. class Dominance_Function >
  565. void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
  566. const EdgeIndexMap& edge_index_map,
  567. typename graph_traits< Graph >::vertex_descriptor s,
  568. typename graph_traits< Graph >::vertex_descriptor t,
  569. // each inner vector corresponds to a pareto-optimal path
  570. std::vector<
  571. std::vector< typename graph_traits< Graph >::edge_descriptor > >&
  572. pareto_optimal_solutions,
  573. std::vector< Resource_Container >& pareto_optimal_resource_containers,
  574. // to initialize the first label/resource container
  575. // and to carry the type information
  576. const Resource_Container& rc, const Resource_Extension_Function& ref,
  577. const Dominance_Function& dominance)
  578. {
  579. r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
  580. pareto_optimal_solutions, pareto_optimal_resource_containers, true, rc,
  581. ref, dominance, default_r_c_shortest_paths_allocator(),
  582. default_r_c_shortest_paths_visitor());
  583. }
  584. // fourth overload:
  585. // - return only one pareto-optimal solution
  586. // - use default Label_Allocator and Visitor
  587. template < class Graph, class VertexIndexMap, class EdgeIndexMap,
  588. class Resource_Container, class Resource_Extension_Function,
  589. class Dominance_Function >
  590. void r_c_shortest_paths(const Graph& g, const VertexIndexMap& vertex_index_map,
  591. const EdgeIndexMap& edge_index_map,
  592. typename graph_traits< Graph >::vertex_descriptor s,
  593. typename graph_traits< Graph >::vertex_descriptor t,
  594. std::vector< typename graph_traits< Graph >::edge_descriptor >&
  595. pareto_optimal_solution,
  596. Resource_Container& pareto_optimal_resource_container,
  597. // to initialize the first label/resource container
  598. // and to carry the type information
  599. const Resource_Container& rc, const Resource_Extension_Function& ref,
  600. const Dominance_Function& dominance)
  601. {
  602. // each inner vector corresponds to a pareto-optimal path
  603. std::vector<
  604. std::vector< typename graph_traits< Graph >::edge_descriptor > >
  605. pareto_optimal_solutions;
  606. std::vector< Resource_Container > pareto_optimal_resource_containers;
  607. r_c_shortest_paths_dispatch(g, vertex_index_map, edge_index_map, s, t,
  608. pareto_optimal_solutions, pareto_optimal_resource_containers, false, rc,
  609. ref, dominance, default_r_c_shortest_paths_allocator(),
  610. default_r_c_shortest_paths_visitor());
  611. if (!pareto_optimal_solutions.empty())
  612. {
  613. pareto_optimal_solution = pareto_optimal_solutions[0];
  614. pareto_optimal_resource_container
  615. = pareto_optimal_resource_containers[0];
  616. }
  617. }
  618. // r_c_shortest_paths
  619. // check_r_c_path function
  620. template < class Graph, class Resource_Container,
  621. class Resource_Extension_Function >
  622. void check_r_c_path(const Graph& g,
  623. const std::vector< typename graph_traits< Graph >::edge_descriptor >&
  624. ed_vec_path,
  625. const Resource_Container& initial_resource_levels,
  626. // if true, computed accumulated final resource levels must
  627. // be equal to desired_final_resource_levels
  628. // if false, computed accumulated final resource levels must
  629. // be less than or equal to desired_final_resource_levels
  630. bool b_result_must_be_equal_to_desired_final_resource_levels,
  631. const Resource_Container& desired_final_resource_levels,
  632. Resource_Container& actual_final_resource_levels,
  633. const Resource_Extension_Function& ref, bool& b_is_a_path_at_all,
  634. bool& b_feasible, bool& b_correctly_extended,
  635. typename graph_traits< Graph >::edge_descriptor& ed_last_extended_arc)
  636. {
  637. size_t i_size_ed_vec_path = ed_vec_path.size();
  638. std::vector< typename graph_traits< Graph >::edge_descriptor > buf_path;
  639. if (i_size_ed_vec_path == 0)
  640. b_feasible = true;
  641. else
  642. {
  643. if (i_size_ed_vec_path == 1
  644. || target(ed_vec_path[0], g) == source(ed_vec_path[1], g))
  645. buf_path = ed_vec_path;
  646. else
  647. for (size_t i = i_size_ed_vec_path; i > 0; --i)
  648. buf_path.push_back(ed_vec_path[i - 1]);
  649. for (size_t i = 0; i < i_size_ed_vec_path - 1; ++i)
  650. {
  651. if (target(buf_path[i], g) != source(buf_path[i + 1], g))
  652. {
  653. b_is_a_path_at_all = false;
  654. b_feasible = false;
  655. b_correctly_extended = false;
  656. return;
  657. }
  658. }
  659. }
  660. b_is_a_path_at_all = true;
  661. b_feasible = true;
  662. b_correctly_extended = false;
  663. Resource_Container current_resource_levels = initial_resource_levels;
  664. actual_final_resource_levels = current_resource_levels;
  665. for (size_t i = 0; i < i_size_ed_vec_path; ++i)
  666. {
  667. ed_last_extended_arc = buf_path[i];
  668. b_feasible = ref(g, actual_final_resource_levels,
  669. current_resource_levels, buf_path[i]);
  670. current_resource_levels = actual_final_resource_levels;
  671. if (!b_feasible)
  672. return;
  673. }
  674. if (b_result_must_be_equal_to_desired_final_resource_levels)
  675. b_correctly_extended
  676. = actual_final_resource_levels == desired_final_resource_levels
  677. ? true
  678. : false;
  679. else
  680. {
  681. if (actual_final_resource_levels < desired_final_resource_levels
  682. || actual_final_resource_levels == desired_final_resource_levels)
  683. b_correctly_extended = true;
  684. }
  685. } // check_path
  686. } // namespace
  687. #endif // BOOST_GRAPH_R_C_SHORTEST_PATHS_HPP