PageRenderTime 57ms CodeModel.GetById 8ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 1ms

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

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