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 192 line context
... ...
@@ -45,202 +45,192 @@
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
/**
Ignore white space 192 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

	
... ...
@@ -137,193 +137,193 @@
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

	
... ...
@@ -561,193 +561,193 @@
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.
... ...
@@ -820,193 +820,193 @@
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;
... ...
@@ -1164,193 +1164,193 @@
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;
0 comments (0 inline)