remove_cross_edges.hpp

Go to the documentation of this file.
00001 
00027 #ifndef MSMAZES_CORE_GRAPH_REMOVE_CROSS_EDGES_HPP
00028 #define MSMAZES_CORE_GRAPH_REMOVE_CROSS_EDGES_HPP
00029 
00030 // std::vector
00031 #include <vector>
00032 // std::map
00033 #include <map>
00034 // std::pair and std::make_pair
00035 #include <utility>
00036 // boost::function_requires and basic concept check templates
00037 #include <boost/concept_check.hpp>
00038 // boost::queue
00039 #include <boost/pending/queue.hpp>
00040 // boost::property_map, boost::associative_property_map,
00041 // boost::make_iterator_property_map, boost::get, and boost::put
00042 #include <boost/property_map.hpp>
00043 // boost::ref
00044 #include <boost/ref.hpp>
00045 // boost::tie
00046 #include <boost/utility.hpp>
00047 // BOOST_PP_LESS
00048 #include <boost/preprocessor/comparison/less.hpp>
00049 // boost::remove_const
00050 #include <boost/type_traits/remove_const.hpp>
00051 // boost::remove_reference
00052 #include <boost/type_traits/remove_reference.hpp>
00053 // BGL concept check templates
00054 #include <boost/graph/graph_concepts.hpp>
00055 // boost::graph_traits
00056 #include <boost/graph/graph_traits.hpp>
00057 // boost::color_traits
00058 #include <boost/graph/properties.hpp>
00059 // boost::predecessor_recorder and boost::null_visitor
00060 #include <boost/graph/visitors.hpp>
00061 // boost::breadth_first_visit and boost::make_bfs_visitor
00062 #include <boost/graph/breadth_first_search.hpp>
00063 // boost::dfs_visitor, boost::depth_first_visit, and boost::make_dfs_visitor
00064 #include <boost/graph/depth_first_search.hpp>
00065 //#include <boost/graph/adjacency_list.hpp> must be included before this file.
00066 // msmazes::hasInEdges and msmazes::removeInEdges
00067 #include <msmazes/core/graph/in_edges.hpp>
00068 // Boost.Parameter keyword objects used by the Core Graph algorithms
00069 #include <msmazes/core/graph/keywords.hpp>
00070 
00071 #if BOOST_PP_LESS(BOOST_PARAMETER_MAX_ARITY, 9)
00072 #error Set BOOST_PARAMETER_MAX_ARITY to 9 or higher, please.
00073 #endif
00074 
00075 namespace msmazes {
00076 
00100 class DefaultCrossEdgeRemovalIntruder
00101 {
00102  public:
00113     template <
00114         typename Graph
00115     >
00116     void
00117         pathEdgeTemporarilyRemoved(
00118             typename boost::graph_traits<Graph>::vertex_descriptor u
00119           , typename boost::graph_traits<Graph>::vertex_descriptor v
00120           , Graph& g
00121         )
00122     {
00123     }
00124 
00136     template <
00137         typename Graph
00138     >
00139     inline bool
00140         canRemoveCrossEdge(
00141             typename boost::graph_traits<Graph>::edge_descriptor e
00142           , Graph& g
00143         )
00144     {
00145         return true;
00146     }
00147 
00157     template <
00158         typename Graph
00159     >
00160     void
00161         pathEdgeReinstated(
00162             typename boost::graph_traits<Graph>::edge_descriptor e
00163           , Graph& g
00164         )
00165     {
00166     }
00167 };
00168 
00169   namespace _removeCrossEdges {
00170 
00171     /*
00172      * This event visitor class template helps the AltPathRanker class template
00173      * by ranking the vertices that the latter class has classified as cycles.
00174      */
00179     template <typename VertexRankMap>
00180     class CycleRanker
00181       : public boost::base_visitor<CycleRanker<VertexRankMap> >
00182     {
00183      public:
00184         typedef boost::on_tree_edge
00185                 event_filter;
00186         typedef typename boost::property_traits<VertexRankMap>::value_type
00187                 Rank;
00188 
00189      private:
00190         VertexRankMap _rank_map;
00191 
00192      public:
00193         explicit CycleRanker(VertexRankMap rank_map)
00194           : _rank_map(rank_map)
00195         {
00196         }
00197 
00198         CycleRanker(const CycleRanker& copy)
00199           : _rank_map(copy._rank_map)
00200         {
00201         }
00202 
00203         ~CycleRanker()
00204         {
00205         }
00206 
00207         template <
00208             typename Graph
00209         >
00210         void
00211             operator()(
00212                 typename boost::graph_traits<Graph>::edge_descriptor e
00213               , Graph& g
00214             )
00215         {
00216             boost::put(
00217                 _rank_map
00218               , boost::target(e, g)
00219               , boost::get(_rank_map, boost::source(e, g))
00220             );
00221         }
00222     };
00223 
00224     /*
00225      * This event visitor class template carries out the actual removal of
00226      * cross-edges (with respect to the main path in the graph, not the
00227      * depth-first traversal that is passed an instance of this class).
00228      */
00233     template <
00234         typename InputGraph
00235       , typename VertexIndexMap
00236       , typename VertexRankMap
00237       , typename CrossEdgeRemovalIntruder
00238     >
00239     class CrossEdgeRemover
00240       : public boost::base_visitor<
00241                    CrossEdgeRemover<
00242                        InputGraph
00243                      , VertexIndexMap
00244                      , VertexRankMap
00245                      , CrossEdgeRemovalIntruder
00246                    >
00247                >
00248     {
00249      public:
00250         typedef boost::on_discover_vertex
00251                 event_filter;
00252         typedef typename boost::property_traits<VertexRankMap>::value_type
00253                 Rank;
00254 
00255      private:
00256         const Rank&               _root_rank;
00257 
00258         CrossEdgeRemovalIntruder& _intruder;
00259         InputGraph&               _g;
00260         VertexIndexMap            _index_map;
00261         VertexRankMap             _rank_map;
00262 
00263      public:
00264         CrossEdgeRemover(
00265             InputGraph& g
00266           , VertexIndexMap index_map
00267           , VertexRankMap rank_map
00268           , Rank& root_rank
00269           , CrossEdgeRemovalIntruder& intruder
00270         )
00271           : _root_rank(root_rank)
00272           , _intruder(intruder)
00273           , _g(g)
00274           , _index_map(index_map)
00275           , _rank_map(rank_map)
00276         {
00277         }
00278 
00279         CrossEdgeRemover(const CrossEdgeRemover& copy)
00280           : _root_rank(copy._root_rank)
00281           , _intruder(copy._intruder)
00282           , _g(copy._g)
00283           , _index_map(copy._index_map)
00284           , _rank_map(copy._rank_map)
00285         {
00286         }
00287 
00288         ~CrossEdgeRemover()
00289         {
00290         }
00291 
00292         template <
00293             typename Graph
00294         >
00295         void
00296             operator()(
00297                 typename boost::graph_traits<Graph>::vertex_descriptor v
00298               , Graph& g
00299             )
00300         {
00301             typename boost::graph_traits<InputGraph>::vertex_descriptor
00302                 vertex = boost::vertex(boost::get(_index_map, v), _g);
00303             typename boost::graph_traits<InputGraph>::out_edge_iterator
00304                 oi, oend;
00305 
00306             boost::tie(oi, oend) = boost::out_edges(vertex, _g);
00307 
00308             while (oi != oend)
00309             {
00310                 if (
00311                     (_root_rank < boost::get(_rank_map, boost::target(*oi, _g)))
00312                  && _intruder.canRemoveCrossEdge(*oi, _g)
00313                 )
00314                 {
00315                     /*
00316                      * This vertex is connected to a vertex that is farther
00317                      * down the main path than the source vertex of this
00318                      * traversal (the vertex whose rank is root_rank).
00319                      * Therefore, this edge is a cross edge.
00320                      */
00321                     boost::remove_edge(oi, _g);
00322                     boost::tie(oi, oend) = boost::out_edges(vertex, _g);
00323                 }
00324                 else
00325                 {
00326                     ++oi;
00327                 }
00328             }
00329         }
00330     };
00331 
00332     /*
00333      * This event visitor class template ranks the vertices that are not part of
00334      * the main path so that the CrossEdgeRemover class template can identify
00335      * which edges to remove.
00336      */
00341     template <
00342         typename VertexRankMap
00343       , typename VertexColorMap
00344     >
00345     class AltPathRanker
00346       : public boost::base_visitor<AltPathRanker<VertexRankMap,VertexColorMap> >
00347     {
00348      public:
00349         typedef boost::on_finish_vertex
00350                 event_filter;
00351         typedef typename boost::property_traits<VertexColorMap>::value_type
00352                 ColorValue;
00353         typedef boost::color_traits<ColorValue>
00354                 Color;
00355         typedef typename boost::property_traits<VertexRankMap>::value_type
00356                 Rank;
00357         typedef boost::dfs_visitor<
00358                     std::pair<CycleRanker<VertexRankMap>,boost::null_visitor>
00359                 >
00360                 CycleVisitor;
00361 
00362      private:
00363         static const Rank zero_rank = Rank();
00364 
00365         VertexRankMap  _rank_map;
00366         VertexColorMap _color_map;
00367         CycleVisitor   _cycle_visitor;
00368 
00369      public:
00370         AltPathRanker(VertexRankMap rank_map, VertexColorMap color_map)
00371           : _rank_map(rank_map)
00372           , _color_map(color_map)
00373           , _cycle_visitor(
00374                 boost::make_dfs_visitor(
00375                     std::make_pair(
00376                         CycleRanker<VertexRankMap>(rank_map)
00377                       , boost::null_visitor()
00378                     )
00379                 )
00380             )
00381         {
00382         }
00383 
00384         AltPathRanker(const AltPathRanker& copy)
00385           : _rank_map(copy._rank_map)
00386           , _color_map(copy._color_map)
00387           , _cycle_visitor(copy._cycle_visitor)
00388         {
00389         }
00390 
00391         ~AltPathRanker()
00392         {
00393         }
00394 
00395         template <typename Graph>
00396         void
00397             operator()(
00398                 typename boost::graph_traits<Graph>::vertex_descriptor v
00399               , Graph& g
00400             )
00401         {
00402             typename boost::graph_traits<Graph>::adjacency_iterator vi, vend;
00403             bool has_cycles = false;
00404             Rank target_rank;
00405 
00406             for (boost::tie(vi, vend) = boost::adjacent_vertices(v, g);
00407                  vi != vend;
00408                  ++vi)
00409             {
00410                 target_rank = boost::get(_rank_map, *vi);
00411 
00412                 if (target_rank == zero_rank)
00413                 {
00414                     /*
00415                      * The out-edge leads to a cycle.
00416                      */
00417                     has_cycles = true;
00418                 }
00419                 else if (
00420                    (boost::get(_color_map, *vi) != Color::gray())
00421                 && (boost::get(_rank_map, v) < target_rank)
00422                 )
00423                 {
00424                     /*
00425                      * This vertex is connected to a vertex with a higher rank
00426                      * than zero (i.e. the first one so far) or a vertex farther
00427                      * down the main path than the one with the current rank but
00428                      * still is a predecessor to the source vertex of this
00429                      * traversal.
00430                      */
00431                     boost::put(_rank_map, v, target_rank);
00432                 }
00433             }
00434 
00435             if (boost::get(_rank_map, v) == zero_rank)
00436             {
00437                 /*
00438                  * Set the main depth-first traversal function to revisit this
00439                  * vertex once it has a non-zero rank.
00440                  */
00441                 boost::put(_color_map, v, Color::white());
00442             }
00443             else if (has_cycles)
00444             {
00445                 /*
00446                  * Give the zero-ranked vertices in the cycle(s) the same rank
00447                  * as that of this vertex.
00448                  */
00449                 boost::depth_first_visit(g, v, _cycle_visitor, _color_map);
00450             }
00451         }
00452     };
00453 
00454     /*
00455      * The implementation.
00456      */
00461     template <
00462         typename PathIterator
00463       , typename InputGraph
00464       , typename PredecessorMap
00465       , typename VertexIndexMap
00466       , typename VertexColorMap
00467       , typename VertexRankMap
00468       , typename Buffer
00469       , typename CrossEdgeRemovalIntruder
00470     >
00471     void
00472         impl(
00473             PathIterator path_begin
00474           , PathIterator path_end
00475           , InputGraph& g
00476           , PredecessorMap predecessor_map
00477           , VertexIndexMap index_map
00478           , VertexColorMap color_map
00479           , VertexRankMap rank_map
00480           , Buffer& Q
00481           , CrossEdgeRemovalIntruder& intruder
00482         )
00483     {
00484         boost::function_requires<
00485             boost::BidirectionalIteratorConcept<PathIterator>
00486         >();
00487         boost::function_requires<
00488             boost::VertexListGraphConcept<InputGraph>
00489         >();
00490         boost::function_requires<
00491             boost::AdjacencyGraphConcept<InputGraph>
00492         >();
00493         boost::function_requires<
00494             boost::EdgeMutableGraphConcept<InputGraph>
00495         >();
00496         typedef boost::graph_traits<InputGraph>
00497                 GraphTraits;
00498         boost::function_requires<
00499             boost::ConvertibleConcept<
00500                 typename GraphTraits::directed_category
00501               , boost::directed_tag
00502             >
00503         >();
00504         typedef typename GraphTraits::edge_descriptor
00505                 Edge;
00506         typedef typename GraphTraits::vertex_descriptor
00507                 Vertex;
00508         boost::function_requires<
00509             boost::ReadWritePropertyMapConcept<PredecessorMap,Vertex>
00510         >();
00511         boost::function_requires<
00512             boost::ReadablePropertyMapConcept<VertexIndexMap,Vertex>
00513         >();
00514         boost::function_requires<
00515             boost::ReadWritePropertyMapConcept<VertexColorMap,Vertex>
00516         >();
00517         boost::function_requires<
00518             boost::ReadWritePropertyMapConcept<VertexRankMap,Vertex>
00519         >();
00520 /*
00521         boost::function_requires<
00522             boost::BufferConcept<Buffer>
00523         >();
00524 */
00525         boost::function_requires<
00526             boost::ConvertibleConcept<typename Buffer::value_type,Vertex>
00527         >();
00528         typedef typename GraphTraits::vertex_iterator
00529                 VertexIterator;
00530         typedef typename boost::property_traits<VertexRankMap>::value_type
00531                 Rank;
00532         typedef typename boost::property_traits<VertexColorMap>::value_type
00533                 ColorValue;
00534         typedef boost::color_traits<ColorValue>
00535                 Color;
00536         typedef boost::predecessor_recorder<PredecessorMap,boost::on_tree_edge>
00537                 PredVisitor;
00538         typedef boost::bfs_visitor<std::pair<PredVisitor,boost::null_visitor> >
00539                 BFSVisitor;
00540         typedef CrossEdgeRemover<
00541                     InputGraph
00542                   , VertexIndexMap
00543                   , VertexRankMap
00544                   , CrossEdgeRemovalIntruder
00545                 >
00546                 CERVisitor;
00547         typedef AltPathRanker<VertexRankMap,VertexColorMap>
00548                 APRVisitor;
00549         typedef boost::dfs_visitor<std::pair<CERVisitor,APRVisitor> >
00550                 DFSVisitor;
00551 
00552         /*
00553          * The purpose of all the preparatory steps from here to the core
00554          * algorithm is to keep as many nontrivial complex paths (the ones that
00555          * don't contain the simple path or almost all of it unbroken) as
00556          * possible in the graph.
00557          *
00558          * Temporarily remove the main path from the graph so that the algorithm
00559          * does not mistake its edges for cross edges.
00560          */
00561         PathIterator path_i = path_begin;
00562         PathIterator path_j = path_i;
00563 
00564         while (++path_j != path_end)
00565         {
00566             boost::remove_edge(*path_i, *path_j, g);
00567             intruder.pathEdgeTemporarilyRemoved(*path_i, *path_j, g);
00568             path_i = path_j;
00569         }
00570 
00571         /*
00572          * Remove all in-edges from the path target.  Also remove all out-edges
00573          * from the path source.
00574          */
00575         boost::clear_out_edges(*path_begin, g);
00576         removeInEdges(*path_i, g);
00577 
00578         /*
00579          * Remove all in-edges from vertices between the farthest vertex down
00580          * the path with a non-zero in-degree (inclusive) and its most immediate
00581          * path predecessor with a non-zero out-degree (exclusive).
00582          */
00583         path_j = path_i;
00584         boost::clear_out_edges(*(--path_j), g);
00585 
00586         while ((path_j != path_begin) && !hasInEdges(*path_j, g))
00587         {
00588             --path_j;
00589         }
00590 
00591         while ((path_j != path_begin) && (boost::out_degree(*path_j, g) == 0))
00592         {
00593             removeInEdges(*path_j, g);
00594             --path_j;
00595         }
00596 
00597         boost::null_visitor
00598           vis_n;
00599         PredVisitor
00600           vis0(predecessor_map);
00601         BFSVisitor
00602           bfs_vis = boost::make_bfs_visitor(std::make_pair(vis0, vis_n));
00603 
00604         /*
00605          * Find the unweighted shortest paths using the path target as the
00606          * source.
00607          */
00608         boost::breadth_first_visit(g, *path_i, Q, bfs_vis, color_map);
00609 
00610         /*
00611          * Initialize all vertices in the graph to the "zero" rank and the
00612          * "unvisited" color.  Do this here, not in a visitor class definition.
00613          */
00614         const Rank zero_rank = Rank();
00615 
00616         VertexIterator v_i, v_end;
00617 
00618         for (boost::tie(v_i, v_end) = boost::vertices(g); v_i != v_end; ++v_i)
00619         {
00620             boost::put(color_map, *v_i, Color::white());
00621             boost::put(rank_map, *v_i, zero_rank);
00622         }
00623 
00624         /*
00625          * Assign ranks to all vertices in the main path, with the source vertex
00626          * having the highest rank and the target vertex having the lowest rank
00627          * higher than the "zero" rank.
00628          */
00629         Rank root_rank = zero_rank;
00630 
00631         for (path_j = path_begin; path_j != path_end; ++path_j)
00632         {
00633             boost::put(rank_map, *path_j, ++root_rank);
00634         }
00635 
00636         /*
00637          * In each "alternate path" resulting from the previous shortest-paths
00638          * call, assign all zero-ranked vertices the same rank as that path's
00639          * target.  If at least two alternate paths share one or more vertices,
00640          * these vertices get the same rank as that of the highest ranking
00641          * target of the alternate paths.
00642          */
00643         Vertex target_v;
00644 
00645         path_j = path_i;
00646 
00647         while (path_j != path_begin)
00648         {
00649             target_v = boost::get(predecessor_map, *(--path_j));
00650 
00651             if (target_v != *path_j)
00652             {
00653                 /*
00654                  * Only use the ranks of the alternate path targets that are
00655                  * actually reachable from the main path target.
00656                  */
00657                 for (
00658                     root_rank = boost::get(rank_map, *path_j);
00659                     boost::get(rank_map, target_v) == zero_rank;
00660                     target_v = boost::get(predecessor_map, target_v)
00661                 )
00662                 {
00663                     boost::put(color_map, target_v, Color::black());
00664                     boost::put(rank_map, target_v, root_rank);
00665                 }
00666             }
00667         }
00668 
00669         /*
00670          * Run the core algorithm on each vertex in the main path, starting with
00671          * the main path target.
00672          */
00673         CERVisitor
00674           vis1(g, index_map, rank_map, root_rank, intruder);
00675         APRVisitor
00676           vis2(rank_map, color_map);
00677         DFSVisitor
00678           dfs_vis = boost::make_dfs_visitor(std::make_pair(vis1, vis2));
00679 
00680         path_j = path_i;
00681 
00682         while (--path_j != path_begin)
00683         {
00684             if (boost::out_degree(*path_j, g) > 0)
00685             {
00686                 root_rank = boost::get(rank_map, *path_j);
00687 
00688                 /*
00689                  * Set the path vertices as terminating vertices for the
00690                  * depth-first traversal.
00691                  */
00692                 for (path_i = path_begin; path_i != path_end; ++path_i)
00693                 {
00694                     boost::put(color_map, *path_i, Color::black());
00695                 }
00696 
00697                 boost::depth_first_visit(g, *path_j, dfs_vis, color_map);
00698 
00699                 /*
00700                  * Reset the color map after each visit.
00701                  */
00702                 for (
00703                     boost::tie(v_i, v_end) = boost::vertices(g);
00704                     v_i != v_end;
00705                     ++v_i
00706                 )
00707                 {
00708                     boost::put(color_map, *v_i, Color::white());
00709                 }
00710             }
00711         }
00712 
00713         /*
00714          * Put the main path back in the graph.
00715          */
00716         Edge e;
00717         bool has_added_edge;
00718 
00719         for (path_i = path_j; ++path_j != path_end; path_i = path_j)
00720         {
00721             boost::tie(e, has_added_edge)
00722               = boost::add_edge(*path_i, *path_j, g);
00723 
00724             if (has_added_edge)
00725             {
00726                 intruder.pathEdgeReinstated(e, g);
00727             }
00728         }
00729 
00730         target_v = *path_i;
00731 
00732         /*
00733          * Remove all edges that lead to dead ends (except for the destination).
00734          */
00735         bool has_dead_ends = true;
00736 
00737         while (has_dead_ends)
00738         {
00739             has_dead_ends = false;
00740 
00741             for (
00742                 boost::tie(v_i, v_end) = boost::vertices(g);
00743                 v_i != v_end;
00744                 ++v_i
00745             )
00746             {
00747                 if (
00748                     (*v_i != target_v)
00749                  && (boost::out_degree(*v_i, g) == 0)
00750                  && hasInEdges(*v_i, g)
00751                 )
00752                 {
00753                     removeInEdges(*v_i, g);
00754                     has_dead_ends = true;
00755                 }
00756             }
00757         }
00758     }
00759 
00764     struct parameters
00765       : boost::parameter::parameters<
00766             boost::parameter::required<keyword_tag::path_begin_arg>
00767           , boost::parameter::required<keyword_tag::path_end_arg>
00768           , boost::parameter::required<keyword_tag::input_graph_arg>
00769           , boost::parameter::optional<keyword_tag::util_predecessor_map_arg>
00770           , boost::parameter::optional<keyword_tag::util_index_map_arg>
00771           , boost::parameter::optional<keyword_tag::util_color_map_arg>
00772           , boost::parameter::optional<keyword_tag::util_rank_map_arg>
00773           , boost::parameter::optional<keyword_tag::util_buffer_arg>
00774           , boost::parameter::optional<keyword_tag::intruder_arg>
00775         >
00776     {
00777     };
00778   }  // namespace _removeCrossEdges
00779 
00780 #ifdef MSMAZES_DOX
00781 
01034 template <
01035     typename PathIterator
01036   , typename InputGraph
01037   , typename PredecessorMap
01038   , typename VertexIndexMap
01039   , typename VertexColorMap
01040   , typename VertexRankMap
01041   , typename Buffer
01042   , typename CrossEdgeRemovalIntruder
01043 >
01044 void
01045     removeCrossEdges(
01046         PathIterator path_begin
01047       , PathIterator path_end
01048       , InputGraph& g
01049       , PredecessorMap predecessor_map
01050       , VertexIndexMap index_map
01051       , VertexColorMap color_map
01052       , VertexRankMap rank_map
01053       , Buffer& Q
01054       , CrossEdgeRemovalIntruder& intruder
01055     );
01056 
01067 template <typename Params>
01068 void removeCrossEdges_with_named_params(Params& p)
01069 #else
01070 BOOST_PARAMETER_FUN(
01071     void
01072   , removeCrossEdges
01073   , 3
01074   , 9
01075   , _removeCrossEdges::parameters
01076 )
01077 #endif  /* MSMAZES_DOX */
01078 {
01079     typedef typename boost::remove_const<
01080                 typename boost::remove_reference<
01081                     typename boost::parameter::binding<
01082                         Params
01083                       , keyword_tag::input_graph_arg
01084                     >::type
01085                 >::type
01086             >::type
01087             InputGraph;
01088     typedef typename boost::graph_traits<InputGraph>::vertex_descriptor
01089             Vertex;
01090     typedef std::map<Vertex,Vertex>
01091             VertexMap;
01092     typedef boost::associative_property_map<VertexMap>
01093             PredecessorMap;
01094     typedef typename boost::remove_const<
01095                 typename boost::remove_reference<
01096                     typename boost::parameter::binding<
01097                         Params
01098                       , keyword_tag::util_index_map_arg
01099                       , typename boost::property_map<
01100                             InputGraph
01101                           , boost::vertex_index_t
01102                         >::type
01103                     >::type
01104                 >::type
01105             >::type
01106             VertexIndexMap;
01107     typedef typename boost::property_traits<VertexIndexMap>::value_type
01108             Rank;
01109 
01110     InputGraph& g
01111       = p[input_graph_arg];
01112     VertexIndexMap index_map
01113       = p[util_index_map_arg | boost::get(boost::vertex_index_t(), g)];
01114     VertexMap v_map;
01115     PredecessorMap pred_map(v_map);
01116     boost::queue<Vertex> Q;
01117     DefaultCrossEdgeRemovalIntruder intruder;
01118 
01119     _removeCrossEdges::impl(
01120         p[path_begin_arg]
01121       , p[path_end_arg]
01122       , g
01123       , p[util_predecessor_map_arg | pred_map]
01124       , index_map
01125       , p[
01126             util_color_map_arg
01127           | boost::make_iterator_property_map(
01128                 std::vector<boost::default_color_type>(
01129                     boost::num_vertices(g)
01130                 ).begin()
01131               , index_map
01132               , boost::white_color
01133             )
01134         ]
01135       , p[
01136             util_rank_map_arg
01137           | boost::make_iterator_property_map(
01138                 std::vector<Rank>(boost::num_vertices(g)).begin()
01139               , index_map
01140               , Rank()
01141             )
01142         ]
01143       , p[util_buffer_arg | Q]
01144       , p[intruder_arg | intruder]
01145     );
01146 }
01147 }  // namespace msmazes
01148 
01149 #endif  /* MSMAZES_CORE_GRAPH_REMOVE_CROSS_EDGES_HPP */

Multi-State Mazes in C++ is hosted by SourceForge.net. Use the Table of Contents for navigation.