r_c_shortest_paths.hpp 28 KB

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