r_c_shortest_paths.hpp 29 KB

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