0
4
1
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 |
* |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 |
* |
|
5 |
* Copyright (C) 2003-2008 |
|
6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
8 |
* |
|
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. |
|
12 |
* |
|
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 |
|
15 |
* purpose. |
|
16 |
* |
|
17 |
*/ |
|
18 |
|
|
19 |
#ifndef HYPERCUBE_GRAPH_H |
|
20 |
#define HYPERCUBE_GRAPH_H |
|
21 |
|
|
22 |
#include <vector> |
|
23 |
#include <lemon/core.h> |
|
24 |
#include <lemon/assert.h> |
|
25 |
#include <lemon/bits/graph_extender.h> |
|
26 |
|
|
27 |
///\ingroup graphs |
|
28 |
///\file |
|
29 |
///\brief HypercubeGraph class. |
|
30 |
|
|
31 |
namespace lemon { |
|
32 |
|
|
33 |
class HypercubeGraphBase { |
|
34 |
|
|
35 |
public: |
|
36 |
|
|
37 |
typedef HypercubeGraphBase Graph; |
|
38 |
|
|
39 |
class Node; |
|
40 |
class Edge; |
|
41 |
class Arc; |
|
42 |
|
|
43 |
public: |
|
44 |
|
|
45 |
HypercubeGraphBase() {} |
|
46 |
|
|
47 |
protected: |
|
48 |
|
|
49 |
void construct(int dim) { |
|
50 |
LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1."); |
|
51 |
_dim = dim; |
|
52 |
_node_num = 1 << dim; |
|
53 |
_edge_num = dim * (1 << dim-1); |
|
54 |
} |
|
55 |
|
|
56 |
public: |
|
57 |
|
|
58 |
typedef True NodeNumTag; |
|
59 |
typedef True EdgeNumTag; |
|
60 |
typedef True ArcNumTag; |
|
61 |
|
|
62 |
int nodeNum() const { return _node_num; } |
|
63 |
int edgeNum() const { return _edge_num; } |
|
64 |
int arcNum() const { return 2 * _edge_num; } |
|
65 |
|
|
66 |
int maxNodeId() const { return _node_num - 1; } |
|
67 |
int maxEdgeId() const { return _edge_num - 1; } |
|
68 |
int maxArcId() const { return 2 * _edge_num - 1; } |
|
69 |
|
|
70 |
static Node nodeFromId(int id) { return Node(id); } |
|
71 |
static Edge edgeFromId(int id) { return Edge(id); } |
|
72 |
static Arc arcFromId(int id) { return Arc(id); } |
|
73 |
|
|
74 |
static int id(Node node) { return node._id; } |
|
75 |
static int id(Edge edge) { return edge._id; } |
|
76 |
static int id(Arc arc) { return arc._id; } |
|
77 |
|
|
78 |
Node u(Edge edge) const { |
|
79 |
int base = edge._id & ((1 << _dim-1) - 1); |
|
80 |
int k = edge._id >> _dim-1; |
|
81 |
return ((base >> k) << k+1) | (base & ((1 << k) - 1)); |
|
82 |
} |
|
83 |
|
|
84 |
Node v(Edge edge) const { |
|
85 |
int base = edge._id & ((1 << _dim-1) - 1); |
|
86 |
int k = edge._id >> _dim-1; |
|
87 |
return ((base >> k) << k+1) | (base & ((1 << k) - 1)) | (1 << k); |
|
88 |
} |
|
89 |
|
|
90 |
Node source(Arc arc) const { |
|
91 |
return (arc._id & 1) == 1 ? u(arc) : v(arc); |
|
92 |
} |
|
93 |
|
|
94 |
Node target(Arc arc) const { |
|
95 |
return (arc._id & 1) == 1 ? v(arc) : u(arc); |
|
96 |
} |
|
97 |
|
|
98 |
typedef True FindEdgeTag; |
|
99 |
typedef True FindArcTag; |
|
100 |
|
|
101 |
Edge findEdge(Node u, Node v, Edge prev = INVALID) const { |
|
102 |
if (prev != INVALID) return INVALID; |
|
103 |
int d = u._id ^ v._id; |
|
104 |
int k = 0; |
|
105 |
if (d == 0) return INVALID; |
|
106 |
for ( ; (d & 1) == 0; d >>= 1) ++k; |
|
107 |
if (d >> 1 != 0) return INVALID; |
|
108 |
return (k << _dim-1) | ((u._id >> k+1) << k) | (u._id & ((1 << k) - 1)); |
|
109 |
} |
|
110 |
|
|
111 |
Arc findArc(Node u, Node v, Arc prev = INVALID) const { |
|
112 |
Edge edge = findEdge(u, v, prev); |
|
113 |
if (edge == INVALID) return INVALID; |
|
114 |
int k = edge._id >> _dim-1; |
|
115 |
return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1; |
|
116 |
} |
|
117 |
|
|
118 |
class Node { |
|
119 |
friend class HypercubeGraphBase; |
|
120 |
|
|
121 |
protected: |
|
122 |
int _id; |
|
123 |
Node(int id) : _id(id) {} |
|
124 |
public: |
|
125 |
Node() {} |
|
126 |
Node (Invalid) : _id(-1) {} |
|
127 |
bool operator==(const Node node) const {return _id == node._id;} |
|
128 |
bool operator!=(const Node node) const {return _id != node._id;} |
|
129 |
bool operator<(const Node node) const {return _id < node._id;} |
|
130 |
}; |
|
131 |
|
|
132 |
class Edge { |
|
133 |
friend class HypercubeGraphBase; |
|
134 |
friend class Arc; |
|
135 |
|
|
136 |
protected: |
|
137 |
int _id; |
|
138 |
|
|
139 |
Edge(int id) : _id(id) {} |
|
140 |
|
|
141 |
public: |
|
142 |
Edge() {} |
|
143 |
Edge (Invalid) : _id(-1) {} |
|
144 |
bool operator==(const Edge edge) const {return _id == edge._id;} |
|
145 |
bool operator!=(const Edge edge) const {return _id != edge._id;} |
|
146 |
bool operator<(const Edge edge) const {return _id < edge._id;} |
|
147 |
}; |
|
148 |
|
|
149 |
class Arc { |
|
150 |
friend class HypercubeGraphBase; |
|
151 |
|
|
152 |
protected: |
|
153 |
int _id; |
|
154 |
|
|
155 |
Arc(int id) : _id(id) {} |
|
156 |
|
|
157 |
public: |
|
158 |
Arc() {} |
|
159 |
Arc (Invalid) : _id(-1) {} |
|
160 |
operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; } |
|
161 |
bool operator==(const Arc arc) const {return _id == arc._id;} |
|
162 |
bool operator!=(const Arc arc) const {return _id != arc._id;} |
|
163 |
bool operator<(const Arc arc) const {return _id < arc._id;} |
|
164 |
}; |
|
165 |
|
|
166 |
void first(Node& node) const { |
|
167 |
node._id = _node_num - 1; |
|
168 |
} |
|
169 |
|
|
170 |
static void next(Node& node) { |
|
171 |
--node._id; |
|
172 |
} |
|
173 |
|
|
174 |
void first(Edge& edge) const { |
|
175 |
edge._id = _edge_num - 1; |
|
176 |
} |
|
177 |
|
|
178 |
static void next(Edge& edge) { |
|
179 |
--edge._id; |
|
180 |
} |
|
181 |
|
|
182 |
void first(Arc& arc) const { |
|
183 |
arc._id = 2 * _edge_num - 1; |
|
184 |
} |
|
185 |
|
|
186 |
static void next(Arc& arc) { |
|
187 |
--arc._id; |
|
188 |
} |
|
189 |
|
|
190 |
void firstInc(Edge& edge, bool& dir, const Node& node) const { |
|
191 |
edge._id = node._id >> 1; |
|
192 |
dir = (node._id & 1) == 0; |
|
193 |
} |
|
194 |
|
|
195 |
void nextInc(Edge& edge, bool& dir) const { |
|
196 |
Node n = dir ? u(edge) : v(edge); |
|
197 |
int k = (edge._id >> _dim-1) + 1; |
|
198 |
if (k < _dim) { |
|
199 |
edge._id = (k << _dim-1) | |
|
200 |
((n._id >> k+1) << k) | (n._id & ((1 << k) - 1)); |
|
201 |
dir = ((n._id >> k) & 1) == 0; |
|
202 |
} else { |
|
203 |
edge._id = -1; |
|
204 |
dir = true; |
|
205 |
} |
|
206 |
} |
|
207 |
|
|
208 |
void firstOut(Arc& arc, const Node& node) const { |
|
209 |
arc._id = ((node._id >> 1) << 1) | (~node._id & 1); |
|
210 |
} |
|
211 |
|
|
212 |
void nextOut(Arc& arc) const { |
|
213 |
Node n = (arc._id & 1) == 1 ? u(arc) : v(arc); |
|
214 |
int k = (arc._id >> _dim) + 1; |
|
215 |
if (k < _dim) { |
|
216 |
arc._id = (k << _dim-1) | |
|
217 |
((n._id >> k+1) << k) | (n._id & ((1 << k) - 1)); |
|
218 |
arc._id = (arc._id << 1) | (~(n._id >> k) & 1); |
|
219 |
} else { |
|
220 |
arc._id = -1; |
|
221 |
} |
|
222 |
} |
|
223 |
|
|
224 |
void firstIn(Arc& arc, const Node& node) const { |
|
225 |
arc._id = ((node._id >> 1) << 1) | (node._id & 1); |
|
226 |
} |
|
227 |
|
|
228 |
void nextIn(Arc& arc) const { |
|
229 |
Node n = (arc._id & 1) == 1 ? v(arc) : u(arc); |
|
230 |
int k = (arc._id >> _dim) + 1; |
|
231 |
if (k < _dim) { |
|
232 |
arc._id = (k << _dim-1) | |
|
233 |
((n._id >> k+1) << k) | (n._id & ((1 << k) - 1)); |
|
234 |
arc._id = (arc._id << 1) | ((n._id >> k) & 1); |
|
235 |
} else { |
|
236 |
arc._id = -1; |
|
237 |
} |
|
238 |
} |
|
239 |
|
|
240 |
static bool direction(Arc arc) { |
|
241 |
return (arc._id & 1) == 1; |
|
242 |
} |
|
243 |
|
|
244 |
static Arc direct(Edge edge, bool dir) { |
|
245 |
return Arc((edge._id << 1) | (dir ? 1 : 0)); |
|
246 |
} |
|
247 |
|
|
248 |
int dimension() const { |
|
249 |
return _dim; |
|
250 |
} |
|
251 |
|
|
252 |
bool projection(Node node, int n) const { |
|
253 |
return static_cast<bool>(node._id & (1 << n)); |
|
254 |
} |
|
255 |
|
|
256 |
int dimension(Edge edge) const { |
|
257 |
return edge._id >> _dim-1; |
|
258 |
} |
|
259 |
|
|
260 |
int dimension(Arc arc) const { |
|
261 |
return arc._id >> _dim; |
|
262 |
} |
|
263 |
|
|
264 |
int index(Node node) const { |
|
265 |
return node._id; |
|
266 |
} |
|
267 |
|
|
268 |
Node operator()(int ix) const { |
|
269 |
return Node(ix); |
|
270 |
} |
|
271 |
|
|
272 |
private: |
|
273 |
int _dim; |
|
274 |
int _node_num, _edge_num; |
|
275 |
}; |
|
276 |
|
|
277 |
|
|
278 |
typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase; |
|
279 |
|
|
280 |
/// \ingroup graphs |
|
281 |
/// |
|
282 |
/// \brief Hypercube graph class |
|
283 |
/// |
|
284 |
/// This class implements a special graph type. The nodes of the graph |
|
285 |
/// are indiced with integers with at most \c dim binary digits. |
|
286 |
/// Two nodes are connected in the graph if and only if their indices |
|
287 |
/// differ only on one position in the binary form. |
|
288 |
/// |
|
289 |
/// \note The type of the indices is chosen to \c int for efficiency |
|
290 |
/// reasons. Thus the maximum dimension of this implementation is 26 |
|
291 |
/// (assuming that the size of \c int is 32 bit). |
|
292 |
/// |
|
293 |
/// This graph type is fully conform to the \ref concepts::Graph |
|
294 |
/// "Graph" concept, and it also has an important extra feature |
|
295 |
/// that its maps are real \ref concepts::ReferenceMap |
|
296 |
/// "reference map"s. |
|
297 |
class HypercubeGraph : public ExtendedHypercubeGraphBase { |
|
298 |
public: |
|
299 |
|
|
300 |
typedef ExtendedHypercubeGraphBase Parent; |
|
301 |
|
|
302 |
/// \brief Constructs a hypercube graph with \c dim dimensions. |
|
303 |
/// |
|
304 |
/// Constructs a hypercube graph with \c dim dimensions. |
|
305 |
HypercubeGraph(int dim) { construct(dim); } |
|
306 |
|
|
307 |
/// \brief The number of dimensions. |
|
308 |
/// |
|
309 |
/// Gives back the number of dimensions. |
|
310 |
int dimension() const { |
|
311 |
return Parent::dimension(); |
|
312 |
} |
|
313 |
|
|
314 |
/// \brief Returns \c true if the n'th bit of the node is one. |
|
315 |
/// |
|
316 |
/// Returns \c true if the n'th bit of the node is one. |
|
317 |
bool projection(Node node, int n) const { |
|
318 |
return Parent::projection(node, n); |
|
319 |
} |
|
320 |
|
|
321 |
/// \brief The dimension id of an edge. |
|
322 |
/// |
|
323 |
/// Gives back the dimension id of the given edge. |
|
324 |
/// It is in the [0..dim-1] range. |
|
325 |
int dimension(Edge edge) const { |
|
326 |
return Parent::dimension(edge); |
|
327 |
} |
|
328 |
|
|
329 |
/// \brief The dimension id of an arc. |
|
330 |
/// |
|
331 |
/// Gives back the dimension id of the given arc. |
|
332 |
/// It is in the [0..dim-1] range. |
|
333 |
int dimension(Arc arc) const { |
|
334 |
return Parent::dimension(arc); |
|
335 |
} |
|
336 |
|
|
337 |
/// \brief The index of a node. |
|
338 |
/// |
|
339 |
/// Gives back the index of the given node. |
|
340 |
/// The lower bits of the integer describes the node. |
|
341 |
int index(Node node) const { |
|
342 |
return Parent::index(node); |
|
343 |
} |
|
344 |
|
|
345 |
/// \brief Gives back a node by its index. |
|
346 |
/// |
|
347 |
/// Gives back a node by its index. |
|
348 |
Node operator()(int ix) const { |
|
349 |
return Parent::operator()(ix); |
|
350 |
} |
|
351 |
|
|
352 |
/// \brief Number of nodes. |
|
353 |
int nodeNum() const { return Parent::nodeNum(); } |
|
354 |
/// \brief Number of edges. |
|
355 |
int edgeNum() const { return Parent::edgeNum(); } |
|
356 |
/// \brief Number of arcs. |
|
357 |
int arcNum() const { return Parent::arcNum(); } |
|
358 |
|
|
359 |
/// \brief Linear combination map. |
|
360 |
/// |
|
361 |
/// This map makes possible to give back a linear combination |
|
362 |
/// for each node. It works like the \c std::accumulate function, |
|
363 |
/// so it accumulates the \c bf binary function with the \c fv first |
|
364 |
/// value. The map accumulates only on that positions (dimensions) |
|
365 |
/// where the index of the node is one. The values that have to be |
|
366 |
/// accumulated should be given by the \c begin and \c end iterators |
|
367 |
/// and the length of this range should be equal to the dimension |
|
368 |
/// number of the graph. |
|
369 |
/// |
|
370 |
///\code |
|
371 |
/// const int DIM = 3; |
|
372 |
/// HypercubeGraph graph(DIM); |
|
373 |
/// dim2::Point<double> base[DIM]; |
|
374 |
/// for (int k = 0; k < DIM; ++k) { |
|
375 |
/// base[k].x = rnd(); |
|
376 |
/// base[k].y = rnd(); |
|
377 |
/// } |
|
378 |
/// HypercubeGraph::HyperMap<dim2::Point<double> > |
|
379 |
/// pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0)); |
|
380 |
///\endcode |
|
381 |
/// |
|
382 |
/// \see HypercubeGraph |
|
383 |
template <typename T, typename BF = std::plus<T> > |
|
384 |
class HyperMap { |
|
385 |
public: |
|
386 |
|
|
387 |
/// \brief The key type of the map |
|
388 |
typedef Node Key; |
|
389 |
/// \brief The value type of the map |
|
390 |
typedef T Value; |
|
391 |
|
|
392 |
/// \brief Constructor for HyperMap. |
|
393 |
/// |
|
394 |
/// Construct a HyperMap for the given graph. The values that have |
|
395 |
/// to be accumulated should be given by the \c begin and \c end |
|
396 |
/// iterators and the length of this range should be equal to the |
|
397 |
/// dimension number of the graph. |
|
398 |
/// |
|
399 |
/// This map accumulates the \c bf binary function with the \c fv |
|
400 |
/// first value on that positions (dimensions) where the index of |
|
401 |
/// the node is one. |
|
402 |
template <typename It> |
|
403 |
HyperMap(const Graph& graph, It begin, It end, |
|
404 |
T fv = 0, const BF& bf = BF()) |
|
405 |
: _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf) |
|
406 |
{ |
|
407 |
LEMON_ASSERT(_values.size() == graph.dimension(), |
|
408 |
"Wrong size of range"); |
|
409 |
} |
|
410 |
|
|
411 |
/// \brief The partial accumulated value. |
|
412 |
/// |
|
413 |
/// Gives back the partial accumulated value. |
|
414 |
Value operator[](const Key& k) const { |
|
415 |
Value val = _first_value; |
|
416 |
int id = _graph.index(k); |
|
417 |
int n = 0; |
|
418 |
while (id != 0) { |
|
419 |
if (id & 1) { |
|
420 |
val = _bin_func(val, _values[n]); |
|
421 |
} |
|
422 |
id >>= 1; |
|
423 |
++n; |
|
424 |
} |
|
425 |
return val; |
|
426 |
} |
|
427 |
|
|
428 |
private: |
|
429 |
const Graph& _graph; |
|
430 |
std::vector<T> _values; |
|
431 |
T _first_value; |
|
432 |
BF _bin_func; |
|
433 |
}; |
|
434 |
|
|
435 |
}; |
|
436 |
|
|
437 |
} |
|
438 |
|
|
439 |
#endif |
... | ... |
@@ -10,48 +10,49 @@ |
10 | 10 |
lemon/arg_parser.cc \ |
11 | 11 |
lemon/base.cc \ |
12 | 12 |
lemon/color.cc \ |
13 | 13 |
lemon/random.cc |
14 | 14 |
|
15 | 15 |
#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS) $(AM_CXXFLAGS) |
16 | 16 |
#lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS) |
17 | 17 |
|
18 | 18 |
lemon_HEADERS += \ |
19 | 19 |
lemon/arg_parser.h \ |
20 | 20 |
lemon/assert.h \ |
21 | 21 |
lemon/bfs.h \ |
22 | 22 |
lemon/bin_heap.h \ |
23 | 23 |
lemon/color.h \ |
24 | 24 |
lemon/concept_check.h \ |
25 | 25 |
lemon/counter.h \ |
26 | 26 |
lemon/core.h \ |
27 | 27 |
lemon/dfs.h \ |
28 | 28 |
lemon/dijkstra.h \ |
29 | 29 |
lemon/dim2.h \ |
30 | 30 |
lemon/error.h \ |
31 | 31 |
lemon/full_graph.h \ |
32 | 32 |
lemon/graph_to_eps.h \ |
33 | 33 |
lemon/grid_graph.h \ |
34 |
lemon/hypercube_graph.h \ |
|
34 | 35 |
lemon/kruskal.h \ |
35 | 36 |
lemon/lgf_reader.h \ |
36 | 37 |
lemon/lgf_writer.h \ |
37 | 38 |
lemon/list_graph.h \ |
38 | 39 |
lemon/maps.h \ |
39 | 40 |
lemon/math.h \ |
40 | 41 |
lemon/max_matching.h \ |
41 | 42 |
lemon/nauty_reader.h \ |
42 | 43 |
lemon/path.h \ |
43 | 44 |
lemon/random.h \ |
44 | 45 |
lemon/smart_graph.h \ |
45 | 46 |
lemon/suurballe.h \ |
46 | 47 |
lemon/time_measure.h \ |
47 | 48 |
lemon/tolerance.h \ |
48 | 49 |
lemon/unionfind.h |
49 | 50 |
|
50 | 51 |
bits_HEADERS += \ |
51 | 52 |
lemon/bits/alteration_notifier.h \ |
52 | 53 |
lemon/bits/array_map.h \ |
53 | 54 |
lemon/bits/base_extender.h \ |
54 | 55 |
lemon/bits/bezier.h \ |
55 | 56 |
lemon/bits/default_map.h \ |
56 | 57 |
lemon/bits/enable_if.h \ |
57 | 58 |
lemon/bits/graph_extender.h \ |
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-2008 |
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 |
//#include <lemon/hypercube_graph.h> |
|
24 | 23 |
|
25 | 24 |
#include "test_tools.h" |
26 | 25 |
#include "graph_test.h" |
27 | 26 |
|
28 | 27 |
using namespace lemon; |
29 | 28 |
using namespace lemon::concepts; |
30 | 29 |
|
31 | 30 |
template <class Digraph> |
32 | 31 |
void checkDigraph() { |
33 | 32 |
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); |
34 | 33 |
Digraph G; |
35 | 34 |
|
36 | 35 |
checkGraphNodeList(G, 0); |
37 | 36 |
checkGraphArcList(G, 0); |
38 | 37 |
|
39 | 38 |
Node |
40 | 39 |
n1 = G.addNode(), |
41 | 40 |
n2 = G.addNode(), |
42 | 41 |
n3 = G.addNode(); |
43 | 42 |
checkGraphNodeList(G, 3); |
44 | 43 |
checkGraphArcList(G, 0); |
45 | 44 |
|
46 | 45 |
Arc a1 = G.addArc(n1, n2); |
47 | 46 |
check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc"); |
... | ... |
@@ -91,84 +90,80 @@ |
91 | 90 |
checkGraphOutArcList(G, n, num); |
92 | 91 |
checkGraphInArcList(G, n, num); |
93 | 92 |
} |
94 | 93 |
|
95 | 94 |
checkGraphConArcList(G, num * num); |
96 | 95 |
|
97 | 96 |
checkNodeIds(G); |
98 | 97 |
checkArcIds(G); |
99 | 98 |
checkGraphNodeMap(G); |
100 | 99 |
checkGraphArcMap(G); |
101 | 100 |
|
102 | 101 |
for (int i = 0; i < G.nodeNum(); ++i) { |
103 | 102 |
check(G.index(G(i)) == i, "Wrong index"); |
104 | 103 |
} |
105 | 104 |
|
106 | 105 |
for (NodeIt s(G); s != INVALID; ++s) { |
107 | 106 |
for (NodeIt t(G); t != INVALID; ++t) { |
108 | 107 |
Arc a = G.arc(s, t); |
109 | 108 |
check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup"); |
110 | 109 |
} |
111 | 110 |
} |
112 | 111 |
|
113 | 112 |
} |
114 | 113 |
|
115 |
|
|
116 | 114 |
void checkConcepts() { |
117 | 115 |
{ // Checking digraph components |
118 | 116 |
checkConcept<BaseDigraphComponent, BaseDigraphComponent >(); |
119 | 117 |
|
120 | 118 |
checkConcept<IDableDigraphComponent<>, |
121 | 119 |
IDableDigraphComponent<> >(); |
122 | 120 |
|
123 | 121 |
checkConcept<IterableDigraphComponent<>, |
124 | 122 |
IterableDigraphComponent<> >(); |
125 | 123 |
|
126 | 124 |
checkConcept<MappableDigraphComponent<>, |
127 | 125 |
MappableDigraphComponent<> >(); |
128 | 126 |
} |
129 | 127 |
{ // Checking skeleton digraph |
130 | 128 |
checkConcept<Digraph, Digraph>(); |
131 | 129 |
} |
132 | 130 |
{ // Checking ListDigraph |
133 | 131 |
checkConcept<Digraph, ListDigraph>(); |
134 | 132 |
checkConcept<AlterableDigraphComponent<>, ListDigraph>(); |
135 | 133 |
checkConcept<ExtendableDigraphComponent<>, ListDigraph>(); |
136 | 134 |
checkConcept<ClearableDigraphComponent<>, ListDigraph>(); |
137 | 135 |
checkConcept<ErasableDigraphComponent<>, ListDigraph>(); |
138 | 136 |
} |
139 | 137 |
{ // Checking SmartDigraph |
140 | 138 |
checkConcept<Digraph, SmartDigraph>(); |
141 | 139 |
checkConcept<AlterableDigraphComponent<>, SmartDigraph>(); |
142 | 140 |
checkConcept<ExtendableDigraphComponent<>, SmartDigraph>(); |
143 | 141 |
checkConcept<ClearableDigraphComponent<>, SmartDigraph>(); |
144 | 142 |
} |
145 | 143 |
{ // Checking FullDigraph |
146 | 144 |
checkConcept<Digraph, FullDigraph>(); |
147 | 145 |
} |
148 |
// { // Checking HyperCubeDigraph |
|
149 |
// checkConcept<Digraph, HyperCubeDigraph>(); |
|
150 |
// } |
|
151 | 146 |
} |
152 | 147 |
|
153 | 148 |
template <typename Digraph> |
154 | 149 |
void checkDigraphValidity() { |
155 | 150 |
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); |
156 | 151 |
Digraph g; |
157 | 152 |
|
158 | 153 |
Node |
159 | 154 |
n1 = g.addNode(), |
160 | 155 |
n2 = g.addNode(), |
161 | 156 |
n3 = g.addNode(); |
162 | 157 |
|
163 | 158 |
Arc |
164 | 159 |
e1 = g.addArc(n1, n2), |
165 | 160 |
e2 = g.addArc(n2, n3); |
166 | 161 |
|
167 | 162 |
check(g.valid(n1), "Wrong validity check"); |
168 | 163 |
check(g.valid(e1), "Wrong validity check"); |
169 | 164 |
|
170 | 165 |
check(!g.valid(g.nodeFromId(-1)), "Wrong validity check"); |
171 | 166 |
check(!g.valid(g.arcFromId(-1)), "Wrong validity check"); |
172 | 167 |
} |
173 | 168 |
|
174 | 169 |
template <typename Digraph> |
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-2008 |
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 |
#include <lemon/hypercube_graph.h> |
|
24 | 25 |
|
25 | 26 |
#include "test_tools.h" |
26 | 27 |
#include "graph_test.h" |
27 | 28 |
|
28 | 29 |
using namespace lemon; |
29 | 30 |
using namespace lemon::concepts; |
30 | 31 |
|
31 | 32 |
template <class Graph> |
32 | 33 |
void checkGraph() { |
33 | 34 |
TEMPLATE_GRAPH_TYPEDEFS(Graph); |
34 | 35 |
|
35 | 36 |
Graph G; |
36 | 37 |
checkGraphNodeList(G, 0); |
37 | 38 |
checkGraphEdgeList(G, 0); |
38 | 39 |
|
39 | 40 |
Node |
40 | 41 |
n1 = G.addNode(), |
41 | 42 |
n2 = G.addNode(), |
42 | 43 |
n3 = G.addNode(); |
43 | 44 |
checkGraphNodeList(G, 3); |
44 | 45 |
checkGraphEdgeList(G, 0); |
45 | 46 |
|
46 | 47 |
Edge e1 = G.addEdge(n1, n2); |
47 | 48 |
check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1), |
... | ... |
@@ -83,66 +84,66 @@ |
83 | 84 |
checkGraphIncEdgeList(G, n3, 1); |
84 | 85 |
|
85 | 86 |
checkGraphConArcList(G, 6); |
86 | 87 |
checkGraphConEdgeList(G, 3); |
87 | 88 |
|
88 | 89 |
checkArcDirections(G); |
89 | 90 |
|
90 | 91 |
checkNodeIds(G); |
91 | 92 |
checkArcIds(G); |
92 | 93 |
checkEdgeIds(G); |
93 | 94 |
checkGraphNodeMap(G); |
94 | 95 |
checkGraphArcMap(G); |
95 | 96 |
checkGraphEdgeMap(G); |
96 | 97 |
} |
97 | 98 |
|
98 | 99 |
void checkFullGraph(int num) { |
99 | 100 |
typedef FullGraph Graph; |
100 | 101 |
GRAPH_TYPEDEFS(Graph); |
101 | 102 |
|
102 | 103 |
Graph G(num); |
103 | 104 |
checkGraphNodeList(G, num); |
104 | 105 |
checkGraphEdgeList(G, num * (num - 1) / 2); |
105 | 106 |
|
106 | 107 |
for (NodeIt n(G); n != INVALID; ++n) { |
107 |
checkGraphOutArcList(G, n, num - 1); |
|
108 |
checkGraphInArcList(G, n, num - 1); |
|
109 |
|
|
108 |
checkGraphOutArcList(G, n, num - 1); |
|
109 |
checkGraphInArcList(G, n, num - 1); |
|
110 |
checkGraphIncEdgeList(G, n, num - 1); |
|
110 | 111 |
} |
111 | 112 |
|
112 | 113 |
checkGraphConArcList(G, num * (num - 1)); |
113 | 114 |
checkGraphConEdgeList(G, num * (num - 1) / 2); |
114 | 115 |
|
115 | 116 |
checkArcDirections(G); |
116 | 117 |
|
117 | 118 |
checkNodeIds(G); |
118 | 119 |
checkArcIds(G); |
119 | 120 |
checkEdgeIds(G); |
120 | 121 |
checkGraphNodeMap(G); |
121 | 122 |
checkGraphArcMap(G); |
122 | 123 |
checkGraphEdgeMap(G); |
123 | 124 |
|
124 |
|
|
125 |
|
|
125 | 126 |
for (int i = 0; i < G.nodeNum(); ++i) { |
126 | 127 |
check(G.index(G(i)) == i, "Wrong index"); |
127 | 128 |
} |
128 | 129 |
|
129 | 130 |
for (NodeIt u(G); u != INVALID; ++u) { |
130 | 131 |
for (NodeIt v(G); v != INVALID; ++v) { |
131 | 132 |
Edge e = G.edge(u, v); |
132 | 133 |
Arc a = G.arc(u, v); |
133 | 134 |
if (u == v) { |
134 | 135 |
check(e == INVALID, "Wrong edge lookup"); |
135 | 136 |
check(a == INVALID, "Wrong arc lookup"); |
136 | 137 |
} else { |
137 | 138 |
check((G.u(e) == u && G.v(e) == v) || |
138 | 139 |
(G.u(e) == v && G.v(e) == u), "Wrong edge lookup"); |
139 | 140 |
check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup"); |
140 | 141 |
} |
141 | 142 |
} |
142 | 143 |
} |
143 | 144 |
} |
144 | 145 |
|
145 | 146 |
void checkConcepts() { |
146 | 147 |
{ // Checking graph components |
147 | 148 |
checkConcept<BaseGraphComponent, BaseGraphComponent >(); |
148 | 149 |
|
... | ... |
@@ -156,48 +157,51 @@ |
156 | 157 |
MappableGraphComponent<> >(); |
157 | 158 |
} |
158 | 159 |
{ // Checking skeleton graph |
159 | 160 |
checkConcept<Graph, Graph>(); |
160 | 161 |
} |
161 | 162 |
{ // Checking ListGraph |
162 | 163 |
checkConcept<Graph, ListGraph>(); |
163 | 164 |
checkConcept<AlterableGraphComponent<>, ListGraph>(); |
164 | 165 |
checkConcept<ExtendableGraphComponent<>, ListGraph>(); |
165 | 166 |
checkConcept<ClearableGraphComponent<>, ListGraph>(); |
166 | 167 |
checkConcept<ErasableGraphComponent<>, ListGraph>(); |
167 | 168 |
} |
168 | 169 |
{ // Checking SmartGraph |
169 | 170 |
checkConcept<Graph, SmartGraph>(); |
170 | 171 |
checkConcept<AlterableGraphComponent<>, SmartGraph>(); |
171 | 172 |
checkConcept<ExtendableGraphComponent<>, SmartGraph>(); |
172 | 173 |
checkConcept<ClearableGraphComponent<>, SmartGraph>(); |
173 | 174 |
} |
174 | 175 |
{ // Checking FullGraph |
175 | 176 |
checkConcept<Graph, FullGraph>(); |
176 | 177 |
} |
177 | 178 |
{ // Checking GridGraph |
178 | 179 |
checkConcept<Graph, GridGraph>(); |
179 | 180 |
} |
181 |
{ // Checking HypercubeGraph |
|
182 |
checkConcept<Graph, HypercubeGraph>(); |
|
183 |
} |
|
180 | 184 |
} |
181 | 185 |
|
182 | 186 |
template <typename Graph> |
183 | 187 |
void checkGraphValidity() { |
184 | 188 |
TEMPLATE_GRAPH_TYPEDEFS(Graph); |
185 | 189 |
Graph g; |
186 | 190 |
|
187 | 191 |
Node |
188 | 192 |
n1 = g.addNode(), |
189 | 193 |
n2 = g.addNode(), |
190 | 194 |
n3 = g.addNode(); |
191 | 195 |
|
192 | 196 |
Edge |
193 | 197 |
e1 = g.addEdge(n1, n2), |
194 | 198 |
e2 = g.addEdge(n2, n3); |
195 | 199 |
|
196 | 200 |
check(g.valid(n1), "Wrong validity check"); |
197 | 201 |
check(g.valid(e1), "Wrong validity check"); |
198 | 202 |
check(g.valid(g.direct(e1, true)), "Wrong validity check"); |
199 | 203 |
|
200 | 204 |
check(!g.valid(g.nodeFromId(-1)), "Wrong validity check"); |
201 | 205 |
check(!g.valid(g.edgeFromId(-1)), "Wrong validity check"); |
202 | 206 |
check(!g.valid(g.arcFromId(-1)), "Wrong validity check"); |
203 | 207 |
} |
... | ... |
@@ -291,51 +295,105 @@ |
291 | 295 |
if (G.col(n) == 0) --nb; |
292 | 296 |
if (G.col(n) == width - 1) --nb; |
293 | 297 |
if (G.row(n) == 0) --nb; |
294 | 298 |
if (G.row(n) == height - 1) --nb; |
295 | 299 |
|
296 | 300 |
checkGraphOutArcList(G, n, nb); |
297 | 301 |
checkGraphInArcList(G, n, nb); |
298 | 302 |
checkGraphIncEdgeList(G, n, nb); |
299 | 303 |
} |
300 | 304 |
|
301 | 305 |
checkArcDirections(G); |
302 | 306 |
|
303 | 307 |
checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height)); |
304 | 308 |
checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height); |
305 | 309 |
|
306 | 310 |
checkNodeIds(G); |
307 | 311 |
checkArcIds(G); |
308 | 312 |
checkEdgeIds(G); |
309 | 313 |
checkGraphNodeMap(G); |
310 | 314 |
checkGraphArcMap(G); |
311 | 315 |
checkGraphEdgeMap(G); |
312 | 316 |
|
313 | 317 |
} |
314 | 318 |
|
319 |
void checkHypercubeGraph(int dim) { |
|
320 |
GRAPH_TYPEDEFS(HypercubeGraph); |
|
321 |
|
|
322 |
HypercubeGraph G(dim); |
|
323 |
checkGraphNodeList(G, 1 << dim); |
|
324 |
checkGraphEdgeList(G, dim * (1 << dim-1)); |
|
325 |
checkGraphArcList(G, dim * (1 << dim)); |
|
326 |
|
|
327 |
Node n = G.nodeFromId(dim); |
|
328 |
|
|
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))) || |
|
334 |
(G.v(e) == n && |
|
335 |
G.id(G.u(e)) == G.id(n) ^ (1 << G.dimension(e))), |
|
336 |
"Wrong edge or wrong dimension"); |
|
337 |
} |
|
338 |
|
|
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"); |
|
344 |
} |
|
345 |
|
|
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"); |
|
351 |
} |
|
352 |
} |
|
353 |
|
|
354 |
checkGraphConArcList(G, (1 << dim) * dim); |
|
355 |
checkGraphConEdgeList(G, dim * (1 << dim-1)); |
|
356 |
|
|
357 |
checkArcDirections(G); |
|
358 |
|
|
359 |
checkNodeIds(G); |
|
360 |
checkArcIds(G); |
|
361 |
checkEdgeIds(G); |
|
362 |
checkGraphNodeMap(G); |
|
363 |
checkGraphArcMap(G); |
|
364 |
checkGraphEdgeMap(G); |
|
365 |
} |
|
366 |
|
|
315 | 367 |
void checkGraphs() { |
316 | 368 |
{ // Checking ListGraph |
317 | 369 |
checkGraph<ListGraph>(); |
318 | 370 |
checkGraphValidityErase<ListGraph>(); |
319 | 371 |
} |
320 | 372 |
{ // Checking SmartGraph |
321 | 373 |
checkGraph<SmartGraph>(); |
322 | 374 |
checkGraphValidity<SmartGraph>(); |
323 | 375 |
} |
324 |
{ // Checking FullGraph |
|
376 |
{ // Checking FullGraph |
|
325 | 377 |
checkFullGraph(7); |
326 | 378 |
checkFullGraph(8); |
327 | 379 |
} |
328 | 380 |
{ // Checking GridGraph |
329 | 381 |
checkGridGraph(5, 8); |
330 | 382 |
checkGridGraph(8, 5); |
331 | 383 |
checkGridGraph(5, 5); |
332 | 384 |
checkGridGraph(0, 0); |
333 | 385 |
checkGridGraph(1, 1); |
334 | 386 |
} |
387 |
{ // Checking HypercubeGraph |
|
388 |
checkHypercubeGraph(1); |
|
389 |
checkHypercubeGraph(2); |
|
390 |
checkHypercubeGraph(3); |
|
391 |
checkHypercubeGraph(4); |
|
392 |
} |
|
335 | 393 |
} |
336 | 394 |
|
337 | 395 |
int main() { |
338 | 396 |
checkConcepts(); |
339 | 397 |
checkGraphs(); |
340 | 398 |
return 0; |
341 | 399 |
} |
... | ... |
@@ -60,37 +60,38 @@ |
60 | 60 |
-e "s/_gr_aph_label_/graph/g"\ |
61 | 61 |
-e "s/_Ar_c_label_/Arc/g"\ |
62 | 62 |
-e "s/_ar_c_label_/arc/g"\ |
63 | 63 |
-e "s/_Ed_ge_label_/Edge/g"\ |
64 | 64 |
-e "s/_ed_ge_label_/edge/g"\ |
65 | 65 |
-e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\ |
66 | 66 |
-e "s/_Re_d_label_/Red/g"\ |
67 | 67 |
-e "s/_Blu_e_label_/Blue/g"\ |
68 | 68 |
-e "s/_re_d_label_/red/g"\ |
69 | 69 |
-e "s/_blu_e_label_/blue/g"\ |
70 | 70 |
-e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\ |
71 | 71 |
-e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\ |
72 | 72 |
-e "s/DigraphToEps/GraphToEps/g"\ |
73 | 73 |
-e "s/digraphToEps/graphToEps/g"\ |
74 | 74 |
-e "s/\<DefPredMap\>/SetPredMap/g"\ |
75 | 75 |
-e "s/\<DefDistMap\>/SetDistMap/g"\ |
76 | 76 |
-e "s/\<DefReachedMap\>/SetReachedMap/g"\ |
77 | 77 |
-e "s/\<DefProcessedMap\>/SetProcessedMap/g"\ |
78 | 78 |
-e "s/\<DefHeap\>/SetHeap/g"\ |
79 | 79 |
-e "s/\<DefStandardHeap\>/SetStandradHeap/g"\ |
80 | 80 |
-e "s/\<DefOperationTraits\>/SetOperationTraits/g"\ |
81 | 81 |
-e "s/\<DefProcessedMapToBeDefaultMap\>/SetStandardProcessedMap/g"\ |
82 | 82 |
-e "s/\<copyGraph\>/graphCopy/g"\ |
83 | 83 |
-e "s/\<copyDigraph\>/digraphCopy/g"\ |
84 |
-e "s/\<HyperCubeDigraph\>/HypercubeGraph/g"\ |
|
84 | 85 |
-e "s/\<IntegerMap\>/RangeMap/g"\ |
85 | 86 |
-e "s/\<integerMap\>/rangeMap/g"\ |
86 | 87 |
-e "s/\<\([sS]\)tdMap\>/\1parseMap/g"\ |
87 | 88 |
-e "s/\<\([Ff]\)unctorMap\>/\1unctorToMap/g"\ |
88 | 89 |
-e "s/\<\([Mm]\)apFunctor\>/\1apToFunctor/g"\ |
89 | 90 |
-e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\ |
90 | 91 |
-e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\ |
91 | 92 |
-e "s/\<storeBoolMap\>/loggerBoolMap/g"\ |
92 | 93 |
-e "s/\<BoundingBox\>/Box/g"\ |
93 | 94 |
-e "s/\<readNauty\>/readNautyGraph/g"\ |
94 | 95 |
<$i > $TMP |
95 | 96 |
mv $TMP $i |
96 | 97 |
done |
0 comments (0 inline)