gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add reserve functions to ListGraph and SmartGraph (#311) ListDigraph and SmartDigraph already have such functions.
0 4 0
default
4 files changed with 46 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 140737488355328 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
#ifndef LEMON_LIST_GRAPH_H
20 20
#define LEMON_LIST_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief ListDigraph and ListGraph classes.
25 25

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

	
30 30
#include <vector>
31 31
#include <list>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  class ListDigraphBase {
36 36

	
37 37
  protected:
38 38
    struct NodeT {
39 39
      int first_in, first_out;
40 40
      int prev, next;
41 41
    };
42 42

	
43 43
    struct ArcT {
44 44
      int target, source;
45 45
      int prev_in, prev_out;
46 46
      int next_in, next_out;
47 47
    };
48 48

	
49 49
    std::vector<NodeT> nodes;
50 50

	
51 51
    int first_node;
52 52

	
53 53
    int first_free_node;
54 54

	
55 55
    std::vector<ArcT> arcs;
56 56

	
57 57
    int first_free_arc;
58 58

	
59 59
  public:
60 60

	
61 61
    typedef ListDigraphBase Digraph;
62 62

	
63 63
    class Node {
64 64
      friend class ListDigraphBase;
65 65
    protected:
66 66

	
67 67
      int id;
68 68
      explicit Node(int pid) { id = pid;}
69 69

	
70 70
    public:
71 71
      Node() {}
72 72
      Node (Invalid) { id = -1; }
73 73
      bool operator==(const Node& node) const {return id == node.id;}
74 74
      bool operator!=(const Node& node) const {return id != node.id;}
75 75
      bool operator<(const Node& node) const {return id < node.id;}
76 76
    };
77 77

	
78 78
    class Arc {
79 79
      friend class ListDigraphBase;
80 80
    protected:
81 81

	
82 82
      int id;
83 83
      explicit Arc(int pid) { id = pid;}
84 84

	
85 85
    public:
86 86
      Arc() {}
87 87
      Arc (Invalid) { id = -1; }
88 88
      bool operator==(const Arc& arc) const {return id == arc.id;}
89 89
      bool operator!=(const Arc& arc) const {return id != arc.id;}
90 90
      bool operator<(const Arc& arc) const {return id < arc.id;}
91 91
    };
92 92

	
93 93

	
94 94

	
95 95
    ListDigraphBase()
96 96
      : nodes(), first_node(-1),
97 97
        first_free_node(-1), arcs(), first_free_arc(-1) {}
98 98

	
99 99

	
100 100
    int maxNodeId() const { return nodes.size()-1; }
101 101
    int maxArcId() const { return arcs.size()-1; }
102 102

	
103 103
    Node source(Arc e) const { return Node(arcs[e.id].source); }
104 104
    Node target(Arc e) const { return Node(arcs[e.id].target); }
105 105

	
106 106

	
107 107
    void first(Node& node) const {
108 108
      node.id = first_node;
109 109
    }
110 110

	
111 111
    void next(Node& node) const {
112 112
      node.id = nodes[node.id].next;
113 113
    }
114 114

	
115 115

	
116 116
    void first(Arc& arc) const {
117 117
      int n;
118 118
      for(n = first_node;
119 119
          n!=-1 && nodes[n].first_in == -1;
120 120
          n = nodes[n].next) {}
121 121
      arc.id = (n == -1) ? -1 : nodes[n].first_in;
122 122
    }
123 123

	
124 124
    void next(Arc& arc) const {
125 125
      if (arcs[arc.id].next_in != -1) {
126 126
        arc.id = arcs[arc.id].next_in;
127 127
      } else {
128 128
        int n;
129 129
        for(n = nodes[arcs[arc.id].target].next;
130 130
            n!=-1 && nodes[n].first_in == -1;
131 131
            n = nodes[n].next) {}
132 132
        arc.id = (n == -1) ? -1 : nodes[n].first_in;
133 133
      }
134 134
    }
135 135

	
136 136
    void firstOut(Arc &e, const Node& v) const {
137 137
      e.id = nodes[v.id].first_out;
138 138
    }
139 139
    void nextOut(Arc &e) const {
140 140
      e.id=arcs[e.id].next_out;
141 141
    }
142 142

	
143 143
    void firstIn(Arc &e, const Node& v) const {
144 144
      e.id = nodes[v.id].first_in;
145 145
    }
146 146
    void nextIn(Arc &e) const {
147 147
      e.id=arcs[e.id].next_in;
148 148
    }
149 149

	
150 150

	
151 151
    static int id(Node v) { return v.id; }
152 152
    static int id(Arc e) { return e.id; }
153 153

	
154 154
    static Node nodeFromId(int id) { return Node(id);}
155 155
    static Arc arcFromId(int id) { return Arc(id);}
156 156

	
157 157
    bool valid(Node n) const {
158 158
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
159 159
        nodes[n.id].prev != -2;
160 160
    }
161 161

	
162 162
    bool valid(Arc a) const {
163 163
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
164 164
        arcs[a.id].prev_in != -2;
165 165
    }
166 166

	
167 167
    Node addNode() {
168 168
      int n;
169 169

	
170 170
      if(first_free_node==-1) {
171 171
        n = nodes.size();
172 172
        nodes.push_back(NodeT());
173 173
      } else {
174 174
        n = first_free_node;
175 175
        first_free_node = nodes[n].next;
176 176
      }
177 177

	
178 178
      nodes[n].next = first_node;
179 179
      if(first_node != -1) nodes[first_node].prev = n;
180 180
      first_node = n;
181 181
      nodes[n].prev = -1;
182 182

	
183 183
      nodes[n].first_in = nodes[n].first_out = -1;
184 184

	
185 185
      return Node(n);
186 186
    }
187 187

	
188 188
    Arc addArc(Node u, Node v) {
189 189
      int n;
190 190

	
191 191
      if (first_free_arc == -1) {
192 192
        n = arcs.size();
193 193
        arcs.push_back(ArcT());
194 194
      } else {
195 195
        n = first_free_arc;
196 196
        first_free_arc = arcs[n].next_in;
197 197
      }
198 198

	
199 199
      arcs[n].source = u.id;
200 200
      arcs[n].target = v.id;
201 201

	
202 202
      arcs[n].next_out = nodes[u.id].first_out;
203 203
      if(nodes[u.id].first_out != -1) {
204 204
        arcs[nodes[u.id].first_out].prev_out = n;
205 205
      }
206 206

	
207 207
      arcs[n].next_in = nodes[v.id].first_in;
208 208
      if(nodes[v.id].first_in != -1) {
209 209
        arcs[nodes[v.id].first_in].prev_in = n;
210 210
      }
211 211

	
212 212
      arcs[n].prev_in = arcs[n].prev_out = -1;
213 213

	
214 214
      nodes[u.id].first_out = nodes[v.id].first_in = n;
215 215

	
216 216
      return Arc(n);
217 217
    }
218 218

	
219 219
    void erase(const Node& node) {
220 220
      int n = node.id;
221 221

	
222 222
      if(nodes[n].next != -1) {
223 223
        nodes[nodes[n].next].prev = nodes[n].prev;
224 224
      }
225 225

	
226 226
      if(nodes[n].prev != -1) {
227 227
        nodes[nodes[n].prev].next = nodes[n].next;
228 228
      } else {
229 229
        first_node = nodes[n].next;
230 230
      }
231 231

	
232 232
      nodes[n].next = first_free_node;
233 233
      first_free_node = n;
234 234
      nodes[n].prev = -2;
235 235

	
236 236
    }
237 237

	
238 238
    void erase(const Arc& arc) {
239 239
      int n = arc.id;
240 240

	
241 241
      if(arcs[n].next_in!=-1) {
242 242
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
243 243
      }
244 244

	
245 245
      if(arcs[n].prev_in!=-1) {
246 246
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
247 247
      } else {
248 248
        nodes[arcs[n].target].first_in = arcs[n].next_in;
249 249
      }
250 250

	
251 251

	
252 252
      if(arcs[n].next_out!=-1) {
253 253
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
254 254
      }
255 255

	
256 256
      if(arcs[n].prev_out!=-1) {
257 257
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
258 258
      } else {
259 259
        nodes[arcs[n].source].first_out = arcs[n].next_out;
260 260
      }
261 261

	
262 262
      arcs[n].next_in = first_free_arc;
263 263
      first_free_arc = n;
264 264
      arcs[n].prev_in = -2;
265 265
    }
266 266

	
267 267
    void clear() {
268 268
      arcs.clear();
269 269
      nodes.clear();
270 270
      first_node = first_free_node = first_free_arc = -1;
271 271
    }
272 272

	
273 273
  protected:
274 274
    void changeTarget(Arc e, Node n)
275 275
    {
276 276
      if(arcs[e.id].next_in != -1)
277 277
        arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
278 278
      if(arcs[e.id].prev_in != -1)
279 279
        arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
280 280
      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
281 281
      if (nodes[n.id].first_in != -1) {
282 282
        arcs[nodes[n.id].first_in].prev_in = e.id;
283 283
      }
284 284
      arcs[e.id].target = n.id;
285 285
      arcs[e.id].prev_in = -1;
286 286
      arcs[e.id].next_in = nodes[n.id].first_in;
287 287
      nodes[n.id].first_in = e.id;
288 288
    }
289 289
    void changeSource(Arc e, Node n)
290 290
    {
291 291
      if(arcs[e.id].next_out != -1)
292 292
        arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
293 293
      if(arcs[e.id].prev_out != -1)
294 294
        arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
295 295
      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
296 296
      if (nodes[n.id].first_out != -1) {
297 297
        arcs[nodes[n.id].first_out].prev_out = e.id;
298 298
      }
299 299
      arcs[e.id].source = n.id;
300 300
      arcs[e.id].prev_out = -1;
301 301
      arcs[e.id].next_out = nodes[n.id].first_out;
302 302
      nodes[n.id].first_out = e.id;
303 303
    }
304 304

	
305 305
  };
306 306

	
307 307
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
308 308

	
309 309
  /// \addtogroup graphs
310 310
  /// @{
311 311

	
312 312
  ///A general directed graph structure.
313 313

	
314 314
  ///\ref ListDigraph is a versatile and fast directed graph
315 315
  ///implementation based on linked lists that are stored in
316 316
  ///\c std::vector structures.
317 317
  ///
318 318
  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
319 319
  ///and it also provides several useful additional functionalities.
320 320
  ///Most of its member functions and nested classes are documented
321 321
  ///only in the concept class.
322 322
  ///
323 323
  ///\sa concepts::Digraph
324 324
  ///\sa ListGraph
325 325
  class ListDigraph : public ExtendedListDigraphBase {
326 326
    typedef ExtendedListDigraphBase Parent;
327 327

	
328 328
  private:
329 329
    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
330 330
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
331 331
    /// \brief Assignment of a digraph to another one is \e not allowed.
332 332
    /// Use DigraphCopy instead.
333 333
    void operator=(const ListDigraph &) {}
334 334
  public:
335 335

	
336 336
    /// Constructor
337 337

	
338 338
    /// Constructor.
339 339
    ///
340 340
    ListDigraph() {}
341 341

	
342 342
    ///Add a new node to the digraph.
343 343

	
344 344
    ///This function adds a new node to the digraph.
345 345
    ///\return The new node.
346 346
    Node addNode() { return Parent::addNode(); }
347 347

	
348 348
    ///Add a new arc to the digraph.
349 349

	
350 350
    ///This function adds a new arc to the digraph with source node \c s
351 351
    ///and target node \c t.
352 352
    ///\return The new arc.
353 353
    Arc addArc(Node s, Node t) {
354 354
      return Parent::addArc(s, t);
355 355
    }
356 356

	
357 357
    ///\brief Erase a node from the digraph.
358 358
    ///
359 359
    ///This function erases the given node from the digraph.
360 360
    void erase(Node n) { Parent::erase(n); }
361 361

	
362 362
    ///\brief Erase an arc from the digraph.
363 363
    ///
364 364
    ///This function erases the given arc from the digraph.
365 365
    void erase(Arc a) { Parent::erase(a); }
366 366

	
367 367
    /// Node validity check
368 368

	
369 369
    /// This function gives back \c true if the given node is valid,
370 370
    /// i.e. it is a real node of the digraph.
371 371
    ///
372 372
    /// \warning A removed node could become valid again if new nodes are
373 373
    /// added to the digraph.
374 374
    bool valid(Node n) const { return Parent::valid(n); }
375 375

	
376 376
    /// Arc validity check
377 377

	
378 378
    /// This function gives back \c true if the given arc is valid,
379 379
    /// i.e. it is a real arc of the digraph.
380 380
    ///
381 381
    /// \warning A removed arc could become valid again if new arcs are
382 382
    /// added to the digraph.
383 383
    bool valid(Arc a) const { return Parent::valid(a); }
384 384

	
385 385
    /// Change the target node of an arc
386 386

	
387 387
    /// This function changes the target node of the given arc \c a to \c n.
388 388
    ///
389 389
    ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
390 390
    ///arc remain valid, however \c InArcIt iterators are invalidated.
391 391
    ///
392 392
    ///\warning This functionality cannot be used together with the Snapshot
393 393
    ///feature.
394 394
    void changeTarget(Arc a, Node n) {
395 395
      Parent::changeTarget(a,n);
396 396
    }
397 397
    /// Change the source node of an arc
398 398

	
399 399
    /// This function changes the source node of the given arc \c a to \c n.
400 400
    ///
401 401
    ///\note \c InArcIt iterators referencing the changed arc remain
402 402
    ///valid, however \c ArcIt and \c OutArcIt iterators are invalidated.
403 403
    ///
404 404
    ///\warning This functionality cannot be used together with the Snapshot
405 405
    ///feature.
406 406
    void changeSource(Arc a, Node n) {
407 407
      Parent::changeSource(a,n);
408 408
    }
409 409

	
410 410
    /// Reverse the direction of an arc.
411 411

	
412 412
    /// This function reverses the direction of the given arc.
413 413
    ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
414 414
    ///the changed arc are invalidated.
415 415
    ///
416 416
    ///\warning This functionality cannot be used together with the Snapshot
417 417
    ///feature.
418 418
    void reverseArc(Arc a) {
419 419
      Node t=target(a);
420 420
      changeTarget(a,source(a));
421 421
      changeSource(a,t);
422 422
    }
423 423

	
424 424
    ///Contract two nodes.
425 425

	
426 426
    ///This function contracts the given two nodes.
427 427
    ///Node \c v is removed, but instead of deleting its
428 428
    ///incident arcs, they are joined to node \c u.
429 429
    ///If the last parameter \c r is \c true (this is the default value),
430 430
    ///then the newly created loops are removed.
431 431
    ///
432 432
    ///\note The moved arcs are joined to node \c u using changeSource()
433 433
    ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
434 434
    ///invalidated for the outgoing arcs of node \c v and \c InArcIt
435 435
    ///iterators are invalidated for the incomming arcs of \c v.
436 436
    ///Moreover all iterators referencing node \c v or the removed 
437 437
    ///loops are also invalidated. Other iterators remain valid.
438 438
    ///
439 439
    ///\warning This functionality cannot be used together with the Snapshot
440 440
    ///feature.
441 441
    void contract(Node u, Node v, bool r = true)
442 442
    {
443 443
      for(OutArcIt e(*this,v);e!=INVALID;) {
444 444
        OutArcIt f=e;
445 445
        ++f;
446 446
        if(r && target(e)==u) erase(e);
447 447
        else changeSource(e,u);
448 448
        e=f;
449 449
      }
450 450
      for(InArcIt e(*this,v);e!=INVALID;) {
451 451
        InArcIt f=e;
452 452
        ++f;
453 453
        if(r && source(e)==u) erase(e);
454 454
        else changeTarget(e,u);
455 455
        e=f;
456 456
      }
457 457
      erase(v);
458 458
    }
459 459

	
460 460
    ///Split a node.
461 461

	
462 462
    ///This function splits the given node. First, a new node is added
463 463
    ///to the digraph, then the source of each outgoing arc of node \c n
464 464
    ///is moved to this new node.
465 465
    ///If the second parameter \c connect is \c true (this is the default
466 466
    ///value), then a new arc from node \c n to the newly created node
467 467
    ///is also added.
468 468
    ///\return The newly created node.
469 469
    ///
470 470
    ///\note \c ArcIt and \c OutArcIt iterators referencing the outgoing
471 471
    ///arcs of node \c n are invalidated. Other iterators remain valid.
472 472
    ///
473 473
    ///\warning This functionality cannot be used together with the
474 474
    ///Snapshot feature.
475 475
    Node split(Node n, bool connect = true) {
476 476
      Node b = addNode();
477 477
      for(OutArcIt e(*this,n);e!=INVALID;) {
478 478
        OutArcIt f=e;
479 479
        ++f;
480 480
        changeSource(e,b);
481 481
        e=f;
482 482
      }
483 483
      if (connect) addArc(n,b);
484 484
      return b;
485 485
    }
486 486

	
487 487
    ///Split an arc.
488 488

	
489 489
    ///This function splits the given arc. First, a new node \c v is
490 490
    ///added to the digraph, then the target node of the original arc
491 491
    ///is set to \c v. Finally, an arc from \c v to the original target
492 492
    ///is added.
493 493
    ///\return The newly created node.
494 494
    ///
495 495
    ///\note \c InArcIt iterators referencing the original arc are
496 496
    ///invalidated. Other iterators remain valid.
497 497
    ///
498 498
    ///\warning This functionality cannot be used together with the
499 499
    ///Snapshot feature.
500 500
    Node split(Arc a) {
501 501
      Node v = addNode();
502 502
      addArc(v,target(a));
503 503
      changeTarget(a,v);
504 504
      return v;
505 505
    }
506 506

	
507 507
    ///Clear the digraph.
508 508

	
509 509
    ///This function erases all nodes and arcs from the digraph.
510 510
    ///
511 511
    void clear() {
512 512
      Parent::clear();
513 513
    }
514 514

	
515 515
    /// Reserve memory for nodes.
516 516

	
517 517
    /// Using this function, it is possible to avoid superfluous memory
518 518
    /// allocation: if you know that the digraph you want to build will
519 519
    /// be large (e.g. it will contain millions of nodes and/or arcs),
520 520
    /// then it is worth reserving space for this amount before starting
521 521
    /// to build the digraph.
522 522
    /// \sa reserveArc()
523 523
    void reserveNode(int n) { nodes.reserve(n); };
524 524

	
525 525
    /// Reserve memory for arcs.
526 526

	
527 527
    /// Using this function, it is possible to avoid superfluous memory
528 528
    /// allocation: if you know that the digraph you want to build will
529 529
    /// be large (e.g. it will contain millions of nodes and/or arcs),
530 530
    /// then it is worth reserving space for this amount before starting
531 531
    /// to build the digraph.
532 532
    /// \sa reserveNode()
533 533
    void reserveArc(int m) { arcs.reserve(m); };
534 534

	
535 535
    /// \brief Class to make a snapshot of the digraph and restore
536 536
    /// it later.
537 537
    ///
538 538
    /// Class to make a snapshot of the digraph and restore it later.
539 539
    ///
540 540
    /// The newly added nodes and arcs can be removed using the
541 541
    /// restore() function.
542 542
    ///
543 543
    /// \note After a state is restored, you cannot restore a later state, 
544 544
    /// i.e. you cannot add the removed nodes and arcs again using
545 545
    /// another Snapshot instance.
546 546
    ///
547 547
    /// \warning Node and arc deletions and other modifications (e.g.
548 548
    /// reversing, contracting, splitting arcs or nodes) cannot be
549 549
    /// restored. These events invalidate the snapshot.
550 550
    /// However the arcs and nodes that were added to the digraph after
551 551
    /// making the current snapshot can be removed without invalidating it.
552 552
    class Snapshot {
553 553
    protected:
554 554

	
555 555
      typedef Parent::NodeNotifier NodeNotifier;
556 556

	
557 557
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
558 558
      public:
559 559

	
560 560
        NodeObserverProxy(Snapshot& _snapshot)
561 561
          : snapshot(_snapshot) {}
562 562

	
563 563
        using NodeNotifier::ObserverBase::attach;
564 564
        using NodeNotifier::ObserverBase::detach;
565 565
        using NodeNotifier::ObserverBase::attached;
566 566

	
567 567
      protected:
568 568

	
569 569
        virtual void add(const Node& node) {
570 570
          snapshot.addNode(node);
571 571
        }
572 572
        virtual void add(const std::vector<Node>& nodes) {
573 573
          for (int i = nodes.size() - 1; i >= 0; ++i) {
574 574
            snapshot.addNode(nodes[i]);
575 575
          }
576 576
        }
577 577
        virtual void erase(const Node& node) {
578 578
          snapshot.eraseNode(node);
579 579
        }
580 580
        virtual void erase(const std::vector<Node>& nodes) {
581 581
          for (int i = 0; i < int(nodes.size()); ++i) {
582 582
            snapshot.eraseNode(nodes[i]);
583 583
          }
584 584
        }
585 585
        virtual void build() {
586 586
          Node node;
587 587
          std::vector<Node> nodes;
588 588
          for (notifier()->first(node); node != INVALID;
589 589
               notifier()->next(node)) {
590 590
            nodes.push_back(node);
591 591
          }
592 592
          for (int i = nodes.size() - 1; i >= 0; --i) {
593 593
            snapshot.addNode(nodes[i]);
594 594
          }
595 595
        }
596 596
        virtual void clear() {
597 597
          Node node;
598 598
          for (notifier()->first(node); node != INVALID;
599 599
               notifier()->next(node)) {
600 600
            snapshot.eraseNode(node);
601 601
          }
602 602
        }
603 603

	
604 604
        Snapshot& snapshot;
605 605
      };
606 606

	
607 607
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
608 608
      public:
609 609

	
610 610
        ArcObserverProxy(Snapshot& _snapshot)
611 611
          : snapshot(_snapshot) {}
612 612

	
613 613
        using ArcNotifier::ObserverBase::attach;
614 614
        using ArcNotifier::ObserverBase::detach;
615 615
        using ArcNotifier::ObserverBase::attached;
616 616

	
617 617
      protected:
618 618

	
619 619
        virtual void add(const Arc& arc) {
620 620
          snapshot.addArc(arc);
621 621
        }
622 622
        virtual void add(const std::vector<Arc>& arcs) {
623 623
          for (int i = arcs.size() - 1; i >= 0; ++i) {
624 624
            snapshot.addArc(arcs[i]);
625 625
          }
626 626
        }
627 627
        virtual void erase(const Arc& arc) {
628 628
          snapshot.eraseArc(arc);
629 629
        }
630 630
        virtual void erase(const std::vector<Arc>& arcs) {
631 631
          for (int i = 0; i < int(arcs.size()); ++i) {
632 632
            snapshot.eraseArc(arcs[i]);
633 633
          }
634 634
        }
635 635
        virtual void build() {
636 636
          Arc arc;
637 637
          std::vector<Arc> arcs;
638 638
          for (notifier()->first(arc); arc != INVALID;
639 639
               notifier()->next(arc)) {
640 640
            arcs.push_back(arc);
641 641
          }
642 642
          for (int i = arcs.size() - 1; i >= 0; --i) {
643 643
            snapshot.addArc(arcs[i]);
644 644
          }
645 645
        }
646 646
        virtual void clear() {
647 647
          Arc arc;
648 648
          for (notifier()->first(arc); arc != INVALID;
649 649
               notifier()->next(arc)) {
650 650
            snapshot.eraseArc(arc);
651 651
          }
652 652
        }
653 653

	
654 654
        Snapshot& snapshot;
655 655
      };
656 656

	
657 657
      ListDigraph *digraph;
658 658

	
659 659
      NodeObserverProxy node_observer_proxy;
660 660
      ArcObserverProxy arc_observer_proxy;
661 661

	
662 662
      std::list<Node> added_nodes;
663 663
      std::list<Arc> added_arcs;
664 664

	
665 665

	
666 666
      void addNode(const Node& node) {
667 667
        added_nodes.push_front(node);
668 668
      }
669 669
      void eraseNode(const Node& node) {
670 670
        std::list<Node>::iterator it =
671 671
          std::find(added_nodes.begin(), added_nodes.end(), node);
672 672
        if (it == added_nodes.end()) {
673 673
          clear();
674 674
          arc_observer_proxy.detach();
675 675
          throw NodeNotifier::ImmediateDetach();
676 676
        } else {
677 677
          added_nodes.erase(it);
678 678
        }
679 679
      }
680 680

	
681 681
      void addArc(const Arc& arc) {
682 682
        added_arcs.push_front(arc);
683 683
      }
684 684
      void eraseArc(const Arc& arc) {
685 685
        std::list<Arc>::iterator it =
686 686
          std::find(added_arcs.begin(), added_arcs.end(), arc);
687 687
        if (it == added_arcs.end()) {
688 688
          clear();
689 689
          node_observer_proxy.detach();
690 690
          throw ArcNotifier::ImmediateDetach();
691 691
        } else {
692 692
          added_arcs.erase(it);
693 693
        }
694 694
      }
695 695

	
696 696
      void attach(ListDigraph &_digraph) {
697 697
        digraph = &_digraph;
698 698
        node_observer_proxy.attach(digraph->notifier(Node()));
699 699
        arc_observer_proxy.attach(digraph->notifier(Arc()));
700 700
      }
701 701

	
702 702
      void detach() {
703 703
        node_observer_proxy.detach();
704 704
        arc_observer_proxy.detach();
705 705
      }
706 706

	
707 707
      bool attached() const {
708 708
        return node_observer_proxy.attached();
709 709
      }
710 710

	
711 711
      void clear() {
712 712
        added_nodes.clear();
713 713
        added_arcs.clear();
714 714
      }
715 715

	
716 716
    public:
717 717

	
718 718
      /// \brief Default constructor.
719 719
      ///
720 720
      /// Default constructor.
721 721
      /// You have to call save() to actually make a snapshot.
722 722
      Snapshot()
723 723
        : digraph(0), node_observer_proxy(*this),
724 724
          arc_observer_proxy(*this) {}
725 725

	
726 726
      /// \brief Constructor that immediately makes a snapshot.
727 727
      ///
728 728
      /// This constructor immediately makes a snapshot of the given digraph.
729 729
      Snapshot(ListDigraph &gr)
730 730
        : node_observer_proxy(*this),
731 731
          arc_observer_proxy(*this) {
732 732
        attach(gr);
733 733
      }
734 734

	
735 735
      /// \brief Make a snapshot.
736 736
      ///
737 737
      /// This function makes a snapshot of the given digraph.
738 738
      /// It can be called more than once. In case of a repeated
739 739
      /// call, the previous snapshot gets lost.
740 740
      void save(ListDigraph &gr) {
741 741
        if (attached()) {
742 742
          detach();
743 743
          clear();
744 744
        }
745 745
        attach(gr);
746 746
      }
747 747

	
748 748
      /// \brief Undo the changes until the last snapshot.
749 749
      ///
750 750
      /// This function undos the changes until the last snapshot
751 751
      /// created by save() or Snapshot(ListDigraph&).
752 752
      void restore() {
753 753
        detach();
754 754
        for(std::list<Arc>::iterator it = added_arcs.begin();
755 755
            it != added_arcs.end(); ++it) {
756 756
          digraph->erase(*it);
757 757
        }
758 758
        for(std::list<Node>::iterator it = added_nodes.begin();
759 759
            it != added_nodes.end(); ++it) {
760 760
          digraph->erase(*it);
761 761
        }
762 762
        clear();
763 763
      }
764 764

	
765 765
      /// \brief Returns \c true if the snapshot is valid.
766 766
      ///
767 767
      /// This function returns \c true if the snapshot is valid.
768 768
      bool valid() const {
769 769
        return attached();
770 770
      }
771 771
    };
772 772

	
773 773
  };
774 774

	
775 775
  ///@}
776 776

	
777 777
  class ListGraphBase {
778 778

	
779 779
  protected:
780 780

	
781 781
    struct NodeT {
782 782
      int first_out;
783 783
      int prev, next;
784 784
    };
785 785

	
786 786
    struct ArcT {
787 787
      int target;
788 788
      int prev_out, next_out;
789 789
    };
790 790

	
791 791
    std::vector<NodeT> nodes;
792 792

	
793 793
    int first_node;
794 794

	
795 795
    int first_free_node;
796 796

	
797 797
    std::vector<ArcT> arcs;
798 798

	
799 799
    int first_free_arc;
800 800

	
801 801
  public:
802 802

	
803 803
    typedef ListGraphBase Graph;
804 804

	
805 805
    class Node {
806 806
      friend class ListGraphBase;
807 807
    protected:
808 808

	
809 809
      int id;
810 810
      explicit Node(int pid) { id = pid;}
811 811

	
812 812
    public:
813 813
      Node() {}
814 814
      Node (Invalid) { id = -1; }
815 815
      bool operator==(const Node& node) const {return id == node.id;}
816 816
      bool operator!=(const Node& node) const {return id != node.id;}
817 817
      bool operator<(const Node& node) const {return id < node.id;}
818 818
    };
819 819

	
820 820
    class Edge {
821 821
      friend class ListGraphBase;
822 822
    protected:
823 823

	
824 824
      int id;
825 825
      explicit Edge(int pid) { id = pid;}
826 826

	
827 827
    public:
828 828
      Edge() {}
829 829
      Edge (Invalid) { id = -1; }
830 830
      bool operator==(const Edge& edge) const {return id == edge.id;}
831 831
      bool operator!=(const Edge& edge) const {return id != edge.id;}
832 832
      bool operator<(const Edge& edge) const {return id < edge.id;}
833 833
    };
834 834

	
835 835
    class Arc {
836 836
      friend class ListGraphBase;
837 837
    protected:
838 838

	
839 839
      int id;
840 840
      explicit Arc(int pid) { id = pid;}
841 841

	
842 842
    public:
843 843
      operator Edge() const {
844 844
        return id != -1 ? edgeFromId(id / 2) : INVALID;
845 845
      }
846 846

	
847 847
      Arc() {}
848 848
      Arc (Invalid) { id = -1; }
849 849
      bool operator==(const Arc& arc) const {return id == arc.id;}
850 850
      bool operator!=(const Arc& arc) const {return id != arc.id;}
851 851
      bool operator<(const Arc& arc) const {return id < arc.id;}
852 852
    };
853 853

	
854 854
    ListGraphBase()
855 855
      : nodes(), first_node(-1),
856 856
        first_free_node(-1), arcs(), first_free_arc(-1) {}
857 857

	
858 858

	
859 859
    int maxNodeId() const { return nodes.size()-1; }
860 860
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
861 861
    int maxArcId() const { return arcs.size()-1; }
862 862

	
863 863
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
864 864
    Node target(Arc e) const { return Node(arcs[e.id].target); }
865 865

	
866 866
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
867 867
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
868 868

	
869 869
    static bool direction(Arc e) {
870 870
      return (e.id & 1) == 1;
871 871
    }
872 872

	
873 873
    static Arc direct(Edge e, bool d) {
874 874
      return Arc(e.id * 2 + (d ? 1 : 0));
875 875
    }
876 876

	
877 877
    void first(Node& node) const {
878 878
      node.id = first_node;
879 879
    }
880 880

	
881 881
    void next(Node& node) const {
882 882
      node.id = nodes[node.id].next;
883 883
    }
884 884

	
885 885
    void first(Arc& e) const {
886 886
      int n = first_node;
887 887
      while (n != -1 && nodes[n].first_out == -1) {
888 888
        n = nodes[n].next;
889 889
      }
890 890
      e.id = (n == -1) ? -1 : nodes[n].first_out;
891 891
    }
892 892

	
893 893
    void next(Arc& e) const {
894 894
      if (arcs[e.id].next_out != -1) {
895 895
        e.id = arcs[e.id].next_out;
896 896
      } else {
897 897
        int n = nodes[arcs[e.id ^ 1].target].next;
898 898
        while(n != -1 && nodes[n].first_out == -1) {
899 899
          n = nodes[n].next;
900 900
        }
901 901
        e.id = (n == -1) ? -1 : nodes[n].first_out;
902 902
      }
903 903
    }
904 904

	
905 905
    void first(Edge& e) const {
906 906
      int n = first_node;
907 907
      while (n != -1) {
908 908
        e.id = nodes[n].first_out;
909 909
        while ((e.id & 1) != 1) {
910 910
          e.id = arcs[e.id].next_out;
911 911
        }
912 912
        if (e.id != -1) {
913 913
          e.id /= 2;
914 914
          return;
915 915
        }
916 916
        n = nodes[n].next;
917 917
      }
918 918
      e.id = -1;
919 919
    }
920 920

	
921 921
    void next(Edge& e) const {
922 922
      int n = arcs[e.id * 2].target;
923 923
      e.id = arcs[(e.id * 2) | 1].next_out;
924 924
      while ((e.id & 1) != 1) {
925 925
        e.id = arcs[e.id].next_out;
926 926
      }
927 927
      if (e.id != -1) {
928 928
        e.id /= 2;
929 929
        return;
930 930
      }
931 931
      n = nodes[n].next;
932 932
      while (n != -1) {
933 933
        e.id = nodes[n].first_out;
934 934
        while ((e.id & 1) != 1) {
935 935
          e.id = arcs[e.id].next_out;
936 936
        }
937 937
        if (e.id != -1) {
938 938
          e.id /= 2;
939 939
          return;
940 940
        }
941 941
        n = nodes[n].next;
942 942
      }
943 943
      e.id = -1;
944 944
    }
945 945

	
946 946
    void firstOut(Arc &e, const Node& v) const {
947 947
      e.id = nodes[v.id].first_out;
948 948
    }
949 949
    void nextOut(Arc &e) const {
950 950
      e.id = arcs[e.id].next_out;
951 951
    }
952 952

	
953 953
    void firstIn(Arc &e, const Node& v) const {
954 954
      e.id = ((nodes[v.id].first_out) ^ 1);
955 955
      if (e.id == -2) e.id = -1;
956 956
    }
957 957
    void nextIn(Arc &e) const {
958 958
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
959 959
      if (e.id == -2) e.id = -1;
960 960
    }
961 961

	
962 962
    void firstInc(Edge &e, bool& d, const Node& v) const {
963 963
      int a = nodes[v.id].first_out;
964 964
      if (a != -1 ) {
965 965
        e.id = a / 2;
966 966
        d = ((a & 1) == 1);
967 967
      } else {
968 968
        e.id = -1;
969 969
        d = true;
970 970
      }
971 971
    }
972 972
    void nextInc(Edge &e, bool& d) const {
973 973
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
974 974
      if (a != -1 ) {
975 975
        e.id = a / 2;
976 976
        d = ((a & 1) == 1);
977 977
      } else {
978 978
        e.id = -1;
979 979
        d = true;
980 980
      }
981 981
    }
982 982

	
983 983
    static int id(Node v) { return v.id; }
984 984
    static int id(Arc e) { return e.id; }
985 985
    static int id(Edge e) { return e.id; }
986 986

	
987 987
    static Node nodeFromId(int id) { return Node(id);}
988 988
    static Arc arcFromId(int id) { return Arc(id);}
989 989
    static Edge edgeFromId(int id) { return Edge(id);}
990 990

	
991 991
    bool valid(Node n) const {
992 992
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
993 993
        nodes[n.id].prev != -2;
994 994
    }
995 995

	
996 996
    bool valid(Arc a) const {
997 997
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
998 998
        arcs[a.id].prev_out != -2;
999 999
    }
1000 1000

	
1001 1001
    bool valid(Edge e) const {
1002 1002
      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1003 1003
        arcs[2 * e.id].prev_out != -2;
1004 1004
    }
1005 1005

	
1006 1006
    Node addNode() {
1007 1007
      int n;
1008 1008

	
1009 1009
      if(first_free_node==-1) {
1010 1010
        n = nodes.size();
1011 1011
        nodes.push_back(NodeT());
1012 1012
      } else {
1013 1013
        n = first_free_node;
1014 1014
        first_free_node = nodes[n].next;
1015 1015
      }
1016 1016

	
1017 1017
      nodes[n].next = first_node;
1018 1018
      if (first_node != -1) nodes[first_node].prev = n;
1019 1019
      first_node = n;
1020 1020
      nodes[n].prev = -1;
1021 1021

	
1022 1022
      nodes[n].first_out = -1;
1023 1023

	
1024 1024
      return Node(n);
1025 1025
    }
1026 1026

	
1027 1027
    Edge addEdge(Node u, Node v) {
1028 1028
      int n;
1029 1029

	
1030 1030
      if (first_free_arc == -1) {
1031 1031
        n = arcs.size();
1032 1032
        arcs.push_back(ArcT());
1033 1033
        arcs.push_back(ArcT());
1034 1034
      } else {
1035 1035
        n = first_free_arc;
1036 1036
        first_free_arc = arcs[n].next_out;
1037 1037
      }
1038 1038

	
1039 1039
      arcs[n].target = u.id;
1040 1040
      arcs[n | 1].target = v.id;
1041 1041

	
1042 1042
      arcs[n].next_out = nodes[v.id].first_out;
1043 1043
      if (nodes[v.id].first_out != -1) {
1044 1044
        arcs[nodes[v.id].first_out].prev_out = n;
1045 1045
      }
1046 1046
      arcs[n].prev_out = -1;
1047 1047
      nodes[v.id].first_out = n;
1048 1048

	
1049 1049
      arcs[n | 1].next_out = nodes[u.id].first_out;
1050 1050
      if (nodes[u.id].first_out != -1) {
1051 1051
        arcs[nodes[u.id].first_out].prev_out = (n | 1);
1052 1052
      }
1053 1053
      arcs[n | 1].prev_out = -1;
1054 1054
      nodes[u.id].first_out = (n | 1);
1055 1055

	
1056 1056
      return Edge(n / 2);
1057 1057
    }
1058 1058

	
1059 1059
    void erase(const Node& node) {
1060 1060
      int n = node.id;
1061 1061

	
1062 1062
      if(nodes[n].next != -1) {
1063 1063
        nodes[nodes[n].next].prev = nodes[n].prev;
1064 1064
      }
1065 1065

	
1066 1066
      if(nodes[n].prev != -1) {
1067 1067
        nodes[nodes[n].prev].next = nodes[n].next;
1068 1068
      } else {
1069 1069
        first_node = nodes[n].next;
1070 1070
      }
1071 1071

	
1072 1072
      nodes[n].next = first_free_node;
1073 1073
      first_free_node = n;
1074 1074
      nodes[n].prev = -2;
1075 1075
    }
1076 1076

	
1077 1077
    void erase(const Edge& edge) {
1078 1078
      int n = edge.id * 2;
1079 1079

	
1080 1080
      if (arcs[n].next_out != -1) {
1081 1081
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1082 1082
      }
1083 1083

	
1084 1084
      if (arcs[n].prev_out != -1) {
1085 1085
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1086 1086
      } else {
1087 1087
        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1088 1088
      }
1089 1089

	
1090 1090
      if (arcs[n | 1].next_out != -1) {
1091 1091
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1092 1092
      }
1093 1093

	
1094 1094
      if (arcs[n | 1].prev_out != -1) {
1095 1095
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1096 1096
      } else {
1097 1097
        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1098 1098
      }
1099 1099

	
1100 1100
      arcs[n].next_out = first_free_arc;
1101 1101
      first_free_arc = n;
1102 1102
      arcs[n].prev_out = -2;
1103 1103
      arcs[n | 1].prev_out = -2;
1104 1104

	
1105 1105
    }
1106 1106

	
1107 1107
    void clear() {
1108 1108
      arcs.clear();
1109 1109
      nodes.clear();
1110 1110
      first_node = first_free_node = first_free_arc = -1;
1111 1111
    }
1112 1112

	
1113 1113
  protected:
1114 1114

	
1115 1115
    void changeV(Edge e, Node n) {
1116 1116
      if(arcs[2 * e.id].next_out != -1) {
1117 1117
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1118 1118
      }
1119 1119
      if(arcs[2 * e.id].prev_out != -1) {
1120 1120
        arcs[arcs[2 * e.id].prev_out].next_out =
1121 1121
          arcs[2 * e.id].next_out;
1122 1122
      } else {
1123 1123
        nodes[arcs[(2 * e.id) | 1].target].first_out =
1124 1124
          arcs[2 * e.id].next_out;
1125 1125
      }
1126 1126

	
1127 1127
      if (nodes[n.id].first_out != -1) {
1128 1128
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1129 1129
      }
1130 1130
      arcs[(2 * e.id) | 1].target = n.id;
1131 1131
      arcs[2 * e.id].prev_out = -1;
1132 1132
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1133 1133
      nodes[n.id].first_out = 2 * e.id;
1134 1134
    }
1135 1135

	
1136 1136
    void changeU(Edge e, Node n) {
1137 1137
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1138 1138
        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1139 1139
          arcs[(2 * e.id) | 1].prev_out;
1140 1140
      }
1141 1141
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1142 1142
        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1143 1143
          arcs[(2 * e.id) | 1].next_out;
1144 1144
      } else {
1145 1145
        nodes[arcs[2 * e.id].target].first_out =
1146 1146
          arcs[(2 * e.id) | 1].next_out;
1147 1147
      }
1148 1148

	
1149 1149
      if (nodes[n.id].first_out != -1) {
1150 1150
        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1151 1151
      }
1152 1152
      arcs[2 * e.id].target = n.id;
1153 1153
      arcs[(2 * e.id) | 1].prev_out = -1;
1154 1154
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1155 1155
      nodes[n.id].first_out = ((2 * e.id) | 1);
1156 1156
    }
1157 1157

	
1158 1158
  };
1159 1159

	
1160 1160
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1161 1161

	
1162 1162

	
1163 1163
  /// \addtogroup graphs
1164 1164
  /// @{
1165 1165

	
1166 1166
  ///A general undirected graph structure.
1167 1167

	
1168 1168
  ///\ref ListGraph is a versatile and fast undirected graph
1169 1169
  ///implementation based on linked lists that are stored in
1170 1170
  ///\c std::vector structures.
1171 1171
  ///
1172 1172
  ///This type fully conforms to the \ref concepts::Graph "Graph concept"
1173 1173
  ///and it also provides several useful additional functionalities.
1174 1174
  ///Most of its member functions and nested classes are documented
1175 1175
  ///only in the concept class.
1176 1176
  ///
1177 1177
  ///\sa concepts::Graph
1178 1178
  ///\sa ListDigraph
1179 1179
  class ListGraph : public ExtendedListGraphBase {
1180 1180
    typedef ExtendedListGraphBase Parent;
1181 1181

	
1182 1182
  private:
1183 1183
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
1184 1184
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1185 1185
    /// \brief Assignment of a graph to another one is \e not allowed.
1186 1186
    /// Use GraphCopy instead.
1187 1187
    void operator=(const ListGraph &) {}
1188 1188
  public:
1189 1189
    /// Constructor
1190 1190

	
1191 1191
    /// Constructor.
1192 1192
    ///
1193 1193
    ListGraph() {}
1194 1194

	
1195 1195
    typedef Parent::OutArcIt IncEdgeIt;
1196 1196

	
1197 1197
    /// \brief Add a new node to the graph.
1198 1198
    ///
1199 1199
    /// This function adds a new node to the graph.
1200 1200
    /// \return The new node.
1201 1201
    Node addNode() { return Parent::addNode(); }
1202 1202

	
1203 1203
    /// \brief Add a new edge to the graph.
1204 1204
    ///
1205 1205
    /// This function adds a new edge to the graph between nodes
1206 1206
    /// \c u and \c v with inherent orientation from node \c u to
1207 1207
    /// node \c v.
1208 1208
    /// \return The new edge.
1209 1209
    Edge addEdge(Node u, Node v) {
1210 1210
      return Parent::addEdge(u, v);
1211 1211
    }
1212 1212

	
1213 1213
    ///\brief Erase a node from the graph.
1214 1214
    ///
1215 1215
    /// This function erases the given node from the graph.
1216 1216
    void erase(Node n) { Parent::erase(n); }
1217 1217

	
1218 1218
    ///\brief Erase an edge from the graph.
1219 1219
    ///
1220 1220
    /// This function erases the given edge from the graph.
1221 1221
    void erase(Edge e) { Parent::erase(e); }
1222 1222
    /// Node validity check
1223 1223

	
1224 1224
    /// This function gives back \c true if the given node is valid,
1225 1225
    /// i.e. it is a real node of the graph.
1226 1226
    ///
1227 1227
    /// \warning A removed node could become valid again if new nodes are
1228 1228
    /// added to the graph.
1229 1229
    bool valid(Node n) const { return Parent::valid(n); }
1230 1230
    /// Edge validity check
1231 1231

	
1232 1232
    /// This function gives back \c true if the given edge is valid,
1233 1233
    /// i.e. it is a real edge of the graph.
1234 1234
    ///
1235 1235
    /// \warning A removed edge could become valid again if new edges are
1236 1236
    /// added to the graph.
1237 1237
    bool valid(Edge e) const { return Parent::valid(e); }
1238 1238
    /// Arc validity check
1239 1239

	
1240 1240
    /// This function gives back \c true if the given arc is valid,
1241 1241
    /// i.e. it is a real arc of the graph.
1242 1242
    ///
1243 1243
    /// \warning A removed arc could become valid again if new edges are
1244 1244
    /// added to the graph.
1245 1245
    bool valid(Arc a) const { return Parent::valid(a); }
1246 1246

	
1247 1247
    /// \brief Change the first node of an edge.
1248 1248
    ///
1249 1249
    /// This function changes the first node of the given edge \c e to \c n.
1250 1250
    ///
1251 1251
    ///\note \c EdgeIt and \c ArcIt iterators referencing the
1252 1252
    ///changed edge are invalidated and all other iterators whose
1253 1253
    ///base node is the changed node are also invalidated.
1254 1254
    ///
1255 1255
    ///\warning This functionality cannot be used together with the
1256 1256
    ///Snapshot feature.
1257 1257
    void changeU(Edge e, Node n) {
1258 1258
      Parent::changeU(e,n);
1259 1259
    }
1260 1260
    /// \brief Change the second node of an edge.
1261 1261
    ///
1262 1262
    /// This function changes the second node of the given edge \c e to \c n.
1263 1263
    ///
1264 1264
    ///\note \c EdgeIt iterators referencing the changed edge remain
1265 1265
    ///valid, however \c ArcIt iterators referencing the changed edge and
1266 1266
    ///all other iterators whose base node is the changed node are also
1267 1267
    ///invalidated.
1268 1268
    ///
1269 1269
    ///\warning This functionality cannot be used together with the
1270 1270
    ///Snapshot feature.
1271 1271
    void changeV(Edge e, Node n) {
1272 1272
      Parent::changeV(e,n);
1273 1273
    }
1274 1274

	
1275 1275
    /// \brief Contract two nodes.
1276 1276
    ///
1277 1277
    /// This function contracts the given two nodes.
1278 1278
    /// Node \c b is removed, but instead of deleting
1279 1279
    /// its incident edges, they are joined to node \c a.
1280 1280
    /// If the last parameter \c r is \c true (this is the default value),
1281 1281
    /// then the newly created loops are removed.
1282 1282
    ///
1283 1283
    /// \note The moved edges are joined to node \c a using changeU()
1284 1284
    /// or changeV(), thus all edge and arc iterators whose base node is
1285 1285
    /// \c b are invalidated.
1286 1286
    /// Moreover all iterators referencing node \c b or the removed 
1287 1287
    /// loops are also invalidated. Other iterators remain valid.
1288 1288
    ///
1289 1289
    ///\warning This functionality cannot be used together with the
1290 1290
    ///Snapshot feature.
1291 1291
    void contract(Node a, Node b, bool r = true) {
1292 1292
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1293 1293
        IncEdgeIt f = e; ++f;
1294 1294
        if (r && runningNode(e) == a) {
1295 1295
          erase(e);
1296 1296
        } else if (u(e) == b) {
1297 1297
          changeU(e, a);
1298 1298
        } else {
1299 1299
          changeV(e, a);
1300 1300
        }
1301 1301
        e = f;
1302 1302
      }
1303 1303
      erase(b);
1304 1304
    }
1305 1305

	
1306 1306
    ///Clear the graph.
1307 1307

	
1308 1308
    ///This function erases all nodes and arcs from the graph.
1309 1309
    ///
1310 1310
    void clear() {
1311 1311
      Parent::clear();
1312 1312
    }
1313 1313

	
1314
    /// Reserve memory for nodes.
1315

	
1316
    /// Using this function, it is possible to avoid superfluous memory
1317
    /// allocation: if you know that the graph you want to build will
1318
    /// be large (e.g. it will contain millions of nodes and/or edges),
1319
    /// then it is worth reserving space for this amount before starting
1320
    /// to build the graph.
1321
    /// \sa reserveEdge()
1322
    void reserveNode(int n) { nodes.reserve(n); };
1323

	
1324
    /// Reserve memory for edges.
1325

	
1326
    /// Using this function, it is possible to avoid superfluous memory
1327
    /// allocation: if you know that the graph you want to build will
1328
    /// be large (e.g. it will contain millions of nodes and/or edges),
1329
    /// then it is worth reserving space for this amount before starting
1330
    /// to build the graph.
1331
    /// \sa reserveNode()
1332
    void reserveEdge(int m) { arcs.reserve(2 * m); };
1333

	
1314 1334
    /// \brief Class to make a snapshot of the graph and restore
1315 1335
    /// it later.
1316 1336
    ///
1317 1337
    /// Class to make a snapshot of the graph and restore it later.
1318 1338
    ///
1319 1339
    /// The newly added nodes and edges can be removed
1320 1340
    /// using the restore() function.
1321 1341
    ///
1322 1342
    /// \note After a state is restored, you cannot restore a later state, 
1323 1343
    /// i.e. you cannot add the removed nodes and edges again using
1324 1344
    /// another Snapshot instance.
1325 1345
    ///
1326 1346
    /// \warning Node and edge deletions and other modifications
1327 1347
    /// (e.g. changing the end-nodes of edges or contracting nodes)
1328 1348
    /// cannot be restored. These events invalidate the snapshot.
1329 1349
    /// However the edges and nodes that were added to the graph after
1330 1350
    /// making the current snapshot can be removed without invalidating it.
1331 1351
    class Snapshot {
1332 1352
    protected:
1333 1353

	
1334 1354
      typedef Parent::NodeNotifier NodeNotifier;
1335 1355

	
1336 1356
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1337 1357
      public:
1338 1358

	
1339 1359
        NodeObserverProxy(Snapshot& _snapshot)
1340 1360
          : snapshot(_snapshot) {}
1341 1361

	
1342 1362
        using NodeNotifier::ObserverBase::attach;
1343 1363
        using NodeNotifier::ObserverBase::detach;
1344 1364
        using NodeNotifier::ObserverBase::attached;
1345 1365

	
1346 1366
      protected:
1347 1367

	
1348 1368
        virtual void add(const Node& node) {
1349 1369
          snapshot.addNode(node);
1350 1370
        }
1351 1371
        virtual void add(const std::vector<Node>& nodes) {
1352 1372
          for (int i = nodes.size() - 1; i >= 0; ++i) {
1353 1373
            snapshot.addNode(nodes[i]);
1354 1374
          }
1355 1375
        }
1356 1376
        virtual void erase(const Node& node) {
1357 1377
          snapshot.eraseNode(node);
1358 1378
        }
1359 1379
        virtual void erase(const std::vector<Node>& nodes) {
1360 1380
          for (int i = 0; i < int(nodes.size()); ++i) {
1361 1381
            snapshot.eraseNode(nodes[i]);
1362 1382
          }
1363 1383
        }
1364 1384
        virtual void build() {
1365 1385
          Node node;
1366 1386
          std::vector<Node> nodes;
1367 1387
          for (notifier()->first(node); node != INVALID;
1368 1388
               notifier()->next(node)) {
1369 1389
            nodes.push_back(node);
1370 1390
          }
1371 1391
          for (int i = nodes.size() - 1; i >= 0; --i) {
1372 1392
            snapshot.addNode(nodes[i]);
1373 1393
          }
1374 1394
        }
1375 1395
        virtual void clear() {
1376 1396
          Node node;
1377 1397
          for (notifier()->first(node); node != INVALID;
1378 1398
               notifier()->next(node)) {
1379 1399
            snapshot.eraseNode(node);
1380 1400
          }
1381 1401
        }
1382 1402

	
1383 1403
        Snapshot& snapshot;
1384 1404
      };
1385 1405

	
1386 1406
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1387 1407
      public:
1388 1408

	
1389 1409
        EdgeObserverProxy(Snapshot& _snapshot)
1390 1410
          : snapshot(_snapshot) {}
1391 1411

	
1392 1412
        using EdgeNotifier::ObserverBase::attach;
1393 1413
        using EdgeNotifier::ObserverBase::detach;
1394 1414
        using EdgeNotifier::ObserverBase::attached;
1395 1415

	
1396 1416
      protected:
1397 1417

	
1398 1418
        virtual void add(const Edge& edge) {
1399 1419
          snapshot.addEdge(edge);
1400 1420
        }
1401 1421
        virtual void add(const std::vector<Edge>& edges) {
1402 1422
          for (int i = edges.size() - 1; i >= 0; ++i) {
1403 1423
            snapshot.addEdge(edges[i]);
1404 1424
          }
1405 1425
        }
1406 1426
        virtual void erase(const Edge& edge) {
1407 1427
          snapshot.eraseEdge(edge);
1408 1428
        }
1409 1429
        virtual void erase(const std::vector<Edge>& edges) {
1410 1430
          for (int i = 0; i < int(edges.size()); ++i) {
1411 1431
            snapshot.eraseEdge(edges[i]);
1412 1432
          }
1413 1433
        }
1414 1434
        virtual void build() {
1415 1435
          Edge edge;
1416 1436
          std::vector<Edge> edges;
1417 1437
          for (notifier()->first(edge); edge != INVALID;
1418 1438
               notifier()->next(edge)) {
1419 1439
            edges.push_back(edge);
1420 1440
          }
1421 1441
          for (int i = edges.size() - 1; i >= 0; --i) {
1422 1442
            snapshot.addEdge(edges[i]);
1423 1443
          }
1424 1444
        }
1425 1445
        virtual void clear() {
1426 1446
          Edge edge;
1427 1447
          for (notifier()->first(edge); edge != INVALID;
1428 1448
               notifier()->next(edge)) {
1429 1449
            snapshot.eraseEdge(edge);
1430 1450
          }
1431 1451
        }
1432 1452

	
1433 1453
        Snapshot& snapshot;
1434 1454
      };
1435 1455

	
1436 1456
      ListGraph *graph;
1437 1457

	
1438 1458
      NodeObserverProxy node_observer_proxy;
1439 1459
      EdgeObserverProxy edge_observer_proxy;
1440 1460

	
1441 1461
      std::list<Node> added_nodes;
1442 1462
      std::list<Edge> added_edges;
1443 1463

	
1444 1464

	
1445 1465
      void addNode(const Node& node) {
1446 1466
        added_nodes.push_front(node);
1447 1467
      }
1448 1468
      void eraseNode(const Node& node) {
1449 1469
        std::list<Node>::iterator it =
1450 1470
          std::find(added_nodes.begin(), added_nodes.end(), node);
1451 1471
        if (it == added_nodes.end()) {
1452 1472
          clear();
1453 1473
          edge_observer_proxy.detach();
1454 1474
          throw NodeNotifier::ImmediateDetach();
1455 1475
        } else {
1456 1476
          added_nodes.erase(it);
1457 1477
        }
1458 1478
      }
1459 1479

	
1460 1480
      void addEdge(const Edge& edge) {
1461 1481
        added_edges.push_front(edge);
1462 1482
      }
1463 1483
      void eraseEdge(const Edge& edge) {
1464 1484
        std::list<Edge>::iterator it =
1465 1485
          std::find(added_edges.begin(), added_edges.end(), edge);
1466 1486
        if (it == added_edges.end()) {
1467 1487
          clear();
1468 1488
          node_observer_proxy.detach();
1469 1489
          throw EdgeNotifier::ImmediateDetach();
1470 1490
        } else {
1471 1491
          added_edges.erase(it);
1472 1492
        }
1473 1493
      }
1474 1494

	
1475 1495
      void attach(ListGraph &_graph) {
1476 1496
        graph = &_graph;
1477 1497
        node_observer_proxy.attach(graph->notifier(Node()));
1478 1498
        edge_observer_proxy.attach(graph->notifier(Edge()));
1479 1499
      }
1480 1500

	
1481 1501
      void detach() {
1482 1502
        node_observer_proxy.detach();
1483 1503
        edge_observer_proxy.detach();
1484 1504
      }
1485 1505

	
1486 1506
      bool attached() const {
1487 1507
        return node_observer_proxy.attached();
1488 1508
      }
1489 1509

	
1490 1510
      void clear() {
1491 1511
        added_nodes.clear();
1492 1512
        added_edges.clear();
1493 1513
      }
1494 1514

	
1495 1515
    public:
1496 1516

	
1497 1517
      /// \brief Default constructor.
1498 1518
      ///
1499 1519
      /// Default constructor.
1500 1520
      /// You have to call save() to actually make a snapshot.
1501 1521
      Snapshot()
1502 1522
        : graph(0), node_observer_proxy(*this),
1503 1523
          edge_observer_proxy(*this) {}
1504 1524

	
1505 1525
      /// \brief Constructor that immediately makes a snapshot.
1506 1526
      ///
1507 1527
      /// This constructor immediately makes a snapshot of the given graph.
1508 1528
      Snapshot(ListGraph &gr)
1509 1529
        : node_observer_proxy(*this),
1510 1530
          edge_observer_proxy(*this) {
1511 1531
        attach(gr);
1512 1532
      }
1513 1533

	
1514 1534
      /// \brief Make a snapshot.
1515 1535
      ///
1516 1536
      /// This function makes a snapshot of the given graph.
1517 1537
      /// It can be called more than once. In case of a repeated
1518 1538
      /// call, the previous snapshot gets lost.
1519 1539
      void save(ListGraph &gr) {
1520 1540
        if (attached()) {
1521 1541
          detach();
1522 1542
          clear();
1523 1543
        }
1524 1544
        attach(gr);
1525 1545
      }
1526 1546

	
1527 1547
      /// \brief Undo the changes until the last snapshot.
1528 1548
      ///
1529 1549
      /// This function undos the changes until the last snapshot
1530 1550
      /// created by save() or Snapshot(ListGraph&).
1531 1551
      void restore() {
1532 1552
        detach();
1533 1553
        for(std::list<Edge>::iterator it = added_edges.begin();
1534 1554
            it != added_edges.end(); ++it) {
1535 1555
          graph->erase(*it);
1536 1556
        }
1537 1557
        for(std::list<Node>::iterator it = added_nodes.begin();
1538 1558
            it != added_nodes.end(); ++it) {
1539 1559
          graph->erase(*it);
1540 1560
        }
1541 1561
        clear();
1542 1562
      }
1543 1563

	
1544 1564
      /// \brief Returns \c true if the snapshot is valid.
1545 1565
      ///
1546 1566
      /// This function returns \c true if the snapshot is valid.
1547 1567
      bool valid() const {
1548 1568
        return attached();
1549 1569
      }
1550 1570
    };
1551 1571
  };
1552 1572

	
1553 1573
  /// @}
1554 1574
} //namespace lemon
1555 1575

	
1556 1576

	
1557 1577
#endif
Ignore white space 140737488355328 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
#ifndef LEMON_SMART_GRAPH_H
20 20
#define LEMON_SMART_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief SmartDigraph and SmartGraph classes.
25 25

	
26 26
#include <vector>
27 27

	
28 28
#include <lemon/core.h>
29 29
#include <lemon/error.h>
30 30
#include <lemon/bits/graph_extender.h>
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  class SmartDigraph;
35 35

	
36 36
  class SmartDigraphBase {
37 37
  protected:
38 38

	
39 39
    struct NodeT
40 40
    {
41 41
      int first_in, first_out;
42 42
      NodeT() {}
43 43
    };
44 44
    struct ArcT
45 45
    {
46 46
      int target, source, next_in, next_out;
47 47
      ArcT() {}
48 48
    };
49 49

	
50 50
    std::vector<NodeT> nodes;
51 51
    std::vector<ArcT> arcs;
52 52

	
53 53
  public:
54 54

	
55 55
    typedef SmartDigraphBase Digraph;
56 56

	
57 57
    class Node;
58 58
    class Arc;
59 59

	
60 60
  public:
61 61

	
62 62
    SmartDigraphBase() : nodes(), arcs() { }
63 63
    SmartDigraphBase(const SmartDigraphBase &_g)
64 64
      : nodes(_g.nodes), arcs(_g.arcs) { }
65 65

	
66 66
    typedef True NodeNumTag;
67 67
    typedef True ArcNumTag;
68 68

	
69 69
    int nodeNum() const { return nodes.size(); }
70 70
    int arcNum() const { return arcs.size(); }
71 71

	
72 72
    int maxNodeId() const { return nodes.size()-1; }
73 73
    int maxArcId() const { return arcs.size()-1; }
74 74

	
75 75
    Node addNode() {
76 76
      int n = nodes.size();
77 77
      nodes.push_back(NodeT());
78 78
      nodes[n].first_in = -1;
79 79
      nodes[n].first_out = -1;
80 80
      return Node(n);
81 81
    }
82 82

	
83 83
    Arc addArc(Node u, Node v) {
84 84
      int n = arcs.size();
85 85
      arcs.push_back(ArcT());
86 86
      arcs[n].source = u._id;
87 87
      arcs[n].target = v._id;
88 88
      arcs[n].next_out = nodes[u._id].first_out;
89 89
      arcs[n].next_in = nodes[v._id].first_in;
90 90
      nodes[u._id].first_out = nodes[v._id].first_in = n;
91 91

	
92 92
      return Arc(n);
93 93
    }
94 94

	
95 95
    void clear() {
96 96
      arcs.clear();
97 97
      nodes.clear();
98 98
    }
99 99

	
100 100
    Node source(Arc a) const { return Node(arcs[a._id].source); }
101 101
    Node target(Arc a) const { return Node(arcs[a._id].target); }
102 102

	
103 103
    static int id(Node v) { return v._id; }
104 104
    static int id(Arc a) { return a._id; }
105 105

	
106 106
    static Node nodeFromId(int id) { return Node(id);}
107 107
    static Arc arcFromId(int id) { return Arc(id);}
108 108

	
109 109
    bool valid(Node n) const {
110 110
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
111 111
    }
112 112
    bool valid(Arc a) const {
113 113
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
114 114
    }
115 115

	
116 116
    class Node {
117 117
      friend class SmartDigraphBase;
118 118
      friend class SmartDigraph;
119 119

	
120 120
    protected:
121 121
      int _id;
122 122
      explicit Node(int id) : _id(id) {}
123 123
    public:
124 124
      Node() {}
125 125
      Node (Invalid) : _id(-1) {}
126 126
      bool operator==(const Node i) const {return _id == i._id;}
127 127
      bool operator!=(const Node i) const {return _id != i._id;}
128 128
      bool operator<(const Node i) const {return _id < i._id;}
129 129
    };
130 130

	
131 131

	
132 132
    class Arc {
133 133
      friend class SmartDigraphBase;
134 134
      friend class SmartDigraph;
135 135

	
136 136
    protected:
137 137
      int _id;
138 138
      explicit Arc(int id) : _id(id) {}
139 139
    public:
140 140
      Arc() { }
141 141
      Arc (Invalid) : _id(-1) {}
142 142
      bool operator==(const Arc i) const {return _id == i._id;}
143 143
      bool operator!=(const Arc i) const {return _id != i._id;}
144 144
      bool operator<(const Arc i) const {return _id < i._id;}
145 145
    };
146 146

	
147 147
    void first(Node& node) const {
148 148
      node._id = nodes.size() - 1;
149 149
    }
150 150

	
151 151
    static void next(Node& node) {
152 152
      --node._id;
153 153
    }
154 154

	
155 155
    void first(Arc& arc) const {
156 156
      arc._id = arcs.size() - 1;
157 157
    }
158 158

	
159 159
    static void next(Arc& arc) {
160 160
      --arc._id;
161 161
    }
162 162

	
163 163
    void firstOut(Arc& arc, const Node& node) const {
164 164
      arc._id = nodes[node._id].first_out;
165 165
    }
166 166

	
167 167
    void nextOut(Arc& arc) const {
168 168
      arc._id = arcs[arc._id].next_out;
169 169
    }
170 170

	
171 171
    void firstIn(Arc& arc, const Node& node) const {
172 172
      arc._id = nodes[node._id].first_in;
173 173
    }
174 174

	
175 175
    void nextIn(Arc& arc) const {
176 176
      arc._id = arcs[arc._id].next_in;
177 177
    }
178 178

	
179 179
  };
180 180

	
181 181
  typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
182 182

	
183 183
  ///\ingroup graphs
184 184
  ///
185 185
  ///\brief A smart directed graph class.
186 186
  ///
187 187
  ///\ref SmartDigraph is a simple and fast digraph implementation.
188 188
  ///It is also quite memory efficient but at the price
189 189
  ///that it does not support node and arc deletion 
190 190
  ///(except for the Snapshot feature).
191 191
  ///
192 192
  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
193 193
  ///and it also provides some additional functionalities.
194 194
  ///Most of its member functions and nested classes are documented
195 195
  ///only in the concept class.
196 196
  ///
197 197
  ///\sa concepts::Digraph
198 198
  ///\sa SmartGraph
199 199
  class SmartDigraph : public ExtendedSmartDigraphBase {
200 200
    typedef ExtendedSmartDigraphBase Parent;
201 201

	
202 202
  private:
203 203
    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
204 204
    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
205 205
    /// \brief Assignment of a digraph to another one is \e not allowed.
206 206
    /// Use DigraphCopy instead.
207 207
    void operator=(const SmartDigraph &) {}
208 208

	
209 209
  public:
210 210

	
211 211
    /// Constructor
212 212

	
213 213
    /// Constructor.
214 214
    ///
215 215
    SmartDigraph() {};
216 216

	
217 217
    ///Add a new node to the digraph.
218 218

	
219 219
    ///This function adds a new node to the digraph.
220 220
    ///\return The new node.
221 221
    Node addNode() { return Parent::addNode(); }
222 222

	
223 223
    ///Add a new arc to the digraph.
224 224

	
225 225
    ///This function adds a new arc to the digraph with source node \c s
226 226
    ///and target node \c t.
227 227
    ///\return The new arc.
228 228
    Arc addArc(Node s, Node t) {
229 229
      return Parent::addArc(s, t);
230 230
    }
231 231

	
232 232
    /// \brief Node validity check
233 233
    ///
234 234
    /// This function gives back \c true if the given node is valid,
235 235
    /// i.e. it is a real node of the digraph.
236 236
    ///
237 237
    /// \warning A removed node (using Snapshot) could become valid again
238 238
    /// if new nodes are added to the digraph.
239 239
    bool valid(Node n) const { return Parent::valid(n); }
240 240

	
241 241
    /// \brief Arc validity check
242 242
    ///
243 243
    /// This function gives back \c true if the given arc is valid,
244 244
    /// i.e. it is a real arc of the digraph.
245 245
    ///
246 246
    /// \warning A removed arc (using Snapshot) could become valid again
247 247
    /// if new arcs are added to the graph.
248 248
    bool valid(Arc a) const { return Parent::valid(a); }
249 249

	
250 250
    ///Split a node.
251 251

	
252 252
    ///This function splits the given node. First, a new node is added
253 253
    ///to the digraph, then the source of each outgoing arc of node \c n
254 254
    ///is moved to this new node.
255 255
    ///If the second parameter \c connect is \c true (this is the default
256 256
    ///value), then a new arc from node \c n to the newly created node
257 257
    ///is also added.
258 258
    ///\return The newly created node.
259 259
    ///
260 260
    ///\note All iterators remain valid.
261 261
    ///
262 262
    ///\warning This functionality cannot be used together with the Snapshot
263 263
    ///feature.
264 264
    Node split(Node n, bool connect = true)
265 265
    {
266 266
      Node b = addNode();
267 267
      nodes[b._id].first_out=nodes[n._id].first_out;
268 268
      nodes[n._id].first_out=-1;
269 269
      for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
270 270
        arcs[i].source=b._id;
271 271
      }
272 272
      if(connect) addArc(n,b);
273 273
      return b;
274 274
    }
275 275

	
276 276
    ///Clear the digraph.
277 277

	
278 278
    ///This function erases all nodes and arcs from the digraph.
279 279
    ///
280 280
    void clear() {
281 281
      Parent::clear();
282 282
    }
283 283

	
284 284
    /// Reserve memory for nodes.
285 285

	
286 286
    /// Using this function, it is possible to avoid superfluous memory
287 287
    /// allocation: if you know that the digraph you want to build will
288 288
    /// be large (e.g. it will contain millions of nodes and/or arcs),
289 289
    /// then it is worth reserving space for this amount before starting
290 290
    /// to build the digraph.
291 291
    /// \sa reserveArc()
292 292
    void reserveNode(int n) { nodes.reserve(n); };
293 293

	
294 294
    /// Reserve memory for arcs.
295 295

	
296 296
    /// Using this function, it is possible to avoid superfluous memory
297 297
    /// allocation: if you know that the digraph you want to build will
298 298
    /// be large (e.g. it will contain millions of nodes and/or arcs),
299 299
    /// then it is worth reserving space for this amount before starting
300 300
    /// to build the digraph.
301 301
    /// \sa reserveNode()
302 302
    void reserveArc(int m) { arcs.reserve(m); };
303 303

	
304 304
  public:
305 305

	
306 306
    class Snapshot;
307 307

	
308 308
  protected:
309 309

	
310 310
    void restoreSnapshot(const Snapshot &s)
311 311
    {
312 312
      while(s.arc_num<arcs.size()) {
313 313
        Arc arc = arcFromId(arcs.size()-1);
314 314
        Parent::notifier(Arc()).erase(arc);
315 315
        nodes[arcs.back().source].first_out=arcs.back().next_out;
316 316
        nodes[arcs.back().target].first_in=arcs.back().next_in;
317 317
        arcs.pop_back();
318 318
      }
319 319
      while(s.node_num<nodes.size()) {
320 320
        Node node = nodeFromId(nodes.size()-1);
321 321
        Parent::notifier(Node()).erase(node);
322 322
        nodes.pop_back();
323 323
      }
324 324
    }
325 325

	
326 326
  public:
327 327

	
328 328
    ///Class to make a snapshot of the digraph and to restore it later.
329 329

	
330 330
    ///Class to make a snapshot of the digraph and to restore it later.
331 331
    ///
332 332
    ///The newly added nodes and arcs can be removed using the
333 333
    ///restore() function. This is the only way for deleting nodes and/or
334 334
    ///arcs from a SmartDigraph structure.
335 335
    ///
336 336
    ///\note After a state is restored, you cannot restore a later state, 
337 337
    ///i.e. you cannot add the removed nodes and arcs again using
338 338
    ///another Snapshot instance.
339 339
    ///
340 340
    ///\warning Node splitting cannot be restored.
341 341
    ///\warning The validity of the snapshot is not stored due to
342 342
    ///performance reasons. If you do not use the snapshot correctly,
343 343
    ///it can cause broken program, invalid or not restored state of
344 344
    ///the digraph or no change.
345 345
    class Snapshot
346 346
    {
347 347
      SmartDigraph *_graph;
348 348
    protected:
349 349
      friend class SmartDigraph;
350 350
      unsigned int node_num;
351 351
      unsigned int arc_num;
352 352
    public:
353 353
      ///Default constructor.
354 354

	
355 355
      ///Default constructor.
356 356
      ///You have to call save() to actually make a snapshot.
357 357
      Snapshot() : _graph(0) {}
358 358
      ///Constructor that immediately makes a snapshot
359 359

	
360 360
      ///This constructor immediately makes a snapshot of the given digraph.
361 361
      ///
362 362
      Snapshot(SmartDigraph &gr) : _graph(&gr) {
363 363
        node_num=_graph->nodes.size();
364 364
        arc_num=_graph->arcs.size();
365 365
      }
366 366

	
367 367
      ///Make a snapshot.
368 368

	
369 369
      ///This function makes a snapshot of the given digraph.
370 370
      ///It can be called more than once. In case of a repeated
371 371
      ///call, the previous snapshot gets lost.
372 372
      void save(SmartDigraph &gr) {
373 373
        _graph=&gr;
374 374
        node_num=_graph->nodes.size();
375 375
        arc_num=_graph->arcs.size();
376 376
      }
377 377

	
378 378
      ///Undo the changes until a snapshot.
379 379

	
380 380
      ///This function undos the changes until the last snapshot
381 381
      ///created by save() or Snapshot(SmartDigraph&).
382 382
      void restore()
383 383
      {
384 384
        _graph->restoreSnapshot(*this);
385 385
      }
386 386
    };
387 387
  };
388 388

	
389 389

	
390 390
  class SmartGraphBase {
391 391

	
392 392
  protected:
393 393

	
394 394
    struct NodeT {
395 395
      int first_out;
396 396
    };
397 397

	
398 398
    struct ArcT {
399 399
      int target;
400 400
      int next_out;
401 401
    };
402 402

	
403 403
    std::vector<NodeT> nodes;
404 404
    std::vector<ArcT> arcs;
405 405

	
406 406
    int first_free_arc;
407 407

	
408 408
  public:
409 409

	
410 410
    typedef SmartGraphBase Graph;
411 411

	
412 412
    class Node;
413 413
    class Arc;
414 414
    class Edge;
415 415

	
416 416
    class Node {
417 417
      friend class SmartGraphBase;
418 418
    protected:
419 419

	
420 420
      int _id;
421 421
      explicit Node(int id) { _id = id;}
422 422

	
423 423
    public:
424 424
      Node() {}
425 425
      Node (Invalid) { _id = -1; }
426 426
      bool operator==(const Node& node) const {return _id == node._id;}
427 427
      bool operator!=(const Node& node) const {return _id != node._id;}
428 428
      bool operator<(const Node& node) const {return _id < node._id;}
429 429
    };
430 430

	
431 431
    class Edge {
432 432
      friend class SmartGraphBase;
433 433
    protected:
434 434

	
435 435
      int _id;
436 436
      explicit Edge(int id) { _id = id;}
437 437

	
438 438
    public:
439 439
      Edge() {}
440 440
      Edge (Invalid) { _id = -1; }
441 441
      bool operator==(const Edge& arc) const {return _id == arc._id;}
442 442
      bool operator!=(const Edge& arc) const {return _id != arc._id;}
443 443
      bool operator<(const Edge& arc) const {return _id < arc._id;}
444 444
    };
445 445

	
446 446
    class Arc {
447 447
      friend class SmartGraphBase;
448 448
    protected:
449 449

	
450 450
      int _id;
451 451
      explicit Arc(int id) { _id = id;}
452 452

	
453 453
    public:
454 454
      operator Edge() const {
455 455
        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
456 456
      }
457 457

	
458 458
      Arc() {}
459 459
      Arc (Invalid) { _id = -1; }
460 460
      bool operator==(const Arc& arc) const {return _id == arc._id;}
461 461
      bool operator!=(const Arc& arc) const {return _id != arc._id;}
462 462
      bool operator<(const Arc& arc) const {return _id < arc._id;}
463 463
    };
464 464

	
465 465

	
466 466

	
467 467
    SmartGraphBase()
468 468
      : nodes(), arcs() {}
469 469

	
470 470
    typedef True NodeNumTag;
471 471
    typedef True EdgeNumTag;
472 472
    typedef True ArcNumTag;
473 473

	
474 474
    int nodeNum() const { return nodes.size(); }
475 475
    int edgeNum() const { return arcs.size() / 2; }
476 476
    int arcNum() const { return arcs.size(); }
477 477

	
478 478
    int maxNodeId() const { return nodes.size()-1; }
479 479
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
480 480
    int maxArcId() const { return arcs.size()-1; }
481 481

	
482 482
    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
483 483
    Node target(Arc e) const { return Node(arcs[e._id].target); }
484 484

	
485 485
    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
486 486
    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
487 487

	
488 488
    static bool direction(Arc e) {
489 489
      return (e._id & 1) == 1;
490 490
    }
491 491

	
492 492
    static Arc direct(Edge e, bool d) {
493 493
      return Arc(e._id * 2 + (d ? 1 : 0));
494 494
    }
495 495

	
496 496
    void first(Node& node) const {
497 497
      node._id = nodes.size() - 1;
498 498
    }
499 499

	
500 500
    void next(Node& node) const {
501 501
      --node._id;
502 502
    }
503 503

	
504 504
    void first(Arc& arc) const {
505 505
      arc._id = arcs.size() - 1;
506 506
    }
507 507

	
508 508
    void next(Arc& arc) const {
509 509
      --arc._id;
510 510
    }
511 511

	
512 512
    void first(Edge& arc) const {
513 513
      arc._id = arcs.size() / 2 - 1;
514 514
    }
515 515

	
516 516
    void next(Edge& arc) const {
517 517
      --arc._id;
518 518
    }
519 519

	
520 520
    void firstOut(Arc &arc, const Node& v) const {
521 521
      arc._id = nodes[v._id].first_out;
522 522
    }
523 523
    void nextOut(Arc &arc) const {
524 524
      arc._id = arcs[arc._id].next_out;
525 525
    }
526 526

	
527 527
    void firstIn(Arc &arc, const Node& v) const {
528 528
      arc._id = ((nodes[v._id].first_out) ^ 1);
529 529
      if (arc._id == -2) arc._id = -1;
530 530
    }
531 531
    void nextIn(Arc &arc) const {
532 532
      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
533 533
      if (arc._id == -2) arc._id = -1;
534 534
    }
535 535

	
536 536
    void firstInc(Edge &arc, bool& d, const Node& v) const {
537 537
      int de = nodes[v._id].first_out;
538 538
      if (de != -1) {
539 539
        arc._id = de / 2;
540 540
        d = ((de & 1) == 1);
541 541
      } else {
542 542
        arc._id = -1;
543 543
        d = true;
544 544
      }
545 545
    }
546 546
    void nextInc(Edge &arc, bool& d) const {
547 547
      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
548 548
      if (de != -1) {
549 549
        arc._id = de / 2;
550 550
        d = ((de & 1) == 1);
551 551
      } else {
552 552
        arc._id = -1;
553 553
        d = true;
554 554
      }
555 555
    }
556 556

	
557 557
    static int id(Node v) { return v._id; }
558 558
    static int id(Arc e) { return e._id; }
559 559
    static int id(Edge e) { return e._id; }
560 560

	
561 561
    static Node nodeFromId(int id) { return Node(id);}
562 562
    static Arc arcFromId(int id) { return Arc(id);}
563 563
    static Edge edgeFromId(int id) { return Edge(id);}
564 564

	
565 565
    bool valid(Node n) const {
566 566
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
567 567
    }
568 568
    bool valid(Arc a) const {
569 569
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
570 570
    }
571 571
    bool valid(Edge e) const {
572 572
      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
573 573
    }
574 574

	
575 575
    Node addNode() {
576 576
      int n = nodes.size();
577 577
      nodes.push_back(NodeT());
578 578
      nodes[n].first_out = -1;
579 579

	
580 580
      return Node(n);
581 581
    }
582 582

	
583 583
    Edge addEdge(Node u, Node v) {
584 584
      int n = arcs.size();
585 585
      arcs.push_back(ArcT());
586 586
      arcs.push_back(ArcT());
587 587

	
588 588
      arcs[n].target = u._id;
589 589
      arcs[n | 1].target = v._id;
590 590

	
591 591
      arcs[n].next_out = nodes[v._id].first_out;
592 592
      nodes[v._id].first_out = n;
593 593

	
594 594
      arcs[n | 1].next_out = nodes[u._id].first_out;
595 595
      nodes[u._id].first_out = (n | 1);
596 596

	
597 597
      return Edge(n / 2);
598 598
    }
599 599

	
600 600
    void clear() {
601 601
      arcs.clear();
602 602
      nodes.clear();
603 603
    }
604 604

	
605 605
  };
606 606

	
607 607
  typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
608 608

	
609 609
  /// \ingroup graphs
610 610
  ///
611 611
  /// \brief A smart undirected graph class.
612 612
  ///
613 613
  /// \ref SmartGraph is a simple and fast graph implementation.
614 614
  /// It is also quite memory efficient but at the price
615 615
  /// that it does not support node and edge deletion 
616 616
  /// (except for the Snapshot feature).
617 617
  ///
618 618
  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
619 619
  /// and it also provides some additional functionalities.
620 620
  /// Most of its member functions and nested classes are documented
621 621
  /// only in the concept class.
622 622
  ///
623 623
  /// \sa concepts::Graph
624 624
  /// \sa SmartDigraph
625 625
  class SmartGraph : public ExtendedSmartGraphBase {
626 626
    typedef ExtendedSmartGraphBase Parent;
627 627

	
628 628
  private:
629 629
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
630 630
    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
631 631
    /// \brief Assignment of a graph to another one is \e not allowed.
632 632
    /// Use GraphCopy instead.
633 633
    void operator=(const SmartGraph &) {}
634 634

	
635 635
  public:
636 636

	
637 637
    /// Constructor
638 638

	
639 639
    /// Constructor.
640 640
    ///
641 641
    SmartGraph() {}
642 642

	
643 643
    /// \brief Add a new node to the graph.
644 644
    ///
645 645
    /// This function adds a new node to the graph.
646 646
    /// \return The new node.
647 647
    Node addNode() { return Parent::addNode(); }
648 648

	
649 649
    /// \brief Add a new edge to the graph.
650 650
    ///
651 651
    /// This function adds a new edge to the graph between nodes
652 652
    /// \c u and \c v with inherent orientation from node \c u to
653 653
    /// node \c v.
654 654
    /// \return The new edge.
655 655
    Edge addEdge(Node u, Node v) {
656 656
      return Parent::addEdge(u, v);
657 657
    }
658 658

	
659 659
    /// \brief Node validity check
660 660
    ///
661 661
    /// This function gives back \c true if the given node is valid,
662 662
    /// i.e. it is a real node of the graph.
663 663
    ///
664 664
    /// \warning A removed node (using Snapshot) could become valid again
665 665
    /// if new nodes are added to the graph.
666 666
    bool valid(Node n) const { return Parent::valid(n); }
667 667

	
668 668
    /// \brief Edge validity check
669 669
    ///
670 670
    /// This function gives back \c true if the given edge is valid,
671 671
    /// i.e. it is a real edge of the graph.
672 672
    ///
673 673
    /// \warning A removed edge (using Snapshot) could become valid again
674 674
    /// if new edges are added to the graph.
675 675
    bool valid(Edge e) const { return Parent::valid(e); }
676 676

	
677 677
    /// \brief Arc validity check
678 678
    ///
679 679
    /// This function gives back \c true if the given arc is valid,
680 680
    /// i.e. it is a real arc of the graph.
681 681
    ///
682 682
    /// \warning A removed arc (using Snapshot) could become valid again
683 683
    /// if new edges are added to the graph.
684 684
    bool valid(Arc a) const { return Parent::valid(a); }
685 685

	
686 686
    ///Clear the graph.
687 687

	
688 688
    ///This function erases all nodes and arcs from the graph.
689 689
    ///
690 690
    void clear() {
691 691
      Parent::clear();
692 692
    }
693 693

	
694
    /// Reserve memory for nodes.
695

	
696
    /// Using this function, it is possible to avoid superfluous memory
697
    /// allocation: if you know that the graph you want to build will
698
    /// be large (e.g. it will contain millions of nodes and/or edges),
699
    /// then it is worth reserving space for this amount before starting
700
    /// to build the graph.
701
    /// \sa reserveEdge()
702
    void reserveNode(int n) { nodes.reserve(n); };
703

	
704
    /// Reserve memory for edges.
705

	
706
    /// Using this function, it is possible to avoid superfluous memory
707
    /// allocation: if you know that the graph you want to build will
708
    /// be large (e.g. it will contain millions of nodes and/or edges),
709
    /// then it is worth reserving space for this amount before starting
710
    /// to build the graph.
711
    /// \sa reserveNode()
712
    void reserveEdge(int m) { arcs.reserve(2 * m); };
713

	
694 714
  public:
695 715

	
696 716
    class Snapshot;
697 717

	
698 718
  protected:
699 719

	
700 720
    void saveSnapshot(Snapshot &s)
701 721
    {
702 722
      s._graph = this;
703 723
      s.node_num = nodes.size();
704 724
      s.arc_num = arcs.size();
705 725
    }
706 726

	
707 727
    void restoreSnapshot(const Snapshot &s)
708 728
    {
709 729
      while(s.arc_num<arcs.size()) {
710 730
        int n=arcs.size()-1;
711 731
        Edge arc=edgeFromId(n/2);
712 732
        Parent::notifier(Edge()).erase(arc);
713 733
        std::vector<Arc> dir;
714 734
        dir.push_back(arcFromId(n));
715 735
        dir.push_back(arcFromId(n-1));
716 736
        Parent::notifier(Arc()).erase(dir);
717 737
        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
718 738
        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
719 739
        arcs.pop_back();
720 740
        arcs.pop_back();
721 741
      }
722 742
      while(s.node_num<nodes.size()) {
723 743
        int n=nodes.size()-1;
724 744
        Node node = nodeFromId(n);
725 745
        Parent::notifier(Node()).erase(node);
726 746
        nodes.pop_back();
727 747
      }
728 748
    }
729 749

	
730 750
  public:
731 751

	
732 752
    ///Class to make a snapshot of the graph and to restore it later.
733 753

	
734 754
    ///Class to make a snapshot of the graph and to restore it later.
735 755
    ///
736 756
    ///The newly added nodes and edges can be removed using the
737 757
    ///restore() function. This is the only way for deleting nodes and/or
738 758
    ///edges from a SmartGraph structure.
739 759
    ///
740 760
    ///\note After a state is restored, you cannot restore a later state, 
741 761
    ///i.e. you cannot add the removed nodes and edges again using
742 762
    ///another Snapshot instance.
743 763
    ///
744 764
    ///\warning The validity of the snapshot is not stored due to
745 765
    ///performance reasons. If you do not use the snapshot correctly,
746 766
    ///it can cause broken program, invalid or not restored state of
747 767
    ///the graph or no change.
748 768
    class Snapshot
749 769
    {
750 770
      SmartGraph *_graph;
751 771
    protected:
752 772
      friend class SmartGraph;
753 773
      unsigned int node_num;
754 774
      unsigned int arc_num;
755 775
    public:
756 776
      ///Default constructor.
757 777

	
758 778
      ///Default constructor.
759 779
      ///You have to call save() to actually make a snapshot.
760 780
      Snapshot() : _graph(0) {}
761 781
      ///Constructor that immediately makes a snapshot
762 782

	
763 783
      /// This constructor immediately makes a snapshot of the given graph.
764 784
      ///
765 785
      Snapshot(SmartGraph &gr) {
766 786
        gr.saveSnapshot(*this);
767 787
      }
768 788

	
769 789
      ///Make a snapshot.
770 790

	
771 791
      ///This function makes a snapshot of the given graph.
772 792
      ///It can be called more than once. In case of a repeated
773 793
      ///call, the previous snapshot gets lost.
774 794
      void save(SmartGraph &gr)
775 795
      {
776 796
        gr.saveSnapshot(*this);
777 797
      }
778 798

	
779 799
      ///Undo the changes until the last snapshot.
780 800

	
781 801
      ///This function undos the changes until the last snapshot
782 802
      ///created by save() or Snapshot(SmartGraph&).
783 803
      void restore()
784 804
      {
785 805
        _graph->restoreSnapshot(*this);
786 806
      }
787 807
    };
788 808
  };
789 809

	
790 810
} //namespace lemon
791 811

	
792 812

	
793 813
#endif //LEMON_SMART_GRAPH_H
Ignore white space 140737488355328 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/full_graph.h>
23 23

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

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

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

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

	
38
  G.reserveNode(3);
39
  G.reserveArc(4);
40

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

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

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

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

	
58 61
  checkGraphConArcList(G, 1);
59 62

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

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

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

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

	
75 78
  checkGraphConArcList(G, 4);
76 79

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

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

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

	
92 95
  Node n4 = G.split(n2);
93 96

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

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

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

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

	
111 114
  checkGraphConArcList(G, 5);
112 115
}
113 116

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

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

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

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

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

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

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

	
144 147
  checkGraphConArcList(G, 5);
145 148

	
146 149
  G.changeSource(a4, n3);
147 150

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

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

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

	
161 164
  checkGraphConArcList(G, 5);
162 165

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

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

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

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

	
177 180
  checkGraphConArcList(G, 5);
178 181

	
179 182
  G.contract(n2, n1);
180 183

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

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

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

	
190 193
  checkGraphConArcList(G, 3);
191 194
}
192 195

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

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

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

	
207 210
  checkGraphNodeList(G, 4);
208 211
  checkGraphArcList(G, 4);
209 212

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

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

	
220 223
  checkGraphConArcList(G, 4);
221 224

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

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

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

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

	
238 241
  checkGraphConArcList(G, 1);
239 242
}
240 243

	
241 244

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

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

	
251 254
  typename Digraph::Snapshot snapshot(G);
252 255

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

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

	
260 263
  snapshot.restore();
261 264

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

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

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

	
273 276
  checkGraphConArcList(G, 4);
274 277

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

	
280 283
  G.addNode();
281 284
  snapshot.save(G);
282 285

	
283 286
  G.addArc(G.addNode(), G.addNode());
284 287

	
285 288
  snapshot.restore();
286 289

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

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

	
295 298
    checkConcept<IDableDigraphComponent<>,
296 299
      IDableDigraphComponent<> >();
297 300

	
298 301
    checkConcept<IterableDigraphComponent<>,
299 302
      IterableDigraphComponent<> >();
300 303

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

	
325 328
template <typename Digraph>
326 329
void checkDigraphValidity() {
327 330
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
328 331
  Digraph g;
329 332

	
330 333
  Node
331 334
    n1 = g.addNode(),
332 335
    n2 = g.addNode(),
333 336
    n3 = g.addNode();
334 337

	
335 338
  Arc
336 339
    e1 = g.addArc(n1, n2),
337 340
    e2 = g.addArc(n2, n3);
338 341

	
339 342
  check(g.valid(n1), "Wrong validity check");
340 343
  check(g.valid(e1), "Wrong validity check");
341 344

	
342 345
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
343 346
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
344 347
}
345 348

	
346 349
template <typename Digraph>
347 350
void checkDigraphValidityErase() {
348 351
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
349 352
  Digraph g;
350 353

	
351 354
  Node
352 355
    n1 = g.addNode(),
353 356
    n2 = g.addNode(),
354 357
    n3 = g.addNode();
355 358

	
356 359
  Arc
357 360
    e1 = g.addArc(n1, n2),
358 361
    e2 = g.addArc(n2, n3);
359 362

	
360 363
  check(g.valid(n1), "Wrong validity check");
361 364
  check(g.valid(e1), "Wrong validity check");
362 365

	
363 366
  g.erase(n1);
364 367

	
365 368
  check(!g.valid(n1), "Wrong validity check");
366 369
  check(g.valid(n2), "Wrong validity check");
367 370
  check(g.valid(n3), "Wrong validity check");
368 371
  check(!g.valid(e1), "Wrong validity check");
369 372
  check(g.valid(e2), "Wrong validity check");
370 373

	
371 374
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
372 375
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
373 376
}
374 377

	
375 378
void checkFullDigraph(int num) {
376 379
  typedef FullDigraph Digraph;
377 380
  DIGRAPH_TYPEDEFS(Digraph);
378 381
  Digraph G(num);
379 382

	
380 383
  checkGraphNodeList(G, num);
381 384
  checkGraphArcList(G, num * num);
382 385

	
383 386
  for (NodeIt n(G); n != INVALID; ++n) {
384 387
    checkGraphOutArcList(G, n, num);
385 388
    checkGraphInArcList(G, n, num);
386 389
  }
387 390

	
388 391
  checkGraphConArcList(G, num * num);
389 392

	
390 393
  checkNodeIds(G);
391 394
  checkArcIds(G);
392 395
  checkGraphNodeMap(G);
393 396
  checkGraphArcMap(G);
394 397

	
395 398
  for (int i = 0; i < G.nodeNum(); ++i) {
396 399
    check(G.index(G(i)) == i, "Wrong index");
397 400
  }
398 401

	
399 402
  for (NodeIt s(G); s != INVALID; ++s) {
400 403
    for (NodeIt t(G); t != INVALID; ++t) {
401 404
      Arc a = G.arc(s, t);
402 405
      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
403 406
    }
404 407
  }
405 408
}
406 409

	
407 410
void checkDigraphs() {
408 411
  { // Checking ListDigraph
409 412
    checkDigraphBuild<ListDigraph>();
410 413
    checkDigraphSplit<ListDigraph>();
411 414
    checkDigraphAlter<ListDigraph>();
412 415
    checkDigraphErase<ListDigraph>();
413 416
    checkDigraphSnapshot<ListDigraph>();
414 417
    checkDigraphValidityErase<ListDigraph>();
415 418
  }
416 419
  { // Checking SmartDigraph
417 420
    checkDigraphBuild<SmartDigraph>();
418 421
    checkDigraphSplit<SmartDigraph>();
419 422
    checkDigraphSnapshot<SmartDigraph>();
420 423
    checkDigraphValidity<SmartDigraph>();
421 424
  }
422 425
  { // Checking FullDigraph
423 426
    checkFullDigraph(8);
424 427
  }
425 428
}
426 429

	
427 430
int main() {
428 431
  checkDigraphs();
429 432
  checkConcepts();
430 433
  return 0;
431 434
}
Ignore white space 140737488355328 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/graph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22 22
#include <lemon/full_graph.h>
23 23
#include <lemon/grid_graph.h>
24 24
#include <lemon/hypercube_graph.h>
25 25

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

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

	
32 32
template <class Graph>
33 33
void checkGraphBuild() {
34 34
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
35 35

	
36 36
  Graph G;
37 37
  checkGraphNodeList(G, 0);
38 38
  checkGraphEdgeList(G, 0);
39 39
  checkGraphArcList(G, 0);
40 40

	
41
  G.reserveNode(3);
42
  G.reserveEdge(3);
43

	
41 44
  Node
42 45
    n1 = G.addNode(),
43 46
    n2 = G.addNode(),
44 47
    n3 = G.addNode();
45 48
  checkGraphNodeList(G, 3);
46 49
  checkGraphEdgeList(G, 0);
47 50
  checkGraphArcList(G, 0);
48 51

	
49 52
  Edge e1 = G.addEdge(n1, n2);
50 53
  check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
51 54
        "Wrong edge");
52 55

	
53 56
  checkGraphNodeList(G, 3);
54 57
  checkGraphEdgeList(G, 1);
55 58
  checkGraphArcList(G, 2);
56 59

	
57 60
  checkGraphIncEdgeArcLists(G, n1, 1);
58 61
  checkGraphIncEdgeArcLists(G, n2, 1);
59 62
  checkGraphIncEdgeArcLists(G, n3, 0);
60 63

	
61 64
  checkGraphConEdgeList(G, 1);
62 65
  checkGraphConArcList(G, 2);
63 66

	
64 67
  Edge e2 = G.addEdge(n2, n1),
65 68
       e3 = G.addEdge(n2, n3);
66 69

	
67 70
  checkGraphNodeList(G, 3);
68 71
  checkGraphEdgeList(G, 3);
69 72
  checkGraphArcList(G, 6);
70 73

	
71 74
  checkGraphIncEdgeArcLists(G, n1, 2);
72 75
  checkGraphIncEdgeArcLists(G, n2, 3);
73 76
  checkGraphIncEdgeArcLists(G, n3, 1);
74 77

	
75 78
  checkGraphConEdgeList(G, 3);
76 79
  checkGraphConArcList(G, 6);
77 80

	
78 81
  checkArcDirections(G);
79 82

	
80 83
  checkNodeIds(G);
81 84
  checkArcIds(G);
82 85
  checkEdgeIds(G);
83 86
  checkGraphNodeMap(G);
84 87
  checkGraphArcMap(G);
85 88
  checkGraphEdgeMap(G);
86 89
}
87 90

	
88 91
template <class Graph>
89 92
void checkGraphAlter() {
90 93
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
91 94

	
92 95
  Graph G;
93 96
  Node n1 = G.addNode(), n2 = G.addNode(),
94 97
       n3 = G.addNode(), n4 = G.addNode();
95 98
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
96 99
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
97 100
       e5 = G.addEdge(n4, n3);
98 101

	
99 102
  checkGraphNodeList(G, 4);
100 103
  checkGraphEdgeList(G, 5);
101 104
  checkGraphArcList(G, 10);
102 105

	
103 106
  // Check changeU() and changeV()
104 107
  if (G.u(e2) == n2) {
105 108
    G.changeU(e2, n3);
106 109
  } else {
107 110
    G.changeV(e2, n3);
108 111
  }
109 112

	
110 113
  checkGraphNodeList(G, 4);
111 114
  checkGraphEdgeList(G, 5);
112 115
  checkGraphArcList(G, 10);
113 116

	
114 117
  checkGraphIncEdgeArcLists(G, n1, 3);
115 118
  checkGraphIncEdgeArcLists(G, n2, 2);
116 119
  checkGraphIncEdgeArcLists(G, n3, 3);
117 120
  checkGraphIncEdgeArcLists(G, n4, 2);
118 121

	
119 122
  checkGraphConEdgeList(G, 5);
120 123
  checkGraphConArcList(G, 10);
121 124

	
122 125
  if (G.u(e2) == n1) {
123 126
    G.changeU(e2, n2);
124 127
  } else {
125 128
    G.changeV(e2, n2);
126 129
  }
127 130

	
128 131
  checkGraphNodeList(G, 4);
129 132
  checkGraphEdgeList(G, 5);
130 133
  checkGraphArcList(G, 10);
131 134

	
132 135
  checkGraphIncEdgeArcLists(G, n1, 2);
133 136
  checkGraphIncEdgeArcLists(G, n2, 3);
134 137
  checkGraphIncEdgeArcLists(G, n3, 3);
135 138
  checkGraphIncEdgeArcLists(G, n4, 2);
136 139

	
137 140
  checkGraphConEdgeList(G, 5);
138 141
  checkGraphConArcList(G, 10);
139 142

	
140 143
  // Check contract()
141 144
  G.contract(n1, n4, false);
142 145

	
143 146
  checkGraphNodeList(G, 3);
144 147
  checkGraphEdgeList(G, 5);
145 148
  checkGraphArcList(G, 10);
146 149

	
147 150
  checkGraphIncEdgeArcLists(G, n1, 4);
148 151
  checkGraphIncEdgeArcLists(G, n2, 3);
149 152
  checkGraphIncEdgeArcLists(G, n3, 3);
150 153

	
151 154
  checkGraphConEdgeList(G, 5);
152 155
  checkGraphConArcList(G, 10);
153 156

	
154 157
  G.contract(n2, n3);
155 158

	
156 159
  checkGraphNodeList(G, 2);
157 160
  checkGraphEdgeList(G, 3);
158 161
  checkGraphArcList(G, 6);
159 162

	
160 163
  checkGraphIncEdgeArcLists(G, n1, 4);
161 164
  checkGraphIncEdgeArcLists(G, n2, 2);
162 165

	
163 166
  checkGraphConEdgeList(G, 3);
164 167
  checkGraphConArcList(G, 6);
165 168
}
166 169

	
167 170
template <class Graph>
168 171
void checkGraphErase() {
169 172
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
170 173

	
171 174
  Graph G;
172 175
  Node n1 = G.addNode(), n2 = G.addNode(),
173 176
       n3 = G.addNode(), n4 = G.addNode();
174 177
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
175 178
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
176 179
       e5 = G.addEdge(n4, n3);
177 180

	
178 181
  // Check edge deletion
179 182
  G.erase(e2);
180 183

	
181 184
  checkGraphNodeList(G, 4);
182 185
  checkGraphEdgeList(G, 4);
183 186
  checkGraphArcList(G, 8);
184 187

	
185 188
  checkGraphIncEdgeArcLists(G, n1, 2);
186 189
  checkGraphIncEdgeArcLists(G, n2, 2);
187 190
  checkGraphIncEdgeArcLists(G, n3, 2);
188 191
  checkGraphIncEdgeArcLists(G, n4, 2);
189 192

	
190 193
  checkGraphConEdgeList(G, 4);
191 194
  checkGraphConArcList(G, 8);
192 195

	
193 196
  // Check node deletion
194 197
  G.erase(n3);
195 198

	
196 199
  checkGraphNodeList(G, 3);
197 200
  checkGraphEdgeList(G, 2);
198 201
  checkGraphArcList(G, 4);
199 202

	
200 203
  checkGraphIncEdgeArcLists(G, n1, 2);
201 204
  checkGraphIncEdgeArcLists(G, n2, 1);
202 205
  checkGraphIncEdgeArcLists(G, n4, 1);
203 206

	
204 207
  checkGraphConEdgeList(G, 2);
205 208
  checkGraphConArcList(G, 4);
206 209
}
207 210

	
208 211

	
209 212
template <class Graph>
210 213
void checkGraphSnapshot() {
211 214
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
212 215

	
213 216
  Graph G;
214 217
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
215 218
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
216 219
       e3 = G.addEdge(n2, n3);
217 220

	
218 221
  checkGraphNodeList(G, 3);
219 222
  checkGraphEdgeList(G, 3);
220 223
  checkGraphArcList(G, 6);
221 224

	
222 225
  typename Graph::Snapshot snapshot(G);
223 226

	
224 227
  Node n = G.addNode();
225 228
  G.addEdge(n3, n);
226 229
  G.addEdge(n, n3);
227 230
  G.addEdge(n3, n2);
228 231

	
229 232
  checkGraphNodeList(G, 4);
230 233
  checkGraphEdgeList(G, 6);
231 234
  checkGraphArcList(G, 12);
232 235

	
233 236
  snapshot.restore();
234 237

	
235 238
  checkGraphNodeList(G, 3);
236 239
  checkGraphEdgeList(G, 3);
237 240
  checkGraphArcList(G, 6);
238 241

	
239 242
  checkGraphIncEdgeArcLists(G, n1, 2);
240 243
  checkGraphIncEdgeArcLists(G, n2, 3);
241 244
  checkGraphIncEdgeArcLists(G, n3, 1);
242 245

	
243 246
  checkGraphConEdgeList(G, 3);
244 247
  checkGraphConArcList(G, 6);
245 248

	
246 249
  checkNodeIds(G);
247 250
  checkEdgeIds(G);
248 251
  checkArcIds(G);
249 252
  checkGraphNodeMap(G);
250 253
  checkGraphEdgeMap(G);
251 254
  checkGraphArcMap(G);
252 255

	
253 256
  G.addNode();
254 257
  snapshot.save(G);
255 258

	
256 259
  G.addEdge(G.addNode(), G.addNode());
257 260

	
258 261
  snapshot.restore();
259 262

	
260 263
  checkGraphNodeList(G, 4);
261 264
  checkGraphEdgeList(G, 3);
262 265
  checkGraphArcList(G, 6);
263 266
}
264 267

	
265 268
void checkFullGraph(int num) {
266 269
  typedef FullGraph Graph;
267 270
  GRAPH_TYPEDEFS(Graph);
268 271

	
269 272
  Graph G(num);
270 273
  checkGraphNodeList(G, num);
271 274
  checkGraphEdgeList(G, num * (num - 1) / 2);
272 275

	
273 276
  for (NodeIt n(G); n != INVALID; ++n) {
274 277
    checkGraphOutArcList(G, n, num - 1);
275 278
    checkGraphInArcList(G, n, num - 1);
276 279
    checkGraphIncEdgeList(G, n, num - 1);
277 280
  }
278 281

	
279 282
  checkGraphConArcList(G, num * (num - 1));
280 283
  checkGraphConEdgeList(G, num * (num - 1) / 2);
281 284

	
282 285
  checkArcDirections(G);
283 286

	
284 287
  checkNodeIds(G);
285 288
  checkArcIds(G);
286 289
  checkEdgeIds(G);
287 290
  checkGraphNodeMap(G);
288 291
  checkGraphArcMap(G);
289 292
  checkGraphEdgeMap(G);
290 293

	
291 294

	
292 295
  for (int i = 0; i < G.nodeNum(); ++i) {
293 296
    check(G.index(G(i)) == i, "Wrong index");
294 297
  }
295 298

	
296 299
  for (NodeIt u(G); u != INVALID; ++u) {
297 300
    for (NodeIt v(G); v != INVALID; ++v) {
298 301
      Edge e = G.edge(u, v);
299 302
      Arc a = G.arc(u, v);
300 303
      if (u == v) {
301 304
        check(e == INVALID, "Wrong edge lookup");
302 305
        check(a == INVALID, "Wrong arc lookup");
303 306
      } else {
304 307
        check((G.u(e) == u && G.v(e) == v) ||
305 308
              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
306 309
        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
307 310
      }
308 311
    }
309 312
  }
310 313
}
311 314

	
312 315
void checkConcepts() {
313 316
  { // Checking graph components
314 317
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
315 318

	
316 319
    checkConcept<IDableGraphComponent<>,
317 320
      IDableGraphComponent<> >();
318 321

	
319 322
    checkConcept<IterableGraphComponent<>,
320 323
      IterableGraphComponent<> >();
321 324

	
322 325
    checkConcept<MappableGraphComponent<>,
323 326
      MappableGraphComponent<> >();
324 327
  }
325 328
  { // Checking skeleton graph
326 329
    checkConcept<Graph, Graph>();
327 330
  }
328 331
  { // Checking ListGraph
329 332
    checkConcept<Graph, ListGraph>();
330 333
    checkConcept<AlterableGraphComponent<>, ListGraph>();
331 334
    checkConcept<ExtendableGraphComponent<>, ListGraph>();
332 335
    checkConcept<ClearableGraphComponent<>, ListGraph>();
333 336
    checkConcept<ErasableGraphComponent<>, ListGraph>();
334 337
  }
335 338
  { // Checking SmartGraph
336 339
    checkConcept<Graph, SmartGraph>();
337 340
    checkConcept<AlterableGraphComponent<>, SmartGraph>();
338 341
    checkConcept<ExtendableGraphComponent<>, SmartGraph>();
339 342
    checkConcept<ClearableGraphComponent<>, SmartGraph>();
340 343
  }
341 344
  { // Checking FullGraph
342 345
    checkConcept<Graph, FullGraph>();
343 346
  }
344 347
  { // Checking GridGraph
345 348
    checkConcept<Graph, GridGraph>();
346 349
  }
347 350
  { // Checking HypercubeGraph
348 351
    checkConcept<Graph, HypercubeGraph>();
349 352
  }
350 353
}
351 354

	
352 355
template <typename Graph>
353 356
void checkGraphValidity() {
354 357
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
355 358
  Graph g;
356 359

	
357 360
  Node
358 361
    n1 = g.addNode(),
359 362
    n2 = g.addNode(),
360 363
    n3 = g.addNode();
361 364

	
362 365
  Edge
363 366
    e1 = g.addEdge(n1, n2),
364 367
    e2 = g.addEdge(n2, n3);
365 368

	
366 369
  check(g.valid(n1), "Wrong validity check");
367 370
  check(g.valid(e1), "Wrong validity check");
368 371
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
369 372

	
370 373
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
371 374
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
372 375
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
373 376
}
374 377

	
375 378
template <typename Graph>
376 379
void checkGraphValidityErase() {
377 380
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
378 381
  Graph g;
379 382

	
380 383
  Node
381 384
    n1 = g.addNode(),
382 385
    n2 = g.addNode(),
383 386
    n3 = g.addNode();
384 387

	
385 388
  Edge
386 389
    e1 = g.addEdge(n1, n2),
387 390
    e2 = g.addEdge(n2, n3);
388 391

	
389 392
  check(g.valid(n1), "Wrong validity check");
390 393
  check(g.valid(e1), "Wrong validity check");
391 394
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
392 395

	
393 396
  g.erase(n1);
394 397

	
395 398
  check(!g.valid(n1), "Wrong validity check");
396 399
  check(g.valid(n2), "Wrong validity check");
397 400
  check(g.valid(n3), "Wrong validity check");
398 401
  check(!g.valid(e1), "Wrong validity check");
399 402
  check(g.valid(e2), "Wrong validity check");
400 403

	
401 404
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
402 405
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
403 406
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
404 407
}
405 408

	
406 409
void checkGridGraph(int width, int height) {
407 410
  typedef GridGraph Graph;
408 411
  GRAPH_TYPEDEFS(Graph);
409 412
  Graph G(width, height);
410 413

	
411 414
  check(G.width() == width, "Wrong column number");
412 415
  check(G.height() == height, "Wrong row number");
413 416

	
414 417
  for (int i = 0; i < width; ++i) {
415 418
    for (int j = 0; j < height; ++j) {
416 419
      check(G.col(G(i, j)) == i, "Wrong column");
417 420
      check(G.row(G(i, j)) == j, "Wrong row");
418 421
      check(G.pos(G(i, j)).x == i, "Wrong column");
419 422
      check(G.pos(G(i, j)).y == j, "Wrong row");
420 423
    }
421 424
  }
422 425

	
423 426
  for (int j = 0; j < height; ++j) {
424 427
    for (int i = 0; i < width - 1; ++i) {
425 428
      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
426 429
      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
427 430
    }
428 431
    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
429 432
  }
430 433

	
431 434
  for (int j = 0; j < height; ++j) {
432 435
    for (int i = 1; i < width; ++i) {
433 436
      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
434 437
      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
435 438
    }
436 439
    check(G.left(G(0, j)) == INVALID, "Wrong left");
437 440
  }
438 441

	
439 442
  for (int i = 0; i < width; ++i) {
440 443
    for (int j = 0; j < height - 1; ++j) {
441 444
      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
442 445
      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
443 446
    }
444 447
    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
445 448
  }
446 449

	
447 450
  for (int i = 0; i < width; ++i) {
448 451
    for (int j = 1; j < height; ++j) {
449 452
      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
450 453
      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
451 454
    }
452 455
    check(G.down(G(i, 0)) == INVALID, "Wrong down");
453 456
  }
454 457

	
455 458
  checkGraphNodeList(G, width * height);
456 459
  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
457 460
  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
458 461

	
459 462
  for (NodeIt n(G); n != INVALID; ++n) {
460 463
    int nb = 4;
461 464
    if (G.col(n) == 0) --nb;
462 465
    if (G.col(n) == width - 1) --nb;
463 466
    if (G.row(n) == 0) --nb;
464 467
    if (G.row(n) == height - 1) --nb;
465 468

	
466 469
    checkGraphOutArcList(G, n, nb);
467 470
    checkGraphInArcList(G, n, nb);
468 471
    checkGraphIncEdgeList(G, n, nb);
469 472
  }
470 473

	
471 474
  checkArcDirections(G);
472 475

	
473 476
  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
474 477
  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
475 478

	
476 479
  checkNodeIds(G);
477 480
  checkArcIds(G);
478 481
  checkEdgeIds(G);
479 482
  checkGraphNodeMap(G);
480 483
  checkGraphArcMap(G);
481 484
  checkGraphEdgeMap(G);
482 485

	
483 486
}
484 487

	
485 488
void checkHypercubeGraph(int dim) {
486 489
  GRAPH_TYPEDEFS(HypercubeGraph);
487 490

	
488 491
  HypercubeGraph G(dim);
489 492
  checkGraphNodeList(G, 1 << dim);
490 493
  checkGraphEdgeList(G, dim * (1 << (dim-1)));
491 494
  checkGraphArcList(G, dim * (1 << dim));
492 495

	
493 496
  Node n = G.nodeFromId(dim);
494 497

	
495 498
  for (NodeIt n(G); n != INVALID; ++n) {
496 499
    checkGraphIncEdgeList(G, n, dim);
497 500
    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
498 501
      check( (G.u(e) == n &&
499 502
              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
500 503
             (G.v(e) == n &&
501 504
              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
502 505
             "Wrong edge or wrong dimension");
503 506
    }
504 507

	
505 508
    checkGraphOutArcList(G, n, dim);
506 509
    for (OutArcIt a(G, n); a != INVALID; ++a) {
507 510
      check(G.source(a) == n &&
508 511
            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
509 512
            "Wrong arc or wrong dimension");
510 513
    }
511 514

	
512 515
    checkGraphInArcList(G, n, dim);
513 516
    for (InArcIt a(G, n); a != INVALID; ++a) {
514 517
      check(G.target(a) == n &&
515 518
            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
516 519
            "Wrong arc or wrong dimension");
517 520
    }
518 521
  }
519 522

	
520 523
  checkGraphConArcList(G, (1 << dim) * dim);
521 524
  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
522 525

	
523 526
  checkArcDirections(G);
524 527

	
525 528
  checkNodeIds(G);
526 529
  checkArcIds(G);
527 530
  checkEdgeIds(G);
528 531
  checkGraphNodeMap(G);
529 532
  checkGraphArcMap(G);
530 533
  checkGraphEdgeMap(G);
531 534
}
532 535

	
533 536
void checkGraphs() {
534 537
  { // Checking ListGraph
535 538
    checkGraphBuild<ListGraph>();
536 539
    checkGraphAlter<ListGraph>();
537 540
    checkGraphErase<ListGraph>();
538 541
    checkGraphSnapshot<ListGraph>();
539 542
    checkGraphValidityErase<ListGraph>();
540 543
  }
541 544
  { // Checking SmartGraph
542 545
    checkGraphBuild<SmartGraph>();
543 546
    checkGraphSnapshot<SmartGraph>();
544 547
    checkGraphValidity<SmartGraph>();
545 548
  }
546 549
  { // Checking FullGraph
547 550
    checkFullGraph(7);
548 551
    checkFullGraph(8);
549 552
  }
550 553
  { // Checking GridGraph
551 554
    checkGridGraph(5, 8);
552 555
    checkGridGraph(8, 5);
553 556
    checkGridGraph(5, 5);
554 557
    checkGridGraph(0, 0);
555 558
    checkGridGraph(1, 1);
556 559
  }
557 560
  { // Checking HypercubeGraph
558 561
    checkHypercubeGraph(1);
559 562
    checkHypercubeGraph(2);
560 563
    checkHypercubeGraph(3);
561 564
    checkHypercubeGraph(4);
562 565
  }
563 566
}
564 567

	
565 568
int main() {
566 569
  checkConcepts();
567 570
  checkGraphs();
568 571
  return 0;
569 572
}
0 comments (0 inline)