1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2010
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);
48 checkGraphNodeList(G, 3);
49 checkGraphEdgeList(G, 0);
50 checkGraphArcList(G, 0);
52 Edge e1 = G.addEdge(n1, n2);
53 check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
56 checkGraphNodeList(G, 3);
57 checkGraphEdgeList(G, 1);
58 checkGraphArcList(G, 2);
60 checkGraphIncEdgeArcLists(G, n1, 1);
61 checkGraphIncEdgeArcLists(G, n2, 1);
62 checkGraphIncEdgeArcLists(G, n3, 0);
64 checkGraphConEdgeList(G, 1);
65 checkGraphConArcList(G, 2);
67 Edge e2 = G.addEdge(n2, n1),
68 e3 = G.addEdge(n2, n3);
70 checkGraphNodeList(G, 3);
71 checkGraphEdgeList(G, 3);
72 checkGraphArcList(G, 6);
74 checkGraphIncEdgeArcLists(G, n1, 2);
75 checkGraphIncEdgeArcLists(G, n2, 3);
76 checkGraphIncEdgeArcLists(G, n3, 1);
78 checkGraphConEdgeList(G, 3);
79 checkGraphConArcList(G, 6);
81 checkArcDirections(G);
91 template <class Graph>
92 void checkGraphAlter() {
93 TEMPLATE_GRAPH_TYPEDEFS(Graph);
96 Node n1 = G.addNode(), n2 = G.addNode(),
97 n3 = G.addNode(), n4 = G.addNode();
98 Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
99 e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
100 e5 = G.addEdge(n4, n3);
102 checkGraphNodeList(G, 4);
103 checkGraphEdgeList(G, 5);
104 checkGraphArcList(G, 10);
106 // Check changeU() and changeV()
113 checkGraphNodeList(G, 4);
114 checkGraphEdgeList(G, 5);
115 checkGraphArcList(G, 10);
117 checkGraphIncEdgeArcLists(G, n1, 3);
118 checkGraphIncEdgeArcLists(G, n2, 2);
119 checkGraphIncEdgeArcLists(G, n3, 3);
120 checkGraphIncEdgeArcLists(G, n4, 2);
122 checkGraphConEdgeList(G, 5);
123 checkGraphConArcList(G, 10);
131 checkGraphNodeList(G, 4);
132 checkGraphEdgeList(G, 5);
133 checkGraphArcList(G, 10);
135 checkGraphIncEdgeArcLists(G, n1, 2);
136 checkGraphIncEdgeArcLists(G, n2, 3);
137 checkGraphIncEdgeArcLists(G, n3, 3);
138 checkGraphIncEdgeArcLists(G, n4, 2);
140 checkGraphConEdgeList(G, 5);
141 checkGraphConArcList(G, 10);
144 G.contract(n1, n4, false);
146 checkGraphNodeList(G, 3);
147 checkGraphEdgeList(G, 5);
148 checkGraphArcList(G, 10);
150 checkGraphIncEdgeArcLists(G, n1, 4);
151 checkGraphIncEdgeArcLists(G, n2, 3);
152 checkGraphIncEdgeArcLists(G, n3, 3);
154 checkGraphConEdgeList(G, 5);
155 checkGraphConArcList(G, 10);
159 checkGraphNodeList(G, 2);
160 checkGraphEdgeList(G, 3);
161 checkGraphArcList(G, 6);
163 checkGraphIncEdgeArcLists(G, n1, 4);
164 checkGraphIncEdgeArcLists(G, n2, 2);
166 checkGraphConEdgeList(G, 3);
167 checkGraphConArcList(G, 6);
170 template <class Graph>
171 void checkGraphErase() {
172 TEMPLATE_GRAPH_TYPEDEFS(Graph);
175 Node n1 = G.addNode(), n2 = G.addNode(),
176 n3 = G.addNode(), n4 = G.addNode();
177 Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
178 e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
179 e5 = G.addEdge(n4, n3);
181 // Check edge deletion
184 checkGraphNodeList(G, 4);
185 checkGraphEdgeList(G, 4);
186 checkGraphArcList(G, 8);
188 checkGraphIncEdgeArcLists(G, n1, 2);
189 checkGraphIncEdgeArcLists(G, n2, 2);
190 checkGraphIncEdgeArcLists(G, n3, 2);
191 checkGraphIncEdgeArcLists(G, n4, 2);
193 checkGraphConEdgeList(G, 4);
194 checkGraphConArcList(G, 8);
196 // Check node deletion
199 checkGraphNodeList(G, 3);
200 checkGraphEdgeList(G, 2);
201 checkGraphArcList(G, 4);
203 checkGraphIncEdgeArcLists(G, n1, 2);
204 checkGraphIncEdgeArcLists(G, n2, 1);
205 checkGraphIncEdgeArcLists(G, n4, 1);
207 checkGraphConEdgeList(G, 2);
208 checkGraphConArcList(G, 4);
212 template <class Graph>
213 void checkGraphSnapshot() {
214 TEMPLATE_GRAPH_TYPEDEFS(Graph);
217 Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
218 Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
219 e3 = G.addEdge(n2, n3);
221 checkGraphNodeList(G, 3);
222 checkGraphEdgeList(G, 3);
223 checkGraphArcList(G, 6);
225 typename Graph::Snapshot snapshot(G);
227 Node n = G.addNode();
232 checkGraphNodeList(G, 4);
233 checkGraphEdgeList(G, 6);
234 checkGraphArcList(G, 12);
238 checkGraphNodeList(G, 3);
239 checkGraphEdgeList(G, 3);
240 checkGraphArcList(G, 6);
242 checkGraphIncEdgeArcLists(G, n1, 2);
243 checkGraphIncEdgeArcLists(G, n2, 3);
244 checkGraphIncEdgeArcLists(G, n3, 1);
246 checkGraphConEdgeList(G, 3);
247 checkGraphConArcList(G, 6);
252 checkGraphNodeMap(G);
253 checkGraphEdgeMap(G);
259 G.addEdge(G.addNode(), G.addNode());
264 checkGraphNodeList(G, 4);
265 checkGraphEdgeList(G, 3);
266 checkGraphArcList(G, 6);
268 G.addEdge(G.addNode(), G.addNode());
272 checkGraphNodeList(G, 4);
273 checkGraphEdgeList(G, 3);
274 checkGraphArcList(G, 6);
277 void checkFullGraph(int num) {
278 typedef FullGraph Graph;
279 GRAPH_TYPEDEFS(Graph);
282 check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
286 check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
289 checkGraphNodeList(G, num);
290 checkGraphEdgeList(G, num * (num - 1) / 2);
292 for (NodeIt n(G); n != INVALID; ++n) {
293 checkGraphOutArcList(G, n, num - 1);
294 checkGraphInArcList(G, n, num - 1);
295 checkGraphIncEdgeList(G, n, num - 1);
298 checkGraphConArcList(G, num * (num - 1));
299 checkGraphConEdgeList(G, num * (num - 1) / 2);
301 checkArcDirections(G);
306 checkGraphNodeMap(G);
308 checkGraphEdgeMap(G);
311 for (int i = 0; i < G.nodeNum(); ++i) {
312 check(G.index(G(i)) == i, "Wrong index");
315 for (NodeIt u(G); u != INVALID; ++u) {
316 for (NodeIt v(G); v != INVALID; ++v) {
317 Edge e = G.edge(u, v);
320 check(e == INVALID, "Wrong edge lookup");
321 check(a == INVALID, "Wrong arc lookup");
323 check((G.u(e) == u && G.v(e) == v) ||
324 (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
325 check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
331 void checkConcepts() {
332 { // Checking graph components
333 checkConcept<BaseGraphComponent, BaseGraphComponent >();
335 checkConcept<IDableGraphComponent<>,
336 IDableGraphComponent<> >();
338 checkConcept<IterableGraphComponent<>,
339 IterableGraphComponent<> >();
341 checkConcept<MappableGraphComponent<>,
342 MappableGraphComponent<> >();
344 { // Checking skeleton graph
345 checkConcept<Graph, Graph>();
347 { // Checking ListGraph
348 checkConcept<Graph, ListGraph>();
349 checkConcept<AlterableGraphComponent<>, ListGraph>();
350 checkConcept<ExtendableGraphComponent<>, ListGraph>();
351 checkConcept<ClearableGraphComponent<>, ListGraph>();
352 checkConcept<ErasableGraphComponent<>, ListGraph>();
354 { // Checking SmartGraph
355 checkConcept<Graph, SmartGraph>();
356 checkConcept<AlterableGraphComponent<>, SmartGraph>();
357 checkConcept<ExtendableGraphComponent<>, SmartGraph>();
358 checkConcept<ClearableGraphComponent<>, SmartGraph>();
360 { // Checking FullGraph
361 checkConcept<Graph, FullGraph>();
363 { // Checking GridGraph
364 checkConcept<Graph, GridGraph>();
366 { // Checking HypercubeGraph
367 checkConcept<Graph, HypercubeGraph>();
371 template <typename Graph>
372 void checkGraphValidity() {
373 TEMPLATE_GRAPH_TYPEDEFS(Graph);
382 e1 = g.addEdge(n1, n2),
383 e2 = g.addEdge(n2, n3);
385 check(g.valid(n1), "Wrong validity check");
386 check(g.valid(e1), "Wrong validity check");
387 check(g.valid(g.direct(e1, true)), "Wrong validity check");
389 check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
390 check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
391 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
394 template <typename Graph>
395 void checkGraphValidityErase() {
396 TEMPLATE_GRAPH_TYPEDEFS(Graph);
405 e1 = g.addEdge(n1, n2),
406 e2 = g.addEdge(n2, n3);
408 check(g.valid(n1), "Wrong validity check");
409 check(g.valid(e1), "Wrong validity check");
410 check(g.valid(g.direct(e1, true)), "Wrong validity check");
414 check(!g.valid(n1), "Wrong validity check");
415 check(g.valid(n2), "Wrong validity check");
416 check(g.valid(n3), "Wrong validity check");
417 check(!g.valid(e1), "Wrong validity check");
418 check(g.valid(e2), "Wrong validity check");
420 check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
421 check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
422 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
425 void checkGridGraph(int width, int height) {
426 typedef GridGraph Graph;
427 GRAPH_TYPEDEFS(Graph);
428 Graph G(width, height);
430 check(G.width() == width, "Wrong column number");
431 check(G.height() == height, "Wrong row number");
433 G.resize(width, height);
434 check(G.width() == width, "Wrong column number");
435 check(G.height() == height, "Wrong row number");
437 for (int i = 0; i < width; ++i) {
438 for (int j = 0; j < height; ++j) {
439 check(G.col(G(i, j)) == i, "Wrong column");
440 check(G.row(G(i, j)) == j, "Wrong row");
441 check(G.pos(G(i, j)).x == i, "Wrong column");
442 check(G.pos(G(i, j)).y == j, "Wrong row");
446 for (int j = 0; j < height; ++j) {
447 for (int i = 0; i < width - 1; ++i) {
448 check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
449 check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
451 check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
454 for (int j = 0; j < height; ++j) {
455 for (int i = 1; i < width; ++i) {
456 check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
457 check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
459 check(G.left(G(0, j)) == INVALID, "Wrong left");
462 for (int i = 0; i < width; ++i) {
463 for (int j = 0; j < height - 1; ++j) {
464 check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
465 check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
467 check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
470 for (int i = 0; i < width; ++i) {
471 for (int j = 1; j < height; ++j) {
472 check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
473 check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
475 check(G.down(G(i, 0)) == INVALID, "Wrong down");
478 checkGraphNodeList(G, width * height);
479 checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
480 checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
482 for (NodeIt n(G); n != INVALID; ++n) {
484 if (G.col(n) == 0) --nb;
485 if (G.col(n) == width - 1) --nb;
486 if (G.row(n) == 0) --nb;
487 if (G.row(n) == height - 1) --nb;
489 checkGraphOutArcList(G, n, nb);
490 checkGraphInArcList(G, n, nb);
491 checkGraphIncEdgeList(G, n, nb);
494 checkArcDirections(G);
496 checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
497 checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
502 checkGraphNodeMap(G);
504 checkGraphEdgeMap(G);
508 void checkHypercubeGraph(int dim) {
509 GRAPH_TYPEDEFS(HypercubeGraph);
511 HypercubeGraph G(dim);
512 check(G.dimension() == dim, "Wrong dimension");
515 check(G.dimension() == dim, "Wrong dimension");
517 checkGraphNodeList(G, 1 << dim);
518 checkGraphEdgeList(G, dim * (1 << (dim-1)));
519 checkGraphArcList(G, dim * (1 << dim));
521 Node n = G.nodeFromId(dim);
523 for (NodeIt n(G); n != INVALID; ++n) {
524 checkGraphIncEdgeList(G, n, dim);
525 for (IncEdgeIt e(G, n); e != INVALID; ++e) {
526 check( (G.u(e) == n &&
527 G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
529 G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
530 "Wrong edge or wrong dimension");
533 checkGraphOutArcList(G, n, dim);
534 for (OutArcIt a(G, n); a != INVALID; ++a) {
535 check(G.source(a) == n &&
536 G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
537 "Wrong arc or wrong dimension");
540 checkGraphInArcList(G, n, dim);
541 for (InArcIt a(G, n); a != INVALID; ++a) {
542 check(G.target(a) == n &&
543 G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
544 "Wrong arc or wrong dimension");
548 checkGraphConArcList(G, (1 << dim) * dim);
549 checkGraphConEdgeList(G, dim * (1 << (dim-1)));
551 checkArcDirections(G);
556 checkGraphNodeMap(G);
558 checkGraphEdgeMap(G);
562 { // Checking ListGraph
563 checkGraphBuild<ListGraph>();
564 checkGraphAlter<ListGraph>();
565 checkGraphErase<ListGraph>();
566 checkGraphSnapshot<ListGraph>();
567 checkGraphValidityErase<ListGraph>();
569 { // Checking SmartGraph
570 checkGraphBuild<SmartGraph>();
571 checkGraphSnapshot<SmartGraph>();
572 checkGraphValidity<SmartGraph>();
574 { // Checking FullGraph
578 { // Checking GridGraph
579 checkGridGraph(5, 8);
580 checkGridGraph(8, 5);
581 checkGridGraph(5, 5);
582 checkGridGraph(0, 0);
583 checkGridGraph(1, 1);
585 { // Checking HypercubeGraph
586 checkHypercubeGraph(1);
587 checkHypercubeGraph(2);
588 checkHypercubeGraph(3);
589 checkHypercubeGraph(4);