src/lemon/graph_utils.h
author klao
Wed, 10 Nov 2004 20:14:32 +0000
changeset 977 48962802d168
parent 967 6563019430ba
child 986 e997802b855c
permissions -rw-r--r--
* enable_if imported from BOOST
* count{Nodes,Edges} implemented via graph tags
* some #include bugs fixed
klao@946
     1
/* -*- C++ -*-
klao@946
     2
 * src/lemon/graph_utils.h - Part of LEMON, a generic C++ optimization library
klao@946
     3
 *
klao@946
     4
 * Copyright (C) 2004 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
alpar@947
    36
/// \addtogroup gutils
alpar@947
    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@946
   106
  /// \brief Function to count the symmetric edges in the graph.
klao@946
   107
  ///
klao@946
   108
  /// This function counts the symmetric edges in the graph.
klao@946
   109
  /// The complexity of the function is O(e) but for some
alpar@964
   110
  /// graph structure it is specialized to run in O(1).
klao@946
   111
  template <typename Graph>
klao@946
   112
  inline int countSymEdges(const Graph& _g) {
klao@946
   113
    return countItems<Graph, typename Graph::SymEdgeIt>(_g);
klao@946
   114
  }
klao@946
   115
klao@977
   116
klao@946
   117
  template <typename Graph, typename DegIt>
klao@946
   118
  inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
klao@946
   119
    int num = 0;
klao@946
   120
    for (DegIt it(_g, _n); it != INVALID; ++it) {
klao@946
   121
      ++num;
klao@946
   122
    }
klao@946
   123
    return num;
klao@946
   124
  }
alpar@967
   125
alpar@967
   126
  /// Finds an edge between two nodes of a graph.
alpar@967
   127
alpar@967
   128
  /// Finds an edge from node \c u to node \c v in graph \c g.
alpar@967
   129
  ///
alpar@967
   130
  /// If \c prev is \ref INVALID (this is the default value), then
alpar@967
   131
  /// it finds the first edge from \c u to \c v. Otherwise it looks for
alpar@967
   132
  /// the next edge from \c u to \c v after \c prev.
alpar@967
   133
  /// \return The found edge or \ref INVALID if there is no such an edge.
alpar@967
   134
  ///
alpar@967
   135
  /// Thus you can iterate through each edge from \c u to \c v as it follows.
alpar@967
   136
  /// \code
alpar@967
   137
  /// for(Edge e=findEdge(g,u,v);e!=INVALID;e=findEdge(g,u,v,e)) {
alpar@967
   138
  ///   ...
alpar@967
   139
  /// }
alpar@967
   140
  /// \endcode
alpar@967
   141
  /// \todo We may want to use the \ref concept::GraphBase "GraphBase"
alpar@967
   142
  /// interface here...
alpar@967
   143
  /// \bug Untested ...
alpar@967
   144
  template <typename Graph>
alpar@967
   145
  typename Graph::Edge findEdge(const Graph &g,
alpar@967
   146
		typename Graph::Node u, typename Graph::Node v,
alpar@967
   147
		typename Graph::Edge prev = INVALID) 
alpar@967
   148
  {
alpar@967
   149
    typename Graph::OutEdgeIt e(g,prev);
alpar@967
   150
    if(prev==INVALID) g.first(e,u);
alpar@967
   151
    else ++e;
alpar@967
   152
    while(e!=INVALID && g.tail(e)!=v) ++e;
alpar@967
   153
    return e;
alpar@967
   154
  }
alpar@964
   155
  
alpar@964
   156
  ///\e
klao@946
   157
alpar@964
   158
  ///\todo Please document.
alpar@964
   159
  ///
klao@946
   160
  template <typename Graph>
klao@946
   161
  inline int countOutEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946
   162
    return countNodeDegree<Graph, typename Graph::OutEdgeIt>(_g, _n);
klao@946
   163
  }
klao@946
   164
alpar@964
   165
  ///\e
alpar@964
   166
alpar@964
   167
  ///\todo Please document.
alpar@964
   168
  ///
klao@946
   169
  template <typename Graph>
klao@946
   170
  inline int countInEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946
   171
    return countNodeDegree<Graph, typename Graph::InEdgeIt>(_g, _n);
klao@946
   172
  }
klao@946
   173
klao@946
   174
  // graph copy
klao@946
   175
klao@946
   176
  template <
klao@946
   177
    typename DestinationGraph, 
klao@946
   178
    typename SourceGraph, 
klao@946
   179
    typename NodeBijection>
klao@946
   180
  void copyNodes(DestinationGraph& _d, const SourceGraph& _s, 
klao@946
   181
		 NodeBijection& _nb) {    
klao@946
   182
    for (typename SourceGraph::NodeIt it(_s); it != INVALID; ++it) {
klao@946
   183
      _nb[it] = _d.addNode();
klao@946
   184
    }
klao@946
   185
  }
klao@946
   186
klao@946
   187
  template <
klao@946
   188
    typename DestinationGraph, 
klao@946
   189
    typename SourceGraph, 
klao@946
   190
    typename NodeBijection,
klao@946
   191
    typename EdgeBijection>
klao@946
   192
  void copyEdges(DestinationGraph& _d, const SourceGraph& _s,
klao@946
   193
		 const NodeBijection& _nb, EdgeBijection& _eb) {    
klao@946
   194
    for (typename SourceGraph::EdgeIt it(_s); it != INVALID; ++it) {
klao@946
   195
      _eb[it] = _d.addEdge(_nb[_s.tail(it)], _nb[_s.head(it)]);
klao@946
   196
    }
klao@946
   197
  }
klao@946
   198
klao@946
   199
  template <
klao@946
   200
    typename DestinationGraph, 
klao@946
   201
    typename SourceGraph, 
klao@946
   202
    typename NodeBijection,
klao@946
   203
    typename EdgeBijection>
klao@946
   204
  void copyGraph(DestinationGraph& _d, const SourceGraph& _s, 
klao@946
   205
		 NodeBijection& _nb, EdgeBijection& _eb) {
klao@946
   206
    nodeCopy(_d, _s, _nb);
klao@946
   207
    edgeCopy(_d, _s, _nb, _eb);
klao@946
   208
  }
klao@946
   209
 
klao@946
   210
   template <
klao@946
   211
    typename _DestinationGraph, 
klao@946
   212
    typename _SourceGraph, 
klao@946
   213
    typename _NodeBijection 
klao@946
   214
    =typename _SourceGraph::template NodeMap<typename _DestinationGraph::Node>,
klao@946
   215
    typename _EdgeBijection 
klao@946
   216
    =typename _SourceGraph::template EdgeMap<typename _DestinationGraph::Edge>
klao@946
   217
   >
klao@946
   218
   class GraphCopy {
klao@946
   219
   public:
klao@946
   220
klao@946
   221
     typedef _DestinationGraph DestinationGraph;
klao@946
   222
     typedef _SourceGraph SourceGraph;
klao@946
   223
klao@946
   224
     typedef _NodeBijection NodeBijection;
klao@946
   225
     typedef _EdgeBijection EdgeBijection;
klao@946
   226
klao@946
   227
   protected:          
klao@946
   228
klao@946
   229
     NodeBijection node_bijection;
klao@946
   230
     EdgeBijection edge_bijection;     
klao@946
   231
klao@946
   232
   public:
klao@946
   233
     
klao@946
   234
     GraphCopy(DestinationGraph& _d, const SourceGraph& _s) {
klao@946
   235
       copyGraph(_d, _s, node_bijection, edge_bijection);
klao@946
   236
     }
klao@946
   237
klao@946
   238
     const NodeBijection& getNodeBijection() const {
klao@946
   239
       return node_bijection;
klao@946
   240
     }
klao@946
   241
klao@946
   242
     const EdgeBijection& getEdgeBijection() const {
klao@946
   243
       return edge_bijection;
klao@946
   244
     }
klao@946
   245
     
klao@946
   246
   };
alpar@947
   247
alpar@947
   248
/// @}
alpar@947
   249
  
alpar@947
   250
} //END OF NAMESPACE LEMON
klao@946
   251
klao@946
   252
#endif