1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2008
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>
34 TEMPLATE_GRAPH_TYPEDEFS(Graph);
37 checkGraphNodeList(G, 0);
38 checkGraphEdgeList(G, 0);
44 checkGraphNodeList(G, 3);
45 checkGraphEdgeList(G, 0);
47 Edge e1 = G.addEdge(n1, n2);
48 check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
50 checkGraphNodeList(G, 3);
51 checkGraphArcList(G, 2);
52 checkGraphEdgeList(G, 1);
54 checkGraphOutArcList(G, n1, 1);
55 checkGraphOutArcList(G, n2, 1);
56 checkGraphOutArcList(G, n3, 0);
58 checkGraphInArcList(G, n1, 1);
59 checkGraphInArcList(G, n2, 1);
60 checkGraphInArcList(G, n3, 0);
62 checkGraphIncEdgeList(G, n1, 1);
63 checkGraphIncEdgeList(G, n2, 1);
64 checkGraphIncEdgeList(G, n3, 0);
66 checkGraphConArcList(G, 2);
67 checkGraphConEdgeList(G, 1);
69 Edge e2 = G.addEdge(n2, n1), e3 = G.addEdge(n2, n3);
70 checkGraphNodeList(G, 3);
71 checkGraphArcList(G, 6);
72 checkGraphEdgeList(G, 3);
74 checkGraphOutArcList(G, n1, 2);
75 checkGraphOutArcList(G, n2, 3);
76 checkGraphOutArcList(G, n3, 1);
78 checkGraphInArcList(G, n1, 2);
79 checkGraphInArcList(G, n2, 3);
80 checkGraphInArcList(G, n3, 1);
82 checkGraphIncEdgeList(G, n1, 2);
83 checkGraphIncEdgeList(G, n2, 3);
84 checkGraphIncEdgeList(G, n3, 1);
86 checkGraphConArcList(G, 6);
87 checkGraphConEdgeList(G, 3);
89 checkArcDirections(G);
99 void checkFullGraph(int num) {
100 typedef FullGraph Graph;
101 GRAPH_TYPEDEFS(Graph);
104 checkGraphNodeList(G, num);
105 checkGraphEdgeList(G, num * (num - 1) / 2);
107 for (NodeIt n(G); n != INVALID; ++n) {
108 checkGraphOutArcList(G, n, num - 1);
109 checkGraphInArcList(G, n, num - 1);
110 checkGraphIncEdgeList(G, n, num - 1);
113 checkGraphConArcList(G, num * (num - 1));
114 checkGraphConEdgeList(G, num * (num - 1) / 2);
116 checkArcDirections(G);
121 checkGraphNodeMap(G);
123 checkGraphEdgeMap(G);
126 for (int i = 0; i < G.nodeNum(); ++i) {
127 check(G.index(G(i)) == i, "Wrong index");
130 for (NodeIt u(G); u != INVALID; ++u) {
131 for (NodeIt v(G); v != INVALID; ++v) {
132 Edge e = G.edge(u, v);
135 check(e == INVALID, "Wrong edge lookup");
136 check(a == INVALID, "Wrong arc lookup");
138 check((G.u(e) == u && G.v(e) == v) ||
139 (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
140 check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
146 void checkConcepts() {
147 { // Checking graph components
148 checkConcept<BaseGraphComponent, BaseGraphComponent >();
150 checkConcept<IDableGraphComponent<>,
151 IDableGraphComponent<> >();
153 checkConcept<IterableGraphComponent<>,
154 IterableGraphComponent<> >();
156 checkConcept<MappableGraphComponent<>,
157 MappableGraphComponent<> >();
159 { // Checking skeleton graph
160 checkConcept<Graph, Graph>();
162 { // Checking ListGraph
163 checkConcept<Graph, ListGraph>();
164 checkConcept<AlterableGraphComponent<>, ListGraph>();
165 checkConcept<ExtendableGraphComponent<>, ListGraph>();
166 checkConcept<ClearableGraphComponent<>, ListGraph>();
167 checkConcept<ErasableGraphComponent<>, ListGraph>();
169 { // Checking SmartGraph
170 checkConcept<Graph, SmartGraph>();
171 checkConcept<AlterableGraphComponent<>, SmartGraph>();
172 checkConcept<ExtendableGraphComponent<>, SmartGraph>();
173 checkConcept<ClearableGraphComponent<>, SmartGraph>();
175 { // Checking FullGraph
176 checkConcept<Graph, FullGraph>();
178 { // Checking GridGraph
179 checkConcept<Graph, GridGraph>();
181 { // Checking HypercubeGraph
182 checkConcept<Graph, HypercubeGraph>();
186 template <typename Graph>
187 void checkGraphValidity() {
188 TEMPLATE_GRAPH_TYPEDEFS(Graph);
197 e1 = g.addEdge(n1, n2),
198 e2 = g.addEdge(n2, n3);
200 check(g.valid(n1), "Wrong validity check");
201 check(g.valid(e1), "Wrong validity check");
202 check(g.valid(g.direct(e1, true)), "Wrong validity check");
204 check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
205 check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
206 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
209 template <typename Graph>
210 void checkGraphValidityErase() {
211 TEMPLATE_GRAPH_TYPEDEFS(Graph);
220 e1 = g.addEdge(n1, n2),
221 e2 = g.addEdge(n2, n3);
223 check(g.valid(n1), "Wrong validity check");
224 check(g.valid(e1), "Wrong validity check");
225 check(g.valid(g.direct(e1, true)), "Wrong validity check");
229 check(!g.valid(n1), "Wrong validity check");
230 check(g.valid(n2), "Wrong validity check");
231 check(g.valid(n3), "Wrong validity check");
232 check(!g.valid(e1), "Wrong validity check");
233 check(g.valid(e2), "Wrong validity check");
235 check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
236 check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
237 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
240 void checkGridGraph(int width, int height) {
241 typedef GridGraph Graph;
242 GRAPH_TYPEDEFS(Graph);
243 Graph G(width, height);
245 check(G.width() == width, "Wrong column number");
246 check(G.height() == height, "Wrong row number");
248 for (int i = 0; i < width; ++i) {
249 for (int j = 0; j < height; ++j) {
250 check(G.col(G(i, j)) == i, "Wrong column");
251 check(G.row(G(i, j)) == j, "Wrong row");
252 check(G.pos(G(i, j)).x == i, "Wrong column");
253 check(G.pos(G(i, j)).y == j, "Wrong row");
257 for (int j = 0; j < height; ++j) {
258 for (int i = 0; i < width - 1; ++i) {
259 check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
260 check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
262 check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
265 for (int j = 0; j < height; ++j) {
266 for (int i = 1; i < width; ++i) {
267 check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
268 check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
270 check(G.left(G(0, j)) == INVALID, "Wrong left");
273 for (int i = 0; i < width; ++i) {
274 for (int j = 0; j < height - 1; ++j) {
275 check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
276 check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
278 check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
281 for (int i = 0; i < width; ++i) {
282 for (int j = 1; j < height; ++j) {
283 check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
284 check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
286 check(G.down(G(i, 0)) == INVALID, "Wrong down");
289 checkGraphNodeList(G, width * height);
290 checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
291 checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
293 for (NodeIt n(G); n != INVALID; ++n) {
295 if (G.col(n) == 0) --nb;
296 if (G.col(n) == width - 1) --nb;
297 if (G.row(n) == 0) --nb;
298 if (G.row(n) == height - 1) --nb;
300 checkGraphOutArcList(G, n, nb);
301 checkGraphInArcList(G, n, nb);
302 checkGraphIncEdgeList(G, n, nb);
305 checkArcDirections(G);
307 checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
308 checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
313 checkGraphNodeMap(G);
315 checkGraphEdgeMap(G);
319 void checkHypercubeGraph(int dim) {
320 GRAPH_TYPEDEFS(HypercubeGraph);
322 HypercubeGraph G(dim);
323 checkGraphNodeList(G, 1 << dim);
324 checkGraphEdgeList(G, dim * (1 << dim-1));
325 checkGraphArcList(G, dim * (1 << dim));
327 Node n = G.nodeFromId(dim);
329 for (NodeIt n(G); n != INVALID; ++n) {
330 checkGraphIncEdgeList(G, n, dim);
331 for (IncEdgeIt e(G, n); e != INVALID; ++e) {
332 check( (G.u(e) == n &&
333 G.id(G.v(e)) == G.id(n) ^ (1 << G.dimension(e))) ||
335 G.id(G.u(e)) == G.id(n) ^ (1 << G.dimension(e))),
336 "Wrong edge or wrong dimension");
339 checkGraphOutArcList(G, n, dim);
340 for (OutArcIt a(G, n); a != INVALID; ++a) {
341 check(G.source(a) == n &&
342 G.id(G.target(a)) == G.id(n) ^ (1 << G.dimension(a)),
343 "Wrong arc or wrong dimension");
346 checkGraphInArcList(G, n, dim);
347 for (InArcIt a(G, n); a != INVALID; ++a) {
348 check(G.target(a) == n &&
349 G.id(G.source(a)) == G.id(n) ^ (1 << G.dimension(a)),
350 "Wrong arc or wrong dimension");
354 checkGraphConArcList(G, (1 << dim) * dim);
355 checkGraphConEdgeList(G, dim * (1 << dim-1));
357 checkArcDirections(G);
362 checkGraphNodeMap(G);
364 checkGraphEdgeMap(G);
368 { // Checking ListGraph
369 checkGraph<ListGraph>();
370 checkGraphValidityErase<ListGraph>();
372 { // Checking SmartGraph
373 checkGraph<SmartGraph>();
374 checkGraphValidity<SmartGraph>();
376 { // Checking FullGraph
380 { // Checking GridGraph
381 checkGridGraph(5, 8);
382 checkGridGraph(8, 5);
383 checkGridGraph(5, 5);
384 checkGridGraph(0, 0);
385 checkGridGraph(1, 1);
387 { // Checking HypercubeGraph
388 checkHypercubeGraph(1);
389 checkHypercubeGraph(2);
390 checkHypercubeGraph(3);
391 checkHypercubeGraph(4);