os/ossrv/ossrv_pub/boost_apis/boost/graph/graph_utility.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
//
sl@0
     2
//=======================================================================
sl@0
     3
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
sl@0
     4
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
sl@0
     5
//
sl@0
     6
// Distributed under the Boost Software License, Version 1.0. (See
sl@0
     7
// accompanying file LICENSE_1_0.txt or copy at
sl@0
     8
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     9
//=======================================================================
sl@0
    10
//
sl@0
    11
#ifndef BOOST_GRAPH_UTILITY_HPP
sl@0
    12
#define BOOST_GRAPH_UTILITY_HPP
sl@0
    13
sl@0
    14
#include <stdlib.h>
sl@0
    15
#include <iostream>
sl@0
    16
#include <algorithm>
sl@0
    17
#include <assert.h>
sl@0
    18
#include <boost/config.hpp>
sl@0
    19
#include <boost/tuple/tuple.hpp>
sl@0
    20
sl@0
    21
#if !defined BOOST_NO_SLIST
sl@0
    22
#  ifdef BOOST_SLIST_HEADER
sl@0
    23
#    include BOOST_SLIST_HEADER
sl@0
    24
#  else
sl@0
    25
#    include <slist>
sl@0
    26
#  endif
sl@0
    27
#endif
sl@0
    28
sl@0
    29
#include <boost/graph/graph_traits.hpp>
sl@0
    30
#include <boost/graph/properties.hpp>
sl@0
    31
#include <boost/pending/container_traits.hpp>
sl@0
    32
#include <boost/graph/depth_first_search.hpp>
sl@0
    33
// iota moved to detail/algorithm.hpp
sl@0
    34
#include <boost/detail/algorithm.hpp>
sl@0
    35
sl@0
    36
namespace boost {
sl@0
    37
sl@0
    38
  // Provide an undirected graph interface alternative to the
sl@0
    39
  // the source() and target() edge functions.
sl@0
    40
  template <class UndirectedGraph>
sl@0
    41
  inline 
sl@0
    42
  std::pair<typename graph_traits<UndirectedGraph>::vertex_descriptor,
sl@0
    43
            typename graph_traits<UndirectedGraph>::vertex_descriptor>
sl@0
    44
  incident(typename graph_traits<UndirectedGraph>::edge_descriptor e,
sl@0
    45
           UndirectedGraph& g)
sl@0
    46
  {
sl@0
    47
    return std::make_pair(source(e,g), target(e,g));
sl@0
    48
  }
sl@0
    49
sl@0
    50
  // Provide an undirected graph interface alternative
sl@0
    51
  // to the out_edges() function.
sl@0
    52
  template <class Graph>
sl@0
    53
  inline 
sl@0
    54
  std::pair<typename graph_traits<Graph>::out_edge_iterator,
sl@0
    55
            typename graph_traits<Graph>::out_edge_iterator>
sl@0
    56
  incident_edges(typename graph_traits<Graph>::vertex_descriptor u,
sl@0
    57
                 Graph& g)
sl@0
    58
  {
sl@0
    59
    return out_edges(u, g);
sl@0
    60
  }
sl@0
    61
sl@0
    62
  template <class Graph>
sl@0
    63
  inline typename graph_traits<Graph>::vertex_descriptor
sl@0
    64
  opposite(typename graph_traits<Graph>::edge_descriptor e,
sl@0
    65
           typename graph_traits<Graph>::vertex_descriptor v,
sl@0
    66
           const Graph& g)
sl@0
    67
  {
sl@0
    68
    typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
sl@0
    69
    if (v == source(e, g))
sl@0
    70
      return target(e, g);
sl@0
    71
    else if (v == target(e, g))
sl@0
    72
      return source(e, g);
sl@0
    73
    else
sl@0
    74
      return vertex_descriptor();
sl@0
    75
  }
sl@0
    76
sl@0
    77
  //===========================================================================
sl@0
    78
  // Some handy predicates
sl@0
    79
sl@0
    80
  template <typename Vertex, typename Graph>
sl@0
    81
  struct incident_from_predicate {
sl@0
    82
    incident_from_predicate(Vertex u, const Graph& g)
sl@0
    83
      : m_u(u), m_g(g) { }
sl@0
    84
    template <class Edge>
sl@0
    85
    bool operator()(const Edge& e) const {
sl@0
    86
      return source(e, m_g) == m_u;
sl@0
    87
    }
sl@0
    88
    Vertex m_u;
sl@0
    89
    const Graph& m_g;
sl@0
    90
  };
sl@0
    91
  template <typename Vertex, typename Graph>
sl@0
    92
  inline incident_from_predicate<Vertex, Graph>
sl@0
    93
  incident_from(Vertex u, const Graph& g) {
sl@0
    94
    return incident_from_predicate<Vertex, Graph>(u, g);
sl@0
    95
  }
sl@0
    96
  
sl@0
    97
  template <typename Vertex, typename Graph>
sl@0
    98
  struct incident_to_predicate {
sl@0
    99
    incident_to_predicate(Vertex u, const Graph& g)
sl@0
   100
      : m_u(u), m_g(g) { }
sl@0
   101
    template <class Edge>
sl@0
   102
    bool operator()(const Edge& e) const {
sl@0
   103
      return target(e, m_g) == m_u;
sl@0
   104
    }
sl@0
   105
    Vertex m_u;
sl@0
   106
    const Graph& m_g;
sl@0
   107
  };
sl@0
   108
  template <typename Vertex, typename Graph>
sl@0
   109
  inline incident_to_predicate<Vertex, Graph>
sl@0
   110
  incident_to(Vertex u, const Graph& g) {
sl@0
   111
    return incident_to_predicate<Vertex, Graph>(u, g);
sl@0
   112
  }
sl@0
   113
sl@0
   114
  template <typename Vertex, typename Graph>
sl@0
   115
  struct incident_on_predicate {
sl@0
   116
    incident_on_predicate(Vertex u, const Graph& g)
sl@0
   117
      : m_u(u), m_g(g) { }
sl@0
   118
    template <class Edge>
sl@0
   119
    bool operator()(const Edge& e) const {
sl@0
   120
      return source(e, m_g) == m_u || target(e, m_g) == m_u;
sl@0
   121
    }
sl@0
   122
    Vertex m_u;
sl@0
   123
    const Graph& m_g;
sl@0
   124
  };
sl@0
   125
  template <typename Vertex, typename Graph>
sl@0
   126
  inline incident_on_predicate<Vertex, Graph>
sl@0
   127
  incident_on(Vertex u, const Graph& g) {
sl@0
   128
    return incident_on_predicate<Vertex, Graph>(u, g);
sl@0
   129
  }
sl@0
   130
  
sl@0
   131
  template <typename Vertex, typename Graph>
sl@0
   132
  struct connects_predicate {
sl@0
   133
    connects_predicate(Vertex u, Vertex v, const Graph& g)
sl@0
   134
      : m_u(u), m_v(v), m_g(g) { }
sl@0
   135
    template <class Edge>
sl@0
   136
    bool operator()(const Edge& e) const {
sl@0
   137
      if (is_directed(m_g))
sl@0
   138
        return source(e, m_g) == m_u && target(e, m_g) == m_v;
sl@0
   139
      else
sl@0
   140
        return (source(e, m_g) == m_u && target(e, m_g) == m_v)
sl@0
   141
          || (source(e, m_g) == m_v && target(e, m_g) == m_u);
sl@0
   142
    }
sl@0
   143
    Vertex m_u, m_v;
sl@0
   144
    const Graph& m_g;
sl@0
   145
  };
sl@0
   146
  template <typename Vertex, typename Graph>
sl@0
   147
  inline connects_predicate<Vertex, Graph>
sl@0
   148
  connects(Vertex u, Vertex v, const Graph& g) {
sl@0
   149
          return connects_predicate<Vertex, Graph>(u, v, g);
sl@0
   150
  }
sl@0
   151
sl@0
   152
sl@0
   153
  // Need to convert all of these printing functions to take an ostream object
sl@0
   154
  // -JGS
sl@0
   155
sl@0
   156
  template <class IncidenceGraph, class Name>
sl@0
   157
  void print_in_edges(const IncidenceGraph& G, Name name)
sl@0
   158
  {
sl@0
   159
    typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
sl@0
   160
    for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
sl@0
   161
      std::cout << get(name,*ui) << " <-- ";
sl@0
   162
      typename graph_traits<IncidenceGraph>
sl@0
   163
        ::in_edge_iterator ei, ei_end;
sl@0
   164
      for(tie(ei,ei_end) = in_edges(*ui,G); ei != ei_end; ++ei)
sl@0
   165
        std::cout << get(name,source(*ei,G)) << " ";
sl@0
   166
      std::cout << std::endl;
sl@0
   167
    }
sl@0
   168
  }
sl@0
   169
sl@0
   170
  template <class IncidenceGraph, class Name>
sl@0
   171
  void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag)
sl@0
   172
  {
sl@0
   173
    typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
sl@0
   174
    for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
sl@0
   175
      std::cout << get(name,*ui) << " --> ";
sl@0
   176
      typename graph_traits<IncidenceGraph>
sl@0
   177
        ::out_edge_iterator ei, ei_end;
sl@0
   178
      for(tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei)
sl@0
   179
        std::cout << get(name,target(*ei,G)) << " ";
sl@0
   180
      std::cout << std::endl;
sl@0
   181
    }
sl@0
   182
  }
sl@0
   183
  template <class IncidenceGraph, class Name>
sl@0
   184
  void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag)
sl@0
   185
  {
sl@0
   186
    typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
sl@0
   187
    for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
sl@0
   188
      std::cout << get(name,*ui) << " <--> ";
sl@0
   189
      typename graph_traits<IncidenceGraph>
sl@0
   190
        ::out_edge_iterator ei, ei_end;
sl@0
   191
      for(tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei)
sl@0
   192
        std::cout << get(name,target(*ei,G)) << " ";
sl@0
   193
      std::cout << std::endl;
sl@0
   194
    }
sl@0
   195
  }
sl@0
   196
  template <class IncidenceGraph, class Name>
sl@0
   197
  void print_graph(const IncidenceGraph& G, Name name)
sl@0
   198
  {
sl@0
   199
    typedef typename graph_traits<IncidenceGraph>
sl@0
   200
      ::directed_category Cat;
sl@0
   201
    print_graph_dispatch(G, name, Cat());
sl@0
   202
  }
sl@0
   203
  template <class IncidenceGraph>
sl@0
   204
  void print_graph(const IncidenceGraph& G) {
sl@0
   205
    print_graph(G, get(vertex_index, G));
sl@0
   206
  }
sl@0
   207
sl@0
   208
  template <class EdgeListGraph, class Name>
sl@0
   209
  void print_edges(const EdgeListGraph& G, Name name)
sl@0
   210
  {
sl@0
   211
    typename graph_traits<EdgeListGraph>::edge_iterator ei, ei_end;
sl@0
   212
    for (tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
sl@0
   213
      std::cout << "(" << get(name, source(*ei, G))
sl@0
   214
                << "," << get(name, target(*ei, G)) << ") ";
sl@0
   215
    std::cout << std::endl;
sl@0
   216
  }
sl@0
   217
sl@0
   218
  template <class EdgeListGraph, class VertexName, class EdgeName>
sl@0
   219
  void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename)
sl@0
   220
  {
sl@0
   221
    typename graph_traits<EdgeListGraph>::edge_iterator ei, ei_end;
sl@0
   222
    for (tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
sl@0
   223
      std::cout << get(ename, *ei) << "(" << get(vname, source(*ei, G))
sl@0
   224
                << "," << get(vname, target(*ei, G)) << ") ";
sl@0
   225
    std::cout << std::endl;
sl@0
   226
  }
sl@0
   227
sl@0
   228
  template <class VertexListGraph, class Name>
sl@0
   229
  void print_vertices(const VertexListGraph& G, Name name)
sl@0
   230
  {
sl@0
   231
    typename graph_traits<VertexListGraph>::vertex_iterator vi,vi_end;
sl@0
   232
    for (tie(vi,vi_end) = vertices(G); vi != vi_end; ++vi)
sl@0
   233
      std::cout << get(name,*vi) << " ";
sl@0
   234
    std::cout << std::endl;
sl@0
   235
  }
sl@0
   236
sl@0
   237
  template <class Graph, class Vertex>
sl@0
   238
  bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag)
sl@0
   239
  {
sl@0
   240
    typedef typename graph_traits<Graph>::edge_descriptor 
sl@0
   241
      edge_descriptor;
sl@0
   242
    typename graph_traits<Graph>::adjacency_iterator vi, viend, 
sl@0
   243
      adj_found;
sl@0
   244
    tie(vi, viend) = adjacent_vertices(a, g);
sl@0
   245
    adj_found = std::find(vi, viend, b);
sl@0
   246
    if (adj_found == viend)
sl@0
   247
      return false;  
sl@0
   248
sl@0
   249
    typename graph_traits<Graph>::out_edge_iterator oi, oiend, 
sl@0
   250
      out_found;
sl@0
   251
    tie(oi, oiend) = out_edges(a, g);
sl@0
   252
    out_found = std::find_if(oi, oiend, incident_to(b, g));
sl@0
   253
    if (out_found == oiend)
sl@0
   254
      return false;
sl@0
   255
sl@0
   256
    typename graph_traits<Graph>::in_edge_iterator ii, iiend, 
sl@0
   257
      in_found;
sl@0
   258
    tie(ii, iiend) = in_edges(b, g);
sl@0
   259
    in_found = std::find_if(ii, iiend, incident_from(a, g));
sl@0
   260
    if (in_found == iiend)
sl@0
   261
      return false;
sl@0
   262
sl@0
   263
    return true;
sl@0
   264
  }
sl@0
   265
  template <class Graph, class Vertex>
sl@0
   266
  bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag)
sl@0
   267
  {
sl@0
   268
    typedef typename graph_traits<Graph>::edge_descriptor 
sl@0
   269
      edge_descriptor;
sl@0
   270
    typename graph_traits<Graph>::adjacency_iterator vi, viend, found;
sl@0
   271
    tie(vi, viend) = adjacent_vertices(a, g);
sl@0
   272
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT)
sl@0
   273
    // Getting internal compiler error with std::find()
sl@0
   274
    found = viend;
sl@0
   275
    for (; vi != viend; ++vi)
sl@0
   276
      if (*vi == b) {
sl@0
   277
        found = vi;
sl@0
   278
        break;
sl@0
   279
      }
sl@0
   280
#else
sl@0
   281
    found = std::find(vi, viend, b);
sl@0
   282
#endif
sl@0
   283
    if ( found == viend )
sl@0
   284
      return false;
sl@0
   285
sl@0
   286
    typename graph_traits<Graph>::out_edge_iterator oi, oiend, 
sl@0
   287
      out_found;
sl@0
   288
    tie(oi, oiend) = out_edges(a, g);
sl@0
   289
sl@0
   290
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT)
sl@0
   291
    // Getting internal compiler error with std::find()
sl@0
   292
    out_found = oiend;
sl@0
   293
    for (; oi != oiend; ++oi)
sl@0
   294
      if (target(*oi, g) == b) {
sl@0
   295
        out_found = oi;
sl@0
   296
        break;
sl@0
   297
      }
sl@0
   298
#else
sl@0
   299
    out_found = std::find_if(oi, oiend, incident_to(b, g));
sl@0
   300
#endif
sl@0
   301
    if (out_found == oiend)
sl@0
   302
      return false;
sl@0
   303
    return true;
sl@0
   304
  }
sl@0
   305
  template <class Graph, class Vertex>
sl@0
   306
  bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, undirected_tag)
sl@0
   307
  {
sl@0
   308
    return is_adj_dispatch(g, a, b, directed_tag());
sl@0
   309
  }
sl@0
   310
sl@0
   311
  template <class Graph, class Vertex>
sl@0
   312
  bool is_adjacent(Graph& g, Vertex a, Vertex b) {
sl@0
   313
    typedef typename graph_traits<Graph>::directed_category Cat;
sl@0
   314
    return is_adj_dispatch(g, a, b, Cat());
sl@0
   315
  }
sl@0
   316
sl@0
   317
  template <class Graph, class Edge>
sl@0
   318
  bool in_edge_set(Graph& g, Edge e)
sl@0
   319
  {
sl@0
   320
    typename Graph::edge_iterator ei, ei_end, found;
sl@0
   321
    tie(ei, ei_end) = edges(g);
sl@0
   322
    found = std::find(ei, ei_end, e);
sl@0
   323
    return found != ei_end;
sl@0
   324
  }
sl@0
   325
sl@0
   326
  template <class Graph, class Vertex>
sl@0
   327
  bool in_vertex_set(Graph& g, Vertex v)
sl@0
   328
  {
sl@0
   329
    typename Graph::vertex_iterator vi, vi_end, found;
sl@0
   330
    tie(vi, vi_end) = vertices(g);
sl@0
   331
    found = std::find(vi, vi_end, v);
sl@0
   332
    return found != vi_end;
sl@0
   333
  }
sl@0
   334
sl@0
   335
  template <class Graph, class Vertex>
sl@0
   336
  bool in_edge_set(Graph& g, Vertex u, Vertex v)
sl@0
   337
  {
sl@0
   338
    typename Graph::edge_iterator ei, ei_end;
sl@0
   339
    for (tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
sl@0
   340
      if (source(*ei,g) == u && target(*ei,g) == v)
sl@0
   341
        return true;
sl@0
   342
    return false;
sl@0
   343
  }
sl@0
   344
sl@0
   345
  // is x a descendant of y?
sl@0
   346
  template <typename ParentMap>
sl@0
   347
  inline bool is_descendant
sl@0
   348
  (typename property_traits<ParentMap>::value_type x,
sl@0
   349
   typename property_traits<ParentMap>::value_type y,
sl@0
   350
   ParentMap parent) 
sl@0
   351
  {
sl@0
   352
    if (get(parent, x) == x) // x is the root of the tree
sl@0
   353
      return false;
sl@0
   354
    else if (get(parent, x) == y)
sl@0
   355
      return true;
sl@0
   356
    else
sl@0
   357
      return is_descendant(get(parent, x), y, parent);
sl@0
   358
  }
sl@0
   359
sl@0
   360
  // is y reachable from x?
sl@0
   361
  template <typename IncidenceGraph, typename VertexColorMap>
sl@0
   362
  inline bool is_reachable
sl@0
   363
    (typename graph_traits<IncidenceGraph>::vertex_descriptor x,
sl@0
   364
     typename graph_traits<IncidenceGraph>::vertex_descriptor y,
sl@0
   365
     const IncidenceGraph& g,
sl@0
   366
     VertexColorMap color) // should start out white for every vertex
sl@0
   367
  {
sl@0
   368
    typedef typename property_traits<VertexColorMap>::value_type ColorValue;
sl@0
   369
    dfs_visitor<> vis;
sl@0
   370
    depth_first_visit(g, x, vis, color);
sl@0
   371
    return get(color, y) != color_traits<ColorValue>::white();
sl@0
   372
  }
sl@0
   373
sl@0
   374
  // Is the undirected graph connected?
sl@0
   375
  // Is the directed graph strongly connected?
sl@0
   376
  template <typename VertexListGraph, typename VertexColorMap>
sl@0
   377
  inline bool is_connected(const VertexListGraph& g, VertexColorMap color)
sl@0
   378
  {
sl@0
   379
    typedef typename property_traits<VertexColorMap>::value_type ColorValue;
sl@0
   380
    typedef color_traits<ColorValue> Color;
sl@0
   381
    typename graph_traits<VertexListGraph>::vertex_iterator 
sl@0
   382
      ui, ui_end, vi, vi_end, ci, ci_end;
sl@0
   383
    for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
sl@0
   384
      for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
sl@0
   385
        if (*ui != *vi) {
sl@0
   386
          for (tie(ci, ci_end) = vertices(g); ci != ci_end; ++ci) 
sl@0
   387
            put(color, *ci, Color::white());
sl@0
   388
          if (! is_reachable(*ui, *vi, color))
sl@0
   389
            return false;
sl@0
   390
        }
sl@0
   391
    return true;
sl@0
   392
  }
sl@0
   393
sl@0
   394
  template <typename Graph>
sl@0
   395
  bool is_self_loop
sl@0
   396
    (typename graph_traits<Graph>::edge_descriptor e,
sl@0
   397
     const Graph& g)
sl@0
   398
  {
sl@0
   399
    return source(e, g) == target(e, g);
sl@0
   400
  }
sl@0
   401
sl@0
   402
sl@0
   403
  template <class T1, class T2>
sl@0
   404
  std::pair<T1,T2> 
sl@0
   405
  make_list(const T1& t1, const T2& t2) 
sl@0
   406
    { return std::make_pair(t1, t2); }
sl@0
   407
sl@0
   408
  template <class T1, class T2, class T3>
sl@0
   409
  std::pair<T1,std::pair<T2,T3> > 
sl@0
   410
  make_list(const T1& t1, const T2& t2, const T3& t3)
sl@0
   411
    { return std::make_pair(t1, std::make_pair(t2, t3)); }
sl@0
   412
sl@0
   413
  template <class T1, class T2, class T3, class T4>
sl@0
   414
  std::pair<T1,std::pair<T2,std::pair<T3,T4> > > 
sl@0
   415
  make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
sl@0
   416
    { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, t4))); }
sl@0
   417
sl@0
   418
  template <class T1, class T2, class T3, class T4, class T5>
sl@0
   419
  std::pair<T1,std::pair<T2,std::pair<T3,std::pair<T4,T5> > > > 
sl@0
   420
  make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
sl@0
   421
    { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, std::make_pair(t4, t5)))); }
sl@0
   422
sl@0
   423
} /* namespace boost */
sl@0
   424
sl@0
   425
#endif /* BOOST_GRAPH_UTILITY_HPP*/