gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add a resize() function to HypercubeGraph (#311) just like the similar functions in other static graph structures, and extend the test files to check these functions.
0 3 0
default
3 files changed with 38 insertions and 1 deletions:
↑ Collapse diff ↑
Show white space 131072 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 HYPERCUBE_GRAPH_H
20 20
#define HYPERCUBE_GRAPH_H
21 21

	
22 22
#include <vector>
23 23
#include <lemon/core.h>
24 24
#include <lemon/assert.h>
25 25
#include <lemon/bits/graph_extender.h>
26 26

	
27 27
///\ingroup graphs
28 28
///\file
29 29
///\brief HypercubeGraph class.
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  class HypercubeGraphBase {
34 34

	
35 35
  public:
36 36

	
37 37
    typedef HypercubeGraphBase Graph;
38 38

	
39 39
    class Node;
40 40
    class Edge;
41 41
    class Arc;
42 42

	
43 43
  public:
44 44

	
45 45
    HypercubeGraphBase() {}
46 46

	
47 47
  protected:
48 48

	
49 49
    void construct(int dim) {
50 50
      LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1.");
51 51
      _dim = dim;
52 52
      _node_num = 1 << dim;
53 53
      _edge_num = dim * (1 << (dim-1));
54 54
    }
55 55

	
56 56
  public:
57 57

	
58 58
    typedef True NodeNumTag;
59 59
    typedef True EdgeNumTag;
60 60
    typedef True ArcNumTag;
61 61

	
62 62
    int nodeNum() const { return _node_num; }
63 63
    int edgeNum() const { return _edge_num; }
64 64
    int arcNum() const { return 2 * _edge_num; }
65 65

	
66 66
    int maxNodeId() const { return _node_num - 1; }
67 67
    int maxEdgeId() const { return _edge_num - 1; }
68 68
    int maxArcId() const { return 2 * _edge_num - 1; }
69 69

	
70 70
    static Node nodeFromId(int id) { return Node(id); }
71 71
    static Edge edgeFromId(int id) { return Edge(id); }
72 72
    static Arc arcFromId(int id) { return Arc(id); }
73 73

	
74 74
    static int id(Node node) { return node._id; }
75 75
    static int id(Edge edge) { return edge._id; }
76 76
    static int id(Arc arc) { return arc._id; }
77 77

	
78 78
    Node u(Edge edge) const {
79 79
      int base = edge._id & ((1 << (_dim-1)) - 1);
80 80
      int k = edge._id >> (_dim-1);
81 81
      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1));
82 82
    }
83 83

	
84 84
    Node v(Edge edge) const {
85 85
      int base = edge._id & ((1 << (_dim-1)) - 1);
86 86
      int k = edge._id >> (_dim-1);
87 87
      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)) | (1 << k);
88 88
    }
89 89

	
90 90
    Node source(Arc arc) const {
91 91
      return (arc._id & 1) == 1 ? u(arc) : v(arc);
92 92
    }
93 93

	
94 94
    Node target(Arc arc) const {
95 95
      return (arc._id & 1) == 1 ? v(arc) : u(arc);
96 96
    }
97 97

	
98 98
    typedef True FindEdgeTag;
99 99
    typedef True FindArcTag;
100 100

	
101 101
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
102 102
      if (prev != INVALID) return INVALID;
103 103
      int d = u._id ^ v._id;
104 104
      int k = 0;
105 105
      if (d == 0) return INVALID;
106 106
      for ( ; (d & 1) == 0; d >>= 1) ++k;
107 107
      if (d >> 1 != 0) return INVALID;
108 108
      return (k << (_dim-1)) | ((u._id >> (k+1)) << k) |
109 109
        (u._id & ((1 << k) - 1));
110 110
    }
111 111

	
112 112
    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
113 113
      Edge edge = findEdge(u, v, prev);
114 114
      if (edge == INVALID) return INVALID;
115 115
      int k = edge._id >> (_dim-1);
116 116
      return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1;
117 117
    }
118 118

	
119 119
    class Node {
120 120
      friend class HypercubeGraphBase;
121 121

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

	
133 133
    class Edge {
134 134
      friend class HypercubeGraphBase;
135 135
      friend class Arc;
136 136

	
137 137
    protected:
138 138
      int _id;
139 139

	
140 140
      Edge(int id) : _id(id) {}
141 141

	
142 142
    public:
143 143
      Edge() {}
144 144
      Edge (Invalid) : _id(-1) {}
145 145
      bool operator==(const Edge edge) const {return _id == edge._id;}
146 146
      bool operator!=(const Edge edge) const {return _id != edge._id;}
147 147
      bool operator<(const Edge edge) const {return _id < edge._id;}
148 148
    };
149 149

	
150 150
    class Arc {
151 151
      friend class HypercubeGraphBase;
152 152

	
153 153
    protected:
154 154
      int _id;
155 155

	
156 156
      Arc(int id) : _id(id) {}
157 157

	
158 158
    public:
159 159
      Arc() {}
160 160
      Arc (Invalid) : _id(-1) {}
161 161
      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
162 162
      bool operator==(const Arc arc) const {return _id == arc._id;}
163 163
      bool operator!=(const Arc arc) const {return _id != arc._id;}
164 164
      bool operator<(const Arc arc) const {return _id < arc._id;}
165 165
    };
166 166

	
167 167
    void first(Node& node) const {
168 168
      node._id = _node_num - 1;
169 169
    }
170 170

	
171 171
    static void next(Node& node) {
172 172
      --node._id;
173 173
    }
174 174

	
175 175
    void first(Edge& edge) const {
176 176
      edge._id = _edge_num - 1;
177 177
    }
178 178

	
179 179
    static void next(Edge& edge) {
180 180
      --edge._id;
181 181
    }
182 182

	
183 183
    void first(Arc& arc) const {
184 184
      arc._id = 2 * _edge_num - 1;
185 185
    }
186 186

	
187 187
    static void next(Arc& arc) {
188 188
      --arc._id;
189 189
    }
190 190

	
191 191
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
192 192
      edge._id = node._id >> 1;
193 193
      dir = (node._id & 1) == 0;
194 194
    }
195 195

	
196 196
    void nextInc(Edge& edge, bool& dir) const {
197 197
      Node n = dir ? u(edge) : v(edge);
198 198
      int k = (edge._id >> (_dim-1)) + 1;
199 199
      if (k < _dim) {
200 200
        edge._id = (k << (_dim-1)) |
201 201
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
202 202
        dir = ((n._id >> k) & 1) == 0;
203 203
      } else {
204 204
        edge._id = -1;
205 205
        dir = true;
206 206
      }
207 207
    }
208 208

	
209 209
    void firstOut(Arc& arc, const Node& node) const {
210 210
      arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
211 211
    }
212 212

	
213 213
    void nextOut(Arc& arc) const {
214 214
      Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
215 215
      int k = (arc._id >> _dim) + 1;
216 216
      if (k < _dim) {
217 217
        arc._id = (k << (_dim-1)) |
218 218
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
219 219
        arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
220 220
      } else {
221 221
        arc._id = -1;
222 222
      }
223 223
    }
224 224

	
225 225
    void firstIn(Arc& arc, const Node& node) const {
226 226
      arc._id = ((node._id >> 1) << 1) | (node._id & 1);
227 227
    }
228 228

	
229 229
    void nextIn(Arc& arc) const {
230 230
      Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
231 231
      int k = (arc._id >> _dim) + 1;
232 232
      if (k < _dim) {
233 233
        arc._id = (k << (_dim-1)) |
234 234
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
235 235
        arc._id = (arc._id << 1) | ((n._id >> k) & 1);
236 236
      } else {
237 237
        arc._id = -1;
238 238
      }
239 239
    }
240 240

	
241 241
    static bool direction(Arc arc) {
242 242
      return (arc._id & 1) == 1;
243 243
    }
244 244

	
245 245
    static Arc direct(Edge edge, bool dir) {
246 246
      return Arc((edge._id << 1) | (dir ? 1 : 0));
247 247
    }
248 248

	
249 249
    int dimension() const {
250 250
      return _dim;
251 251
    }
252 252

	
253 253
    bool projection(Node node, int n) const {
254 254
      return static_cast<bool>(node._id & (1 << n));
255 255
    }
256 256

	
257 257
    int dimension(Edge edge) const {
258 258
      return edge._id >> (_dim-1);
259 259
    }
260 260

	
261 261
    int dimension(Arc arc) const {
262 262
      return arc._id >> _dim;
263 263
    }
264 264

	
265 265
    int index(Node node) const {
266 266
      return node._id;
267 267
    }
268 268

	
269 269
    Node operator()(int ix) const {
270 270
      return Node(ix);
271 271
    }
272 272

	
273 273
  private:
274 274
    int _dim;
275 275
    int _node_num, _edge_num;
276 276
  };
277 277

	
278 278

	
279 279
  typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
280 280

	
281 281
  /// \ingroup graphs
282 282
  ///
283 283
  /// \brief Hypercube graph class
284 284
  ///
285 285
  /// HypercubeGraph implements a special graph type. The nodes of the
286 286
  /// graph are indexed with integers having at most \c dim binary digits.
287 287
  /// Two nodes are connected in the graph if and only if their indices
288 288
  /// differ only on one position in the binary form.
289 289
  /// This class is completely static and it needs constant memory space.
290
  /// Thus you can neither add nor delete nodes or edges.
290
  /// Thus you can neither add nor delete nodes or edges, however 
291
  /// the structure can be resized using resize().
291 292
  ///
292 293
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
293 294
  /// Most of its member functions and nested classes are documented
294 295
  /// only in the concept class.
295 296
  ///
296 297
  /// \note The type of the indices is chosen to \c int for efficiency
297 298
  /// reasons. Thus the maximum dimension of this implementation is 26
298 299
  /// (assuming that the size of \c int is 32 bit).
299 300
  class HypercubeGraph : public ExtendedHypercubeGraphBase {
300 301
    typedef ExtendedHypercubeGraphBase Parent;
301 302

	
302 303
  public:
303 304

	
304 305
    /// \brief Constructs a hypercube graph with \c dim dimensions.
305 306
    ///
306 307
    /// Constructs a hypercube graph with \c dim dimensions.
307 308
    HypercubeGraph(int dim) { construct(dim); }
308 309

	
310
    /// \brief Resizes the graph
311
    ///
312
    /// This function resizes the graph. It fully destroys and
313
    /// rebuilds the structure, therefore the maps of the graph will be
314
    /// reallocated automatically and the previous values will be lost.
315
    void resize(int dim) {
316
      Parent::notifier(Arc()).clear();
317
      Parent::notifier(Edge()).clear();
318
      Parent::notifier(Node()).clear();
319
      construct(dim);
320
      Parent::notifier(Node()).build();
321
      Parent::notifier(Edge()).build();
322
      Parent::notifier(Arc()).build();
323
    }
324

	
309 325
    /// \brief The number of dimensions.
310 326
    ///
311 327
    /// Gives back the number of dimensions.
312 328
    int dimension() const {
313 329
      return Parent::dimension();
314 330
    }
315 331

	
316 332
    /// \brief Returns \c true if the n'th bit of the node is one.
317 333
    ///
318 334
    /// Returns \c true if the n'th bit of the node is one.
319 335
    bool projection(Node node, int n) const {
320 336
      return Parent::projection(node, n);
321 337
    }
322 338

	
323 339
    /// \brief The dimension id of an edge.
324 340
    ///
325 341
    /// Gives back the dimension id of the given edge.
326 342
    /// It is in the range <tt>[0..dim-1]</tt>.
327 343
    int dimension(Edge edge) const {
328 344
      return Parent::dimension(edge);
329 345
    }
330 346

	
331 347
    /// \brief The dimension id of an arc.
332 348
    ///
333 349
    /// Gives back the dimension id of the given arc.
334 350
    /// It is in the range <tt>[0..dim-1]</tt>.
335 351
    int dimension(Arc arc) const {
336 352
      return Parent::dimension(arc);
337 353
    }
338 354

	
339 355
    /// \brief The index of a node.
340 356
    ///
341 357
    /// Gives back the index of the given node.
342 358
    /// The lower bits of the integer describes the node.
343 359
    int index(Node node) const {
344 360
      return Parent::index(node);
345 361
    }
346 362

	
347 363
    /// \brief Gives back a node by its index.
348 364
    ///
349 365
    /// Gives back a node by its index.
350 366
    Node operator()(int ix) const {
351 367
      return Parent::operator()(ix);
352 368
    }
353 369

	
354 370
    /// \brief Number of nodes.
355 371
    int nodeNum() const { return Parent::nodeNum(); }
356 372
    /// \brief Number of edges.
357 373
    int edgeNum() const { return Parent::edgeNum(); }
358 374
    /// \brief Number of arcs.
359 375
    int arcNum() const { return Parent::arcNum(); }
360 376

	
361 377
    /// \brief Linear combination map.
362 378
    ///
363 379
    /// This map makes possible to give back a linear combination
364 380
    /// for each node. It works like the \c std::accumulate function,
365 381
    /// so it accumulates the \c bf binary function with the \c fv first
366 382
    /// value. The map accumulates only on that positions (dimensions)
367 383
    /// where the index of the node is one. The values that have to be
368 384
    /// accumulated should be given by the \c begin and \c end iterators
369 385
    /// and the length of this range should be equal to the dimension
370 386
    /// number of the graph.
371 387
    ///
372 388
    ///\code
373 389
    /// const int DIM = 3;
374 390
    /// HypercubeGraph graph(DIM);
375 391
    /// dim2::Point<double> base[DIM];
376 392
    /// for (int k = 0; k < DIM; ++k) {
377 393
    ///   base[k].x = rnd();
378 394
    ///   base[k].y = rnd();
379 395
    /// }
380 396
    /// HypercubeGraph::HyperMap<dim2::Point<double> >
381 397
    ///   pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
382 398
    ///\endcode
383 399
    ///
384 400
    /// \see HypercubeGraph
385 401
    template <typename T, typename BF = std::plus<T> >
386 402
    class HyperMap {
387 403
    public:
388 404

	
389 405
      /// \brief The key type of the map
390 406
      typedef Node Key;
391 407
      /// \brief The value type of the map
392 408
      typedef T Value;
393 409

	
394 410
      /// \brief Constructor for HyperMap.
395 411
      ///
396 412
      /// Construct a HyperMap for the given graph. The values that have
397 413
      /// to be accumulated should be given by the \c begin and \c end
398 414
      /// iterators and the length of this range should be equal to the
399 415
      /// dimension number of the graph.
400 416
      ///
401 417
      /// This map accumulates the \c bf binary function with the \c fv
402 418
      /// first value on that positions (dimensions) where the index of
403 419
      /// the node is one.
404 420
      template <typename It>
405 421
      HyperMap(const Graph& graph, It begin, It end,
406 422
               T fv = 0, const BF& bf = BF())
407 423
        : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
408 424
      {
409 425
        LEMON_ASSERT(_values.size() == graph.dimension(),
410 426
                     "Wrong size of range");
411 427
      }
412 428

	
413 429
      /// \brief The partial accumulated value.
414 430
      ///
415 431
      /// Gives back the partial accumulated value.
416 432
      Value operator[](const Key& k) const {
417 433
        Value val = _first_value;
418 434
        int id = _graph.index(k);
419 435
        int n = 0;
420 436
        while (id != 0) {
421 437
          if (id & 1) {
422 438
            val = _bin_func(val, _values[n]);
423 439
          }
424 440
          id >>= 1;
425 441
          ++n;
426 442
        }
427 443
        return val;
428 444
      }
429 445

	
430 446
    private:
431 447
      const Graph& _graph;
432 448
      std::vector<T> _values;
433 449
      T _first_value;
434 450
      BF _bin_func;
435 451
    };
436 452

	
437 453
  };
438 454

	
439 455
}
440 456

	
441 457
#endif
Show white space 131072 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 38
  G.reserveNode(3);
39 39
  G.reserveArc(4);
40 40

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

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

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

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

	
61 61
  checkGraphConArcList(G, 1);
62 62

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

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

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

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

	
78 78
  checkGraphConArcList(G, 4);
79 79

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

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

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

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

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

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

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

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

	
114 114
  checkGraphConArcList(G, 5);
115 115
}
116 116

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

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

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

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

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

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

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

	
147 147
  checkGraphConArcList(G, 5);
148 148

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

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

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

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

	
164 164
  checkGraphConArcList(G, 5);
165 165

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

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

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

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

	
180 180
  checkGraphConArcList(G, 5);
181 181

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

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

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

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

	
193 193
  checkGraphConArcList(G, 3);
194 194
}
195 195

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

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

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

	
210 210
  checkGraphNodeList(G, 4);
211 211
  checkGraphArcList(G, 4);
212 212

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

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

	
223 223
  checkGraphConArcList(G, 4);
224 224

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

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

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

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

	
241 241
  checkGraphConArcList(G, 1);
242 242
}
243 243

	
244 244

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

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

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

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

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

	
263 263
  snapshot.restore();
264 264

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

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

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

	
276 276
  checkGraphConArcList(G, 4);
277 277

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

	
283 283
  G.addNode();
284 284
  snapshot.save(G);
285 285

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

	
288 288
  snapshot.restore();
289 289

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

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

	
298 298
    checkConcept<IDableDigraphComponent<>,
299 299
      IDableDigraphComponent<> >();
300 300

	
301 301
    checkConcept<IterableDigraphComponent<>,
302 302
      IterableDigraphComponent<> >();
303 303

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

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

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

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

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

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

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

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

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

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

	
366 366
  g.erase(n1);
367 367

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

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

	
378 378
void checkFullDigraph(int num) {
379 379
  typedef FullDigraph Digraph;
380 380
  DIGRAPH_TYPEDEFS(Digraph);
381

	
381 382
  Digraph G(num);
383
  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
384

	
385
  G.resize(num);
386
  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
382 387

	
383 388
  checkGraphNodeList(G, num);
384 389
  checkGraphArcList(G, num * num);
385 390

	
386 391
  for (NodeIt n(G); n != INVALID; ++n) {
387 392
    checkGraphOutArcList(G, n, num);
388 393
    checkGraphInArcList(G, n, num);
389 394
  }
390 395

	
391 396
  checkGraphConArcList(G, num * num);
392 397

	
393 398
  checkNodeIds(G);
394 399
  checkArcIds(G);
395 400
  checkGraphNodeMap(G);
396 401
  checkGraphArcMap(G);
397 402

	
398 403
  for (int i = 0; i < G.nodeNum(); ++i) {
399 404
    check(G.index(G(i)) == i, "Wrong index");
400 405
  }
401 406

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

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

	
430 435
int main() {
431 436
  checkDigraphs();
432 437
  checkConcepts();
433 438
  return 0;
434 439
}
Show white space 131072 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 41
  G.reserveNode(3);
42 42
  G.reserveEdge(3);
43 43

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

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

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

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

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

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

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

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

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

	
81 81
  checkArcDirections(G);
82 82

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
211 211

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

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

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

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

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

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

	
236 236
  snapshot.restore();
237 237

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

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

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

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

	
256 256
  G.addNode();
257 257
  snapshot.save(G);
258 258

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

	
261 261
  snapshot.restore();
262 262

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

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

	
272 272
  Graph G(num);
273
  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
274
        "Wrong size");
275

	
276
  G.resize(num);
277
  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
278
        "Wrong size");
279

	
273 280
  checkGraphNodeList(G, num);
274 281
  checkGraphEdgeList(G, num * (num - 1) / 2);
275 282

	
276 283
  for (NodeIt n(G); n != INVALID; ++n) {
277 284
    checkGraphOutArcList(G, n, num - 1);
278 285
    checkGraphInArcList(G, n, num - 1);
279 286
    checkGraphIncEdgeList(G, n, num - 1);
280 287
  }
281 288

	
282 289
  checkGraphConArcList(G, num * (num - 1));
283 290
  checkGraphConEdgeList(G, num * (num - 1) / 2);
284 291

	
285 292
  checkArcDirections(G);
286 293

	
287 294
  checkNodeIds(G);
288 295
  checkArcIds(G);
289 296
  checkEdgeIds(G);
290 297
  checkGraphNodeMap(G);
291 298
  checkGraphArcMap(G);
292 299
  checkGraphEdgeMap(G);
293 300

	
294 301

	
295 302
  for (int i = 0; i < G.nodeNum(); ++i) {
296 303
    check(G.index(G(i)) == i, "Wrong index");
297 304
  }
298 305

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

	
315 322
void checkConcepts() {
316 323
  { // Checking graph components
317 324
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
318 325

	
319 326
    checkConcept<IDableGraphComponent<>,
320 327
      IDableGraphComponent<> >();
321 328

	
322 329
    checkConcept<IterableGraphComponent<>,
323 330
      IterableGraphComponent<> >();
324 331

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

	
355 362
template <typename Graph>
356 363
void checkGraphValidity() {
357 364
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
358 365
  Graph g;
359 366

	
360 367
  Node
361 368
    n1 = g.addNode(),
362 369
    n2 = g.addNode(),
363 370
    n3 = g.addNode();
364 371

	
365 372
  Edge
366 373
    e1 = g.addEdge(n1, n2),
367 374
    e2 = g.addEdge(n2, n3);
368 375

	
369 376
  check(g.valid(n1), "Wrong validity check");
370 377
  check(g.valid(e1), "Wrong validity check");
371 378
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
372 379

	
373 380
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
374 381
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
375 382
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
376 383
}
377 384

	
378 385
template <typename Graph>
379 386
void checkGraphValidityErase() {
380 387
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
381 388
  Graph g;
382 389

	
383 390
  Node
384 391
    n1 = g.addNode(),
385 392
    n2 = g.addNode(),
386 393
    n3 = g.addNode();
387 394

	
388 395
  Edge
389 396
    e1 = g.addEdge(n1, n2),
390 397
    e2 = g.addEdge(n2, n3);
391 398

	
392 399
  check(g.valid(n1), "Wrong validity check");
393 400
  check(g.valid(e1), "Wrong validity check");
394 401
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
395 402

	
396 403
  g.erase(n1);
397 404

	
398 405
  check(!g.valid(n1), "Wrong validity check");
399 406
  check(g.valid(n2), "Wrong validity check");
400 407
  check(g.valid(n3), "Wrong validity check");
401 408
  check(!g.valid(e1), "Wrong validity check");
402 409
  check(g.valid(e2), "Wrong validity check");
403 410

	
404 411
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
405 412
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
406 413
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
407 414
}
408 415

	
409 416
void checkGridGraph(int width, int height) {
410 417
  typedef GridGraph Graph;
411 418
  GRAPH_TYPEDEFS(Graph);
412 419
  Graph G(width, height);
413 420

	
414 421
  check(G.width() == width, "Wrong column number");
415 422
  check(G.height() == height, "Wrong row number");
416 423

	
424
  G.resize(width, height);
425
  check(G.width() == width, "Wrong column number");
426
  check(G.height() == height, "Wrong row number");
427

	
417 428
  for (int i = 0; i < width; ++i) {
418 429
    for (int j = 0; j < height; ++j) {
419 430
      check(G.col(G(i, j)) == i, "Wrong column");
420 431
      check(G.row(G(i, j)) == j, "Wrong row");
421 432
      check(G.pos(G(i, j)).x == i, "Wrong column");
422 433
      check(G.pos(G(i, j)).y == j, "Wrong row");
423 434
    }
424 435
  }
425 436

	
426 437
  for (int j = 0; j < height; ++j) {
427 438
    for (int i = 0; i < width - 1; ++i) {
428 439
      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
429 440
      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
430 441
    }
431 442
    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
432 443
  }
433 444

	
434 445
  for (int j = 0; j < height; ++j) {
435 446
    for (int i = 1; i < width; ++i) {
436 447
      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
437 448
      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
438 449
    }
439 450
    check(G.left(G(0, j)) == INVALID, "Wrong left");
440 451
  }
441 452

	
442 453
  for (int i = 0; i < width; ++i) {
443 454
    for (int j = 0; j < height - 1; ++j) {
444 455
      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
445 456
      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
446 457
    }
447 458
    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
448 459
  }
449 460

	
450 461
  for (int i = 0; i < width; ++i) {
451 462
    for (int j = 1; j < height; ++j) {
452 463
      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
453 464
      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
454 465
    }
455 466
    check(G.down(G(i, 0)) == INVALID, "Wrong down");
456 467
  }
457 468

	
458 469
  checkGraphNodeList(G, width * height);
459 470
  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
460 471
  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
461 472

	
462 473
  for (NodeIt n(G); n != INVALID; ++n) {
463 474
    int nb = 4;
464 475
    if (G.col(n) == 0) --nb;
465 476
    if (G.col(n) == width - 1) --nb;
466 477
    if (G.row(n) == 0) --nb;
467 478
    if (G.row(n) == height - 1) --nb;
468 479

	
469 480
    checkGraphOutArcList(G, n, nb);
470 481
    checkGraphInArcList(G, n, nb);
471 482
    checkGraphIncEdgeList(G, n, nb);
472 483
  }
473 484

	
474 485
  checkArcDirections(G);
475 486

	
476 487
  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
477 488
  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
478 489

	
479 490
  checkNodeIds(G);
480 491
  checkArcIds(G);
481 492
  checkEdgeIds(G);
482 493
  checkGraphNodeMap(G);
483 494
  checkGraphArcMap(G);
484 495
  checkGraphEdgeMap(G);
485 496

	
486 497
}
487 498

	
488 499
void checkHypercubeGraph(int dim) {
489 500
  GRAPH_TYPEDEFS(HypercubeGraph);
490 501

	
491 502
  HypercubeGraph G(dim);
503
  check(G.dimension() == dim, "Wrong dimension");
504

	
505
  G.resize(dim);
506
  check(G.dimension() == dim, "Wrong dimension");
507
  
492 508
  checkGraphNodeList(G, 1 << dim);
493 509
  checkGraphEdgeList(G, dim * (1 << (dim-1)));
494 510
  checkGraphArcList(G, dim * (1 << dim));
495 511

	
496 512
  Node n = G.nodeFromId(dim);
497 513

	
498 514
  for (NodeIt n(G); n != INVALID; ++n) {
499 515
    checkGraphIncEdgeList(G, n, dim);
500 516
    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
501 517
      check( (G.u(e) == n &&
502 518
              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
503 519
             (G.v(e) == n &&
504 520
              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
505 521
             "Wrong edge or wrong dimension");
506 522
    }
507 523

	
508 524
    checkGraphOutArcList(G, n, dim);
509 525
    for (OutArcIt a(G, n); a != INVALID; ++a) {
510 526
      check(G.source(a) == n &&
511 527
            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
512 528
            "Wrong arc or wrong dimension");
513 529
    }
514 530

	
515 531
    checkGraphInArcList(G, n, dim);
516 532
    for (InArcIt a(G, n); a != INVALID; ++a) {
517 533
      check(G.target(a) == n &&
518 534
            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
519 535
            "Wrong arc or wrong dimension");
520 536
    }
521 537
  }
522 538

	
523 539
  checkGraphConArcList(G, (1 << dim) * dim);
524 540
  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
525 541

	
526 542
  checkArcDirections(G);
527 543

	
528 544
  checkNodeIds(G);
529 545
  checkArcIds(G);
530 546
  checkEdgeIds(G);
531 547
  checkGraphNodeMap(G);
532 548
  checkGraphArcMap(G);
533 549
  checkGraphEdgeMap(G);
534 550
}
535 551

	
536 552
void checkGraphs() {
537 553
  { // Checking ListGraph
538 554
    checkGraphBuild<ListGraph>();
539 555
    checkGraphAlter<ListGraph>();
540 556
    checkGraphErase<ListGraph>();
541 557
    checkGraphSnapshot<ListGraph>();
542 558
    checkGraphValidityErase<ListGraph>();
543 559
  }
544 560
  { // Checking SmartGraph
545 561
    checkGraphBuild<SmartGraph>();
546 562
    checkGraphSnapshot<SmartGraph>();
547 563
    checkGraphValidity<SmartGraph>();
548 564
  }
549 565
  { // Checking FullGraph
550 566
    checkFullGraph(7);
551 567
    checkFullGraph(8);
552 568
  }
553 569
  { // Checking GridGraph
554 570
    checkGridGraph(5, 8);
555 571
    checkGridGraph(8, 5);
556 572
    checkGridGraph(5, 5);
557 573
    checkGridGraph(0, 0);
558 574
    checkGridGraph(1, 1);
559 575
  }
560 576
  { // Checking HypercubeGraph
561 577
    checkHypercubeGraph(1);
562 578
    checkHypercubeGraph(2);
563 579
    checkHypercubeGraph(3);
564 580
    checkHypercubeGraph(4);
565 581
  }
566 582
}
567 583

	
568 584
int main() {
569 585
  checkConcepts();
570 586
  checkGraphs();
571 587
  return 0;
572 588
}
0 comments (0 inline)