/Src/Dependencies/Boost/boost/graph/r_c_shortest_paths.hpp

http://hadesmem.googlecode.com/ · C++ Header · 733 lines · 630 code · 34 blank · 69 comment · 68 complexity · 2d9a3947850a8d65f5e623b646e4a1f2 MD5 · raw file

  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. unsigned long i_label_num = 0;
  172. typedef
  173. typename
  174. Label_Allocator::template rebind
  175. <r_c_shortest_paths_label
  176. <Graph, Resource_Container> >::other LAlloc;
  177. LAlloc l_alloc;
  178. typedef
  179. ks_smart_pointer
  180. <r_c_shortest_paths_label<Graph, Resource_Container> > Splabel;
  181. std::priority_queue<Splabel, std::vector<Splabel>, std::greater<Splabel> >
  182. unprocessed_labels;
  183. bool b_feasible = true;
  184. r_c_shortest_paths_label<Graph, Resource_Container>* first_label =
  185. l_alloc.allocate( 1 );
  186. l_alloc.construct
  187. ( first_label,
  188. r_c_shortest_paths_label
  189. <Graph, Resource_Container>( i_label_num++,
  190. rc,
  191. 0,
  192. typename graph_traits<Graph>::
  193. edge_descriptor(),
  194. s ) );
  195. Splabel splabel_first_label = Splabel( first_label );
  196. unprocessed_labels.push( splabel_first_label );
  197. std::vector<std::list<Splabel> > vec_vertex_labels( num_vertices( g ) );
  198. vec_vertex_labels[vertex_index_map[s]].push_back( splabel_first_label );
  199. std::vector<typename std::list<Splabel>::iterator>
  200. vec_last_valid_positions_for_dominance( num_vertices( g ) );
  201. for( int i = 0; i < static_cast<int>( num_vertices( g ) ); ++i )
  202. vec_last_valid_positions_for_dominance[i] = vec_vertex_labels[i].begin();
  203. std::vector<int> vec_last_valid_index_for_dominance( num_vertices( g ), 0 );
  204. std::vector<bool>
  205. b_vec_vertex_already_checked_for_dominance( num_vertices( g ), false );
  206. while( unprocessed_labels.size() )
  207. {
  208. Splabel cur_label = unprocessed_labels.top();
  209. unprocessed_labels.pop();
  210. vis.on_label_popped( *cur_label, g );
  211. // an Splabel object in unprocessed_labels and the respective Splabel
  212. // object in the respective list<Splabel> of vec_vertex_labels share their
  213. // embedded r_c_shortest_paths_label object
  214. // to avoid memory leaks, dominated
  215. // r_c_shortest_paths_label objects are marked and deleted when popped
  216. // from unprocessed_labels, as they can no longer be deleted at the end of
  217. // the function; only the Splabel object in unprocessed_labels still
  218. // references the r_c_shortest_paths_label object
  219. // this is also for efficiency, because the else branch is executed only
  220. // if there is a chance that extending the
  221. // label leads to new undominated labels, which in turn is possible only
  222. // if the label to be extended is undominated
  223. if( !cur_label->b_is_dominated )
  224. {
  225. int i_cur_resident_vertex_num = cur_label->resident_vertex;
  226. std::list<Splabel>& list_labels_cur_vertex =
  227. vec_vertex_labels[i_cur_resident_vertex_num];
  228. if( static_cast<int>( list_labels_cur_vertex.size() ) >= 2
  229. && vec_last_valid_index_for_dominance[i_cur_resident_vertex_num]
  230. < static_cast<int>( list_labels_cur_vertex.size() ) )
  231. {
  232. typename std::list<Splabel>::iterator outer_iter =
  233. list_labels_cur_vertex.begin();
  234. bool b_outer_iter_at_or_beyond_last_valid_pos_for_dominance = false;
  235. while( outer_iter != list_labels_cur_vertex.end() )
  236. {
  237. Splabel cur_outer_splabel = *outer_iter;
  238. typename std::list<Splabel>::iterator inner_iter = outer_iter;
  239. if( !b_outer_iter_at_or_beyond_last_valid_pos_for_dominance
  240. && outer_iter ==
  241. vec_last_valid_positions_for_dominance
  242. [i_cur_resident_vertex_num] )
  243. b_outer_iter_at_or_beyond_last_valid_pos_for_dominance = true;
  244. if( !b_vec_vertex_already_checked_for_dominance
  245. [i_cur_resident_vertex_num]
  246. || b_outer_iter_at_or_beyond_last_valid_pos_for_dominance )
  247. {
  248. ++inner_iter;
  249. }
  250. else
  251. {
  252. inner_iter =
  253. vec_last_valid_positions_for_dominance
  254. [i_cur_resident_vertex_num];
  255. ++inner_iter;
  256. }
  257. bool b_outer_iter_erased = false;
  258. while( inner_iter != list_labels_cur_vertex.end() )
  259. {
  260. Splabel cur_inner_splabel = *inner_iter;
  261. if( dominance( cur_outer_splabel->
  262. cumulated_resource_consumption,
  263. cur_inner_splabel->
  264. cumulated_resource_consumption ) )
  265. {
  266. typename std::list<Splabel>::iterator buf = inner_iter;
  267. ++inner_iter;
  268. list_labels_cur_vertex.erase( buf );
  269. if( cur_inner_splabel->b_is_processed )
  270. {
  271. l_alloc.destroy( cur_inner_splabel.get() );
  272. l_alloc.deallocate( cur_inner_splabel.get(), 1 );
  273. }
  274. else
  275. cur_inner_splabel->b_is_dominated = true;
  276. continue;
  277. }
  278. else
  279. ++inner_iter;
  280. if( dominance( cur_inner_splabel->
  281. cumulated_resource_consumption,
  282. cur_outer_splabel->
  283. cumulated_resource_consumption ) )
  284. {
  285. typename std::list<Splabel>::iterator buf = outer_iter;
  286. ++outer_iter;
  287. list_labels_cur_vertex.erase( buf );
  288. b_outer_iter_erased = true;
  289. if( cur_outer_splabel->b_is_processed )
  290. {
  291. l_alloc.destroy( cur_outer_splabel.get() );
  292. l_alloc.deallocate( cur_outer_splabel.get(), 1 );
  293. }
  294. else
  295. cur_outer_splabel->b_is_dominated = true;
  296. break;
  297. }
  298. }
  299. if( !b_outer_iter_erased )
  300. ++outer_iter;
  301. }
  302. if( static_cast<int>( list_labels_cur_vertex.size() ) > 1 )
  303. vec_last_valid_positions_for_dominance[i_cur_resident_vertex_num] =
  304. (--(list_labels_cur_vertex.end()));
  305. else
  306. vec_last_valid_positions_for_dominance[i_cur_resident_vertex_num] =
  307. list_labels_cur_vertex.begin();
  308. b_vec_vertex_already_checked_for_dominance
  309. [i_cur_resident_vertex_num] = true;
  310. vec_last_valid_index_for_dominance[i_cur_resident_vertex_num] =
  311. static_cast<int>( list_labels_cur_vertex.size() ) - 1;
  312. }
  313. }
  314. if( !b_all_pareto_optimal_solutions && cur_label->resident_vertex == t )
  315. {
  316. // the devil don't sleep
  317. if( cur_label->b_is_dominated )
  318. {
  319. l_alloc.destroy( cur_label.get() );
  320. l_alloc.deallocate( cur_label.get(), 1 );
  321. }
  322. while( unprocessed_labels.size() )
  323. {
  324. Splabel l = unprocessed_labels.top();
  325. unprocessed_labels.pop();
  326. // delete only dominated labels, because nondominated labels are
  327. // deleted at the end of the function
  328. if( l->b_is_dominated )
  329. {
  330. l_alloc.destroy( l.get() );
  331. l_alloc.deallocate( l.get(), 1 );
  332. }
  333. }
  334. break;
  335. }
  336. if( !cur_label->b_is_dominated )
  337. {
  338. cur_label->b_is_processed = true;
  339. vis.on_label_not_dominated( *cur_label, g );
  340. typename graph_traits<Graph>::vertex_descriptor cur_vertex =
  341. cur_label->resident_vertex;
  342. typename graph_traits<Graph>::out_edge_iterator oei, oei_end;
  343. for( boost::tie( oei, oei_end ) = out_edges( cur_vertex, g );
  344. oei != oei_end;
  345. ++oei )
  346. {
  347. b_feasible = true;
  348. r_c_shortest_paths_label<Graph, Resource_Container>* new_label =
  349. l_alloc.allocate( 1 );
  350. l_alloc.construct( new_label,
  351. r_c_shortest_paths_label
  352. <Graph, Resource_Container>
  353. ( i_label_num++,
  354. cur_label->cumulated_resource_consumption,
  355. cur_label.get(),
  356. *oei,
  357. target( *oei, g ) ) );
  358. b_feasible =
  359. ref( g,
  360. new_label->cumulated_resource_consumption,
  361. new_label->p_pred_label->cumulated_resource_consumption,
  362. new_label->pred_edge );
  363. if( !b_feasible )
  364. {
  365. vis.on_label_not_feasible( *new_label, g );
  366. l_alloc.destroy( new_label );
  367. l_alloc.deallocate( new_label, 1 );
  368. }
  369. else
  370. {
  371. const r_c_shortest_paths_label<Graph, Resource_Container>&
  372. ref_new_label = *new_label;
  373. vis.on_label_feasible( ref_new_label, g );
  374. Splabel new_sp_label( new_label );
  375. vec_vertex_labels[vertex_index_map[new_sp_label->resident_vertex]].
  376. push_back( new_sp_label );
  377. unprocessed_labels.push( new_sp_label );
  378. }
  379. }
  380. }
  381. else
  382. {
  383. vis.on_label_dominated( *cur_label, g );
  384. l_alloc.destroy( cur_label.get() );
  385. l_alloc.deallocate( cur_label.get(), 1 );
  386. }
  387. }
  388. std::list<Splabel> dsplabels = vec_vertex_labels[vertex_index_map[t]];
  389. typename std::list<Splabel>::const_iterator csi = dsplabels.begin();
  390. typename std::list<Splabel>::const_iterator csi_end = dsplabels.end();
  391. // if d could be reached from o
  392. if( dsplabels.size() )
  393. {
  394. for( ; csi != csi_end; ++csi )
  395. {
  396. std::vector<typename graph_traits<Graph>::edge_descriptor>
  397. cur_pareto_optimal_path;
  398. const r_c_shortest_paths_label<Graph, Resource_Container>* p_cur_label =
  399. (*csi).get();
  400. pareto_optimal_resource_containers.
  401. push_back( p_cur_label->cumulated_resource_consumption );
  402. while( p_cur_label->num != 0 )
  403. {
  404. cur_pareto_optimal_path.push_back( p_cur_label->pred_edge );
  405. p_cur_label = p_cur_label->p_pred_label;
  406. }
  407. pareto_optimal_solutions.push_back( cur_pareto_optimal_path );
  408. if( !b_all_pareto_optimal_solutions )
  409. break;
  410. }
  411. }
  412. int i_size = static_cast<int>( vec_vertex_labels.size() );
  413. for( int i = 0; i < i_size; ++i )
  414. {
  415. const std::list<Splabel>& list_labels_cur_vertex = vec_vertex_labels[i];
  416. csi_end = list_labels_cur_vertex.end();
  417. for( csi = list_labels_cur_vertex.begin(); csi != csi_end; ++csi )
  418. {
  419. l_alloc.destroy( (*csi).get() );
  420. l_alloc.deallocate( (*csi).get(), 1 );
  421. }
  422. }
  423. } // r_c_shortest_paths_dispatch
  424. } // detail
  425. // default_r_c_shortest_paths_visitor struct
  426. struct default_r_c_shortest_paths_visitor
  427. {
  428. template<class Label, class Graph>
  429. void on_label_popped( const Label&, const Graph& ) {}
  430. template<class Label, class Graph>
  431. void on_label_feasible( const Label&, const Graph& ) {}
  432. template<class Label, class Graph>
  433. void on_label_not_feasible( const Label&, const Graph& ) {}
  434. template<class Label, class Graph>
  435. void on_label_dominated( const Label&, const Graph& ) {}
  436. template<class Label, class Graph>
  437. void on_label_not_dominated( const Label&, const Graph& ) {}
  438. }; // default_r_c_shortest_paths_visitor
  439. // default_r_c_shortest_paths_allocator
  440. typedef
  441. std::allocator<int> default_r_c_shortest_paths_allocator;
  442. // default_r_c_shortest_paths_allocator
  443. // r_c_shortest_paths functions (handle/interface)
  444. // first overload:
  445. // - return all pareto-optimal solutions
  446. // - specify Label_Allocator and Visitor arguments
  447. template<class Graph,
  448. class VertexIndexMap,
  449. class EdgeIndexMap,
  450. class Resource_Container,
  451. class Resource_Extension_Function,
  452. class Dominance_Function,
  453. class Label_Allocator,
  454. class Visitor>
  455. void r_c_shortest_paths
  456. ( const Graph& g,
  457. const VertexIndexMap& vertex_index_map,
  458. const EdgeIndexMap& edge_index_map,
  459. typename graph_traits<Graph>::vertex_descriptor s,
  460. typename graph_traits<Graph>::vertex_descriptor t,
  461. // each inner vector corresponds to a pareto-optimal path
  462. std::vector<std::vector<typename graph_traits<Graph>::edge_descriptor> >&
  463. pareto_optimal_solutions,
  464. std::vector<Resource_Container>& pareto_optimal_resource_containers,
  465. // to initialize the first label/resource container
  466. // and to carry the type information
  467. const Resource_Container& rc,
  468. const Resource_Extension_Function& ref,
  469. const Dominance_Function& dominance,
  470. // to specify the memory management strategy for the labels
  471. Label_Allocator la,
  472. Visitor vis )
  473. {
  474. r_c_shortest_paths_dispatch( g,
  475. vertex_index_map,
  476. edge_index_map,
  477. s,
  478. t,
  479. pareto_optimal_solutions,
  480. pareto_optimal_resource_containers,
  481. true,
  482. rc,
  483. ref,
  484. dominance,
  485. la,
  486. vis );
  487. }
  488. // second overload:
  489. // - return only one pareto-optimal solution
  490. // - specify Label_Allocator and Visitor arguments
  491. template<class Graph,
  492. class VertexIndexMap,
  493. class EdgeIndexMap,
  494. class Resource_Container,
  495. class Resource_Extension_Function,
  496. class Dominance_Function,
  497. class Label_Allocator,
  498. class Visitor>
  499. void r_c_shortest_paths
  500. ( const Graph& g,
  501. const VertexIndexMap& vertex_index_map,
  502. const EdgeIndexMap& edge_index_map,
  503. typename graph_traits<Graph>::vertex_descriptor s,
  504. typename graph_traits<Graph>::vertex_descriptor t,
  505. std::vector<typename graph_traits<Graph>::edge_descriptor>&
  506. pareto_optimal_solution,
  507. Resource_Container& pareto_optimal_resource_container,
  508. // to initialize the first label/resource container
  509. // and to carry the type information
  510. const Resource_Container& rc,
  511. const Resource_Extension_Function& ref,
  512. const Dominance_Function& dominance,
  513. // to specify the memory management strategy for the labels
  514. Label_Allocator la,
  515. Visitor vis )
  516. {
  517. // each inner vector corresponds to a pareto-optimal path
  518. std::vector<std::vector<typename graph_traits<Graph>::edge_descriptor> >
  519. pareto_optimal_solutions;
  520. std::vector<Resource_Container> pareto_optimal_resource_containers;
  521. r_c_shortest_paths_dispatch( g,
  522. vertex_index_map,
  523. edge_index_map,
  524. s,
  525. t,
  526. pareto_optimal_solutions,
  527. pareto_optimal_resource_containers,
  528. false,
  529. rc,
  530. ref,
  531. dominance,
  532. la,
  533. vis );
  534. if (!pareto_optimal_solutions.empty()) {
  535. pareto_optimal_solution = pareto_optimal_solutions[0];
  536. pareto_optimal_resource_container = pareto_optimal_resource_containers[0];
  537. }
  538. }
  539. // third overload:
  540. // - return all pareto-optimal solutions
  541. // - use default Label_Allocator and Visitor
  542. template<class Graph,
  543. class VertexIndexMap,
  544. class EdgeIndexMap,
  545. class Resource_Container,
  546. class Resource_Extension_Function,
  547. class Dominance_Function>
  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. // each inner vector corresponds to a pareto-optimal path
  555. std::vector<std::vector<typename graph_traits<Graph>::edge_descriptor> >&
  556. pareto_optimal_solutions,
  557. std::vector<Resource_Container>& pareto_optimal_resource_containers,
  558. // to initialize the first label/resource container
  559. // and to carry the type information
  560. const Resource_Container& rc,
  561. const Resource_Extension_Function& ref,
  562. const Dominance_Function& dominance )
  563. {
  564. r_c_shortest_paths_dispatch( g,
  565. vertex_index_map,
  566. edge_index_map,
  567. s,
  568. t,
  569. pareto_optimal_solutions,
  570. pareto_optimal_resource_containers,
  571. true,
  572. rc,
  573. ref,
  574. dominance,
  575. default_r_c_shortest_paths_allocator(),
  576. default_r_c_shortest_paths_visitor() );
  577. }
  578. // fourth overload:
  579. // - return only one pareto-optimal solution
  580. // - use default Label_Allocator and Visitor
  581. template<class Graph,
  582. class VertexIndexMap,
  583. class EdgeIndexMap,
  584. class Resource_Container,
  585. class Resource_Extension_Function,
  586. class Dominance_Function>
  587. void r_c_shortest_paths
  588. ( const Graph& g,
  589. const VertexIndexMap& vertex_index_map,
  590. const EdgeIndexMap& edge_index_map,
  591. typename graph_traits<Graph>::vertex_descriptor s,
  592. typename graph_traits<Graph>::vertex_descriptor t,
  593. std::vector<typename graph_traits<Graph>::edge_descriptor>&
  594. pareto_optimal_solution,
  595. Resource_Container& pareto_optimal_resource_container,
  596. // to initialize the first label/resource container
  597. // and to carry the type information
  598. const Resource_Container& rc,
  599. const Resource_Extension_Function& ref,
  600. const Dominance_Function& dominance )
  601. {
  602. // each inner vector corresponds to a pareto-optimal path
  603. std::vector<std::vector<typename graph_traits<Graph>::edge_descriptor> >
  604. pareto_optimal_solutions;
  605. std::vector<Resource_Container> pareto_optimal_resource_containers;
  606. r_c_shortest_paths_dispatch( g,
  607. vertex_index_map,
  608. edge_index_map,
  609. s,
  610. t,
  611. pareto_optimal_solutions,
  612. pareto_optimal_resource_containers,
  613. false,
  614. rc,
  615. ref,
  616. dominance,
  617. default_r_c_shortest_paths_allocator(),
  618. default_r_c_shortest_paths_visitor() );
  619. if (!pareto_optimal_solutions.empty()) {
  620. pareto_optimal_solution = pareto_optimal_solutions[0];
  621. pareto_optimal_resource_container = pareto_optimal_resource_containers[0];
  622. }
  623. }
  624. // r_c_shortest_paths
  625. // check_r_c_path function
  626. template<class Graph,
  627. class Resource_Container,
  628. class Resource_Extension_Function>
  629. void check_r_c_path( const Graph& g,
  630. const std::vector
  631. <typename graph_traits
  632. <Graph>::edge_descriptor>& ed_vec_path,
  633. const Resource_Container& initial_resource_levels,
  634. // if true, computed accumulated final resource levels must
  635. // be equal to desired_final_resource_levels
  636. // if false, computed accumulated final resource levels must
  637. // be less than or equal to desired_final_resource_levels
  638. bool b_result_must_be_equal_to_desired_final_resource_levels,
  639. const Resource_Container& desired_final_resource_levels,
  640. Resource_Container& actual_final_resource_levels,
  641. const Resource_Extension_Function& ref,
  642. bool& b_is_a_path_at_all,
  643. bool& b_feasible,
  644. bool& b_correctly_extended,
  645. typename graph_traits<Graph>::edge_descriptor&
  646. ed_last_extended_arc )
  647. {
  648. int i_size_ed_vec_path = static_cast<int>( ed_vec_path.size() );
  649. std::vector<typename graph_traits<Graph>::edge_descriptor> buf_path;
  650. if( i_size_ed_vec_path == 0 )
  651. b_feasible = true;
  652. else
  653. {
  654. if( i_size_ed_vec_path == 1
  655. || target( ed_vec_path[0], g ) == source( ed_vec_path[1], g ) )
  656. buf_path = ed_vec_path;
  657. else
  658. for( int i = i_size_ed_vec_path - 1; i >= 0; --i )
  659. buf_path.push_back( ed_vec_path[i] );
  660. for( int i = 0; i < i_size_ed_vec_path - 1; ++i )
  661. {
  662. if( target( buf_path[i], g ) != source( buf_path[i + 1], g ) )
  663. {
  664. b_is_a_path_at_all = false;
  665. b_feasible = false;
  666. b_correctly_extended = false;
  667. return;
  668. }
  669. }
  670. }
  671. b_is_a_path_at_all = true;
  672. b_feasible = true;
  673. b_correctly_extended = false;
  674. Resource_Container current_resource_levels = initial_resource_levels;
  675. actual_final_resource_levels = current_resource_levels;
  676. for( int i = 0; i < i_size_ed_vec_path; ++i )
  677. {
  678. ed_last_extended_arc = buf_path[i];
  679. b_feasible = ref( g,
  680. actual_final_resource_levels,
  681. current_resource_levels,
  682. buf_path[i] );
  683. current_resource_levels = actual_final_resource_levels;
  684. if( !b_feasible )
  685. return;
  686. }
  687. if( b_result_must_be_equal_to_desired_final_resource_levels )
  688. b_correctly_extended =
  689. actual_final_resource_levels == desired_final_resource_levels ?
  690. true : false;
  691. else
  692. {
  693. if( actual_final_resource_levels < desired_final_resource_levels
  694. || actual_final_resource_levels == desired_final_resource_levels )
  695. b_correctly_extended = true;
  696. }
  697. } // check_path
  698. } // namespace
  699. #endif // BOOST_GRAPH_R_C_SHORTEST_PATHS_HPP