os/ossrv/ossrv_pub/boost_apis/boost/graph/biconnected_components.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) Jeremy Siek 2001
sl@0
     2
// Copyright (c) Douglas Gregor 2004
sl@0
     3
//
sl@0
     4
// Distributed under the Boost Software License, Version 1.0. (See
sl@0
     5
// accompanying file LICENSE_1_0.txt or copy at
sl@0
     6
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     7
sl@0
     8
// NOTE: this final is generated by libs/graph/doc/biconnected_components.w
sl@0
     9
sl@0
    10
#ifndef BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
sl@0
    11
#define BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
sl@0
    12
sl@0
    13
#include <stack>
sl@0
    14
#include <vector>
sl@0
    15
#include <algorithm> // for std::min and std::max
sl@0
    16
#include <boost/config.hpp>
sl@0
    17
#include <boost/limits.hpp>
sl@0
    18
#include <boost/graph/graph_traits.hpp>
sl@0
    19
#include <boost/graph/graph_concepts.hpp>
sl@0
    20
#include <boost/property_map.hpp>
sl@0
    21
#include <boost/graph/depth_first_search.hpp>
sl@0
    22
#include <boost/graph/graph_utility.hpp>
sl@0
    23
sl@0
    24
namespace boost
sl@0
    25
{
sl@0
    26
  namespace detail
sl@0
    27
  {
sl@0
    28
    template<typename ComponentMap, typename DiscoverTimeMap,
sl@0
    29
             typename LowPointMap, typename PredecessorMap,
sl@0
    30
             typename OutputIterator, typename Stack, 
sl@0
    31
             typename DFSVisitor>
sl@0
    32
    struct biconnected_components_visitor : public dfs_visitor<>
sl@0
    33
    {
sl@0
    34
      biconnected_components_visitor
sl@0
    35
        (ComponentMap comp, std::size_t& c, DiscoverTimeMap dtm,
sl@0
    36
         std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred,
sl@0
    37
         OutputIterator out, Stack& S, DFSVisitor vis)
sl@0
    38
          : comp(comp), c(c), dtm(dtm), dfs_time(dfs_time), lowpt(lowpt),
sl@0
    39
            pred(pred), out(out), S(S), vis(vis) { }
sl@0
    40
sl@0
    41
      template <typename Vertex, typename Graph>
sl@0
    42
      void initialize_vertex(const Vertex& u, Graph& g)
sl@0
    43
      {
sl@0
    44
        vis.initialize_vertex(u, g);
sl@0
    45
      }
sl@0
    46
sl@0
    47
      template <typename Vertex, typename Graph>
sl@0
    48
      void start_vertex(const Vertex& u, Graph& g)
sl@0
    49
      {
sl@0
    50
        put(pred, u, u);
sl@0
    51
        vis.start_vertex(u, g);
sl@0
    52
      }
sl@0
    53
sl@0
    54
      template <typename Vertex, typename Graph>
sl@0
    55
      void discover_vertex(const Vertex& u, Graph& g)
sl@0
    56
      {
sl@0
    57
        put(dtm, u, ++dfs_time);
sl@0
    58
        put(lowpt, u, get(dtm, u));
sl@0
    59
        vis.discover_vertex(u, g);
sl@0
    60
      }
sl@0
    61
sl@0
    62
      template <typename Edge, typename Graph>
sl@0
    63
      void examine_edge(const Edge& e, Graph& g)
sl@0
    64
      {
sl@0
    65
        vis.examine_edge(e, g);
sl@0
    66
      }
sl@0
    67
sl@0
    68
      template <typename Edge, typename Graph>
sl@0
    69
      void tree_edge(const Edge& e, Graph& g)
sl@0
    70
      {
sl@0
    71
        S.push(e);
sl@0
    72
        put(pred, target(e, g), source(e, g));
sl@0
    73
        vis.tree_edge(e, g);
sl@0
    74
      }
sl@0
    75
sl@0
    76
      template <typename Edge, typename Graph>
sl@0
    77
      void back_edge(const Edge& e, Graph& g)
sl@0
    78
      {
sl@0
    79
        BOOST_USING_STD_MIN();
sl@0
    80
sl@0
    81
        if ( target(e, g) != get(pred, source(e, g)) ) {
sl@0
    82
          S.push(e);
sl@0
    83
          put(lowpt, source(e, g),
sl@0
    84
              min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, source(e, g)),
sl@0
    85
                                                   get(dtm, target(e, g))));
sl@0
    86
        vis.back_edge(e, g);
sl@0
    87
      }
sl@0
    88
      }
sl@0
    89
sl@0
    90
      template <typename Edge, typename Graph>
sl@0
    91
      void forward_or_cross_edge(const Edge& e, Graph& g)
sl@0
    92
      {
sl@0
    93
        vis.forward_or_cross_edge(e, g);
sl@0
    94
      }
sl@0
    95
sl@0
    96
      template <typename Vertex, typename Graph>
sl@0
    97
      void finish_vertex(const Vertex& u, Graph& g)
sl@0
    98
      {
sl@0
    99
        BOOST_USING_STD_MIN();
sl@0
   100
        Vertex parent = get(pred, u);
sl@0
   101
        const std::size_t dtm_of_dubious_parent = get(dtm, parent);
sl@0
   102
        bool is_art_point = false;
sl@0
   103
        if ( dtm_of_dubious_parent > get(dtm, u) ) {
sl@0
   104
          parent = get(pred, parent);
sl@0
   105
          is_art_point = true;
sl@0
   106
          put(pred, get(pred, u), u);
sl@0
   107
          put(pred, u, parent);
sl@0
   108
        }
sl@0
   109
sl@0
   110
        if ( parent == u ) { // at top
sl@0
   111
          if ( get(dtm, u) + 1 == dtm_of_dubious_parent )
sl@0
   112
            is_art_point = false;
sl@0
   113
        } else {
sl@0
   114
          put(lowpt, parent,
sl@0
   115
              min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent),
sl@0
   116
                                                   get(lowpt, u)));
sl@0
   117
sl@0
   118
          if (get(lowpt, u) >= get(dtm, parent)) {
sl@0
   119
            if ( get(dtm, parent) > get(dtm, get(pred, parent)) ) {
sl@0
   120
              put(pred, u, get(pred, parent));
sl@0
   121
              put(pred, parent, u);
sl@0
   122
            }
sl@0
   123
sl@0
   124
            while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) {
sl@0
   125
              put(comp, S.top(), c);
sl@0
   126
              S.pop();
sl@0
   127
            }
sl@0
   128
            put(comp, S.top(), c);
sl@0
   129
              S.pop();
sl@0
   130
            ++c;
sl@0
   131
            if ( S.empty() ) {
sl@0
   132
              put(pred, u, parent);
sl@0
   133
              put(pred, parent, u);
sl@0
   134
            }
sl@0
   135
          }
sl@0
   136
        }
sl@0
   137
        if ( is_art_point )
sl@0
   138
          *out++ = u;
sl@0
   139
        vis.finish_vertex(u, g);
sl@0
   140
      }
sl@0
   141
sl@0
   142
      ComponentMap comp;
sl@0
   143
      std::size_t& c;
sl@0
   144
      DiscoverTimeMap dtm;
sl@0
   145
      std::size_t& dfs_time;
sl@0
   146
      LowPointMap lowpt;
sl@0
   147
      PredecessorMap pred;
sl@0
   148
      OutputIterator out;
sl@0
   149
      Stack& S;
sl@0
   150
      DFSVisitor vis;
sl@0
   151
    };
sl@0
   152
sl@0
   153
  template<typename Graph, typename ComponentMap, typename OutputIterator,
sl@0
   154
        typename VertexIndexMap, typename DiscoverTimeMap, typename LowPointMap,
sl@0
   155
        typename PredecessorMap, typename DFSVisitor>
sl@0
   156
  std::pair<std::size_t, OutputIterator>
sl@0
   157
    biconnected_components_impl(const Graph & g, ComponentMap comp,
sl@0
   158
        OutputIterator out, VertexIndexMap index_map, DiscoverTimeMap dtm,
sl@0
   159
        LowPointMap lowpt, PredecessorMap pred, DFSVisitor dfs_vis)
sl@0
   160
  {
sl@0
   161
    typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
sl@0
   162
    typedef typename graph_traits<Graph>::edge_descriptor edge_t;
sl@0
   163
    function_requires<VertexListGraphConcept<Graph> >();
sl@0
   164
    function_requires<IncidenceGraphConcept<Graph> >();
sl@0
   165
    function_requires<WritablePropertyMapConcept<ComponentMap, edge_t> >();
sl@0
   166
    function_requires<ReadWritePropertyMapConcept<DiscoverTimeMap,
sl@0
   167
                                                  vertex_t> >();
sl@0
   168
    function_requires<ReadWritePropertyMapConcept<LowPointMap, vertex_t > >();
sl@0
   169
    function_requires<ReadWritePropertyMapConcept<PredecessorMap,
sl@0
   170
                                                  vertex_t> >();
sl@0
   171
sl@0
   172
    std::size_t num_components = 0;
sl@0
   173
    std::size_t dfs_time = 0;
sl@0
   174
      std::stack<edge_t> S;
sl@0
   175
sl@0
   176
      biconnected_components_visitor<ComponentMap, DiscoverTimeMap,
sl@0
   177
          LowPointMap, PredecessorMap, OutputIterator, std::stack<edge_t>, 
sl@0
   178
          DFSVisitor>
sl@0
   179
      vis(comp, num_components, dtm, dfs_time, lowpt, pred, out, 
sl@0
   180
          S, dfs_vis);
sl@0
   181
sl@0
   182
    depth_first_search(g, visitor(vis).vertex_index_map(index_map));
sl@0
   183
sl@0
   184
    return std::pair<std::size_t, OutputIterator>(num_components, vis.out);
sl@0
   185
  }
sl@0
   186
sl@0
   187
    template <typename PredecessorMap>
sl@0
   188
    struct bicomp_dispatch3
sl@0
   189
    {
sl@0
   190
  template<typename Graph, typename ComponentMap, typename OutputIterator,
sl@0
   191
                typename VertexIndexMap, typename DiscoverTimeMap, 
sl@0
   192
                typename LowPointMap, class P, class T, class R>
sl@0
   193
      static std::pair<std::size_t, OutputIterator> apply (const Graph & g, 
sl@0
   194
          ComponentMap comp, OutputIterator out, VertexIndexMap index_map, 
sl@0
   195
          DiscoverTimeMap dtm, LowPointMap lowpt, 
sl@0
   196
          const bgl_named_params<P, T, R>& params, PredecessorMap pred)
sl@0
   197
      {
sl@0
   198
        return biconnected_components_impl
sl@0
   199
                (g, comp, out, index_map, dtm, lowpt, pred,
sl@0
   200
                 choose_param(get_param(params, graph_visitor),
sl@0
   201
                    make_dfs_visitor(null_visitor())));
sl@0
   202
      }
sl@0
   203
    };
sl@0
   204
    
sl@0
   205
    template <>
sl@0
   206
    struct bicomp_dispatch3<error_property_not_found>
sl@0
   207
    {
sl@0
   208
      template<typename Graph, typename ComponentMap, typename OutputIterator,
sl@0
   209
                typename VertexIndexMap, typename DiscoverTimeMap, 
sl@0
   210
                typename LowPointMap, class P, class T, class R>
sl@0
   211
      static std::pair<std::size_t, OutputIterator> apply (const Graph & g, 
sl@0
   212
          ComponentMap comp, OutputIterator out, VertexIndexMap index_map, 
sl@0
   213
          DiscoverTimeMap dtm, LowPointMap lowpt, 
sl@0
   214
          const bgl_named_params<P, T, R>& params, 
sl@0
   215
          error_property_not_found)
sl@0
   216
  {
sl@0
   217
    typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
sl@0
   218
    std::vector<vertex_t> pred(num_vertices(g));
sl@0
   219
    vertex_t vert = graph_traits<Graph>::null_vertex();
sl@0
   220
sl@0
   221
        return biconnected_components_impl
sl@0
   222
                (g, comp, out, index_map, dtm, lowpt, 
sl@0
   223
              make_iterator_property_map(pred.begin(), index_map, vert),
sl@0
   224
                 choose_param(get_param(params, graph_visitor),
sl@0
   225
                    make_dfs_visitor(null_visitor())));
sl@0
   226
  }
sl@0
   227
    };
sl@0
   228
sl@0
   229
    template <typename LowPointMap>
sl@0
   230
    struct bicomp_dispatch2
sl@0
   231
    {
sl@0
   232
  template<typename Graph, typename ComponentMap, typename OutputIterator,
sl@0
   233
                typename VertexIndexMap, typename DiscoverTimeMap, 
sl@0
   234
                typename P, typename T, typename R>
sl@0
   235
      static std::pair<std::size_t, OutputIterator> apply (const Graph& g, 
sl@0
   236
          ComponentMap comp, OutputIterator out, VertexIndexMap index_map, 
sl@0
   237
          DiscoverTimeMap dtm, const bgl_named_params<P, T, R>& params, 
sl@0
   238
          LowPointMap lowpt)
sl@0
   239
      {
sl@0
   240
        typedef typename property_value< bgl_named_params<P,T,R>,
sl@0
   241
            vertex_predecessor_t>::type dispatch_type;
sl@0
   242
sl@0
   243
        return bicomp_dispatch3<dispatch_type>::apply
sl@0
   244
            (g, comp, out, index_map, dtm, lowpt, params, 
sl@0
   245
             get_param(params, vertex_predecessor));
sl@0
   246
      }
sl@0
   247
    };
sl@0
   248
sl@0
   249
sl@0
   250
    template <>
sl@0
   251
    struct bicomp_dispatch2<error_property_not_found>
sl@0
   252
    {
sl@0
   253
      template<typename Graph, typename ComponentMap, typename OutputIterator,
sl@0
   254
                typename VertexIndexMap, typename DiscoverTimeMap, 
sl@0
   255
                typename P, typename T, typename R>
sl@0
   256
      static std::pair<std::size_t, OutputIterator> apply (const Graph& g, 
sl@0
   257
          ComponentMap comp, OutputIterator out, VertexIndexMap index_map, 
sl@0
   258
          DiscoverTimeMap dtm, const bgl_named_params<P, T, R>& params, 
sl@0
   259
          error_property_not_found)
sl@0
   260
  {
sl@0
   261
    typedef typename graph_traits<Graph>::vertices_size_type
sl@0
   262
      vertices_size_type;
sl@0
   263
    std::vector<vertices_size_type> lowpt(num_vertices(g));
sl@0
   264
        vertices_size_type vst(0);
sl@0
   265
sl@0
   266
        typedef typename property_value< bgl_named_params<P,T,R>,
sl@0
   267
            vertex_predecessor_t>::type dispatch_type;
sl@0
   268
  
sl@0
   269
        return bicomp_dispatch3<dispatch_type>::apply
sl@0
   270
            (g, comp, out, index_map, dtm,
sl@0
   271
             make_iterator_property_map(lowpt.begin(), index_map, vst),
sl@0
   272
             params, get_param(params, vertex_predecessor));
sl@0
   273
      }
sl@0
   274
    };
sl@0
   275
sl@0
   276
    template <typename DiscoverTimeMap>
sl@0
   277
    struct bicomp_dispatch1
sl@0
   278
    {
sl@0
   279
      template<typename Graph, typename ComponentMap, typename OutputIterator,
sl@0
   280
                typename VertexIndexMap, class P, class T, class R>
sl@0
   281
      static std::pair<std::size_t, OutputIterator> apply(const Graph& g, 
sl@0
   282
          ComponentMap comp, OutputIterator out, VertexIndexMap index_map, 
sl@0
   283
          const bgl_named_params<P, T, R>& params, DiscoverTimeMap dtm)
sl@0
   284
      {
sl@0
   285
        typedef typename property_value< bgl_named_params<P,T,R>,
sl@0
   286
            vertex_lowpoint_t>::type dispatch_type;
sl@0
   287
sl@0
   288
        return bicomp_dispatch2<dispatch_type>::apply
sl@0
   289
            (g, comp, out, index_map, dtm, params, 
sl@0
   290
             get_param(params, vertex_lowpoint));
sl@0
   291
      }
sl@0
   292
    };
sl@0
   293
sl@0
   294
    template <>
sl@0
   295
    struct bicomp_dispatch1<error_property_not_found>
sl@0
   296
    {
sl@0
   297
      template<typename Graph, typename ComponentMap, typename OutputIterator,
sl@0
   298
                typename VertexIndexMap, class P, class T, class R>
sl@0
   299
      static std::pair<std::size_t, OutputIterator> apply(const Graph& g, 
sl@0
   300
          ComponentMap comp, OutputIterator out, VertexIndexMap index_map, 
sl@0
   301
          const bgl_named_params<P, T, R>& params, error_property_not_found)
sl@0
   302
      {
sl@0
   303
        typedef typename graph_traits<Graph>::vertices_size_type
sl@0
   304
            vertices_size_type;
sl@0
   305
        std::vector<vertices_size_type> discover_time(num_vertices(g));
sl@0
   306
    vertices_size_type vst(0);
sl@0
   307
sl@0
   308
        typedef typename property_value< bgl_named_params<P,T,R>,
sl@0
   309
            vertex_lowpoint_t>::type dispatch_type;
sl@0
   310
sl@0
   311
        return bicomp_dispatch2<dispatch_type>::apply
sl@0
   312
            (g, comp, out, index_map, 
sl@0
   313
              make_iterator_property_map(discover_time.begin(), index_map, vst),
sl@0
   314
             params, get_param(params, vertex_lowpoint));
sl@0
   315
      }
sl@0
   316
    };
sl@0
   317
sl@0
   318
  }
sl@0
   319
sl@0
   320
  template<typename Graph, typename ComponentMap, typename OutputIterator,
sl@0
   321
      typename DiscoverTimeMap, typename LowPointMap>
sl@0
   322
  std::pair<std::size_t, OutputIterator>
sl@0
   323
  biconnected_components(const Graph& g, ComponentMap comp, 
sl@0
   324
      OutputIterator out, DiscoverTimeMap dtm, LowPointMap lowpt)
sl@0
   325
  {
sl@0
   326
    typedef detail::error_property_not_found dispatch_type;
sl@0
   327
sl@0
   328
    return detail::bicomp_dispatch3<dispatch_type>::apply
sl@0
   329
            (g, comp, out, 
sl@0
   330
             get(vertex_index, g), 
sl@0
   331
             dtm, lowpt, 
sl@0
   332
             bgl_named_params<int, buffer_param_t>(0), 
sl@0
   333
             detail::error_property_not_found());
sl@0
   334
  }
sl@0
   335
sl@0
   336
  template <typename Graph, typename ComponentMap, typename OutputIterator,
sl@0
   337
      typename P, typename T, typename R>
sl@0
   338
  std::pair<std::size_t, OutputIterator>
sl@0
   339
  biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, 
sl@0
   340
      const bgl_named_params<P, T, R>& params)
sl@0
   341
  {
sl@0
   342
    typedef typename property_value< bgl_named_params<P,T,R>,
sl@0
   343
        vertex_discover_time_t>::type dispatch_type;
sl@0
   344
sl@0
   345
    return detail::bicomp_dispatch1<dispatch_type>::apply(g, comp, out, 
sl@0
   346
        choose_const_pmap(get_param(params, vertex_index), g, vertex_index), 
sl@0
   347
        params, get_param(params, vertex_discover_time));
sl@0
   348
  }
sl@0
   349
sl@0
   350
  template < typename Graph, typename ComponentMap, typename OutputIterator>
sl@0
   351
  std::pair<std::size_t, OutputIterator>
sl@0
   352
  biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out)
sl@0
   353
  {
sl@0
   354
    return biconnected_components(g, comp, out,  
sl@0
   355
        bgl_named_params<int, buffer_param_t>(0));
sl@0
   356
  }
sl@0
   357
sl@0
   358
  namespace graph_detail {
sl@0
   359
    struct dummy_output_iterator
sl@0
   360
    {
sl@0
   361
      typedef std::output_iterator_tag iterator_category;
sl@0
   362
      typedef void value_type;
sl@0
   363
      typedef void pointer;
sl@0
   364
      typedef void difference_type;
sl@0
   365
sl@0
   366
      struct reference {
sl@0
   367
        template<typename T>
sl@0
   368
        reference& operator=(const T&) { return *this; }
sl@0
   369
      };
sl@0
   370
sl@0
   371
      reference operator*() const { return reference(); }
sl@0
   372
      dummy_output_iterator& operator++() { return *this; }
sl@0
   373
      dummy_output_iterator operator++(int) { return *this; }
sl@0
   374
    };
sl@0
   375
  } // end namespace graph_detail
sl@0
   376
sl@0
   377
  template <typename Graph, typename ComponentMap,
sl@0
   378
      typename P, typename T, typename R>
sl@0
   379
  std::size_t
sl@0
   380
  biconnected_components(const Graph& g, ComponentMap comp, 
sl@0
   381
      const bgl_named_params<P, T, R>& params)
sl@0
   382
  {
sl@0
   383
    return biconnected_components(g, comp,
sl@0
   384
        graph_detail::dummy_output_iterator(), params).first;
sl@0
   385
  }
sl@0
   386
sl@0
   387
  template <typename Graph, typename ComponentMap>
sl@0
   388
  std::size_t
sl@0
   389
  biconnected_components(const Graph& g, ComponentMap comp)
sl@0
   390
  {
sl@0
   391
    return biconnected_components(g, comp,
sl@0
   392
                                  graph_detail::dummy_output_iterator()).first;
sl@0
   393
  }
sl@0
   394
sl@0
   395
  template<typename Graph, typename OutputIterator, 
sl@0
   396
      typename P, typename T, typename R>
sl@0
   397
  OutputIterator
sl@0
   398
  articulation_points(const Graph& g, OutputIterator out, 
sl@0
   399
      const bgl_named_params<P, T, R>& params)
sl@0
   400
  {
sl@0
   401
    return biconnected_components(g, dummy_property_map(), out, 
sl@0
   402
        params).second;
sl@0
   403
  }
sl@0
   404
sl@0
   405
  template<typename Graph, typename OutputIterator>
sl@0
   406
  OutputIterator
sl@0
   407
  articulation_points(const Graph& g, OutputIterator out)
sl@0
   408
  {
sl@0
   409
    return biconnected_components(g, dummy_property_map(), out, 
sl@0
   410
        bgl_named_params<int, buffer_param_t>(0)).second;
sl@0
   411
  }
sl@0
   412
sl@0
   413
}                               // namespace boost
sl@0
   414
sl@0
   415
#endif  /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */