r_c_shortest_paths.hpp 27 KB

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