1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2009
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #include <lemon/concepts/graph.h>
20 #include <lemon/list_graph.h>
21 #include <lemon/smart_graph.h>
22 #include <lemon/full_graph.h>
23 #include <lemon/grid_graph.h>
24 #include <lemon/hypercube_graph.h>
26 #include "test_tools.h"
27 #include "graph_test.h"
29 using namespace lemon;
30 using namespace lemon::concepts;
32 template <class Graph>
33 void checkGraphBuild() {
34 TEMPLATE_GRAPH_TYPEDEFS(Graph);
37 checkGraphNodeList(G, 0);
38 checkGraphEdgeList(G, 0);
39 checkGraphArcList(G, 0);
45 checkGraphNodeList(G, 3);
46 checkGraphEdgeList(G, 0);
47 checkGraphArcList(G, 0);
49 Edge e1 = G.addEdge(n1, n2);
50 check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
53 checkGraphNodeList(G, 3);
54 checkGraphEdgeList(G, 1);
55 checkGraphArcList(G, 2);
57 checkGraphIncEdgeArcLists(G, n1, 1);
58 checkGraphIncEdgeArcLists(G, n2, 1);
59 checkGraphIncEdgeArcLists(G, n3, 0);
61 checkGraphConEdgeList(G, 1);
62 checkGraphConArcList(G, 2);
64 Edge e2 = G.addEdge(n2, n1),
65 e3 = G.addEdge(n2, n3);
67 checkGraphNodeList(G, 3);
68 checkGraphEdgeList(G, 3);
69 checkGraphArcList(G, 6);
71 checkGraphIncEdgeArcLists(G, n1, 2);
72 checkGraphIncEdgeArcLists(G, n2, 3);
73 checkGraphIncEdgeArcLists(G, n3, 1);
75 checkGraphConEdgeList(G, 3);
76 checkGraphConArcList(G, 6);
78 checkArcDirections(G);
88 template <class Graph>
89 void checkGraphAlter() {
90 TEMPLATE_GRAPH_TYPEDEFS(Graph);
93 Node n1 = G.addNode(), n2 = G.addNode(),
94 n3 = G.addNode(), n4 = G.addNode();
95 Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
96 e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
97 e5 = G.addEdge(n4, n3);
99 checkGraphNodeList(G, 4);
100 checkGraphEdgeList(G, 5);
101 checkGraphArcList(G, 10);
103 // Check changeU() and changeV()
110 checkGraphNodeList(G, 4);
111 checkGraphEdgeList(G, 5);
112 checkGraphArcList(G, 10);
114 checkGraphIncEdgeArcLists(G, n1, 3);
115 checkGraphIncEdgeArcLists(G, n2, 2);
116 checkGraphIncEdgeArcLists(G, n3, 3);
117 checkGraphIncEdgeArcLists(G, n4, 2);
119 checkGraphConEdgeList(G, 5);
120 checkGraphConArcList(G, 10);
128 checkGraphNodeList(G, 4);
129 checkGraphEdgeList(G, 5);
130 checkGraphArcList(G, 10);
132 checkGraphIncEdgeArcLists(G, n1, 2);
133 checkGraphIncEdgeArcLists(G, n2, 3);
134 checkGraphIncEdgeArcLists(G, n3, 3);
135 checkGraphIncEdgeArcLists(G, n4, 2);
137 checkGraphConEdgeList(G, 5);
138 checkGraphConArcList(G, 10);
141 G.contract(n1, n4, false);
143 checkGraphNodeList(G, 3);
144 checkGraphEdgeList(G, 5);
145 checkGraphArcList(G, 10);
147 checkGraphIncEdgeArcLists(G, n1, 4);
148 checkGraphIncEdgeArcLists(G, n2, 3);
149 checkGraphIncEdgeArcLists(G, n3, 3);
151 checkGraphConEdgeList(G, 5);
152 checkGraphConArcList(G, 10);
156 checkGraphNodeList(G, 2);
157 checkGraphEdgeList(G, 3);
158 checkGraphArcList(G, 6);
160 checkGraphIncEdgeArcLists(G, n1, 4);
161 checkGraphIncEdgeArcLists(G, n2, 2);
163 checkGraphConEdgeList(G, 3);
164 checkGraphConArcList(G, 6);
167 template <class Graph>
168 void checkGraphErase() {
169 TEMPLATE_GRAPH_TYPEDEFS(Graph);
172 Node n1 = G.addNode(), n2 = G.addNode(),
173 n3 = G.addNode(), n4 = G.addNode();
174 Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
175 e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
176 e5 = G.addEdge(n4, n3);
178 // Check edge deletion
181 checkGraphNodeList(G, 4);
182 checkGraphEdgeList(G, 4);
183 checkGraphArcList(G, 8);
185 checkGraphIncEdgeArcLists(G, n1, 2);
186 checkGraphIncEdgeArcLists(G, n2, 2);
187 checkGraphIncEdgeArcLists(G, n3, 2);
188 checkGraphIncEdgeArcLists(G, n4, 2);
190 checkGraphConEdgeList(G, 4);
191 checkGraphConArcList(G, 8);
193 // Check node deletion
196 checkGraphNodeList(G, 3);
197 checkGraphEdgeList(G, 2);
198 checkGraphArcList(G, 4);
200 checkGraphIncEdgeArcLists(G, n1, 2);
201 checkGraphIncEdgeArcLists(G, n2, 1);
202 checkGraphIncEdgeArcLists(G, n4, 1);
204 checkGraphConEdgeList(G, 2);
205 checkGraphConArcList(G, 4);
209 template <class Graph>
210 void checkGraphSnapshot() {
211 TEMPLATE_GRAPH_TYPEDEFS(Graph);
214 Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
215 Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
216 e3 = G.addEdge(n2, n3);
218 checkGraphNodeList(G, 3);
219 checkGraphEdgeList(G, 3);
220 checkGraphArcList(G, 6);
222 typename Graph::Snapshot snapshot(G);
224 Node n = G.addNode();
229 checkGraphNodeList(G, 4);
230 checkGraphEdgeList(G, 6);
231 checkGraphArcList(G, 12);
235 checkGraphNodeList(G, 3);
236 checkGraphEdgeList(G, 3);
237 checkGraphArcList(G, 6);
239 checkGraphIncEdgeArcLists(G, n1, 2);
240 checkGraphIncEdgeArcLists(G, n2, 3);
241 checkGraphIncEdgeArcLists(G, n3, 1);
243 checkGraphConEdgeList(G, 3);
244 checkGraphConArcList(G, 6);
249 checkGraphNodeMap(G);
250 checkGraphEdgeMap(G);
256 G.addEdge(G.addNode(), G.addNode());
260 checkGraphNodeList(G, 4);
261 checkGraphEdgeList(G, 3);
262 checkGraphArcList(G, 6);
265 void checkFullGraph(int num) {
266 typedef FullGraph Graph;
267 GRAPH_TYPEDEFS(Graph);
270 checkGraphNodeList(G, num);
271 checkGraphEdgeList(G, num * (num - 1) / 2);
273 for (NodeIt n(G); n != INVALID; ++n) {
274 checkGraphOutArcList(G, n, num - 1);
275 checkGraphInArcList(G, n, num - 1);
276 checkGraphIncEdgeList(G, n, num - 1);
279 checkGraphConArcList(G, num * (num - 1));
280 checkGraphConEdgeList(G, num * (num - 1) / 2);
282 checkArcDirections(G);
287 checkGraphNodeMap(G);
289 checkGraphEdgeMap(G);
292 for (int i = 0; i < G.nodeNum(); ++i) {
293 check(G.index(G(i)) == i, "Wrong index");
296 for (NodeIt u(G); u != INVALID; ++u) {
297 for (NodeIt v(G); v != INVALID; ++v) {
298 Edge e = G.edge(u, v);
301 check(e == INVALID, "Wrong edge lookup");
302 check(a == INVALID, "Wrong arc lookup");
304 check((G.u(e) == u && G.v(e) == v) ||
305 (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
306 check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
312 void checkConcepts() {
313 { // Checking graph components
314 checkConcept<BaseGraphComponent, BaseGraphComponent >();
316 checkConcept<IDableGraphComponent<>,
317 IDableGraphComponent<> >();
319 checkConcept<IterableGraphComponent<>,
320 IterableGraphComponent<> >();
322 checkConcept<MappableGraphComponent<>,
323 MappableGraphComponent<> >();
325 { // Checking skeleton graph
326 checkConcept<Graph, Graph>();
328 { // Checking ListGraph
329 checkConcept<Graph, ListGraph>();
330 checkConcept<AlterableGraphComponent<>, ListGraph>();
331 checkConcept<ExtendableGraphComponent<>, ListGraph>();
332 checkConcept<ClearableGraphComponent<>, ListGraph>();
333 checkConcept<ErasableGraphComponent<>, ListGraph>();
335 { // Checking SmartGraph
336 checkConcept<Graph, SmartGraph>();
337 checkConcept<AlterableGraphComponent<>, SmartGraph>();
338 checkConcept<ExtendableGraphComponent<>, SmartGraph>();
339 checkConcept<ClearableGraphComponent<>, SmartGraph>();
341 { // Checking FullGraph
342 checkConcept<Graph, FullGraph>();
344 { // Checking GridGraph
345 checkConcept<Graph, GridGraph>();
347 { // Checking HypercubeGraph
348 checkConcept<Graph, HypercubeGraph>();
352 template <typename Graph>
353 void checkGraphValidity() {
354 TEMPLATE_GRAPH_TYPEDEFS(Graph);
363 e1 = g.addEdge(n1, n2),
364 e2 = g.addEdge(n2, n3);
366 check(g.valid(n1), "Wrong validity check");
367 check(g.valid(e1), "Wrong validity check");
368 check(g.valid(g.direct(e1, true)), "Wrong validity check");
370 check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
371 check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
372 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
375 template <typename Graph>
376 void checkGraphValidityErase() {
377 TEMPLATE_GRAPH_TYPEDEFS(Graph);
386 e1 = g.addEdge(n1, n2),
387 e2 = g.addEdge(n2, n3);
389 check(g.valid(n1), "Wrong validity check");
390 check(g.valid(e1), "Wrong validity check");
391 check(g.valid(g.direct(e1, true)), "Wrong validity check");
395 check(!g.valid(n1), "Wrong validity check");
396 check(g.valid(n2), "Wrong validity check");
397 check(g.valid(n3), "Wrong validity check");
398 check(!g.valid(e1), "Wrong validity check");
399 check(g.valid(e2), "Wrong validity check");
401 check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
402 check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
403 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
406 void checkGridGraph(int width, int height) {
407 typedef GridGraph Graph;
408 GRAPH_TYPEDEFS(Graph);
409 Graph G(width, height);
411 check(G.width() == width, "Wrong column number");
412 check(G.height() == height, "Wrong row number");
414 for (int i = 0; i < width; ++i) {
415 for (int j = 0; j < height; ++j) {
416 check(G.col(G(i, j)) == i, "Wrong column");
417 check(G.row(G(i, j)) == j, "Wrong row");
418 check(G.pos(G(i, j)).x == i, "Wrong column");
419 check(G.pos(G(i, j)).y == j, "Wrong row");
423 for (int j = 0; j < height; ++j) {
424 for (int i = 0; i < width - 1; ++i) {
425 check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
426 check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
428 check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
431 for (int j = 0; j < height; ++j) {
432 for (int i = 1; i < width; ++i) {
433 check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
434 check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
436 check(G.left(G(0, j)) == INVALID, "Wrong left");
439 for (int i = 0; i < width; ++i) {
440 for (int j = 0; j < height - 1; ++j) {
441 check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
442 check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
444 check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
447 for (int i = 0; i < width; ++i) {
448 for (int j = 1; j < height; ++j) {
449 check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
450 check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
452 check(G.down(G(i, 0)) == INVALID, "Wrong down");
455 checkGraphNodeList(G, width * height);
456 checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
457 checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
459 for (NodeIt n(G); n != INVALID; ++n) {
461 if (G.col(n) == 0) --nb;
462 if (G.col(n) == width - 1) --nb;
463 if (G.row(n) == 0) --nb;
464 if (G.row(n) == height - 1) --nb;
466 checkGraphOutArcList(G, n, nb);
467 checkGraphInArcList(G, n, nb);
468 checkGraphIncEdgeList(G, n, nb);
471 checkArcDirections(G);
473 checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
474 checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
479 checkGraphNodeMap(G);
481 checkGraphEdgeMap(G);
485 void checkHypercubeGraph(int dim) {
486 GRAPH_TYPEDEFS(HypercubeGraph);
488 HypercubeGraph G(dim);
489 checkGraphNodeList(G, 1 << dim);
490 checkGraphEdgeList(G, dim * (1 << (dim-1)));
491 checkGraphArcList(G, dim * (1 << dim));
493 Node n = G.nodeFromId(dim);
495 for (NodeIt n(G); n != INVALID; ++n) {
496 checkGraphIncEdgeList(G, n, dim);
497 for (IncEdgeIt e(G, n); e != INVALID; ++e) {
498 check( (G.u(e) == n &&
499 G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
501 G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
502 "Wrong edge or wrong dimension");
505 checkGraphOutArcList(G, n, dim);
506 for (OutArcIt a(G, n); a != INVALID; ++a) {
507 check(G.source(a) == n &&
508 G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
509 "Wrong arc or wrong dimension");
512 checkGraphInArcList(G, n, dim);
513 for (InArcIt a(G, n); a != INVALID; ++a) {
514 check(G.target(a) == n &&
515 G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
516 "Wrong arc or wrong dimension");
520 checkGraphConArcList(G, (1 << dim) * dim);
521 checkGraphConEdgeList(G, dim * (1 << (dim-1)));
523 checkArcDirections(G);
528 checkGraphNodeMap(G);
530 checkGraphEdgeMap(G);
534 { // Checking ListGraph
535 checkGraphBuild<ListGraph>();
536 checkGraphAlter<ListGraph>();
537 checkGraphErase<ListGraph>();
538 checkGraphSnapshot<ListGraph>();
539 checkGraphValidityErase<ListGraph>();
541 { // Checking SmartGraph
542 checkGraphBuild<SmartGraph>();
543 checkGraphSnapshot<SmartGraph>();
544 checkGraphValidity<SmartGraph>();
546 { // Checking FullGraph
550 { // Checking GridGraph
551 checkGridGraph(5, 8);
552 checkGridGraph(8, 5);
553 checkGridGraph(5, 5);
554 checkGridGraph(0, 0);
555 checkGridGraph(1, 1);
557 { // Checking HypercubeGraph
558 checkHypercubeGraph(1);
559 checkHypercubeGraph(2);
560 checkHypercubeGraph(3);
561 checkHypercubeGraph(4);