src/lemon/graph_utils.h
author alpar
Fri, 18 Mar 2005 06:00:20 +0000
changeset 1226 71fcebd3a041
parent 1164 80bb73097736
child 1267 a93f94dbe3d3
permissions -rw-r--r--
Minor changes for educational purposes.
(Much more would be necessary...)
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>
deba@1192
    24
#include <lemon/map_utils.h>
klao@946
    25
alpar@947
    26
///\ingroup gutils
klao@946
    27
///\file
alpar@947
    28
///\brief Graph utilities.
klao@946
    29
///
alpar@964
    30
///\todo Please
alpar@964
    31
///revise the documentation.
alpar@964
    32
///
klao@946
    33
klao@946
    34
klao@946
    35
namespace lemon {
klao@946
    36
alpar@947
    37
/// \addtogroup gutils
alpar@947
    38
/// @{
alpar@947
    39
klao@946
    40
  /// \brief Function to count the items in the graph.
klao@946
    41
  ///
klao@946
    42
  /// This function counts the items in the graph.
klao@946
    43
  /// The complexity of the function is O(n) because
klao@946
    44
  /// it iterates on all of the items.
klao@946
    45
klao@946
    46
  template <typename Graph, typename ItemIt>
klao@977
    47
  inline int countItems(const Graph& g) {
klao@946
    48
    int num = 0;
klao@977
    49
    for (ItemIt it(g); it != INVALID; ++it) {
klao@946
    50
      ++num;
klao@946
    51
    }
klao@946
    52
    return num;
klao@946
    53
  }
klao@946
    54
klao@977
    55
  // Node counting:
klao@977
    56
klao@977
    57
  template <typename Graph>
klao@977
    58
  inline
klao@977
    59
  typename enable_if<typename Graph::NodeNumTag, int>::type
klao@977
    60
  _countNodes(const Graph &g) {
klao@977
    61
    return g.nodeNum();
klao@977
    62
  }
klao@977
    63
klao@977
    64
  template <typename Graph>
klao@977
    65
  inline int _countNodes(Wrap<Graph> w) {
klao@977
    66
    return countItems<Graph, typename Graph::NodeIt>(w.value);
klao@977
    67
  }
klao@977
    68
klao@946
    69
  /// \brief Function to count the nodes in the graph.
klao@946
    70
  ///
klao@946
    71
  /// This function counts the nodes in the graph.
klao@946
    72
  /// The complexity of the function is O(n) but for some
alpar@964
    73
  /// graph structure it is specialized to run in O(1).
klao@977
    74
  ///
klao@977
    75
  /// \todo refer how to specialize it
klao@946
    76
klao@946
    77
  template <typename Graph>
klao@977
    78
  inline int countNodes(const Graph& g) {
klao@977
    79
    return _countNodes<Graph>(g);
klao@977
    80
  }
klao@977
    81
klao@977
    82
  // Edge counting:
klao@977
    83
klao@977
    84
  template <typename Graph>
klao@977
    85
  inline
klao@977
    86
  typename enable_if<typename Graph::EdgeNumTag, int>::type
klao@977
    87
  _countEdges(const Graph &g) {
klao@977
    88
    return g.edgeNum();
klao@977
    89
  }
klao@977
    90
klao@977
    91
  template <typename Graph>
klao@977
    92
  inline int _countEdges(Wrap<Graph> w) {
klao@977
    93
    return countItems<Graph, typename Graph::EdgeIt>(w.value);
klao@946
    94
  }
klao@946
    95
klao@946
    96
  /// \brief Function to count the edges in the graph.
klao@946
    97
  ///
klao@946
    98
  /// This function counts the edges in the graph.
klao@946
    99
  /// The complexity of the function is O(e) but for some
alpar@964
   100
  /// graph structure it is specialized to run in O(1).
klao@977
   101
klao@946
   102
  template <typename Graph>
klao@977
   103
  inline int countEdges(const Graph& g) {
klao@977
   104
    return _countEdges<Graph>(g);
klao@946
   105
  }
klao@946
   106
klao@1053
   107
  // Undirected edge counting:
klao@1053
   108
klao@1053
   109
  template <typename Graph>
klao@1053
   110
  inline
klao@1053
   111
  typename enable_if<typename Graph::EdgeNumTag, int>::type
klao@1053
   112
  _countUndirEdges(const Graph &g) {
klao@1053
   113
    return g.undirEdgeNum();
klao@1053
   114
  }
klao@1053
   115
klao@1053
   116
  template <typename Graph>
klao@1053
   117
  inline int _countUndirEdges(Wrap<Graph> w) {
klao@1053
   118
    return countItems<Graph, typename Graph::UndirEdgeIt>(w.value);
klao@1053
   119
  }
klao@1053
   120
klao@1053
   121
  /// \brief Function to count the edges in the graph.
klao@946
   122
  ///
klao@1053
   123
  /// This function counts the edges in the graph.
klao@946
   124
  /// The complexity of the function is O(e) but for some
alpar@964
   125
  /// graph structure it is specialized to run in O(1).
klao@1053
   126
klao@946
   127
  template <typename Graph>
klao@1053
   128
  inline int countUndirEdges(const Graph& g) {
klao@1053
   129
    return _countUndirEdges<Graph>(g);
klao@946
   130
  }
klao@946
   131
klao@977
   132
klao@1053
   133
klao@946
   134
  template <typename Graph, typename DegIt>
klao@946
   135
  inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
klao@946
   136
    int num = 0;
klao@946
   137
    for (DegIt it(_g, _n); it != INVALID; ++it) {
klao@946
   138
      ++num;
klao@946
   139
    }
klao@946
   140
    return num;
klao@946
   141
  }
alpar@967
   142
alpar@967
   143
  /// Finds an edge between two nodes of a graph.
alpar@967
   144
alpar@967
   145
  /// Finds an edge from node \c u to node \c v in graph \c g.
alpar@967
   146
  ///
alpar@967
   147
  /// If \c prev is \ref INVALID (this is the default value), then
alpar@967
   148
  /// it finds the first edge from \c u to \c v. Otherwise it looks for
alpar@967
   149
  /// the next edge from \c u to \c v after \c prev.
alpar@967
   150
  /// \return The found edge or \ref INVALID if there is no such an edge.
alpar@967
   151
  ///
alpar@967
   152
  /// Thus you can iterate through each edge from \c u to \c v as it follows.
alpar@967
   153
  /// \code
alpar@967
   154
  /// for(Edge e=findEdge(g,u,v);e!=INVALID;e=findEdge(g,u,v,e)) {
alpar@967
   155
  ///   ...
alpar@967
   156
  /// }
alpar@967
   157
  /// \endcode
alpar@967
   158
  /// \todo We may want to use the \ref concept::GraphBase "GraphBase"
alpar@967
   159
  /// interface here...
alpar@967
   160
  /// \bug Untested ...
alpar@967
   161
  template <typename Graph>
alpar@967
   162
  typename Graph::Edge findEdge(const Graph &g,
alpar@967
   163
		typename Graph::Node u, typename Graph::Node v,
alpar@967
   164
		typename Graph::Edge prev = INVALID) 
alpar@967
   165
  {
alpar@967
   166
    typename Graph::OutEdgeIt e(g,prev);
alpar@1079
   167
    //    if(prev==INVALID) g.first(e,u);
alpar@1079
   168
    if(prev==INVALID) e=typename Graph::OutEdgeIt(g,u);
alpar@967
   169
    else ++e;
alpar@1079
   170
    while(e!=INVALID && g.target(e)!=v) ++e;
alpar@967
   171
    return e;
alpar@967
   172
  }
alpar@964
   173
  
alpar@964
   174
  ///\e
klao@946
   175
alpar@964
   176
  ///\todo Please document.
alpar@964
   177
  ///
klao@946
   178
  template <typename Graph>
klao@946
   179
  inline int countOutEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946
   180
    return countNodeDegree<Graph, typename Graph::OutEdgeIt>(_g, _n);
klao@946
   181
  }
klao@946
   182
alpar@964
   183
  ///\e
alpar@964
   184
alpar@964
   185
  ///\todo Please document.
alpar@964
   186
  ///
klao@946
   187
  template <typename Graph>
klao@946
   188
  inline int countInEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946
   189
    return countNodeDegree<Graph, typename Graph::InEdgeIt>(_g, _n);
klao@946
   190
  }
klao@946
   191
klao@946
   192
  // graph copy
klao@946
   193
klao@946
   194
  template <
klao@946
   195
    typename DestinationGraph, 
klao@946
   196
    typename SourceGraph, 
klao@946
   197
    typename NodeBijection>
klao@946
   198
  void copyNodes(DestinationGraph& _d, const SourceGraph& _s, 
klao@946
   199
		 NodeBijection& _nb) {    
klao@946
   200
    for (typename SourceGraph::NodeIt it(_s); it != INVALID; ++it) {
klao@946
   201
      _nb[it] = _d.addNode();
klao@946
   202
    }
klao@946
   203
  }
klao@946
   204
klao@946
   205
  template <
klao@946
   206
    typename DestinationGraph, 
klao@946
   207
    typename SourceGraph, 
klao@946
   208
    typename NodeBijection,
klao@946
   209
    typename EdgeBijection>
klao@946
   210
  void copyEdges(DestinationGraph& _d, const SourceGraph& _s,
klao@946
   211
		 const NodeBijection& _nb, EdgeBijection& _eb) {    
klao@946
   212
    for (typename SourceGraph::EdgeIt it(_s); it != INVALID; ++it) {
alpar@986
   213
      _eb[it] = _d.addEdge(_nb[_s.source(it)], _nb[_s.target(it)]);
klao@946
   214
    }
klao@946
   215
  }
klao@946
   216
klao@946
   217
  template <
klao@946
   218
    typename DestinationGraph, 
klao@946
   219
    typename SourceGraph, 
klao@946
   220
    typename NodeBijection,
klao@946
   221
    typename EdgeBijection>
klao@946
   222
  void copyGraph(DestinationGraph& _d, const SourceGraph& _s, 
klao@946
   223
		 NodeBijection& _nb, EdgeBijection& _eb) {
klao@946
   224
    nodeCopy(_d, _s, _nb);
klao@946
   225
    edgeCopy(_d, _s, _nb, _eb);
klao@946
   226
  }
klao@946
   227
 
klao@946
   228
   template <
klao@946
   229
    typename _DestinationGraph, 
klao@946
   230
    typename _SourceGraph, 
klao@946
   231
    typename _NodeBijection 
klao@946
   232
    =typename _SourceGraph::template NodeMap<typename _DestinationGraph::Node>,
klao@946
   233
    typename _EdgeBijection 
klao@946
   234
    =typename _SourceGraph::template EdgeMap<typename _DestinationGraph::Edge>
klao@946
   235
   >
klao@946
   236
   class GraphCopy {
klao@946
   237
   public:
klao@946
   238
klao@946
   239
     typedef _DestinationGraph DestinationGraph;
klao@946
   240
     typedef _SourceGraph SourceGraph;
klao@946
   241
klao@946
   242
     typedef _NodeBijection NodeBijection;
klao@946
   243
     typedef _EdgeBijection EdgeBijection;
klao@946
   244
klao@946
   245
   protected:          
klao@946
   246
klao@946
   247
     NodeBijection node_bijection;
klao@946
   248
     EdgeBijection edge_bijection;     
klao@946
   249
klao@946
   250
   public:
klao@946
   251
     
klao@946
   252
     GraphCopy(DestinationGraph& _d, const SourceGraph& _s) {
klao@946
   253
       copyGraph(_d, _s, node_bijection, edge_bijection);
klao@946
   254
     }
klao@946
   255
klao@946
   256
     const NodeBijection& getNodeBijection() const {
klao@946
   257
       return node_bijection;
klao@946
   258
     }
klao@946
   259
klao@946
   260
     const EdgeBijection& getEdgeBijection() const {
klao@946
   261
       return edge_bijection;
klao@946
   262
     }
klao@946
   263
     
klao@946
   264
   };
deba@1192
   265
  
deba@1192
   266
  template <typename _Graph>
deba@1192
   267
  class GraphNodeSet {
deba@1192
   268
  public:
deba@1192
   269
    
deba@1192
   270
    typedef _Graph Graph;
alpar@947
   271
deba@1192
   272
    typedef typename Graph::Node Item;
deba@1192
   273
    typedef typename Graph::NodeIt ItemIt;
deba@1192
   274
deba@1192
   275
    template <typename _Value>
deba@1192
   276
    class Map : public Graph::template NodeMap<_Value> {
deba@1192
   277
    public:
deba@1192
   278
      typedef typename Graph::template NodeMap<_Value> Parent; 
deba@1192
   279
      typedef typename Parent::Value Value;
deba@1192
   280
deba@1192
   281
      Map(const Graph& _graph) : Parent(_graph) {}
deba@1192
   282
      Map(const Graph& _graph, const Value& _value) 
deba@1192
   283
	: Parent(_graph, _value) {}
deba@1192
   284
    };
deba@1192
   285
deba@1192
   286
    typedef IdMap<Graph, Item> IdMap;
deba@1192
   287
    
deba@1192
   288
  private:
deba@1192
   289
    Graph* graph;
deba@1192
   290
  };
deba@1192
   291
deba@1192
   292
  template <typename _Graph>
deba@1192
   293
  class GraphEdgeSet {
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
    typedef IdMap<Graph, Item> IdMap;
deba@1192
   313
    
deba@1192
   314
  private:
deba@1192
   315
    Graph* graph;
deba@1192
   316
  };
deba@1192
   317
deba@1192
   318
deba@1192
   319
  /// @}
alpar@947
   320
  
alpar@947
   321
} //END OF NAMESPACE LEMON
klao@946
   322
klao@946
   323
#endif