gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add a new build() function to StaticDigraph (#68) This function builds the digraph from an arc list that contains pairs of integer indices from the range [0..n-1]. It is useful in the cases when you would like to build a StaticDigraph from scratch, i.e. you do not want to build another digraph that can be copied using the other build() function.
0 2 0
default
2 files changed with 111 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 24576 line context
1 1
/* -*- C++ -*-
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_STATIC_GRAPH_H
20 20
#define LEMON_STATIC_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief StaticDigraph class.
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/bits/graph_extender.h>
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  class StaticDigraphBase {
32 32
  public:
33 33

	
34 34
    StaticDigraphBase() 
35 35
      : built(false), node_num(0), arc_num(0), 
36 36
        node_first_out(NULL), node_first_in(NULL),
37 37
        arc_source(NULL), arc_target(NULL), 
38 38
        arc_next_in(NULL), arc_next_out(NULL) {}
39 39
    
40 40
    ~StaticDigraphBase() {
41 41
      if (built) {
42 42
        delete[] node_first_out;
43 43
        delete[] node_first_in;
44 44
        delete[] arc_source;
45 45
        delete[] arc_target;
46 46
        delete[] arc_next_out;
47 47
        delete[] arc_next_in;
48 48
      }
49 49
    }
50 50

	
51 51
    class Node {
52 52
      friend class StaticDigraphBase;
53 53
    protected:
54 54
      int id;
55 55
      Node(int _id) : id(_id) {}
56 56
    public:
57 57
      Node() {}
58 58
      Node (Invalid) : id(-1) {}
59 59
      bool operator==(const Node& node) const { return id == node.id; }
60 60
      bool operator!=(const Node& node) const { return id != node.id; }
61 61
      bool operator<(const Node& node) const { return id < node.id; }
62 62
    };
63 63

	
64 64
    class Arc {
65 65
      friend class StaticDigraphBase;      
66 66
    protected:
67 67
      int id;
68 68
      Arc(int _id) : id(_id) {}
69 69
    public:
70 70
      Arc() { }
71 71
      Arc (Invalid) : id(-1) {}
72 72
      bool operator==(const Arc& arc) const { return id == arc.id; }
73 73
      bool operator!=(const Arc& arc) const { return id != arc.id; }
74 74
      bool operator<(const Arc& arc) const { return id < arc.id; }
75 75
    };
76 76

	
77 77
    Node source(const Arc& e) const { return Node(arc_source[e.id]); }
78 78
    Node target(const Arc& e) const { return Node(arc_target[e.id]); }
79 79

	
80 80
    void first(Node& n) const { n.id = node_num - 1; }
81 81
    static void next(Node& n) { --n.id; }
82 82

	
83 83
    void first(Arc& e) const { e.id = arc_num - 1; }
84 84
    static void next(Arc& e) { --e.id; }
85 85

	
86 86
    void firstOut(Arc& e, const Node& n) const { 
87 87
      e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? 
88 88
        node_first_out[n.id] : -1;
89 89
    }
90 90
    void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
91 91

	
92 92
    void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
93 93
    void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
94 94

	
95 95
    int id(const Node& n) const { return n.id; }
96 96
    Node nodeFromId(int id) const { return Node(id); }
97 97
    int maxNodeId() const { return node_num - 1; }
98 98

	
99 99
    int id(const Arc& e) const { return e.id; }
100 100
    Arc arcFromId(int id) const { return Arc(id); }
101 101
    int maxArcId() const { return arc_num - 1; }
102 102

	
103 103
    typedef True NodeNumTag;
104 104
    typedef True ArcNumTag;
105 105

	
106 106
    int nodeNum() const { return node_num; }
107 107
    int arcNum() const { return arc_num; }
108 108

	
109 109
  private:
110 110

	
111 111
    template <typename Digraph, typename NodeRefMap>
112 112
    class ArcLess {
113 113
    public:
114 114
      typedef typename Digraph::Arc Arc;
115 115

	
116 116
      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) 
117 117
        : digraph(_graph), nodeRef(_nodeRef) {}
118 118
      
119 119
      bool operator()(const Arc& left, const Arc& right) const {
120 120
	return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
121 121
      }
122 122
    private:
123 123
      const Digraph& digraph;
124 124
      const NodeRefMap& nodeRef;
125 125
    };
126 126
    
127 127
  public:
128 128

	
129 129
    typedef True BuildTag;
130 130
    
131 131
    void clear() {
132 132
      if (built) {
133 133
        delete[] node_first_out;
134 134
        delete[] node_first_in;
135 135
        delete[] arc_source;
136 136
        delete[] arc_target;
137 137
        delete[] arc_next_out;
138 138
        delete[] arc_next_in;
139 139
      }
140 140
      built = false;
141 141
      node_num = 0;
142 142
      arc_num = 0;
143 143
    }
144 144
    
145 145
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
146 146
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
147 147
      typedef typename Digraph::Node GNode;
148 148
      typedef typename Digraph::Arc GArc;
149 149

	
150 150
      built = true;
151 151

	
152 152
      node_num = countNodes(digraph);
153 153
      arc_num = countArcs(digraph);
154 154

	
155 155
      node_first_out = new int[node_num + 1];
156 156
      node_first_in = new int[node_num];
157 157

	
158 158
      arc_source = new int[arc_num];
159 159
      arc_target = new int[arc_num];
160 160
      arc_next_out = new int[arc_num];
161 161
      arc_next_in = new int[arc_num];
162 162

	
163 163
      int node_index = 0;
164 164
      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
165 165
        nodeRef[n] = Node(node_index);
166 166
        node_first_in[node_index] = -1;
167 167
        ++node_index;
168 168
      }
169 169

	
170 170
      ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
171 171

	
172 172
      int arc_index = 0;
173 173
      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
174 174
        int source = nodeRef[n].id;
175 175
        std::vector<GArc> arcs;
176 176
        for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
177 177
          arcs.push_back(e);
178 178
        }
179 179
        if (!arcs.empty()) {
180 180
          node_first_out[source] = arc_index;
181 181
          std::sort(arcs.begin(), arcs.end(), arcLess);
182 182
          for (typename std::vector<GArc>::iterator it = arcs.begin();
183 183
               it != arcs.end(); ++it) {
184 184
            int target = nodeRef[digraph.target(*it)].id;
185 185
            arcRef[*it] = Arc(arc_index);
186 186
            arc_source[arc_index] = source; 
187 187
            arc_target[arc_index] = target;
188 188
            arc_next_in[arc_index] = node_first_in[target];
189 189
            node_first_in[target] = arc_index;
190 190
            arc_next_out[arc_index] = arc_index + 1;
191 191
            ++arc_index;
192 192
          }
193 193
          arc_next_out[arc_index - 1] = -1;
194 194
        } else {
195 195
          node_first_out[source] = arc_index;
196 196
        }
197 197
      }
198 198
      node_first_out[node_num] = arc_num;
199 199
    }
200
    
201
    template <typename ArcListIterator>
202
    void build(int n, ArcListIterator first, ArcListIterator last) {
203
      built = true;
204

	
205
      node_num = n;
206
      arc_num = std::distance(first, last);
207

	
208
      node_first_out = new int[node_num + 1];
209
      node_first_in = new int[node_num];
210

	
211
      arc_source = new int[arc_num];
212
      arc_target = new int[arc_num];
213
      arc_next_out = new int[arc_num];
214
      arc_next_in = new int[arc_num];
215
      
216
      for (int i = 0; i != node_num; ++i) {
217
        node_first_in[i] = -1;
218
      }      
219
      
220
      int arc_index = 0;
221
      for (int i = 0; i != node_num; ++i) {
222
        node_first_out[i] = arc_index;
223
        for ( ; first != last && (*first).first == i; ++first) {
224
          int j = (*first).second;
225
          LEMON_ASSERT(j >= 0 && j < node_num,
226
            "Wrong arc list for StaticDigraph::build()");
227
          arc_source[arc_index] = i;
228
          arc_target[arc_index] = j;
229
          arc_next_in[arc_index] = node_first_in[j];
230
          node_first_in[j] = arc_index;
231
          arc_next_out[arc_index] = arc_index + 1;
232
          ++arc_index;
233
        }
234
        if (arc_index > node_first_out[i])
235
          arc_next_out[arc_index - 1] = -1;
236
      }
237
      LEMON_ASSERT(first == last,
238
        "Wrong arc list for StaticDigraph::build()");
239
      node_first_out[node_num] = arc_num;
240
    }
200 241

	
201 242
  protected:
202 243

	
203 244
    void fastFirstOut(Arc& e, const Node& n) const {
204 245
      e.id = node_first_out[n.id];
205 246
    }
206 247

	
207 248
    static void fastNextOut(Arc& e) {
208 249
      ++e.id;
209 250
    }
210 251
    void fastLastOut(Arc& e, const Node& n) const {
211 252
      e.id = node_first_out[n.id + 1];
212 253
    }
213 254

	
214 255
  protected:
215 256
    bool built;
216 257
    int node_num;
217 258
    int arc_num;
218 259
    int *node_first_out;
219 260
    int *node_first_in;
220 261
    int *arc_source;
221 262
    int *arc_target;
222 263
    int *arc_next_in;
223 264
    int *arc_next_out;
224 265
  };
225 266

	
226 267
  typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
227 268

	
228 269

	
229 270
  /// \ingroup graphs
230 271
  ///
231 272
  /// \brief A static directed graph class.
232 273
  ///
233 274
  /// \ref StaticDigraph is a highly efficient digraph implementation,
234 275
  /// but it is fully static.
235 276
  /// It stores only two \c int values for each node and only four \c int
236 277
  /// values for each arc. Moreover it provides faster item iteration than
237 278
  /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
238 279
  /// iterators, since its arcs are stored in an appropriate order.
239 280
  /// However it only provides build() and clear() functions and does not
240 281
  /// support any other modification of the digraph.
241 282
  ///
242 283
  /// Since this digraph structure is completely static, its nodes and arcs
243 284
  /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
244 285
  /// and <tt>[0..arcNum()-1]</tt>, respectively. 
245 286
  /// The index of an item is the same as its ID, it can be obtained
246 287
  /// using the corresponding \ref index() or \ref concepts::Digraph::id()
247 288
  /// "id()" function. A node or arc with a certain index can be obtained
248 289
  /// using node() or arc().
249 290
  ///
250 291
  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
251 292
  /// Most of its member functions and nested classes are documented
252 293
  /// only in the concept class.
253 294
  ///
254 295
  /// \sa concepts::Digraph
255 296
  class StaticDigraph : public ExtendedStaticDigraphBase {
256 297
  public:
257 298

	
258 299
    typedef ExtendedStaticDigraphBase Parent;
259 300
  
260 301
  public:
261 302
  
262 303
    /// \brief Constructor
263 304
    ///
264 305
    /// Default constructor.
265 306
    StaticDigraph() : Parent() {}
266 307

	
267 308
    /// \brief The node with the given index.
268 309
    ///
269 310
    /// This function returns the node with the given index.
270 311
    /// \sa index()
271 312
    Node node(int ix) const { return Parent::nodeFromId(ix); }
272 313

	
273 314
    /// \brief The arc with the given index.
274 315
    ///
275 316
    /// This function returns the arc with the given index.
276 317
    /// \sa index()
277 318
    Arc arc(int ix) const { return Parent::arcFromId(ix); }
278 319

	
279 320
    /// \brief The index of the given node.
280 321
    ///
281 322
    /// This function returns the index of the the given node.
282 323
    /// \sa node()
283 324
    int index(Node node) const { return Parent::id(node); }
284 325

	
285 326
    /// \brief The index of the given arc.
286 327
    ///
287 328
    /// This function returns the index of the the given arc.
288 329
    /// \sa arc()
289 330
    int index(Arc arc) const { return Parent::id(arc); }
290 331

	
291 332
    /// \brief Number of nodes.
292 333
    ///
293 334
    /// This function returns the number of nodes.
294 335
    int nodeNum() const { return node_num; }
295 336

	
296 337
    /// \brief Number of arcs.
297 338
    ///
298 339
    /// This function returns the number of arcs.
299 340
    int arcNum() const { return arc_num; }
300 341

	
301 342
    /// \brief Build the digraph copying another digraph.
302 343
    ///
303 344
    /// This function builds the digraph copying another digraph of any
304 345
    /// kind. It can be called more than once, but in such case, the whole
305 346
    /// structure and all maps will be cleared and rebuilt.
306 347
    ///
307 348
    /// This method also makes possible to copy a digraph to a StaticDigraph
308 349
    /// structure using \ref DigraphCopy.
309 350
    /// 
310 351
    /// \param digraph An existing digraph to be copied.
311 352
    /// \param nodeRef The node references will be copied into this map.
312 353
    /// Its key type must be \c Digraph::Node and its value type must be
313 354
    /// \c StaticDigraph::Node.
314 355
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
315 356
    /// concept.
316 357
    /// \param arcRef The arc references will be copied into this map.
317 358
    /// Its key type must be \c Digraph::Arc and its value type must be
318 359
    /// \c StaticDigraph::Arc.
319 360
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
320 361
    ///
321 362
    /// \note If you do not need the arc references, then you could use
322 363
    /// \ref NullMap for the last parameter. However the node references
323 364
    /// are required by the function itself, thus they must be readable
324 365
    /// from the map.
325 366
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
326 367
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
327 368
      if (built) Parent::clear();
328 369
      Parent::build(digraph, nodeRef, arcRef);
329 370
    }
330 371
  
372
    /// \brief Build the digraph from an arc list.
373
    ///
374
    /// This function builds the digraph from the given arc list.
375
    /// It can be called more than once, but in such case, the whole
376
    /// structure and all maps will be cleared and rebuilt.
377
    ///
378
    /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
379
    /// specified by STL compatible itartors whose \c value_type must be
380
    /// <tt>std::pair<int,int></tt>.
381
    /// Each arc must be specified by a pair of integer indices
382
    /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
383
    /// non-decreasing order with respect to their first values.</i>
384
    /// If the k-th pair in the list is <tt>(i,j)</tt>, then
385
    /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
386
    ///
387
    /// \param n The number of nodes.
388
    /// \param begin An iterator pointing to the beginning of the arc list.
389
    /// \param end An iterator pointing to the end of the arc list.
390
    ///
391
    /// For example, a simple digraph can be constructed like this.
392
    /// \code
393
    ///   std::vector<std::pair<int,int> > arcs;
394
    ///   arcs.push_back(std::make_pair(0,1));
395
    ///   arcs.push_back(std::make_pair(0,2));
396
    ///   arcs.push_back(std::make_pair(1,3));
397
    ///   arcs.push_back(std::make_pair(1,2));
398
    ///   arcs.push_back(std::make_pair(3,0));
399
    ///   StaticDigraph gr;
400
    ///   gr.build(4, arcs.begin(), arcs.end());
401
    /// \endcode
402
    template <typename ArcListIterator>
403
    void build(int n, ArcListIterator begin, ArcListIterator end) {
404
      if (built) Parent::clear();
405
      StaticDigraphBase::build(n, begin, end);
406
      notifier(Node()).build();
407
      notifier(Arc()).build();
408
    }
409

	
331 410
    /// \brief Clear the digraph.
332 411
    ///
333 412
    /// This function erases all nodes and arcs from the digraph.
334 413
    void clear() {
335 414
      Parent::clear();
336 415
    }
337 416

	
338 417
  protected:
339 418

	
340 419
    using Parent::fastFirstOut;
341 420
    using Parent::fastNextOut;
342 421
    using Parent::fastLastOut;
343 422
    
344 423
  public:
345 424

	
346 425
    class OutArcIt : public Arc {
347 426
    public:
348 427

	
349 428
      OutArcIt() { }
350 429

	
351 430
      OutArcIt(Invalid i) : Arc(i) { }
352 431

	
353 432
      OutArcIt(const StaticDigraph& digraph, const Node& node) {
354 433
	digraph.fastFirstOut(*this, node);
355 434
	digraph.fastLastOut(last, node);
356 435
        if (last == *this) *this = INVALID;
357 436
      }
358 437

	
359 438
      OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
360 439
        if (arc != INVALID) {
361 440
          digraph.fastLastOut(last, digraph.source(arc));
362 441
        }
363 442
      }
364 443

	
365 444
      OutArcIt& operator++() { 
366 445
        StaticDigraph::fastNextOut(*this);
367 446
        if (last == *this) *this = INVALID;
368 447
        return *this; 
369 448
      }
370 449

	
371 450
    private:
372 451
      Arc last;
373 452
    };
374 453

	
375 454
    Node baseNode(const OutArcIt &arc) const {
376 455
      return Parent::source(static_cast<const Arc&>(arc));
377 456
    }
378 457

	
379 458
    Node runningNode(const OutArcIt &arc) const {
380 459
      return Parent::target(static_cast<const Arc&>(arc));
381 460
    }
382 461

	
383 462
    Node baseNode(const InArcIt &arc) const {
384 463
      return Parent::target(static_cast<const Arc&>(arc));
385 464
    }
386 465

	
387 466
    Node runningNode(const InArcIt &arc) const {
388 467
      return Parent::source(static_cast<const Arc&>(arc));
389 468
    }
390 469

	
391 470
  };
392 471

	
393 472
}
394 473

	
395 474
#endif
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
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22 22
#include <lemon/static_graph.h>
23 23
#include <lemon/full_graph.h>
24 24

	
25 25
#include "test_tools.h"
26 26
#include "graph_test.h"
27 27

	
28 28
using namespace lemon;
29 29
using namespace lemon::concepts;
30 30

	
31 31
template <class Digraph>
32 32
void checkDigraphBuild() {
33 33
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
34 34
  Digraph G;
35 35

	
36 36
  checkGraphNodeList(G, 0);
37 37
  checkGraphArcList(G, 0);
38 38

	
39 39
  Node
40 40
    n1 = G.addNode(),
41 41
    n2 = G.addNode(),
42 42
    n3 = G.addNode();
43 43
  checkGraphNodeList(G, 3);
44 44
  checkGraphArcList(G, 0);
45 45

	
46 46
  Arc a1 = G.addArc(n1, n2);
47 47
  check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc");
48 48
  checkGraphNodeList(G, 3);
49 49
  checkGraphArcList(G, 1);
50 50

	
51 51
  checkGraphOutArcList(G, n1, 1);
52 52
  checkGraphOutArcList(G, n2, 0);
53 53
  checkGraphOutArcList(G, n3, 0);
54 54

	
55 55
  checkGraphInArcList(G, n1, 0);
56 56
  checkGraphInArcList(G, n2, 1);
57 57
  checkGraphInArcList(G, n3, 0);
58 58

	
59 59
  checkGraphConArcList(G, 1);
60 60

	
61 61
  Arc a2 = G.addArc(n2, n1),
62 62
      a3 = G.addArc(n2, n3),
63 63
      a4 = G.addArc(n2, n3);
64 64

	
65 65
  checkGraphNodeList(G, 3);
66 66
  checkGraphArcList(G, 4);
67 67

	
68 68
  checkGraphOutArcList(G, n1, 1);
69 69
  checkGraphOutArcList(G, n2, 3);
70 70
  checkGraphOutArcList(G, n3, 0);
71 71

	
72 72
  checkGraphInArcList(G, n1, 1);
73 73
  checkGraphInArcList(G, n2, 1);
74 74
  checkGraphInArcList(G, n3, 2);
75 75

	
76 76
  checkGraphConArcList(G, 4);
77 77

	
78 78
  checkNodeIds(G);
79 79
  checkArcIds(G);
80 80
  checkGraphNodeMap(G);
81 81
  checkGraphArcMap(G);
82 82
}
83 83

	
84 84
template <class Digraph>
85 85
void checkDigraphSplit() {
86 86
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
87 87

	
88 88
  Digraph G;
89 89
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
90 90
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
91 91
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
92 92

	
93 93
  Node n4 = G.split(n2);
94 94

	
95 95
  check(G.target(OutArcIt(G, n2)) == n4 &&
96 96
        G.source(InArcIt(G, n4)) == n2,
97 97
        "Wrong split.");
98 98

	
99 99
  checkGraphNodeList(G, 4);
100 100
  checkGraphArcList(G, 5);
101 101

	
102 102
  checkGraphOutArcList(G, n1, 1);
103 103
  checkGraphOutArcList(G, n2, 1);
104 104
  checkGraphOutArcList(G, n3, 0);
105 105
  checkGraphOutArcList(G, n4, 3);
106 106

	
107 107
  checkGraphInArcList(G, n1, 1);
108 108
  checkGraphInArcList(G, n2, 1);
109 109
  checkGraphInArcList(G, n3, 2);
110 110
  checkGraphInArcList(G, n4, 1);
111 111

	
112 112
  checkGraphConArcList(G, 5);
113 113
}
114 114

	
115 115
template <class Digraph>
116 116
void checkDigraphAlter() {
117 117
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
118 118

	
119 119
  Digraph G;
120 120
  Node n1 = G.addNode(), n2 = G.addNode(),
121 121
       n3 = G.addNode(), n4 = G.addNode();
122 122
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
123 123
      a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
124 124
      a5 = G.addArc(n2, n4);
125 125

	
126 126
  checkGraphNodeList(G, 4);
127 127
  checkGraphArcList(G, 5);
128 128

	
129 129
  // Check changeSource() and changeTarget()
130 130
  G.changeTarget(a4, n1);
131 131

	
132 132
  checkGraphNodeList(G, 4);
133 133
  checkGraphArcList(G, 5);
134 134

	
135 135
  checkGraphOutArcList(G, n1, 1);
136 136
  checkGraphOutArcList(G, n2, 1);
137 137
  checkGraphOutArcList(G, n3, 0);
138 138
  checkGraphOutArcList(G, n4, 3);
139 139

	
140 140
  checkGraphInArcList(G, n1, 2);
141 141
  checkGraphInArcList(G, n2, 1);
142 142
  checkGraphInArcList(G, n3, 1);
143 143
  checkGraphInArcList(G, n4, 1);
144 144

	
145 145
  checkGraphConArcList(G, 5);
146 146

	
147 147
  G.changeSource(a4, n3);
148 148

	
149 149
  checkGraphNodeList(G, 4);
150 150
  checkGraphArcList(G, 5);
151 151

	
152 152
  checkGraphOutArcList(G, n1, 1);
153 153
  checkGraphOutArcList(G, n2, 1);
154 154
  checkGraphOutArcList(G, n3, 1);
155 155
  checkGraphOutArcList(G, n4, 2);
156 156

	
157 157
  checkGraphInArcList(G, n1, 2);
158 158
  checkGraphInArcList(G, n2, 1);
159 159
  checkGraphInArcList(G, n3, 1);
160 160
  checkGraphInArcList(G, n4, 1);
161 161

	
162 162
  checkGraphConArcList(G, 5);
163 163

	
164 164
  // Check contract()
165 165
  G.contract(n2, n4, false);
166 166

	
167 167
  checkGraphNodeList(G, 3);
168 168
  checkGraphArcList(G, 5);
169 169

	
170 170
  checkGraphOutArcList(G, n1, 1);
171 171
  checkGraphOutArcList(G, n2, 3);
172 172
  checkGraphOutArcList(G, n3, 1);
173 173

	
174 174
  checkGraphInArcList(G, n1, 2);
175 175
  checkGraphInArcList(G, n2, 2);
176 176
  checkGraphInArcList(G, n3, 1);
177 177

	
178 178
  checkGraphConArcList(G, 5);
179 179

	
180 180
  G.contract(n2, n1);
181 181

	
182 182
  checkGraphNodeList(G, 2);
183 183
  checkGraphArcList(G, 3);
184 184

	
185 185
  checkGraphOutArcList(G, n2, 2);
186 186
  checkGraphOutArcList(G, n3, 1);
187 187

	
188 188
  checkGraphInArcList(G, n2, 2);
189 189
  checkGraphInArcList(G, n3, 1);
190 190

	
191 191
  checkGraphConArcList(G, 3);
192 192
}
193 193

	
194 194
template <class Digraph>
195 195
void checkDigraphErase() {
196 196
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
197 197

	
198 198
  Digraph G;
199 199
  Node n1 = G.addNode(), n2 = G.addNode(),
200 200
       n3 = G.addNode(), n4 = G.addNode();
201 201
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
202 202
      a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
203 203
      a5 = G.addArc(n2, n4);
204 204

	
205 205
  // Check arc deletion
206 206
  G.erase(a1);
207 207

	
208 208
  checkGraphNodeList(G, 4);
209 209
  checkGraphArcList(G, 4);
210 210

	
211 211
  checkGraphOutArcList(G, n1, 0);
212 212
  checkGraphOutArcList(G, n2, 1);
213 213
  checkGraphOutArcList(G, n3, 1);
214 214
  checkGraphOutArcList(G, n4, 2);
215 215

	
216 216
  checkGraphInArcList(G, n1, 2);
217 217
  checkGraphInArcList(G, n2, 0);
218 218
  checkGraphInArcList(G, n3, 1);
219 219
  checkGraphInArcList(G, n4, 1);
220 220

	
221 221
  checkGraphConArcList(G, 4);
222 222

	
223 223
  // Check node deletion
224 224
  G.erase(n4);
225 225

	
226 226
  checkGraphNodeList(G, 3);
227 227
  checkGraphArcList(G, 1);
228 228

	
229 229
  checkGraphOutArcList(G, n1, 0);
230 230
  checkGraphOutArcList(G, n2, 0);
231 231
  checkGraphOutArcList(G, n3, 1);
232 232
  checkGraphOutArcList(G, n4, 0);
233 233

	
234 234
  checkGraphInArcList(G, n1, 1);
235 235
  checkGraphInArcList(G, n2, 0);
236 236
  checkGraphInArcList(G, n3, 0);
237 237
  checkGraphInArcList(G, n4, 0);
238 238

	
239 239
  checkGraphConArcList(G, 1);
240 240
}
241 241

	
242 242

	
243 243
template <class Digraph>
244 244
void checkDigraphSnapshot() {
245 245
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
246 246

	
247 247
  Digraph G;
248 248
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
249 249
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
250 250
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
251 251

	
252 252
  typename Digraph::Snapshot snapshot(G);
253 253

	
254 254
  Node n = G.addNode();
255 255
  G.addArc(n3, n);
256 256
  G.addArc(n, n3);
257 257

	
258 258
  checkGraphNodeList(G, 4);
259 259
  checkGraphArcList(G, 6);
260 260

	
261 261
  snapshot.restore();
262 262

	
263 263
  checkGraphNodeList(G, 3);
264 264
  checkGraphArcList(G, 4);
265 265

	
266 266
  checkGraphOutArcList(G, n1, 1);
267 267
  checkGraphOutArcList(G, n2, 3);
268 268
  checkGraphOutArcList(G, n3, 0);
269 269

	
270 270
  checkGraphInArcList(G, n1, 1);
271 271
  checkGraphInArcList(G, n2, 1);
272 272
  checkGraphInArcList(G, n3, 2);
273 273

	
274 274
  checkGraphConArcList(G, 4);
275 275

	
276 276
  checkNodeIds(G);
277 277
  checkArcIds(G);
278 278
  checkGraphNodeMap(G);
279 279
  checkGraphArcMap(G);
280 280

	
281 281
  G.addNode();
282 282
  snapshot.save(G);
283 283

	
284 284
  G.addArc(G.addNode(), G.addNode());
285 285

	
286 286
  snapshot.restore();
287 287

	
288 288
  checkGraphNodeList(G, 4);
289 289
  checkGraphArcList(G, 4);
290 290
}
291 291

	
292 292
void checkConcepts() {
293 293
  { // Checking digraph components
294 294
    checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
295 295

	
296 296
    checkConcept<IDableDigraphComponent<>,
297 297
      IDableDigraphComponent<> >();
298 298

	
299 299
    checkConcept<IterableDigraphComponent<>,
300 300
      IterableDigraphComponent<> >();
301 301

	
302 302
    checkConcept<MappableDigraphComponent<>,
303 303
      MappableDigraphComponent<> >();
304 304
  }
305 305
  { // Checking skeleton digraph
306 306
    checkConcept<Digraph, Digraph>();
307 307
  }
308 308
  { // Checking ListDigraph
309 309
    checkConcept<Digraph, ListDigraph>();
310 310
    checkConcept<AlterableDigraphComponent<>, ListDigraph>();
311 311
    checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
312 312
    checkConcept<ClearableDigraphComponent<>, ListDigraph>();
313 313
    checkConcept<ErasableDigraphComponent<>, ListDigraph>();
314 314
  }
315 315
  { // Checking SmartDigraph
316 316
    checkConcept<Digraph, SmartDigraph>();
317 317
    checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
318 318
    checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
319 319
    checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
320 320
  }
321 321
  { // Checking StaticDigraph
322 322
    checkConcept<Digraph, StaticDigraph>();
323 323
    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
324 324
  }
325 325
  { // Checking FullDigraph
326 326
    checkConcept<Digraph, FullDigraph>();
327 327
  }
328 328
}
329 329

	
330 330
template <typename Digraph>
331 331
void checkDigraphValidity() {
332 332
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
333 333
  Digraph g;
334 334

	
335 335
  Node
336 336
    n1 = g.addNode(),
337 337
    n2 = g.addNode(),
338 338
    n3 = g.addNode();
339 339

	
340 340
  Arc
341 341
    e1 = g.addArc(n1, n2),
342 342
    e2 = g.addArc(n2, n3);
343 343

	
344 344
  check(g.valid(n1), "Wrong validity check");
345 345
  check(g.valid(e1), "Wrong validity check");
346 346

	
347 347
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
348 348
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
349 349
}
350 350

	
351 351
template <typename Digraph>
352 352
void checkDigraphValidityErase() {
353 353
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
354 354
  Digraph g;
355 355

	
356 356
  Node
357 357
    n1 = g.addNode(),
358 358
    n2 = g.addNode(),
359 359
    n3 = g.addNode();
360 360

	
361 361
  Arc
362 362
    e1 = g.addArc(n1, n2),
363 363
    e2 = g.addArc(n2, n3);
364 364

	
365 365
  check(g.valid(n1), "Wrong validity check");
366 366
  check(g.valid(e1), "Wrong validity check");
367 367

	
368 368
  g.erase(n1);
369 369

	
370 370
  check(!g.valid(n1), "Wrong validity check");
371 371
  check(g.valid(n2), "Wrong validity check");
372 372
  check(g.valid(n3), "Wrong validity check");
373 373
  check(!g.valid(e1), "Wrong validity check");
374 374
  check(g.valid(e2), "Wrong validity check");
375 375

	
376 376
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
377 377
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
378 378
}
379 379

	
380 380
void checkStaticDigraph() {
381 381
  SmartDigraph g;
382 382
  SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
383 383
  SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
384 384
  
385 385
  StaticDigraph G;
386 386
  
387 387
  checkGraphNodeList(G, 0);
388 388
  checkGraphArcList(G, 0);
389 389

	
390 390
  G.build(g, nref, aref);
391 391

	
392 392
  checkGraphNodeList(G, 0);
393 393
  checkGraphArcList(G, 0);
394 394

	
395 395
  SmartDigraph::Node
396 396
    n1 = g.addNode(),
397 397
    n2 = g.addNode(),
398 398
    n3 = g.addNode();
399 399

	
400 400
  G.build(g, nref, aref);
401 401

	
402 402
  checkGraphNodeList(G, 3);
403 403
  checkGraphArcList(G, 0);
404 404

	
405 405
  SmartDigraph::Arc a1 = g.addArc(n1, n2);
406 406

	
407 407
  G.build(g, nref, aref);
408 408

	
409 409
  check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
410 410
        "Wrong arc or wrong references");
411 411
  checkGraphNodeList(G, 3);
412 412
  checkGraphArcList(G, 1);
413 413

	
414 414
  checkGraphOutArcList(G, nref[n1], 1);
415 415
  checkGraphOutArcList(G, nref[n2], 0);
416 416
  checkGraphOutArcList(G, nref[n3], 0);
417 417

	
418 418
  checkGraphInArcList(G, nref[n1], 0);
419 419
  checkGraphInArcList(G, nref[n2], 1);
420 420
  checkGraphInArcList(G, nref[n3], 0);
421 421

	
422 422
  checkGraphConArcList(G, 1);
423 423

	
424 424
  SmartDigraph::Arc
425 425
    a2 = g.addArc(n2, n1),
426 426
    a3 = g.addArc(n2, n3),
427 427
    a4 = g.addArc(n2, n3);
428 428

	
429 429
  digraphCopy(g, G).nodeRef(nref).run();
430 430

	
431 431
  checkGraphNodeList(G, 3);
432 432
  checkGraphArcList(G, 4);
433 433

	
434 434
  checkGraphOutArcList(G, nref[n1], 1);
435 435
  checkGraphOutArcList(G, nref[n2], 3);
436 436
  checkGraphOutArcList(G, nref[n3], 0);
437 437

	
438 438
  checkGraphInArcList(G, nref[n1], 1);
439 439
  checkGraphInArcList(G, nref[n2], 1);
440 440
  checkGraphInArcList(G, nref[n3], 2);
441 441

	
442 442
  checkGraphConArcList(G, 4);
443 443

	
444
  std::vector<std::pair<int,int> > arcs;
445
  arcs.push_back(std::make_pair(0,1));
446
  arcs.push_back(std::make_pair(0,2));
447
  arcs.push_back(std::make_pair(1,3));
448
  arcs.push_back(std::make_pair(1,2));
449
  arcs.push_back(std::make_pair(3,0));
450
  arcs.push_back(std::make_pair(3,3));
451
  arcs.push_back(std::make_pair(4,2));
452
  arcs.push_back(std::make_pair(4,3));
453
  arcs.push_back(std::make_pair(4,1));
454

	
455
  G.build(6, arcs.begin(), arcs.end());
456
  
457
  checkGraphNodeList(G, 6);
458
  checkGraphArcList(G, 9);
459

	
460
  checkGraphOutArcList(G, G.node(0), 2);
461
  checkGraphOutArcList(G, G.node(1), 2);
462
  checkGraphOutArcList(G, G.node(2), 0);
463
  checkGraphOutArcList(G, G.node(3), 2);
464
  checkGraphOutArcList(G, G.node(4), 3);
465
  checkGraphOutArcList(G, G.node(5), 0);
466

	
467
  checkGraphInArcList(G, G.node(0), 1);
468
  checkGraphInArcList(G, G.node(1), 2);
469
  checkGraphInArcList(G, G.node(2), 3);
470
  checkGraphInArcList(G, G.node(3), 3);
471
  checkGraphInArcList(G, G.node(4), 0);
472
  checkGraphInArcList(G, G.node(5), 0);
473

	
474
  checkGraphConArcList(G, 9);
475

	
444 476
  checkNodeIds(G);
445 477
  checkArcIds(G);
446 478
  checkGraphNodeMap(G);
447 479
  checkGraphArcMap(G);
448 480
  
449 481
  int n = G.nodeNum();
450 482
  int m = G.arcNum();
451 483
  check(G.index(G.node(n-1)) == n-1, "Wrong index.");
452 484
  check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
453 485
}
454 486

	
455 487
void checkFullDigraph(int num) {
456 488
  typedef FullDigraph Digraph;
457 489
  DIGRAPH_TYPEDEFS(Digraph);
458 490
  Digraph G(num);
459 491

	
460 492
  checkGraphNodeList(G, num);
461 493
  checkGraphArcList(G, num * num);
462 494

	
463 495
  for (NodeIt n(G); n != INVALID; ++n) {
464 496
    checkGraphOutArcList(G, n, num);
465 497
    checkGraphInArcList(G, n, num);
466 498
  }
467 499

	
468 500
  checkGraphConArcList(G, num * num);
469 501

	
470 502
  checkNodeIds(G);
471 503
  checkArcIds(G);
472 504
  checkGraphNodeMap(G);
473 505
  checkGraphArcMap(G);
474 506

	
475 507
  for (int i = 0; i < G.nodeNum(); ++i) {
476 508
    check(G.index(G(i)) == i, "Wrong index");
477 509
  }
478 510

	
479 511
  for (NodeIt s(G); s != INVALID; ++s) {
480 512
    for (NodeIt t(G); t != INVALID; ++t) {
481 513
      Arc a = G.arc(s, t);
482 514
      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
483 515
    }
484 516
  }
485 517
}
486 518

	
487 519
void checkDigraphs() {
488 520
  { // Checking ListDigraph
489 521
    checkDigraphBuild<ListDigraph>();
490 522
    checkDigraphSplit<ListDigraph>();
491 523
    checkDigraphAlter<ListDigraph>();
492 524
    checkDigraphErase<ListDigraph>();
493 525
    checkDigraphSnapshot<ListDigraph>();
494 526
    checkDigraphValidityErase<ListDigraph>();
495 527
  }
496 528
  { // Checking SmartDigraph
497 529
    checkDigraphBuild<SmartDigraph>();
498 530
    checkDigraphSplit<SmartDigraph>();
499 531
    checkDigraphSnapshot<SmartDigraph>();
500 532
    checkDigraphValidity<SmartDigraph>();
501 533
  }
502 534
  { // Checking StaticDigraph
503 535
    checkStaticDigraph();
504 536
  }
505 537
  { // Checking FullDigraph
506 538
    checkFullDigraph(8);
507 539
  }
508 540
}
509 541

	
510 542
int main() {
511 543
  checkDigraphs();
512 544
  checkConcepts();
513 545
  return 0;
514 546
}
0 comments (0 inline)