gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Move list and edge sets to the graph module (#290)
0 2 0
default
2 files changed with 5 insertions and 15 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
namespace lemon {
20 20

	
21 21
/**
22 22
@defgroup datas Data Structures
23 23
This group contains the several data structures implemented in LEMON.
24 24
*/
25 25

	
26 26
/**
27 27
@defgroup graphs Graph Structures
28 28
@ingroup datas
29 29
\brief Graph structures implemented in LEMON.
30 30

	
31 31
The implementation of combinatorial algorithms heavily relies on
32 32
efficient graph implementations. LEMON offers data structures which are
33 33
planned to be easily used in an experimental phase of implementation studies,
34 34
and thereafter the program code can be made efficient by small modifications.
35 35

	
36 36
The most efficient implementation of diverse applications require the
37 37
usage of different physical graph implementations. These differences
38 38
appear in the size of graph we require to handle, memory or time usage
39 39
limitations or in the set of operations through which the graph can be
40 40
accessed.  LEMON provides several physical graph structures to meet
41 41
the diverging requirements of the possible users.  In order to save on
42 42
running time or on memory usage, some structures may fail to provide
43 43
some graph features like arc/edge or node deletion.
44 44

	
45 45
Alteration of standard containers need a very limited number of
46 46
operations, these together satisfy the everyday requirements.
47 47
In the case of graph structures, different operations are needed which do
48 48
not alter the physical graph, but gives another view. If some nodes or
49 49
arcs have to be hidden or the reverse oriented graph have to be used, then
50 50
this is the case. It also may happen that in a flow implementation
51 51
the residual graph can be accessed by another algorithm, or a node-set
52 52
is to be shrunk for another algorithm.
53 53
LEMON also provides a variety of graphs for these requirements called
54 54
\ref graph_adaptors "graph adaptors". Adaptors cannot be used alone but only
55 55
in conjunction with other graph representations.
56 56

	
57 57
You are free to use the graph structure that fit your requirements
58 58
the best, most graph algorithms and auxiliary data structures can be used
59 59
with any graph structure.
60 60

	
61 61
<b>See also:</b> \ref graph_concepts "Graph Structure Concepts".
62 62
*/
63 63

	
64 64
/**
65 65
@defgroup graph_adaptors Adaptor Classes for Graphs
66 66
@ingroup graphs
67 67
\brief Adaptor classes for digraphs and graphs
68 68

	
69 69
This group contains several useful adaptor classes for digraphs and graphs.
70 70

	
71 71
The main parts of LEMON are the different graph structures, generic
72 72
graph algorithms, graph concepts, which couple them, and graph
73 73
adaptors. While the previous notions are more or less clear, the
74 74
latter one needs further explanation. Graph adaptors are graph classes
75 75
which serve for considering graph structures in different ways.
76 76

	
77 77
A short example makes this much clearer.  Suppose that we have an
78 78
instance \c g of a directed graph type, say ListDigraph and an algorithm
79 79
\code
80 80
template <typename Digraph>
81 81
int algorithm(const Digraph&);
82 82
\endcode
83 83
is needed to run on the reverse oriented graph.  It may be expensive
84 84
(in time or in memory usage) to copy \c g with the reversed
85 85
arcs.  In this case, an adaptor class is used, which (according
86 86
to LEMON \ref concepts::Digraph "digraph concepts") works as a digraph.
87 87
The adaptor uses the original digraph structure and digraph operations when
88 88
methods of the reversed oriented graph are called.  This means that the adaptor
89 89
have minor memory usage, and do not perform sophisticated algorithmic
90 90
actions.  The purpose of it is to give a tool for the cases when a
91 91
graph have to be used in a specific alteration.  If this alteration is
92 92
obtained by a usual construction like filtering the node or the arc set or
93 93
considering a new orientation, then an adaptor is worthwhile to use.
94 94
To come back to the reverse oriented graph, in this situation
95 95
\code
96 96
template<typename Digraph> class ReverseDigraph;
97 97
\endcode
98 98
template class can be used. The code looks as follows
99 99
\code
100 100
ListDigraph g;
101 101
ReverseDigraph<ListDigraph> rg(g);
102 102
int result = algorithm(rg);
103 103
\endcode
104 104
During running the algorithm, the original digraph \c g is untouched.
105 105
This techniques give rise to an elegant code, and based on stable
106 106
graph adaptors, complex algorithms can be implemented easily.
107 107

	
108 108
In flow, circulation and matching problems, the residual
109 109
graph is of particular importance. Combining an adaptor implementing
110 110
this with shortest path algorithms or minimum mean cycle algorithms,
111 111
a range of weighted and cardinality optimization algorithms can be
112 112
obtained. For other examples, the interested user is referred to the
113 113
detailed documentation of particular adaptors.
114 114

	
115 115
The behavior of graph adaptors can be very different. Some of them keep
116 116
capabilities of the original graph while in other cases this would be
117 117
meaningless. This means that the concepts that they meet depend
118 118
on the graph adaptor, and the wrapped graph.
119 119
For example, if an arc of a reversed digraph is deleted, this is carried
120 120
out by deleting the corresponding arc of the original digraph, thus the
121 121
adaptor modifies the original digraph.
122 122
However in case of a residual digraph, this operation has no sense.
123 123

	
124 124
Let us stand one more example here to simplify your work.
125 125
ReverseDigraph has constructor
126 126
\code
127 127
ReverseDigraph(Digraph& digraph);
128 128
\endcode
129 129
This means that in a situation, when a <tt>const %ListDigraph&</tt>
130 130
reference to a graph is given, then it have to be instantiated with
131 131
<tt>Digraph=const %ListDigraph</tt>.
132 132
\code
133 133
int algorithm1(const ListDigraph& g) {
134 134
  ReverseDigraph<const ListDigraph> rg(g);
135 135
  return algorithm2(rg);
136 136
}
137 137
\endcode
138 138
*/
139 139

	
140 140
/**
141
@defgroup semi_adaptors Semi-Adaptor Classes for Graphs
142
@ingroup graphs
143
\brief Graph types between real graphs and graph adaptors.
144

	
145
This group contains some graph types between real graphs and graph adaptors.
146
These classes wrap graphs to give new functionality as the adaptors do it.
147
On the other hand they are not light-weight structures as the adaptors.
148
*/
149

	
150
/**
151 141
@defgroup maps Maps
152 142
@ingroup datas
153 143
\brief Map structures implemented in LEMON.
154 144

	
155 145
This group contains the map structures implemented in LEMON.
156 146

	
157 147
LEMON provides several special purpose maps and map adaptors that e.g. combine
158 148
new maps from existing ones.
159 149

	
160 150
<b>See also:</b> \ref map_concepts "Map Concepts".
161 151
*/
162 152

	
163 153
/**
164 154
@defgroup graph_maps Graph Maps
165 155
@ingroup maps
166 156
\brief Special graph-related maps.
167 157

	
168 158
This group contains maps that are specifically designed to assign
169 159
values to the nodes and arcs/edges of graphs.
170 160

	
171 161
If you are looking for the standard graph maps (\c NodeMap, \c ArcMap,
172 162
\c EdgeMap), see the \ref graph_concepts "Graph Structure Concepts".
173 163
*/
174 164

	
175 165
/**
176 166
\defgroup map_adaptors Map Adaptors
177 167
\ingroup maps
178 168
\brief Tools to create new maps from existing ones
179 169

	
180 170
This group contains map adaptors that are used to create "implicit"
181 171
maps from other maps.
182 172

	
183 173
Most of them are \ref concepts::ReadMap "read-only maps".
184 174
They can make arithmetic and logical operations between one or two maps
185 175
(negation, shifting, addition, multiplication, logical 'and', 'or',
186 176
'not' etc.) or e.g. convert a map to another one of different Value type.
187 177

	
188 178
The typical usage of this classes is passing implicit maps to
189 179
algorithms.  If a function type algorithm is called then the function
190 180
type map adaptors can be used comfortable. For example let's see the
191 181
usage of map adaptors with the \c graphToEps() function.
192 182
\code
193 183
  Color nodeColor(int deg) {
194 184
    if (deg >= 2) {
195 185
      return Color(0.5, 0.0, 0.5);
196 186
    } else if (deg == 1) {
197 187
      return Color(1.0, 0.5, 1.0);
198 188
    } else {
199 189
      return Color(0.0, 0.0, 0.0);
200 190
    }
201 191
  }
202 192

	
203 193
  Digraph::NodeMap<int> degree_map(graph);
204 194

	
205 195
  graphToEps(graph, "graph.eps")
206 196
    .coords(coords).scaleToA4().undirected()
207 197
    .nodeColors(composeMap(functorToMap(nodeColor), degree_map))
208 198
    .run();
209 199
\endcode
210 200
The \c functorToMap() function makes an \c int to \c Color map from the
211 201
\c nodeColor() function. The \c composeMap() compose the \c degree_map
212 202
and the previously created map. The composed map is a proper function to
213 203
get the color of each node.
214 204

	
215 205
The usage with class type algorithms is little bit harder. In this
216 206
case the function type map adaptors can not be used, because the
217 207
function map adaptors give back temporary objects.
218 208
\code
219 209
  Digraph graph;
220 210

	
221 211
  typedef Digraph::ArcMap<double> DoubleArcMap;
222 212
  DoubleArcMap length(graph);
223 213
  DoubleArcMap speed(graph);
224 214

	
225 215
  typedef DivMap<DoubleArcMap, DoubleArcMap> TimeMap;
226 216
  TimeMap time(length, speed);
227 217

	
228 218
  Dijkstra<Digraph, TimeMap> dijkstra(graph, time);
229 219
  dijkstra.run(source, target);
230 220
\endcode
231 221
We have a length map and a maximum speed map on the arcs of a digraph.
232 222
The minimum time to pass the arc can be calculated as the division of
233 223
the two maps which can be done implicitly with the \c DivMap template
234 224
class. We use the implicit minimum time map as the length map of the
235 225
\c Dijkstra algorithm.
236 226
*/
237 227

	
238 228
/**
239 229
@defgroup matrices Matrices
240 230
@ingroup datas
241 231
\brief Two dimensional data storages implemented in LEMON.
242 232

	
243 233
This group contains two dimensional data storages implemented in LEMON.
244 234
*/
245 235

	
246 236
/**
247 237
@defgroup paths Path Structures
248 238
@ingroup datas
249 239
\brief %Path structures implemented in LEMON.
250 240

	
251 241
This group contains the path structures implemented in LEMON.
252 242

	
253 243
LEMON provides flexible data structures to work with paths.
254 244
All of them have similar interfaces and they can be copied easily with
255 245
assignment operators and copy constructors. This makes it easy and
256 246
efficient to have e.g. the Dijkstra algorithm to store its result in
257 247
any kind of path structure.
258 248

	
259 249
\sa lemon::concepts::Path
260 250
*/
261 251

	
262 252
/**
263 253
@defgroup auxdat Auxiliary Data Structures
264 254
@ingroup datas
265 255
\brief Auxiliary data structures implemented in LEMON.
266 256

	
267 257
This group contains some data structures implemented in LEMON in
268 258
order to make it easier to implement combinatorial algorithms.
269 259
*/
270 260

	
271 261
/**
272 262
@defgroup algs Algorithms
273 263
\brief This group contains the several algorithms
274 264
implemented in LEMON.
275 265

	
276 266
This group contains the several algorithms
277 267
implemented in LEMON.
278 268
*/
279 269

	
280 270
/**
281 271
@defgroup search Graph Search
282 272
@ingroup algs
283 273
\brief Common graph search algorithms.
284 274

	
285 275
This group contains the common graph search algorithms, namely
286 276
\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
287 277
*/
288 278

	
289 279
/**
290 280
@defgroup shortest_path Shortest Path Algorithms
291 281
@ingroup algs
292 282
\brief Algorithms for finding shortest paths.
293 283

	
294 284
This group contains the algorithms for finding shortest paths in digraphs.
295 285

	
296 286
 - \ref Dijkstra algorithm for finding shortest paths from a source node
297 287
   when all arc lengths are non-negative.
298 288
 - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
299 289
   from a source node when arc lenghts can be either positive or negative,
300 290
   but the digraph should not contain directed cycles with negative total
301 291
   length.
302 292
 - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
303 293
   for solving the \e all-pairs \e shortest \e paths \e problem when arc
304 294
   lenghts can be either positive or negative, but the digraph should
305 295
   not contain directed cycles with negative total length.
306 296
 - \ref Suurballe A successive shortest path algorithm for finding
307 297
   arc-disjoint paths between two nodes having minimum total length.
308 298
*/
309 299

	
310 300
/**
311 301
@defgroup max_flow Maximum Flow Algorithms
312 302
@ingroup algs
313 303
\brief Algorithms for finding maximum flows.
314 304

	
315 305
This group contains the algorithms for finding maximum flows and
316 306
feasible circulations.
317 307

	
318 308
The \e maximum \e flow \e problem is to find a flow of maximum value between
319 309
a single source and a single target. Formally, there is a \f$G=(V,A)\f$
320 310
digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
321 311
\f$s, t \in V\f$ source and target nodes.
322 312
A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
323 313
following optimization problem.
324 314

	
325 315
\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
326 316
\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
327 317
    \quad \forall u\in V\setminus\{s,t\} \f]
328 318
\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
329 319

	
330 320
LEMON contains several algorithms for solving maximum flow problems:
331 321
- \ref EdmondsKarp Edmonds-Karp algorithm.
332 322
- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
333 323
- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
334 324
- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
335 325

	
336 326
In most cases the \ref Preflow "Preflow" algorithm provides the
337 327
fastest method for computing a maximum flow. All implementations
338 328
also provide functions to query the minimum cut, which is the dual
339 329
problem of maximum flow.
340 330

	
341 331
\ref Circulation is a preflow push-relabel algorithm implemented directly 
342 332
for finding feasible circulations, which is a somewhat different problem,
Ignore white space 384 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_EDGE_SET_H
20 20
#define LEMON_EDGE_SET_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/bits/edge_set_extender.h>
24 24

	
25
/// \ingroup semi_adaptors
25
/// \ingroup graphs
26 26
/// \file
27 27
/// \brief ArcSet and EdgeSet classes.
28 28
///
29 29
/// Graphs which use another graph's node-set as own.
30 30
namespace lemon {
31 31

	
32 32
  template <typename GR>
33 33
  class ListArcSetBase {
34 34
  public:
35 35

	
36 36
    typedef typename GR::Node Node;
37 37
    typedef typename GR::NodeIt NodeIt;
38 38

	
39 39
  protected:
40 40

	
41 41
    struct NodeT {
42 42
      int first_out, first_in;
43 43
      NodeT() : first_out(-1), first_in(-1) {}
44 44
    };
45 45

	
46 46
    typedef typename ItemSetTraits<GR, Node>::
47 47
    template Map<NodeT>::Type NodesImplBase;
48 48

	
49 49
    NodesImplBase* _nodes;
50 50

	
51 51
    struct ArcT {
52 52
      Node source, target;
53 53
      int next_out, next_in;
54 54
      int prev_out, prev_in;
55 55
      ArcT() : prev_out(-1), prev_in(-1) {}
56 56
    };
57 57

	
58 58
    std::vector<ArcT> arcs;
59 59

	
60 60
    int first_arc;
61 61
    int first_free_arc;
62 62

	
63 63
    const GR* _graph;
64 64

	
65 65
    void initalize(const GR& graph, NodesImplBase& nodes) {
66 66
      _graph = &graph;
67 67
      _nodes = &nodes;
68 68
    }
69 69

	
70 70
  public:
71 71

	
72 72
    class Arc {
73 73
      friend class ListArcSetBase<GR>;
74 74
    protected:
75 75
      Arc(int _id) : id(_id) {}
76 76
      int id;
77 77
    public:
78 78
      Arc() {}
79 79
      Arc(Invalid) : id(-1) {}
80 80
      bool operator==(const Arc& arc) const { return id == arc.id; }
81 81
      bool operator!=(const Arc& arc) const { return id != arc.id; }
82 82
      bool operator<(const Arc& arc) const { return id < arc.id; }
83 83
    };
84 84

	
85 85
    ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
86 86

	
87 87
    Arc addArc(const Node& u, const Node& v) {
88 88
      int n;
89 89
      if (first_free_arc == -1) {
90 90
        n = arcs.size();
91 91
        arcs.push_back(ArcT());
92 92
      } else {
93 93
        n = first_free_arc;
94 94
        first_free_arc = arcs[first_free_arc].next_in;
95 95
      }
96 96
      arcs[n].next_in = (*_nodes)[v].first_in;
97 97
      if ((*_nodes)[v].first_in != -1) {
98 98
        arcs[(*_nodes)[v].first_in].prev_in = n;
99 99
      }
100 100
      (*_nodes)[v].first_in = n;
101 101
      arcs[n].next_out = (*_nodes)[u].first_out;
102 102
      if ((*_nodes)[u].first_out != -1) {
103 103
        arcs[(*_nodes)[u].first_out].prev_out = n;
104 104
      }
105 105
      (*_nodes)[u].first_out = n;
106 106
      arcs[n].source = u;
107 107
      arcs[n].target = v;
108 108
      return Arc(n);
109 109
    }
110 110

	
111 111
    void erase(const Arc& arc) {
112 112
      int n = arc.id;
113 113
      if (arcs[n].prev_in != -1) {
114 114
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
115 115
      } else {
116 116
        (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
117 117
      }
118 118
      if (arcs[n].next_in != -1) {
119 119
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
120 120
      }
121 121

	
122 122
      if (arcs[n].prev_out != -1) {
123 123
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
124 124
      } else {
125 125
        (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
126 126
      }
127 127
      if (arcs[n].next_out != -1) {
128 128
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
129 129
      }
130 130

	
131 131
    }
132 132

	
133 133
    void clear() {
134 134
      Node node;
135 135
      for (first(node); node != INVALID; next(node)) {
136 136
        (*_nodes)[node].first_in = -1;
137 137
        (*_nodes)[node].first_out = -1;
138 138
      }
139 139
      arcs.clear();
140 140
      first_arc = -1;
141 141
      first_free_arc = -1;
142 142
    }
143 143

	
144 144
    void first(Node& node) const {
145 145
      _graph->first(node);
146 146
    }
147 147

	
148 148
    void next(Node& node) const {
149 149
      _graph->next(node);
150 150
    }
151 151

	
152 152
    void first(Arc& arc) const {
153 153
      Node node;
154 154
      first(node);
155 155
      while (node != INVALID && (*_nodes)[node].first_in == -1) {
156 156
        next(node);
157 157
      }
158 158
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
159 159
    }
160 160

	
161 161
    void next(Arc& arc) const {
162 162
      if (arcs[arc.id].next_in != -1) {
163 163
        arc.id = arcs[arc.id].next_in;
164 164
      } else {
165 165
        Node node = arcs[arc.id].target;
166 166
        next(node);
167 167
        while (node != INVALID && (*_nodes)[node].first_in == -1) {
168 168
          next(node);
169 169
        }
170 170
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
171 171
      }
172 172
    }
173 173

	
174 174
    void firstOut(Arc& arc, const Node& node) const {
175 175
      arc.id = (*_nodes)[node].first_out;
176 176
    }
177 177

	
178 178
    void nextOut(Arc& arc) const {
179 179
      arc.id = arcs[arc.id].next_out;
180 180
    }
181 181

	
182 182
    void firstIn(Arc& arc, const Node& node) const {
183 183
      arc.id = (*_nodes)[node].first_in;
184 184
    }
185 185

	
186 186
    void nextIn(Arc& arc) const {
187 187
      arc.id = arcs[arc.id].next_in;
188 188
    }
189 189

	
190 190
    int id(const Node& node) const { return _graph->id(node); }
191 191
    int id(const Arc& arc) const { return arc.id; }
192 192

	
193 193
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
194 194
    Arc arcFromId(int ix) const { return Arc(ix); }
195 195

	
196 196
    int maxNodeId() const { return _graph->maxNodeId(); };
197 197
    int maxArcId() const { return arcs.size() - 1; }
198 198

	
199 199
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
200 200
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
201 201

	
202 202
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
203 203

	
204 204
    NodeNotifier& notifier(Node) const {
205 205
      return _graph->notifier(Node());
206 206
    }
207 207

	
208 208
    template <typename V>
209 209
    class NodeMap : public GR::template NodeMap<V> {
210 210
      typedef typename GR::template NodeMap<V> Parent;
211 211

	
212 212
    public:
213 213

	
214 214
      explicit NodeMap(const ListArcSetBase<GR>& arcset)
215 215
        : Parent(*arcset._graph) {}
216 216

	
217 217
      NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
218 218
        : Parent(*arcset._graph, value) {}
219 219

	
220 220
      NodeMap& operator=(const NodeMap& cmap) {
221 221
        return operator=<NodeMap>(cmap);
222 222
      }
223 223

	
224 224
      template <typename CMap>
225 225
      NodeMap& operator=(const CMap& cmap) {
226 226
        Parent::operator=(cmap);
227 227
        return *this;
228 228
      }
229 229
    };
230 230

	
231 231
  };
232 232

	
233
  /// \ingroup semi_adaptors
233
  /// \ingroup graphs
234 234
  ///
235 235
  /// \brief Digraph using a node set of another digraph or graph and
236 236
  /// an own arc set.
237 237
  ///
238 238
  /// This structure can be used to establish another directed graph
239 239
  /// over a node set of an existing one. This class uses the same
240 240
  /// Node type as the underlying graph, and each valid node of the
241 241
  /// original graph is valid in this arc set, therefore the node
242 242
  /// objects of the original graph can be used directly with this
243 243
  /// class. The node handling functions (id handling, observing, and
244 244
  /// iterators) works equivalently as in the original graph.
245 245
  ///
246 246
  /// This implementation is based on doubly-linked lists, from each
247 247
  /// node the outgoing and the incoming arcs make up lists, therefore
248 248
  /// one arc can be erased in constant time. It also makes possible,
249 249
  /// that node can be removed from the underlying graph, in this case
250 250
  /// all arcs incident to the given node is erased from the arc set.
251 251
  ///
252 252
  /// \param GR The type of the graph which shares its node set with
253 253
  /// this class. Its interface must conform to the
254 254
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
255 255
  /// concept.
256 256
  ///
257 257
  /// This class fully conforms to the \ref concepts::Digraph
258 258
  /// "Digraph" concept.
259 259
  template <typename GR>
260 260
  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
261 261
    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
262 262

	
263 263
  public:
264 264

	
265 265
    typedef typename Parent::Node Node;
266 266
    typedef typename Parent::Arc Arc;
267 267

	
268 268
    typedef typename Parent::NodesImplBase NodesImplBase;
269 269

	
270 270
    void eraseNode(const Node& node) {
271 271
      Arc arc;
272 272
      Parent::firstOut(arc, node);
273 273
      while (arc != INVALID ) {
274 274
        erase(arc);
275 275
        Parent::firstOut(arc, node);
276 276
      }
277 277

	
278 278
      Parent::firstIn(arc, node);
279 279
      while (arc != INVALID ) {
280 280
        erase(arc);
281 281
        Parent::firstIn(arc, node);
282 282
      }
283 283
    }
284 284

	
285 285
    void clearNodes() {
286 286
      Parent::clear();
287 287
    }
288 288

	
289 289
    class NodesImpl : public NodesImplBase {
290 290
      typedef NodesImplBase Parent;
291 291

	
292 292
    public:
293 293
      NodesImpl(const GR& graph, ListArcSet& arcset)
294 294
        : Parent(graph), _arcset(arcset) {}
295 295

	
296 296
      virtual ~NodesImpl() {}
297 297

	
298 298
    protected:
299 299

	
300 300
      virtual void erase(const Node& node) {
301 301
        _arcset.eraseNode(node);
302 302
        Parent::erase(node);
303 303
      }
304 304
      virtual void erase(const std::vector<Node>& nodes) {
305 305
        for (int i = 0; i < int(nodes.size()); ++i) {
306 306
          _arcset.eraseNode(nodes[i]);
307 307
        }
308 308
        Parent::erase(nodes);
309 309
      }
310 310
      virtual void clear() {
311 311
        _arcset.clearNodes();
312 312
        Parent::clear();
313 313
      }
314 314

	
315 315
    private:
316 316
      ListArcSet& _arcset;
317 317
    };
318 318

	
319 319
    NodesImpl _nodes;
320 320

	
321 321
  public:
322 322

	
323 323
    /// \brief Constructor of the ArcSet.
324 324
    ///
325 325
    /// Constructor of the ArcSet.
326 326
    ListArcSet(const GR& graph) : _nodes(graph, *this) {
327 327
      Parent::initalize(graph, _nodes);
328 328
    }
329 329

	
330 330
    /// \brief Add a new arc to the digraph.
331 331
    ///
332 332
    /// Add a new arc to the digraph with source node \c s
333 333
    /// and target node \c t.
334 334
    /// \return The new arc.
335 335
    Arc addArc(const Node& s, const Node& t) {
336 336
      return Parent::addArc(s, t);
337 337
    }
338 338

	
339 339
    /// \brief Erase an arc from the digraph.
340 340
    ///
341 341
    /// Erase an arc \c a from the digraph.
342 342
    void erase(const Arc& a) {
343 343
      return Parent::erase(a);
344 344
    }
345 345

	
346 346
  };
347 347

	
348 348
  template <typename GR>
349 349
  class ListEdgeSetBase {
350 350
  public:
351 351

	
352 352
    typedef typename GR::Node Node;
353 353
    typedef typename GR::NodeIt NodeIt;
354 354

	
355 355
  protected:
356 356

	
357 357
    struct NodeT {
358 358
      int first_out;
359 359
      NodeT() : first_out(-1) {}
360 360
    };
361 361

	
362 362
    typedef typename ItemSetTraits<GR, Node>::
363 363
    template Map<NodeT>::Type NodesImplBase;
364 364

	
365 365
    NodesImplBase* _nodes;
366 366

	
367 367
    struct ArcT {
368 368
      Node target;
369 369
      int prev_out, next_out;
370 370
      ArcT() : prev_out(-1), next_out(-1) {}
371 371
    };
372 372

	
373 373
    std::vector<ArcT> arcs;
374 374

	
375 375
    int first_arc;
376 376
    int first_free_arc;
377 377

	
378 378
    const GR* _graph;
379 379

	
380 380
    void initalize(const GR& graph, NodesImplBase& nodes) {
381 381
      _graph = &graph;
382 382
      _nodes = &nodes;
383 383
    }
384 384

	
385 385
  public:
386 386

	
387 387
    class Edge {
388 388
      friend class ListEdgeSetBase;
389 389
    protected:
390 390

	
391 391
      int id;
392 392
      explicit Edge(int _id) { id = _id;}
393 393

	
394 394
    public:
395 395
      Edge() {}
396 396
      Edge (Invalid) { id = -1; }
397 397
      bool operator==(const Edge& arc) const {return id == arc.id;}
398 398
      bool operator!=(const Edge& arc) const {return id != arc.id;}
399 399
      bool operator<(const Edge& arc) const {return id < arc.id;}
400 400
    };
401 401

	
402 402
    class Arc {
403 403
      friend class ListEdgeSetBase;
404 404
    protected:
405 405
      Arc(int _id) : id(_id) {}
406 406
      int id;
407 407
    public:
408 408
      operator Edge() const { return edgeFromId(id / 2); }
409 409

	
410 410
      Arc() {}
411 411
      Arc(Invalid) : id(-1) {}
412 412
      bool operator==(const Arc& arc) const { return id == arc.id; }
413 413
      bool operator!=(const Arc& arc) const { return id != arc.id; }
414 414
      bool operator<(const Arc& arc) const { return id < arc.id; }
415 415
    };
416 416

	
417 417
    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
418 418

	
419 419
    Edge addEdge(const Node& u, const Node& v) {
420 420
      int n;
421 421

	
422 422
      if (first_free_arc == -1) {
423 423
        n = arcs.size();
424 424
        arcs.push_back(ArcT());
425 425
        arcs.push_back(ArcT());
... ...
@@ -465,928 +465,928 @@
465 465
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
466 466
      }
467 467

	
468 468
      if (arcs[n | 1].prev_out != -1) {
469 469
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
470 470
      } else {
471 471
        (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
472 472
      }
473 473

	
474 474
      arcs[n].next_out = first_free_arc;
475 475
      first_free_arc = n;
476 476

	
477 477
    }
478 478

	
479 479
    void clear() {
480 480
      Node node;
481 481
      for (first(node); node != INVALID; next(node)) {
482 482
        (*_nodes)[node].first_out = -1;
483 483
      }
484 484
      arcs.clear();
485 485
      first_arc = -1;
486 486
      first_free_arc = -1;
487 487
    }
488 488

	
489 489
    void first(Node& node) const {
490 490
      _graph->first(node);
491 491
    }
492 492

	
493 493
    void next(Node& node) const {
494 494
      _graph->next(node);
495 495
    }
496 496

	
497 497
    void first(Arc& arc) const {
498 498
      Node node;
499 499
      first(node);
500 500
      while (node != INVALID && (*_nodes)[node].first_out == -1) {
501 501
        next(node);
502 502
      }
503 503
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
504 504
    }
505 505

	
506 506
    void next(Arc& arc) const {
507 507
      if (arcs[arc.id].next_out != -1) {
508 508
        arc.id = arcs[arc.id].next_out;
509 509
      } else {
510 510
        Node node = arcs[arc.id ^ 1].target;
511 511
        next(node);
512 512
        while(node != INVALID && (*_nodes)[node].first_out == -1) {
513 513
          next(node);
514 514
        }
515 515
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
516 516
      }
517 517
    }
518 518

	
519 519
    void first(Edge& edge) const {
520 520
      Node node;
521 521
      first(node);
522 522
      while (node != INVALID) {
523 523
        edge.id = (*_nodes)[node].first_out;
524 524
        while ((edge.id & 1) != 1) {
525 525
          edge.id = arcs[edge.id].next_out;
526 526
        }
527 527
        if (edge.id != -1) {
528 528
          edge.id /= 2;
529 529
          return;
530 530
        }
531 531
        next(node);
532 532
      }
533 533
      edge.id = -1;
534 534
    }
535 535

	
536 536
    void next(Edge& edge) const {
537 537
      Node node = arcs[edge.id * 2].target;
538 538
      edge.id = arcs[(edge.id * 2) | 1].next_out;
539 539
      while ((edge.id & 1) != 1) {
540 540
        edge.id = arcs[edge.id].next_out;
541 541
      }
542 542
      if (edge.id != -1) {
543 543
        edge.id /= 2;
544 544
        return;
545 545
      }
546 546
      next(node);
547 547
      while (node != INVALID) {
548 548
        edge.id = (*_nodes)[node].first_out;
549 549
        while ((edge.id & 1) != 1) {
550 550
          edge.id = arcs[edge.id].next_out;
551 551
        }
552 552
        if (edge.id != -1) {
553 553
          edge.id /= 2;
554 554
          return;
555 555
        }
556 556
        next(node);
557 557
      }
558 558
      edge.id = -1;
559 559
    }
560 560

	
561 561
    void firstOut(Arc& arc, const Node& node) const {
562 562
      arc.id = (*_nodes)[node].first_out;
563 563
    }
564 564

	
565 565
    void nextOut(Arc& arc) const {
566 566
      arc.id = arcs[arc.id].next_out;
567 567
    }
568 568

	
569 569
    void firstIn(Arc& arc, const Node& node) const {
570 570
      arc.id = (((*_nodes)[node].first_out) ^ 1);
571 571
      if (arc.id == -2) arc.id = -1;
572 572
    }
573 573

	
574 574
    void nextIn(Arc& arc) const {
575 575
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
576 576
      if (arc.id == -2) arc.id = -1;
577 577
    }
578 578

	
579 579
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
580 580
      int de = (*_nodes)[node].first_out;
581 581
      if (de != -1 ) {
582 582
        arc.id = de / 2;
583 583
        dir = ((de & 1) == 1);
584 584
      } else {
585 585
        arc.id = -1;
586 586
        dir = true;
587 587
      }
588 588
    }
589 589
    void nextInc(Edge &arc, bool& dir) const {
590 590
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
591 591
      if (de != -1 ) {
592 592
        arc.id = de / 2;
593 593
        dir = ((de & 1) == 1);
594 594
      } else {
595 595
        arc.id = -1;
596 596
        dir = true;
597 597
      }
598 598
    }
599 599

	
600 600
    static bool direction(Arc arc) {
601 601
      return (arc.id & 1) == 1;
602 602
    }
603 603

	
604 604
    static Arc direct(Edge edge, bool dir) {
605 605
      return Arc(edge.id * 2 + (dir ? 1 : 0));
606 606
    }
607 607

	
608 608
    int id(const Node& node) const { return _graph->id(node); }
609 609
    static int id(Arc e) { return e.id; }
610 610
    static int id(Edge e) { return e.id; }
611 611

	
612 612
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
613 613
    static Arc arcFromId(int id) { return Arc(id);}
614 614
    static Edge edgeFromId(int id) { return Edge(id);}
615 615

	
616 616
    int maxNodeId() const { return _graph->maxNodeId(); };
617 617
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
618 618
    int maxArcId() const { return arcs.size()-1; }
619 619

	
620 620
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
621 621
    Node target(Arc e) const { return arcs[e.id].target; }
622 622

	
623 623
    Node u(Edge e) const { return arcs[2 * e.id].target; }
624 624
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
625 625

	
626 626
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
627 627

	
628 628
    NodeNotifier& notifier(Node) const {
629 629
      return _graph->notifier(Node());
630 630
    }
631 631

	
632 632
    template <typename V>
633 633
    class NodeMap : public GR::template NodeMap<V> {
634 634
      typedef typename GR::template NodeMap<V> Parent;
635 635

	
636 636
    public:
637 637

	
638 638
      explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
639 639
        : Parent(*arcset._graph) {}
640 640

	
641 641
      NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
642 642
        : Parent(*arcset._graph, value) {}
643 643

	
644 644
      NodeMap& operator=(const NodeMap& cmap) {
645 645
        return operator=<NodeMap>(cmap);
646 646
      }
647 647

	
648 648
      template <typename CMap>
649 649
      NodeMap& operator=(const CMap& cmap) {
650 650
        Parent::operator=(cmap);
651 651
        return *this;
652 652
      }
653 653
    };
654 654

	
655 655
  };
656 656

	
657
  /// \ingroup semi_adaptors
657
  /// \ingroup graphs
658 658
  ///
659 659
  /// \brief Graph using a node set of another digraph or graph and an
660 660
  /// own edge set.
661 661
  ///
662 662
  /// This structure can be used to establish another graph over a
663 663
  /// node set of an existing one. This class uses the same Node type
664 664
  /// as the underlying graph, and each valid node of the original
665 665
  /// graph is valid in this arc set, therefore the node objects of
666 666
  /// the original graph can be used directly with this class. The
667 667
  /// node handling functions (id handling, observing, and iterators)
668 668
  /// works equivalently as in the original graph.
669 669
  ///
670 670
  /// This implementation is based on doubly-linked lists, from each
671 671
  /// node the incident edges make up lists, therefore one edge can be
672 672
  /// erased in constant time. It also makes possible, that node can
673 673
  /// be removed from the underlying graph, in this case all edges
674 674
  /// incident to the given node is erased from the arc set.
675 675
  ///
676 676
  /// \param GR The type of the graph which shares its node set
677 677
  /// with this class. Its interface must conform to the
678 678
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
679 679
  /// concept.
680 680
  ///
681 681
  /// This class fully conforms to the \ref concepts::Graph "Graph"
682 682
  /// concept.
683 683
  template <typename GR>
684 684
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
685 685
    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
686 686

	
687 687
  public:
688 688

	
689 689
    typedef typename Parent::Node Node;
690 690
    typedef typename Parent::Arc Arc;
691 691
    typedef typename Parent::Edge Edge;
692 692

	
693 693
    typedef typename Parent::NodesImplBase NodesImplBase;
694 694

	
695 695
    void eraseNode(const Node& node) {
696 696
      Arc arc;
697 697
      Parent::firstOut(arc, node);
698 698
      while (arc != INVALID ) {
699 699
        erase(arc);
700 700
        Parent::firstOut(arc, node);
701 701
      }
702 702

	
703 703
    }
704 704

	
705 705
    void clearNodes() {
706 706
      Parent::clear();
707 707
    }
708 708

	
709 709
    class NodesImpl : public NodesImplBase {
710 710
      typedef NodesImplBase Parent;
711 711

	
712 712
    public:
713 713
      NodesImpl(const GR& graph, ListEdgeSet& arcset)
714 714
        : Parent(graph), _arcset(arcset) {}
715 715

	
716 716
      virtual ~NodesImpl() {}
717 717

	
718 718
    protected:
719 719

	
720 720
      virtual void erase(const Node& node) {
721 721
        _arcset.eraseNode(node);
722 722
        Parent::erase(node);
723 723
      }
724 724
      virtual void erase(const std::vector<Node>& nodes) {
725 725
        for (int i = 0; i < int(nodes.size()); ++i) {
726 726
          _arcset.eraseNode(nodes[i]);
727 727
        }
728 728
        Parent::erase(nodes);
729 729
      }
730 730
      virtual void clear() {
731 731
        _arcset.clearNodes();
732 732
        Parent::clear();
733 733
      }
734 734

	
735 735
    private:
736 736
      ListEdgeSet& _arcset;
737 737
    };
738 738

	
739 739
    NodesImpl _nodes;
740 740

	
741 741
  public:
742 742

	
743 743
    /// \brief Constructor of the EdgeSet.
744 744
    ///
745 745
    /// Constructor of the EdgeSet.
746 746
    ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
747 747
      Parent::initalize(graph, _nodes);
748 748
    }
749 749

	
750 750
    /// \brief Add a new edge to the graph.
751 751
    ///
752 752
    /// Add a new edge to the graph with node \c u
753 753
    /// and node \c v endpoints.
754 754
    /// \return The new edge.
755 755
    Edge addEdge(const Node& u, const Node& v) {
756 756
      return Parent::addEdge(u, v);
757 757
    }
758 758

	
759 759
    /// \brief Erase an edge from the graph.
760 760
    ///
761 761
    /// Erase the edge \c e from the graph.
762 762
    void erase(const Edge& e) {
763 763
      return Parent::erase(e);
764 764
    }
765 765

	
766 766
  };
767 767

	
768 768
  template <typename GR>
769 769
  class SmartArcSetBase {
770 770
  public:
771 771

	
772 772
    typedef typename GR::Node Node;
773 773
    typedef typename GR::NodeIt NodeIt;
774 774

	
775 775
  protected:
776 776

	
777 777
    struct NodeT {
778 778
      int first_out, first_in;
779 779
      NodeT() : first_out(-1), first_in(-1) {}
780 780
    };
781 781

	
782 782
    typedef typename ItemSetTraits<GR, Node>::
783 783
    template Map<NodeT>::Type NodesImplBase;
784 784

	
785 785
    NodesImplBase* _nodes;
786 786

	
787 787
    struct ArcT {
788 788
      Node source, target;
789 789
      int next_out, next_in;
790 790
      ArcT() {}
791 791
    };
792 792

	
793 793
    std::vector<ArcT> arcs;
794 794

	
795 795
    const GR* _graph;
796 796

	
797 797
    void initalize(const GR& graph, NodesImplBase& nodes) {
798 798
      _graph = &graph;
799 799
      _nodes = &nodes;
800 800
    }
801 801

	
802 802
  public:
803 803

	
804 804
    class Arc {
805 805
      friend class SmartArcSetBase<GR>;
806 806
    protected:
807 807
      Arc(int _id) : id(_id) {}
808 808
      int id;
809 809
    public:
810 810
      Arc() {}
811 811
      Arc(Invalid) : id(-1) {}
812 812
      bool operator==(const Arc& arc) const { return id == arc.id; }
813 813
      bool operator!=(const Arc& arc) const { return id != arc.id; }
814 814
      bool operator<(const Arc& arc) const { return id < arc.id; }
815 815
    };
816 816

	
817 817
    SmartArcSetBase() {}
818 818

	
819 819
    Arc addArc(const Node& u, const Node& v) {
820 820
      int n = arcs.size();
821 821
      arcs.push_back(ArcT());
822 822
      arcs[n].next_in = (*_nodes)[v].first_in;
823 823
      (*_nodes)[v].first_in = n;
824 824
      arcs[n].next_out = (*_nodes)[u].first_out;
825 825
      (*_nodes)[u].first_out = n;
826 826
      arcs[n].source = u;
827 827
      arcs[n].target = v;
828 828
      return Arc(n);
829 829
    }
830 830

	
831 831
    void clear() {
832 832
      Node node;
833 833
      for (first(node); node != INVALID; next(node)) {
834 834
        (*_nodes)[node].first_in = -1;
835 835
        (*_nodes)[node].first_out = -1;
836 836
      }
837 837
      arcs.clear();
838 838
    }
839 839

	
840 840
    void first(Node& node) const {
841 841
      _graph->first(node);
842 842
    }
843 843

	
844 844
    void next(Node& node) const {
845 845
      _graph->next(node);
846 846
    }
847 847

	
848 848
    void first(Arc& arc) const {
849 849
      arc.id = arcs.size() - 1;
850 850
    }
851 851

	
852 852
    void next(Arc& arc) const {
853 853
      --arc.id;
854 854
    }
855 855

	
856 856
    void firstOut(Arc& arc, const Node& node) const {
857 857
      arc.id = (*_nodes)[node].first_out;
858 858
    }
859 859

	
860 860
    void nextOut(Arc& arc) const {
861 861
      arc.id = arcs[arc.id].next_out;
862 862
    }
863 863

	
864 864
    void firstIn(Arc& arc, const Node& node) const {
865 865
      arc.id = (*_nodes)[node].first_in;
866 866
    }
867 867

	
868 868
    void nextIn(Arc& arc) const {
869 869
      arc.id = arcs[arc.id].next_in;
870 870
    }
871 871

	
872 872
    int id(const Node& node) const { return _graph->id(node); }
873 873
    int id(const Arc& arc) const { return arc.id; }
874 874

	
875 875
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
876 876
    Arc arcFromId(int ix) const { return Arc(ix); }
877 877

	
878 878
    int maxNodeId() const { return _graph->maxNodeId(); };
879 879
    int maxArcId() const { return arcs.size() - 1; }
880 880

	
881 881
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
882 882
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
883 883

	
884 884
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
885 885

	
886 886
    NodeNotifier& notifier(Node) const {
887 887
      return _graph->notifier(Node());
888 888
    }
889 889

	
890 890
    template <typename V>
891 891
    class NodeMap : public GR::template NodeMap<V> {
892 892
      typedef typename GR::template NodeMap<V> Parent;
893 893

	
894 894
    public:
895 895

	
896 896
      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
897 897
        : Parent(*arcset._graph) { }
898 898

	
899 899
      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
900 900
        : Parent(*arcset._graph, value) { }
901 901

	
902 902
      NodeMap& operator=(const NodeMap& cmap) {
903 903
        return operator=<NodeMap>(cmap);
904 904
      }
905 905

	
906 906
      template <typename CMap>
907 907
      NodeMap& operator=(const CMap& cmap) {
908 908
        Parent::operator=(cmap);
909 909
        return *this;
910 910
      }
911 911
    };
912 912

	
913 913
  };
914 914

	
915 915

	
916
  /// \ingroup semi_adaptors
916
  /// \ingroup graphs
917 917
  ///
918 918
  /// \brief Digraph using a node set of another digraph or graph and
919 919
  /// an own arc set.
920 920
  ///
921 921
  /// This structure can be used to establish another directed graph
922 922
  /// over a node set of an existing one. This class uses the same
923 923
  /// Node type as the underlying graph, and each valid node of the
924 924
  /// original graph is valid in this arc set, therefore the node
925 925
  /// objects of the original graph can be used directly with this
926 926
  /// class. The node handling functions (id handling, observing, and
927 927
  /// iterators) works equivalently as in the original graph.
928 928
  ///
929 929
  /// \param GR The type of the graph which shares its node set with
930 930
  /// this class. Its interface must conform to the
931 931
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
932 932
  /// concept.
933 933
  ///
934 934
  /// This implementation is slightly faster than the \c ListArcSet,
935 935
  /// because it uses continuous storage for arcs and it uses just
936 936
  /// single-linked lists for enumerate outgoing and incoming
937 937
  /// arcs. Therefore the arcs cannot be erased from the arc sets.
938 938
  ///
939 939
  /// \warning If a node is erased from the underlying graph and this
940 940
  /// node is the source or target of one arc in the arc set, then
941 941
  /// the arc set is invalidated, and it cannot be used anymore. The
942 942
  /// validity can be checked with the \c valid() member function.
943 943
  ///
944 944
  /// This class fully conforms to the \ref concepts::Digraph
945 945
  /// "Digraph" concept.
946 946
  template <typename GR>
947 947
  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
948 948
    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
949 949

	
950 950
  public:
951 951

	
952 952
    typedef typename Parent::Node Node;
953 953
    typedef typename Parent::Arc Arc;
954 954

	
955 955
  protected:
956 956

	
957 957
    typedef typename Parent::NodesImplBase NodesImplBase;
958 958

	
959 959
    void eraseNode(const Node& node) {
960 960
      if (typename Parent::InArcIt(*this, node) == INVALID &&
961 961
          typename Parent::OutArcIt(*this, node) == INVALID) {
962 962
        return;
963 963
      }
964 964
      throw typename NodesImplBase::Notifier::ImmediateDetach();
965 965
    }
966 966

	
967 967
    void clearNodes() {
968 968
      Parent::clear();
969 969
    }
970 970

	
971 971
    class NodesImpl : public NodesImplBase {
972 972
      typedef NodesImplBase Parent;
973 973

	
974 974
    public:
975 975
      NodesImpl(const GR& graph, SmartArcSet& arcset)
976 976
        : Parent(graph), _arcset(arcset) {}
977 977

	
978 978
      virtual ~NodesImpl() {}
979 979

	
980 980
      bool attached() const {
981 981
        return Parent::attached();
982 982
      }
983 983

	
984 984
    protected:
985 985

	
986 986
      virtual void erase(const Node& node) {
987 987
        try {
988 988
          _arcset.eraseNode(node);
989 989
          Parent::erase(node);
990 990
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
991 991
          Parent::clear();
992 992
          throw;
993 993
        }
994 994
      }
995 995
      virtual void erase(const std::vector<Node>& nodes) {
996 996
        try {
997 997
          for (int i = 0; i < int(nodes.size()); ++i) {
998 998
            _arcset.eraseNode(nodes[i]);
999 999
          }
1000 1000
          Parent::erase(nodes);
1001 1001
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1002 1002
          Parent::clear();
1003 1003
          throw;
1004 1004
        }
1005 1005
      }
1006 1006
      virtual void clear() {
1007 1007
        _arcset.clearNodes();
1008 1008
        Parent::clear();
1009 1009
      }
1010 1010

	
1011 1011
    private:
1012 1012
      SmartArcSet& _arcset;
1013 1013
    };
1014 1014

	
1015 1015
    NodesImpl _nodes;
1016 1016

	
1017 1017
  public:
1018 1018

	
1019 1019
    /// \brief Constructor of the ArcSet.
1020 1020
    ///
1021 1021
    /// Constructor of the ArcSet.
1022 1022
    SmartArcSet(const GR& graph) : _nodes(graph, *this) {
1023 1023
      Parent::initalize(graph, _nodes);
1024 1024
    }
1025 1025

	
1026 1026
    /// \brief Add a new arc to the digraph.
1027 1027
    ///
1028 1028
    /// Add a new arc to the digraph with source node \c s
1029 1029
    /// and target node \c t.
1030 1030
    /// \return The new arc.
1031 1031
    Arc addArc(const Node& s, const Node& t) {
1032 1032
      return Parent::addArc(s, t);
1033 1033
    }
1034 1034

	
1035 1035
    /// \brief Validity check
1036 1036
    ///
1037 1037
    /// This functions gives back false if the ArcSet is
1038 1038
    /// invalidated. It occurs when a node in the underlying graph is
1039 1039
    /// erased and it is not isolated in the ArcSet.
1040 1040
    bool valid() const {
1041 1041
      return _nodes.attached();
1042 1042
    }
1043 1043

	
1044 1044
  };
1045 1045

	
1046 1046

	
1047 1047
  template <typename GR>
1048 1048
  class SmartEdgeSetBase {
1049 1049
  public:
1050 1050

	
1051 1051
    typedef typename GR::Node Node;
1052 1052
    typedef typename GR::NodeIt NodeIt;
1053 1053

	
1054 1054
  protected:
1055 1055

	
1056 1056
    struct NodeT {
1057 1057
      int first_out;
1058 1058
      NodeT() : first_out(-1) {}
1059 1059
    };
1060 1060

	
1061 1061
    typedef typename ItemSetTraits<GR, Node>::
1062 1062
    template Map<NodeT>::Type NodesImplBase;
1063 1063

	
1064 1064
    NodesImplBase* _nodes;
1065 1065

	
1066 1066
    struct ArcT {
1067 1067
      Node target;
1068 1068
      int next_out;
1069 1069
      ArcT() {}
1070 1070
    };
1071 1071

	
1072 1072
    std::vector<ArcT> arcs;
1073 1073

	
1074 1074
    const GR* _graph;
1075 1075

	
1076 1076
    void initalize(const GR& graph, NodesImplBase& nodes) {
1077 1077
      _graph = &graph;
1078 1078
      _nodes = &nodes;
1079 1079
    }
1080 1080

	
1081 1081
  public:
1082 1082

	
1083 1083
    class Edge {
1084 1084
      friend class SmartEdgeSetBase;
1085 1085
    protected:
1086 1086

	
1087 1087
      int id;
1088 1088
      explicit Edge(int _id) { id = _id;}
1089 1089

	
1090 1090
    public:
1091 1091
      Edge() {}
1092 1092
      Edge (Invalid) { id = -1; }
1093 1093
      bool operator==(const Edge& arc) const {return id == arc.id;}
1094 1094
      bool operator!=(const Edge& arc) const {return id != arc.id;}
1095 1095
      bool operator<(const Edge& arc) const {return id < arc.id;}
1096 1096
    };
1097 1097

	
1098 1098
    class Arc {
1099 1099
      friend class SmartEdgeSetBase;
1100 1100
    protected:
1101 1101
      Arc(int _id) : id(_id) {}
1102 1102
      int id;
1103 1103
    public:
1104 1104
      operator Edge() const { return edgeFromId(id / 2); }
1105 1105

	
1106 1106
      Arc() {}
1107 1107
      Arc(Invalid) : id(-1) {}
1108 1108
      bool operator==(const Arc& arc) const { return id == arc.id; }
1109 1109
      bool operator!=(const Arc& arc) const { return id != arc.id; }
1110 1110
      bool operator<(const Arc& arc) const { return id < arc.id; }
1111 1111
    };
1112 1112

	
1113 1113
    SmartEdgeSetBase() {}
1114 1114

	
1115 1115
    Edge addEdge(const Node& u, const Node& v) {
1116 1116
      int n = arcs.size();
1117 1117
      arcs.push_back(ArcT());
1118 1118
      arcs.push_back(ArcT());
1119 1119

	
1120 1120
      arcs[n].target = u;
1121 1121
      arcs[n | 1].target = v;
1122 1122

	
1123 1123
      arcs[n].next_out = (*_nodes)[v].first_out;
1124 1124
      (*_nodes)[v].first_out = n;
1125 1125

	
1126 1126
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
1127 1127
      (*_nodes)[u].first_out = (n | 1);
1128 1128

	
1129 1129
      return Edge(n / 2);
1130 1130
    }
1131 1131

	
1132 1132
    void clear() {
1133 1133
      Node node;
1134 1134
      for (first(node); node != INVALID; next(node)) {
1135 1135
        (*_nodes)[node].first_out = -1;
1136 1136
      }
1137 1137
      arcs.clear();
1138 1138
    }
1139 1139

	
1140 1140
    void first(Node& node) const {
1141 1141
      _graph->first(node);
1142 1142
    }
1143 1143

	
1144 1144
    void next(Node& node) const {
1145 1145
      _graph->next(node);
1146 1146
    }
1147 1147

	
1148 1148
    void first(Arc& arc) const {
1149 1149
      arc.id = arcs.size() - 1;
1150 1150
    }
1151 1151

	
1152 1152
    void next(Arc& arc) const {
1153 1153
      --arc.id;
1154 1154
    }
1155 1155

	
1156 1156
    void first(Edge& arc) const {
1157 1157
      arc.id = arcs.size() / 2 - 1;
1158 1158
    }
1159 1159

	
1160 1160
    void next(Edge& arc) const {
1161 1161
      --arc.id;
1162 1162
    }
1163 1163

	
1164 1164
    void firstOut(Arc& arc, const Node& node) const {
1165 1165
      arc.id = (*_nodes)[node].first_out;
1166 1166
    }
1167 1167

	
1168 1168
    void nextOut(Arc& arc) const {
1169 1169
      arc.id = arcs[arc.id].next_out;
1170 1170
    }
1171 1171

	
1172 1172
    void firstIn(Arc& arc, const Node& node) const {
1173 1173
      arc.id = (((*_nodes)[node].first_out) ^ 1);
1174 1174
      if (arc.id == -2) arc.id = -1;
1175 1175
    }
1176 1176

	
1177 1177
    void nextIn(Arc& arc) const {
1178 1178
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
1179 1179
      if (arc.id == -2) arc.id = -1;
1180 1180
    }
1181 1181

	
1182 1182
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
1183 1183
      int de = (*_nodes)[node].first_out;
1184 1184
      if (de != -1 ) {
1185 1185
        arc.id = de / 2;
1186 1186
        dir = ((de & 1) == 1);
1187 1187
      } else {
1188 1188
        arc.id = -1;
1189 1189
        dir = true;
1190 1190
      }
1191 1191
    }
1192 1192
    void nextInc(Edge &arc, bool& dir) const {
1193 1193
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
1194 1194
      if (de != -1 ) {
1195 1195
        arc.id = de / 2;
1196 1196
        dir = ((de & 1) == 1);
1197 1197
      } else {
1198 1198
        arc.id = -1;
1199 1199
        dir = true;
1200 1200
      }
1201 1201
    }
1202 1202

	
1203 1203
    static bool direction(Arc arc) {
1204 1204
      return (arc.id & 1) == 1;
1205 1205
    }
1206 1206

	
1207 1207
    static Arc direct(Edge edge, bool dir) {
1208 1208
      return Arc(edge.id * 2 + (dir ? 1 : 0));
1209 1209
    }
1210 1210

	
1211 1211
    int id(Node node) const { return _graph->id(node); }
1212 1212
    static int id(Arc arc) { return arc.id; }
1213 1213
    static int id(Edge arc) { return arc.id; }
1214 1214

	
1215 1215
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
1216 1216
    static Arc arcFromId(int id) { return Arc(id); }
1217 1217
    static Edge edgeFromId(int id) { return Edge(id);}
1218 1218

	
1219 1219
    int maxNodeId() const { return _graph->maxNodeId(); };
1220 1220
    int maxArcId() const { return arcs.size() - 1; }
1221 1221
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
1222 1222

	
1223 1223
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
1224 1224
    Node target(Arc e) const { return arcs[e.id].target; }
1225 1225

	
1226 1226
    Node u(Edge e) const { return arcs[2 * e.id].target; }
1227 1227
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
1228 1228

	
1229 1229
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
1230 1230

	
1231 1231
    NodeNotifier& notifier(Node) const {
1232 1232
      return _graph->notifier(Node());
1233 1233
    }
1234 1234

	
1235 1235
    template <typename V>
1236 1236
    class NodeMap : public GR::template NodeMap<V> {
1237 1237
      typedef typename GR::template NodeMap<V> Parent;
1238 1238

	
1239 1239
    public:
1240 1240

	
1241 1241
      explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
1242 1242
        : Parent(*arcset._graph) { }
1243 1243

	
1244 1244
      NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
1245 1245
        : Parent(*arcset._graph, value) { }
1246 1246

	
1247 1247
      NodeMap& operator=(const NodeMap& cmap) {
1248 1248
        return operator=<NodeMap>(cmap);
1249 1249
      }
1250 1250

	
1251 1251
      template <typename CMap>
1252 1252
      NodeMap& operator=(const CMap& cmap) {
1253 1253
        Parent::operator=(cmap);
1254 1254
        return *this;
1255 1255
      }
1256 1256
    };
1257 1257

	
1258 1258
  };
1259 1259

	
1260
  /// \ingroup semi_adaptors
1260
  /// \ingroup graphs
1261 1261
  ///
1262 1262
  /// \brief Graph using a node set of another digraph or graph and an
1263 1263
  /// own edge set.
1264 1264
  ///
1265 1265
  /// This structure can be used to establish another graph over a
1266 1266
  /// node set of an existing one. This class uses the same Node type
1267 1267
  /// as the underlying graph, and each valid node of the original
1268 1268
  /// graph is valid in this arc set, therefore the node objects of
1269 1269
  /// the original graph can be used directly with this class. The
1270 1270
  /// node handling functions (id handling, observing, and iterators)
1271 1271
  /// works equivalently as in the original graph.
1272 1272
  ///
1273 1273
  /// \param GR The type of the graph which shares its node set
1274 1274
  /// with this class. Its interface must conform to the
1275 1275
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
1276 1276
  ///  concept.
1277 1277
  ///
1278 1278
  /// This implementation is slightly faster than the \c ListEdgeSet,
1279 1279
  /// because it uses continuous storage for edges and it uses just
1280 1280
  /// single-linked lists for enumerate incident edges. Therefore the
1281 1281
  /// edges cannot be erased from the edge sets.
1282 1282
  ///
1283 1283
  /// \warning If a node is erased from the underlying graph and this
1284 1284
  /// node is incident to one edge in the edge set, then the edge set
1285 1285
  /// is invalidated, and it cannot be used anymore. The validity can
1286 1286
  /// be checked with the \c valid() member function.
1287 1287
  ///
1288 1288
  /// This class fully conforms to the \ref concepts::Graph
1289 1289
  /// "Graph" concept.
1290 1290
  template <typename GR>
1291 1291
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
1292 1292
    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
1293 1293

	
1294 1294
  public:
1295 1295

	
1296 1296
    typedef typename Parent::Node Node;
1297 1297
    typedef typename Parent::Arc Arc;
1298 1298
    typedef typename Parent::Edge Edge;
1299 1299

	
1300 1300
  protected:
1301 1301

	
1302 1302
    typedef typename Parent::NodesImplBase NodesImplBase;
1303 1303

	
1304 1304
    void eraseNode(const Node& node) {
1305 1305
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
1306 1306
        return;
1307 1307
      }
1308 1308
      throw typename NodesImplBase::Notifier::ImmediateDetach();
1309 1309
    }
1310 1310

	
1311 1311
    void clearNodes() {
1312 1312
      Parent::clear();
1313 1313
    }
1314 1314

	
1315 1315
    class NodesImpl : public NodesImplBase {
1316 1316
      typedef NodesImplBase Parent;
1317 1317

	
1318 1318
    public:
1319 1319
      NodesImpl(const GR& graph, SmartEdgeSet& arcset)
1320 1320
        : Parent(graph), _arcset(arcset) {}
1321 1321

	
1322 1322
      virtual ~NodesImpl() {}
1323 1323

	
1324 1324
      bool attached() const {
1325 1325
        return Parent::attached();
1326 1326
      }
1327 1327

	
1328 1328
    protected:
1329 1329

	
1330 1330
      virtual void erase(const Node& node) {
1331 1331
        try {
1332 1332
          _arcset.eraseNode(node);
1333 1333
          Parent::erase(node);
1334 1334
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1335 1335
          Parent::clear();
1336 1336
          throw;
1337 1337
        }
1338 1338
      }
1339 1339
      virtual void erase(const std::vector<Node>& nodes) {
1340 1340
        try {
1341 1341
          for (int i = 0; i < int(nodes.size()); ++i) {
1342 1342
            _arcset.eraseNode(nodes[i]);
1343 1343
          }
1344 1344
          Parent::erase(nodes);
1345 1345
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1346 1346
          Parent::clear();
1347 1347
          throw;
1348 1348
        }
1349 1349
      }
1350 1350
      virtual void clear() {
1351 1351
        _arcset.clearNodes();
1352 1352
        Parent::clear();
1353 1353
      }
1354 1354

	
1355 1355
    private:
1356 1356
      SmartEdgeSet& _arcset;
1357 1357
    };
1358 1358

	
1359 1359
    NodesImpl _nodes;
1360 1360

	
1361 1361
  public:
1362 1362

	
1363 1363
    /// \brief Constructor of the EdgeSet.
1364 1364
    ///
1365 1365
    /// Constructor of the EdgeSet.
1366 1366
    SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
1367 1367
      Parent::initalize(graph, _nodes);
1368 1368
    }
1369 1369

	
1370 1370
    /// \brief Add a new edge to the graph.
1371 1371
    ///
1372 1372
    /// Add a new edge to the graph with node \c u
1373 1373
    /// and node \c v endpoints.
1374 1374
    /// \return The new edge.
1375 1375
    Edge addEdge(const Node& u, const Node& v) {
1376 1376
      return Parent::addEdge(u, v);
1377 1377
    }
1378 1378

	
1379 1379
    /// \brief Validity check
1380 1380
    ///
1381 1381
    /// This functions gives back false if the EdgeSet is
1382 1382
    /// invalidated. It occurs when a node in the underlying graph is
1383 1383
    /// erased and it is not isolated in the EdgeSet.
1384 1384
    bool valid() const {
1385 1385
      return _nodes.attached();
1386 1386
    }
1387 1387

	
1388 1388
  };
1389 1389

	
1390 1390
}
1391 1391

	
1392 1392
#endif
0 comments (0 inline)