src/lemon/graph_utils.h
author alpar
Fri, 08 Apr 2005 06:33:11 +0000
changeset 1321 bc3a4c498eb2
parent 1192 aa4483befa56
child 1359 1581f961cfaa
permissions -rw-r--r--
No output messages by default
klao@946
     1
/* -*- C++ -*-
klao@946
     2
 * src/lemon/graph_utils.h - Part of LEMON, a generic C++ optimization library
klao@946
     3
 *
alpar@1164
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
klao@946
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
klao@946
     6
 *
klao@946
     7
 * Permission to use, modify and distribute this software is granted
klao@946
     8
 * provided that this copyright notice appears in all copies. For
klao@946
     9
 * precise terms see the accompanying LICENSE file.
klao@946
    10
 *
klao@946
    11
 * This software is provided "AS IS" with no warranty of any kind,
klao@946
    12
 * express or implied, and with no claim as to its suitability for any
klao@946
    13
 * purpose.
klao@946
    14
 *
klao@946
    15
 */
klao@946
    16
klao@946
    17
#ifndef LEMON_GRAPH_UTILS_H
klao@946
    18
#define LEMON_GRAPH_UTILS_H
klao@946
    19
klao@946
    20
#include <iterator>
klao@946
    21
klao@946
    22
#include <lemon/invalid.h>
klao@977
    23
#include <lemon/utility.h>
klao@946
    24
alpar@947
    25
///\ingroup gutils
klao@946
    26
///\file
alpar@947
    27
///\brief Graph utilities.
klao@946
    28
///
alpar@964
    29
///\todo Please
alpar@964
    30
///revise the documentation.
alpar@964
    31
///
klao@946
    32
klao@946
    33
klao@946
    34
namespace lemon {
klao@946
    35
deba@1267
    36
  /// \addtogroup gutils
deba@1267
    37
  /// @{
alpar@947
    38
klao@946
    39
  /// \brief Function to count the items in the graph.
klao@946
    40
  ///
klao@946
    41
  /// This function counts the items in the graph.
klao@946
    42
  /// The complexity of the function is O(n) because
klao@946
    43
  /// it iterates on all of the items.
klao@946
    44
klao@946
    45
  template <typename Graph, typename ItemIt>
klao@977
    46
  inline int countItems(const Graph& g) {
klao@946
    47
    int num = 0;
klao@977
    48
    for (ItemIt it(g); it != INVALID; ++it) {
klao@946
    49
      ++num;
klao@946
    50
    }
klao@946
    51
    return num;
klao@946
    52
  }
klao@946
    53
klao@977
    54
  // Node counting:
klao@977
    55
klao@977
    56
  template <typename Graph>
klao@977
    57
  inline
klao@977
    58
  typename enable_if<typename Graph::NodeNumTag, int>::type
klao@977
    59
  _countNodes(const Graph &g) {
klao@977
    60
    return g.nodeNum();
klao@977
    61
  }
klao@977
    62
klao@977
    63
  template <typename Graph>
klao@977
    64
  inline int _countNodes(Wrap<Graph> w) {
klao@977
    65
    return countItems<Graph, typename Graph::NodeIt>(w.value);
klao@977
    66
  }
klao@977
    67
klao@946
    68
  /// \brief Function to count the nodes in the graph.
klao@946
    69
  ///
klao@946
    70
  /// This function counts the nodes in the graph.
klao@946
    71
  /// The complexity of the function is O(n) but for some
alpar@964
    72
  /// graph structure it is specialized to run in O(1).
klao@977
    73
  ///
klao@977
    74
  /// \todo refer how to specialize it
klao@946
    75
klao@946
    76
  template <typename Graph>
klao@977
    77
  inline int countNodes(const Graph& g) {
klao@977
    78
    return _countNodes<Graph>(g);
klao@977
    79
  }
klao@977
    80
klao@977
    81
  // Edge counting:
klao@977
    82
klao@977
    83
  template <typename Graph>
klao@977
    84
  inline
klao@977
    85
  typename enable_if<typename Graph::EdgeNumTag, int>::type
klao@977
    86
  _countEdges(const Graph &g) {
klao@977
    87
    return g.edgeNum();
klao@977
    88
  }
klao@977
    89
klao@977
    90
  template <typename Graph>
klao@977
    91
  inline int _countEdges(Wrap<Graph> w) {
klao@977
    92
    return countItems<Graph, typename Graph::EdgeIt>(w.value);
klao@946
    93
  }
klao@946
    94
klao@946
    95
  /// \brief Function to count the edges in the graph.
klao@946
    96
  ///
klao@946
    97
  /// This function counts the edges in the graph.
klao@946
    98
  /// The complexity of the function is O(e) but for some
alpar@964
    99
  /// graph structure it is specialized to run in O(1).
klao@977
   100
klao@946
   101
  template <typename Graph>
klao@977
   102
  inline int countEdges(const Graph& g) {
klao@977
   103
    return _countEdges<Graph>(g);
klao@946
   104
  }
klao@946
   105
klao@1053
   106
  // Undirected edge counting:
klao@1053
   107
klao@1053
   108
  template <typename Graph>
klao@1053
   109
  inline
klao@1053
   110
  typename enable_if<typename Graph::EdgeNumTag, int>::type
klao@1053
   111
  _countUndirEdges(const Graph &g) {
klao@1053
   112
    return g.undirEdgeNum();
klao@1053
   113
  }
klao@1053
   114
klao@1053
   115
  template <typename Graph>
klao@1053
   116
  inline int _countUndirEdges(Wrap<Graph> w) {
klao@1053
   117
    return countItems<Graph, typename Graph::UndirEdgeIt>(w.value);
klao@1053
   118
  }
klao@1053
   119
klao@1053
   120
  /// \brief Function to count the edges in the graph.
klao@946
   121
  ///
klao@1053
   122
  /// This function counts the edges in the graph.
klao@946
   123
  /// The complexity of the function is O(e) but for some
alpar@964
   124
  /// graph structure it is specialized to run in O(1).
klao@1053
   125
klao@946
   126
  template <typename Graph>
klao@1053
   127
  inline int countUndirEdges(const Graph& g) {
klao@1053
   128
    return _countUndirEdges<Graph>(g);
klao@946
   129
  }
klao@946
   130
klao@977
   131
klao@1053
   132
klao@946
   133
  template <typename Graph, typename DegIt>
klao@946
   134
  inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
klao@946
   135
    int num = 0;
klao@946
   136
    for (DegIt it(_g, _n); it != INVALID; ++it) {
klao@946
   137
      ++num;
klao@946
   138
    }
klao@946
   139
    return num;
klao@946
   140
  }
alpar@967
   141
alpar@967
   142
  /// Finds an edge between two nodes of a graph.
alpar@967
   143
alpar@967
   144
  /// Finds an edge from node \c u to node \c v in graph \c g.
alpar@967
   145
  ///
alpar@967
   146
  /// If \c prev is \ref INVALID (this is the default value), then
alpar@967
   147
  /// it finds the first edge from \c u to \c v. Otherwise it looks for
alpar@967
   148
  /// the next edge from \c u to \c v after \c prev.
alpar@967
   149
  /// \return The found edge or \ref INVALID if there is no such an edge.
alpar@967
   150
  ///
alpar@967
   151
  /// Thus you can iterate through each edge from \c u to \c v as it follows.
alpar@967
   152
  /// \code
alpar@967
   153
  /// for(Edge e=findEdge(g,u,v);e!=INVALID;e=findEdge(g,u,v,e)) {
alpar@967
   154
  ///   ...
alpar@967
   155
  /// }
alpar@967
   156
  /// \endcode
alpar@967
   157
  /// \todo We may want to use the \ref concept::GraphBase "GraphBase"
alpar@967
   158
  /// interface here...
alpar@967
   159
  /// \bug Untested ...
alpar@967
   160
  template <typename Graph>
alpar@967
   161
  typename Graph::Edge findEdge(const Graph &g,
deba@1267
   162
				typename Graph::Node u, typename Graph::Node v,
deba@1267
   163
				typename Graph::Edge prev = INVALID) 
alpar@967
   164
  {
alpar@967
   165
    typename Graph::OutEdgeIt e(g,prev);
alpar@1079
   166
    //    if(prev==INVALID) g.first(e,u);
alpar@1079
   167
    if(prev==INVALID) e=typename Graph::OutEdgeIt(g,u);
alpar@967
   168
    else ++e;
alpar@1079
   169
    while(e!=INVALID && g.target(e)!=v) ++e;
alpar@967
   170
    return e;
alpar@967
   171
  }
alpar@964
   172
  
alpar@964
   173
  ///\e
klao@946
   174
alpar@964
   175
  ///\todo Please document.
alpar@964
   176
  ///
klao@946
   177
  template <typename Graph>
klao@946
   178
  inline int countOutEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946
   179
    return countNodeDegree<Graph, typename Graph::OutEdgeIt>(_g, _n);
klao@946
   180
  }
klao@946
   181
alpar@964
   182
  ///\e
alpar@964
   183
alpar@964
   184
  ///\todo Please document.
alpar@964
   185
  ///
klao@946
   186
  template <typename Graph>
klao@946
   187
  inline int countInEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946
   188
    return countNodeDegree<Graph, typename Graph::InEdgeIt>(_g, _n);
klao@946
   189
  }
klao@946
   190
klao@946
   191
  // graph copy
klao@946
   192
klao@946
   193
  template <
klao@946
   194
    typename DestinationGraph, 
klao@946
   195
    typename SourceGraph, 
klao@946
   196
    typename NodeBijection>
klao@946
   197
  void copyNodes(DestinationGraph& _d, const SourceGraph& _s, 
klao@946
   198
		 NodeBijection& _nb) {    
klao@946
   199
    for (typename SourceGraph::NodeIt it(_s); it != INVALID; ++it) {
klao@946
   200
      _nb[it] = _d.addNode();
klao@946
   201
    }
klao@946
   202
  }
klao@946
   203
klao@946
   204
  template <
klao@946
   205
    typename DestinationGraph, 
klao@946
   206
    typename SourceGraph, 
klao@946
   207
    typename NodeBijection,
klao@946
   208
    typename EdgeBijection>
klao@946
   209
  void copyEdges(DestinationGraph& _d, const SourceGraph& _s,
klao@946
   210
		 const NodeBijection& _nb, EdgeBijection& _eb) {    
klao@946
   211
    for (typename SourceGraph::EdgeIt it(_s); it != INVALID; ++it) {
alpar@986
   212
      _eb[it] = _d.addEdge(_nb[_s.source(it)], _nb[_s.target(it)]);
klao@946
   213
    }
klao@946
   214
  }
klao@946
   215
klao@946
   216
  template <
klao@946
   217
    typename DestinationGraph, 
klao@946
   218
    typename SourceGraph, 
klao@946
   219
    typename NodeBijection,
klao@946
   220
    typename EdgeBijection>
klao@946
   221
  void copyGraph(DestinationGraph& _d, const SourceGraph& _s, 
klao@946
   222
		 NodeBijection& _nb, EdgeBijection& _eb) {
klao@946
   223
    nodeCopy(_d, _s, _nb);
klao@946
   224
    edgeCopy(_d, _s, _nb, _eb);
klao@946
   225
  }
klao@946
   226
 
deba@1267
   227
  template <
klao@946
   228
    typename _DestinationGraph, 
klao@946
   229
    typename _SourceGraph, 
klao@946
   230
    typename _NodeBijection 
klao@946
   231
    =typename _SourceGraph::template NodeMap<typename _DestinationGraph::Node>,
klao@946
   232
    typename _EdgeBijection 
deba@1267
   233
    = typename _SourceGraph::template EdgeMap<typename _DestinationGraph::Edge>
deba@1267
   234
  >
deba@1267
   235
  class GraphCopy {
deba@1267
   236
  public:
deba@1267
   237
    
deba@1267
   238
    typedef _DestinationGraph DestinationGraph;
deba@1267
   239
    typedef _SourceGraph SourceGraph;
klao@946
   240
deba@1267
   241
    typedef _NodeBijection NodeBijection;
deba@1267
   242
    typedef _EdgeBijection EdgeBijection;
deba@1267
   243
    
deba@1267
   244
  protected:          
deba@1267
   245
    
deba@1267
   246
    NodeBijection node_bijection;
deba@1267
   247
    EdgeBijection edge_bijection;     
klao@946
   248
deba@1267
   249
  public:
deba@1267
   250
     
deba@1267
   251
    GraphCopy(DestinationGraph& _d, const SourceGraph& _s) {
deba@1267
   252
      copyGraph(_d, _s, node_bijection, edge_bijection);
deba@1267
   253
    }
deba@1267
   254
    
deba@1267
   255
    const NodeBijection& getNodeBijection() const {
deba@1267
   256
      return node_bijection;
deba@1267
   257
    }
klao@946
   258
deba@1267
   259
    const EdgeBijection& getEdgeBijection() const {
deba@1267
   260
      return edge_bijection;
deba@1267
   261
    }
deba@1267
   262
     
deba@1267
   263
  };
klao@946
   264
klao@946
   265
deba@1267
   266
  template <typename _Graph, typename _Item>
deba@1267
   267
  class ItemSetTraits {
deba@1267
   268
  };
deba@1192
   269
  
deba@1192
   270
  template <typename _Graph>
deba@1267
   271
  class ItemSetTraits<_Graph, typename _Graph::Node> {
deba@1192
   272
  public:
deba@1192
   273
    
deba@1192
   274
    typedef _Graph Graph;
alpar@947
   275
deba@1192
   276
    typedef typename Graph::Node Item;
deba@1192
   277
    typedef typename Graph::NodeIt ItemIt;
deba@1192
   278
deba@1192
   279
    template <typename _Value>
deba@1192
   280
    class Map : public Graph::template NodeMap<_Value> {
deba@1192
   281
    public:
deba@1192
   282
      typedef typename Graph::template NodeMap<_Value> Parent; 
deba@1192
   283
      typedef typename Parent::Value Value;
deba@1192
   284
deba@1192
   285
      Map(const Graph& _graph) : Parent(_graph) {}
deba@1192
   286
      Map(const Graph& _graph, const Value& _value) 
deba@1192
   287
	: Parent(_graph, _value) {}
deba@1192
   288
    };
deba@1192
   289
deba@1192
   290
  };
deba@1192
   291
deba@1192
   292
  template <typename _Graph>
deba@1267
   293
  class ItemSetTraits<_Graph, typename _Graph::Edge> {
deba@1192
   294
  public:
deba@1192
   295
    
deba@1192
   296
    typedef _Graph Graph;
deba@1192
   297
deba@1192
   298
    typedef typename Graph::Edge Item;
deba@1192
   299
    typedef typename Graph::EdgeIt ItemIt;
deba@1192
   300
deba@1192
   301
    template <typename _Value>
deba@1192
   302
    class Map : public Graph::template EdgeMap<_Value> {
deba@1192
   303
    public:
deba@1192
   304
      typedef typename Graph::template EdgeMap<_Value> Parent; 
deba@1192
   305
      typedef typename Parent::Value Value;
deba@1192
   306
deba@1192
   307
      Map(const Graph& _graph) : Parent(_graph) {}
deba@1192
   308
      Map(const Graph& _graph, const Value& _value) 
deba@1192
   309
	: Parent(_graph, _value) {}
deba@1192
   310
    };
deba@1192
   311
deba@1192
   312
  };
deba@1192
   313
deba@1267
   314
  template <typename _Graph>
deba@1267
   315
  class ItemSetTraits<_Graph, typename _Graph::UndirEdge> {
deba@1267
   316
  public:
deba@1267
   317
    
deba@1267
   318
    typedef _Graph Graph;
deba@1267
   319
deba@1267
   320
    typedef typename Graph::UndirEdge Item;
deba@1267
   321
    typedef typename Graph::UndirEdgeIt ItemIt;
deba@1267
   322
deba@1267
   323
    template <typename _Value>
deba@1267
   324
    class Map : public Graph::template UndirEdgeMap<_Value> {
deba@1267
   325
    public:
deba@1267
   326
      typedef typename Graph::template UndirEdgeMap<_Value> Parent; 
deba@1267
   327
      typedef typename Parent::Value Value;
deba@1267
   328
deba@1267
   329
      Map(const Graph& _graph) : Parent(_graph) {}
deba@1267
   330
      Map(const Graph& _graph, const Value& _value) 
deba@1267
   331
	: Parent(_graph, _value) {}
deba@1267
   332
    };
deba@1267
   333
deba@1267
   334
  };
deba@1192
   335
deba@1192
   336
  /// @}
alpar@947
   337
  
alpar@947
   338
} //END OF NAMESPACE LEMON
klao@946
   339
klao@946
   340
#endif