gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge bugfix #371 to branch 1.2
0 2 0
merge 1.2
2 files changed with 26 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
... ...
@@ -349,123 +349,125 @@
349 349
        _it = refMap[_item];
350 350
      }
351 351

	
352 352
    private:
353 353
      Item _item;
354 354
      It& _it;
355 355
    };
356 356

	
357 357
    template <typename Digraph, typename Item, typename RefMap, typename Ref>
358 358
    class RefCopy : public MapCopyBase<Digraph, Item, RefMap> {
359 359
    public:
360 360

	
361 361
      RefCopy(Ref& map) : _map(map) {}
362 362

	
363 363
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
364 364
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
365 365
        for (ItemIt it(digraph); it != INVALID; ++it) {
366 366
          _map.set(it, refMap[it]);
367 367
        }
368 368
      }
369 369

	
370 370
    private:
371 371
      Ref& _map;
372 372
    };
373 373

	
374 374
    template <typename Digraph, typename Item, typename RefMap,
375 375
              typename CrossRef>
376 376
    class CrossRefCopy : public MapCopyBase<Digraph, Item, RefMap> {
377 377
    public:
378 378

	
379 379
      CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {}
380 380

	
381 381
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
382 382
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
383 383
        for (ItemIt it(digraph); it != INVALID; ++it) {
384 384
          _cmap.set(refMap[it], it);
385 385
        }
386 386
      }
387 387

	
388 388
    private:
389 389
      CrossRef& _cmap;
390 390
    };
391 391

	
392 392
    template <typename Digraph, typename Enable = void>
393 393
    struct DigraphCopySelector {
394 394
      template <typename From, typename NodeRefMap, typename ArcRefMap>
395 395
      static void copy(const From& from, Digraph &to,
396 396
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
397
        to.clear();
397 398
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
398 399
          nodeRefMap[it] = to.addNode();
399 400
        }
400 401
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
401 402
          arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)],
402 403
                                    nodeRefMap[from.target(it)]);
403 404
        }
404 405
      }
405 406
    };
406 407

	
407 408
    template <typename Digraph>
408 409
    struct DigraphCopySelector<
409 410
      Digraph,
410 411
      typename enable_if<typename Digraph::BuildTag, void>::type>
411 412
    {
412 413
      template <typename From, typename NodeRefMap, typename ArcRefMap>
413 414
      static void copy(const From& from, Digraph &to,
414 415
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
415 416
        to.build(from, nodeRefMap, arcRefMap);
416 417
      }
417 418
    };
418 419

	
419 420
    template <typename Graph, typename Enable = void>
420 421
    struct GraphCopySelector {
421 422
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
422 423
      static void copy(const From& from, Graph &to,
423 424
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
425
        to.clear();
424 426
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
425 427
          nodeRefMap[it] = to.addNode();
426 428
        }
427 429
        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
428 430
          edgeRefMap[it] = to.addEdge(nodeRefMap[from.u(it)],
429 431
                                      nodeRefMap[from.v(it)]);
430 432
        }
431 433
      }
432 434
    };
433 435

	
434 436
    template <typename Graph>
435 437
    struct GraphCopySelector<
436 438
      Graph,
437 439
      typename enable_if<typename Graph::BuildTag, void>::type>
438 440
    {
439 441
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
440 442
      static void copy(const From& from, Graph &to,
441 443
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
442 444
        to.build(from, nodeRefMap, edgeRefMap);
443 445
      }
444 446
    };
445 447

	
446 448
  }
447 449

	
448 450
  /// \brief Class to copy a digraph.
449 451
  ///
450 452
  /// Class to copy a digraph to another digraph (duplicate a digraph). The
451 453
  /// simplest way of using it is through the \c digraphCopy() function.
452 454
  ///
453 455
  /// This class not only make a copy of a digraph, but it can create
454 456
  /// references and cross references between the nodes and arcs of
455 457
  /// the two digraphs, and it can copy maps to use with the newly created
456 458
  /// digraph.
457 459
  ///
458 460
  /// To make a copy from a digraph, first an instance of DigraphCopy
459 461
  /// should be created, then the data belongs to the digraph should
460 462
  /// assigned to copy. In the end, the \c run() member should be
461 463
  /// called.
462 464
  ///
463 465
  /// The next code copies a digraph with several data:
464 466
  ///\code
465 467
  ///  DigraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
466 468
  ///  // Create references for the nodes
467 469
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
468 470
  ///  cg.nodeRef(nr);
469 471
  ///  // Create cross references (inverse) for the arcs
470 472
  ///  NewGraph::ArcMap<OrigGraph::Arc> acr(new_graph);
471 473
  ///  cg.arcCrossRef(acr);
Ignore white space 96 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/smart_graph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/lgf_reader.h>
22 22
#include <lemon/error.h>
23 23

	
24 24
#include "test_tools.h"
25 25

	
26 26
using namespace std;
27 27
using namespace lemon;
28 28

	
29 29
void digraph_copy_test() {
30 30
  const int nn = 10;
31 31

	
32
  // Build a digraph
32 33
  SmartDigraph from;
33 34
  SmartDigraph::NodeMap<int> fnm(from);
34 35
  SmartDigraph::ArcMap<int> fam(from);
35 36
  SmartDigraph::Node fn = INVALID;
36 37
  SmartDigraph::Arc fa = INVALID;
37 38

	
38 39
  std::vector<SmartDigraph::Node> fnv;
39 40
  for (int i = 0; i < nn; ++i) {
40 41
    SmartDigraph::Node node = from.addNode();
41 42
    fnv.push_back(node);
42 43
    fnm[node] = i * i;
43 44
    if (i == 0) fn = node;
44 45
  }
45 46

	
46 47
  for (int i = 0; i < nn; ++i) {
47 48
    for (int j = 0; j < nn; ++j) {
48 49
      SmartDigraph::Arc arc = from.addArc(fnv[i], fnv[j]);
49 50
      fam[arc] = i + j * j;
50 51
      if (i == 0 && j == 0) fa = arc;
51 52
    }
52 53
  }
53 54

	
55
  // Test digraph copy
54 56
  ListDigraph to;
55 57
  ListDigraph::NodeMap<int> tnm(to);
56 58
  ListDigraph::ArcMap<int> tam(to);
57 59
  ListDigraph::Node tn;
58 60
  ListDigraph::Arc ta;
59 61

	
60 62
  SmartDigraph::NodeMap<ListDigraph::Node> nr(from);
61 63
  SmartDigraph::ArcMap<ListDigraph::Arc> er(from);
62 64

	
63 65
  ListDigraph::NodeMap<SmartDigraph::Node> ncr(to);
64 66
  ListDigraph::ArcMap<SmartDigraph::Arc> ecr(to);
65 67

	
66 68
  digraphCopy(from, to).
67 69
    nodeMap(fnm, tnm).arcMap(fam, tam).
68 70
    nodeRef(nr).arcRef(er).
69 71
    nodeCrossRef(ncr).arcCrossRef(ecr).
70 72
    node(fn, tn).arc(fa, ta).run();
73
  
74
  check(countNodes(from) == countNodes(to), "Wrong copy.");
75
  check(countArcs(from) == countArcs(to), "Wrong copy.");
71 76

	
72 77
  for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) {
73 78
    check(ncr[nr[it]] == it, "Wrong copy.");
74 79
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
75 80
  }
76 81

	
77 82
  for (SmartDigraph::ArcIt it(from); it != INVALID; ++it) {
78 83
    check(ecr[er[it]] == it, "Wrong copy.");
79 84
    check(fam[it] == tam[er[it]], "Wrong copy.");
80 85
    check(nr[from.source(it)] == to.source(er[it]), "Wrong copy.");
81 86
    check(nr[from.target(it)] == to.target(er[it]), "Wrong copy.");
82 87
  }
83 88

	
84 89
  for (ListDigraph::NodeIt it(to); it != INVALID; ++it) {
85 90
    check(nr[ncr[it]] == it, "Wrong copy.");
86 91
  }
87 92

	
88 93
  for (ListDigraph::ArcIt it(to); it != INVALID; ++it) {
89 94
    check(er[ecr[it]] == it, "Wrong copy.");
90 95
  }
91 96
  check(tn == nr[fn], "Wrong copy.");
92 97
  check(ta == er[fa], "Wrong copy.");
98

	
99
  // Test repeated copy
100
  digraphCopy(from, to).run();
101
  
102
  check(countNodes(from) == countNodes(to), "Wrong copy.");
103
  check(countArcs(from) == countArcs(to), "Wrong copy.");
93 104
}
94 105

	
95 106
void graph_copy_test() {
96 107
  const int nn = 10;
97 108

	
109
  // Build a graph
98 110
  SmartGraph from;
99 111
  SmartGraph::NodeMap<int> fnm(from);
100 112
  SmartGraph::ArcMap<int> fam(from);
101 113
  SmartGraph::EdgeMap<int> fem(from);
102 114
  SmartGraph::Node fn = INVALID;
103 115
  SmartGraph::Arc fa = INVALID;
104 116
  SmartGraph::Edge fe = INVALID;
105 117

	
106 118
  std::vector<SmartGraph::Node> fnv;
107 119
  for (int i = 0; i < nn; ++i) {
108 120
    SmartGraph::Node node = from.addNode();
109 121
    fnv.push_back(node);
110 122
    fnm[node] = i * i;
111 123
    if (i == 0) fn = node;
112 124
  }
113 125

	
114 126
  for (int i = 0; i < nn; ++i) {
115 127
    for (int j = 0; j < nn; ++j) {
116 128
      SmartGraph::Edge edge = from.addEdge(fnv[i], fnv[j]);
117 129
      fem[edge] = i * i + j * j;
118 130
      fam[from.direct(edge, true)] = i + j * j;
119 131
      fam[from.direct(edge, false)] = i * i + j;
120 132
      if (i == 0 && j == 0) fa = from.direct(edge, true);
121 133
      if (i == 0 && j == 0) fe = edge;
122 134
    }
123 135
  }
124 136

	
137
  // Test graph copy
125 138
  ListGraph to;
126 139
  ListGraph::NodeMap<int> tnm(to);
127 140
  ListGraph::ArcMap<int> tam(to);
128 141
  ListGraph::EdgeMap<int> tem(to);
129 142
  ListGraph::Node tn;
130 143
  ListGraph::Arc ta;
131 144
  ListGraph::Edge te;
132 145

	
133 146
  SmartGraph::NodeMap<ListGraph::Node> nr(from);
134 147
  SmartGraph::ArcMap<ListGraph::Arc> ar(from);
135 148
  SmartGraph::EdgeMap<ListGraph::Edge> er(from);
136 149

	
137 150
  ListGraph::NodeMap<SmartGraph::Node> ncr(to);
138 151
  ListGraph::ArcMap<SmartGraph::Arc> acr(to);
139 152
  ListGraph::EdgeMap<SmartGraph::Edge> ecr(to);
140 153

	
141 154
  graphCopy(from, to).
142 155
    nodeMap(fnm, tnm).arcMap(fam, tam).edgeMap(fem, tem).
143 156
    nodeRef(nr).arcRef(ar).edgeRef(er).
144 157
    nodeCrossRef(ncr).arcCrossRef(acr).edgeCrossRef(ecr).
145 158
    node(fn, tn).arc(fa, ta).edge(fe, te).run();
146 159

	
160
  check(countNodes(from) == countNodes(to), "Wrong copy.");
161
  check(countEdges(from) == countEdges(to), "Wrong copy.");
162
  check(countArcs(from) == countArcs(to), "Wrong copy.");
163

	
147 164
  for (SmartGraph::NodeIt it(from); it != INVALID; ++it) {
148 165
    check(ncr[nr[it]] == it, "Wrong copy.");
149 166
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
150 167
  }
151 168

	
152 169
  for (SmartGraph::ArcIt it(from); it != INVALID; ++it) {
153 170
    check(acr[ar[it]] == it, "Wrong copy.");
154 171
    check(fam[it] == tam[ar[it]], "Wrong copy.");
155 172
    check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
156 173
    check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
157 174
  }
158 175

	
159 176
  for (SmartGraph::EdgeIt it(from); it != INVALID; ++it) {
160 177
    check(ecr[er[it]] == it, "Wrong copy.");
161 178
    check(fem[it] == tem[er[it]], "Wrong copy.");
162 179
    check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
163 180
          "Wrong copy.");
164 181
    check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
165 182
          "Wrong copy.");
166 183
    check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
167 184
          "Wrong copy.");
168 185
  }
169 186

	
170 187
  for (ListGraph::NodeIt it(to); it != INVALID; ++it) {
171 188
    check(nr[ncr[it]] == it, "Wrong copy.");
172 189
  }
173 190

	
174 191
  for (ListGraph::ArcIt it(to); it != INVALID; ++it) {
175 192
    check(ar[acr[it]] == it, "Wrong copy.");
176 193
  }
177 194
  for (ListGraph::EdgeIt it(to); it != INVALID; ++it) {
178 195
    check(er[ecr[it]] == it, "Wrong copy.");
179 196
  }
180 197
  check(tn == nr[fn], "Wrong copy.");
181 198
  check(ta == ar[fa], "Wrong copy.");
182 199
  check(te == er[fe], "Wrong copy.");
200

	
201
  // Test repeated copy
202
  graphCopy(from, to).run();
203
  
204
  check(countNodes(from) == countNodes(to), "Wrong copy.");
205
  check(countEdges(from) == countEdges(to), "Wrong copy.");
206
  check(countArcs(from) == countArcs(to), "Wrong copy.");
183 207
}
184 208

	
185 209

	
186 210
int main() {
187 211
  digraph_copy_test();
188 212
  graph_copy_test();
189 213

	
190 214
  return 0;
191 215
}
0 comments (0 inline)