src/lemon/graph_utils.h
author klao
Wed, 05 Jan 2005 14:34:00 +0000
changeset 1053 90f8696360b2
parent 986 e997802b855c
child 1079 81addddaf3d3
permissions -rw-r--r--
UndirGraphs: invalid edge bug
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@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,
alpar@967
   162
		typename Graph::Node u, typename Graph::Node v,
alpar@967
   163
		typename Graph::Edge prev = INVALID) 
alpar@967
   164
  {
alpar@967
   165
    typename Graph::OutEdgeIt e(g,prev);
alpar@967
   166
    if(prev==INVALID) g.first(e,u);
alpar@967
   167
    else ++e;
alpar@986
   168
    while(e!=INVALID && g.source(e)!=v) ++e;
alpar@967
   169
    return e;
alpar@967
   170
  }
alpar@964
   171
  
alpar@964
   172
  ///\e
klao@946
   173
alpar@964
   174
  ///\todo Please document.
alpar@964
   175
  ///
klao@946
   176
  template <typename Graph>
klao@946
   177
  inline int countOutEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946
   178
    return countNodeDegree<Graph, typename Graph::OutEdgeIt>(_g, _n);
klao@946
   179
  }
klao@946
   180
alpar@964
   181
  ///\e
alpar@964
   182
alpar@964
   183
  ///\todo Please document.
alpar@964
   184
  ///
klao@946
   185
  template <typename Graph>
klao@946
   186
  inline int countInEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946
   187
    return countNodeDegree<Graph, typename Graph::InEdgeIt>(_g, _n);
klao@946
   188
  }
klao@946
   189
klao@946
   190
  // graph copy
klao@946
   191
klao@946
   192
  template <
klao@946
   193
    typename DestinationGraph, 
klao@946
   194
    typename SourceGraph, 
klao@946
   195
    typename NodeBijection>
klao@946
   196
  void copyNodes(DestinationGraph& _d, const SourceGraph& _s, 
klao@946
   197
		 NodeBijection& _nb) {    
klao@946
   198
    for (typename SourceGraph::NodeIt it(_s); it != INVALID; ++it) {
klao@946
   199
      _nb[it] = _d.addNode();
klao@946
   200
    }
klao@946
   201
  }
klao@946
   202
klao@946
   203
  template <
klao@946
   204
    typename DestinationGraph, 
klao@946
   205
    typename SourceGraph, 
klao@946
   206
    typename NodeBijection,
klao@946
   207
    typename EdgeBijection>
klao@946
   208
  void copyEdges(DestinationGraph& _d, const SourceGraph& _s,
klao@946
   209
		 const NodeBijection& _nb, EdgeBijection& _eb) {    
klao@946
   210
    for (typename SourceGraph::EdgeIt it(_s); it != INVALID; ++it) {
alpar@986
   211
      _eb[it] = _d.addEdge(_nb[_s.source(it)], _nb[_s.target(it)]);
klao@946
   212
    }
klao@946
   213
  }
klao@946
   214
klao@946
   215
  template <
klao@946
   216
    typename DestinationGraph, 
klao@946
   217
    typename SourceGraph, 
klao@946
   218
    typename NodeBijection,
klao@946
   219
    typename EdgeBijection>
klao@946
   220
  void copyGraph(DestinationGraph& _d, const SourceGraph& _s, 
klao@946
   221
		 NodeBijection& _nb, EdgeBijection& _eb) {
klao@946
   222
    nodeCopy(_d, _s, _nb);
klao@946
   223
    edgeCopy(_d, _s, _nb, _eb);
klao@946
   224
  }
klao@946
   225
 
klao@946
   226
   template <
klao@946
   227
    typename _DestinationGraph, 
klao@946
   228
    typename _SourceGraph, 
klao@946
   229
    typename _NodeBijection 
klao@946
   230
    =typename _SourceGraph::template NodeMap<typename _DestinationGraph::Node>,
klao@946
   231
    typename _EdgeBijection 
klao@946
   232
    =typename _SourceGraph::template EdgeMap<typename _DestinationGraph::Edge>
klao@946
   233
   >
klao@946
   234
   class GraphCopy {
klao@946
   235
   public:
klao@946
   236
klao@946
   237
     typedef _DestinationGraph DestinationGraph;
klao@946
   238
     typedef _SourceGraph SourceGraph;
klao@946
   239
klao@946
   240
     typedef _NodeBijection NodeBijection;
klao@946
   241
     typedef _EdgeBijection EdgeBijection;
klao@946
   242
klao@946
   243
   protected:          
klao@946
   244
klao@946
   245
     NodeBijection node_bijection;
klao@946
   246
     EdgeBijection edge_bijection;     
klao@946
   247
klao@946
   248
   public:
klao@946
   249
     
klao@946
   250
     GraphCopy(DestinationGraph& _d, const SourceGraph& _s) {
klao@946
   251
       copyGraph(_d, _s, node_bijection, edge_bijection);
klao@946
   252
     }
klao@946
   253
klao@946
   254
     const NodeBijection& getNodeBijection() const {
klao@946
   255
       return node_bijection;
klao@946
   256
     }
klao@946
   257
klao@946
   258
     const EdgeBijection& getEdgeBijection() const {
klao@946
   259
       return edge_bijection;
klao@946
   260
     }
klao@946
   261
     
klao@946
   262
   };
alpar@947
   263
alpar@947
   264
/// @}
alpar@947
   265
  
alpar@947
   266
} //END OF NAMESPACE LEMON
klao@946
   267
klao@946
   268
#endif