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 6 line context
... ...
@@ -1266,96 +1266,116 @@
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]);
Ignore white space 96 line context
... ...
@@ -646,96 +646,116 @@
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
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22 22
#include <lemon/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);
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/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>
0 comments (0 inline)