gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Rework hypercube graph implementation to be undirected (#57)
0 4 0
default
4 files changed with 293 insertions and 151 deletions:
↑ Collapse diff ↑
Ignore white space 6 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-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
#ifndef HYPERCUBE_GRAPH_H
20 20
#define HYPERCUBE_GRAPH_H
21 21

	
22
#include <iostream>
23 22
#include <vector>
24 23
#include <lemon/core.h>
25
#include <lemon/error.h>
26

	
27
#include <lemon/bits/base_extender.h>
24
#include <lemon/assert.h>
28 25
#include <lemon/bits/graph_extender.h>
29 26

	
30 27
///\ingroup graphs
31 28
///\file
32
///\brief HypercubeDigraph class.
29
///\brief HypercubeGraph class.
33 30

	
34 31
namespace lemon {
35 32

	
36
  class HypercubeDigraphBase {
33
  class HypercubeGraphBase {
37 34

	
38 35
  public:
39 36

	
40
    typedef HypercubeDigraphBase Digraph;
37
    typedef HypercubeGraphBase Graph;
41 38

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

	
45 43
  public:
46 44

	
47
    HypercubeDigraphBase() {}
45
    HypercubeGraphBase() {}
48 46

	
49 47
  protected:
50 48

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

	
56 56
  public:
57 57

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

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

	
64
    int maxNodeId() const { return nodeNum() - 1; }
65
    int maxArcId() const { return arcNum() - 1; }
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; }
66 69

	
67
    Node source(Arc e) const {
68
      return e.id / _dim;
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));
69 82
    }
70 83

	
71
    Node target(Arc e) const {
72
      return (e.id / _dim) ^ (1 << (e.id % _dim));
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);
73 88
    }
74 89

	
75
    static int id(Node v) { return v.id; }
76
    static int id(Arc e) { return e.id; }
90
    Node source(Arc arc) const {
91
      return (arc._id & 1) == 1 ? u(arc) : v(arc);
92
    }
77 93

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

	
80
    static Arc arcFromId(int id) { return Arc(id); }
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
    }
81 117

	
82 118
    class Node {
83
      friend class HypercubeDigraphBase;
119
      friend class HypercubeGraphBase;
120

	
84 121
    protected:
85
      int id;
86
      Node(int _id) { id = _id;}
122
      int _id;
123
      Node(int id) : _id(id) {}
87 124
    public:
88 125
      Node() {}
89
      Node (Invalid) { id = -1; }
90
      bool operator==(const Node node) const { return id == node.id; }
91
      bool operator!=(const Node node) const { return id != node.id; }
92
      bool operator<(const Node node) const { return id < node.id; }
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;}
93 147
    };
94 148

	
95 149
    class Arc {
96
      friend class HypercubeDigraphBase;
150
      friend class HypercubeGraphBase;
151

	
97 152
    protected:
98
      int id;
99
      Arc(int _id) : id(_id) {}
153
      int _id;
154

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

	
100 157
    public:
101
      Arc() { }
102
      Arc (Invalid) { id = -1; }
103
      bool operator==(const Arc arc) const { return id == arc.id; }
104
      bool operator!=(const Arc arc) const { return id != arc.id; }
105
      bool operator<(const Arc arc) const { return id < arc.id; }
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;}
106 164
    };
107 165

	
108 166
    void first(Node& node) const {
109
      node.id = nodeNum() - 1;
167
      node._id = _node_num - 1;
110 168
    }
111 169

	
112 170
    static void next(Node& node) {
113
      --node.id;
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;
114 180
    }
115 181

	
116 182
    void first(Arc& arc) const {
117
      arc.id = arcNum() - 1;
183
      arc._id = 2 * _edge_num - 1;
118 184
    }
119 185

	
120 186
    static void next(Arc& arc) {
121
      --arc.id;
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
      }
122 206
    }
123 207

	
124 208
    void firstOut(Arc& arc, const Node& node) const {
125
      arc.id = node.id * _dim;
209
      arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
126 210
    }
127 211

	
128 212
    void nextOut(Arc& arc) const {
129
      ++arc.id;
130
      if (arc.id % _dim == 0) arc.id = -1;
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
      }
131 222
    }
132 223

	
133 224
    void firstIn(Arc& arc, const Node& node) const {
134
      arc.id = (node.id ^ 1) * _dim;
225
      arc._id = ((node._id >> 1) << 1) | (node._id & 1);
135 226
    }
136 227

	
137 228
    void nextIn(Arc& arc) const {
138
      int cnt = arc.id % _dim;
139
      if ((cnt + 1) % _dim == 0) {
140
        arc.id = -1;
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);
141 235
      } else {
142
        arc.id = ((arc.id / _dim) ^ ((1 << cnt) * 3)) * _dim + cnt + 1;
236
        arc._id = -1;
143 237
      }
144 238
    }
145 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

	
146 248
    int dimension() const {
147 249
      return _dim;
148 250
    }
149 251

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

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

	
154 260
    int dimension(Arc arc) const {
155
      return arc.id % _dim;
261
      return arc._id >> _dim;
156 262
    }
157 263

	
158 264
    int index(Node node) const {
159
      return node.id;
265
      return node._id;
160 266
    }
161 267

	
162 268
    Node operator()(int ix) const {
163 269
      return Node(ix);
164 270
    }
165 271

	
166 272
  private:
167
    int _dim, _nodeNum;
273
    int _dim;
274
    int _node_num, _edge_num;
168 275
  };
169 276

	
170 277

	
171
  typedef DigraphExtender<HypercubeDigraphBase> ExtendedHypercubeDigraphBase;
278
  typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
172 279

	
173
  /// \ingroup digraphs
280
  /// \ingroup graphs
174 281
  ///
175
  /// \brief Hypercube digraph class
282
  /// \brief Hypercube graph class
176 283
  ///
177
  /// This class implements a special digraph type. The nodes of the
178
  /// digraph are indiced with integers with at most \c dim binary digits.
179
  /// Two nodes are connected in the digraph if the indices differ only
180
  /// on one position in the binary form.
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.
181 288
  ///
182
  /// \note The type of the \c ids is chosen to \c int because efficiency
183
  /// reasons. Thus the maximum dimension of this implementation is 26.
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).
184 292
  ///
185
  /// The digraph type is fully conform to the \ref concepts::Digraph
186
  /// concept but it does not conform to \ref concepts::Graph.
187
  class HypercubeDigraph : public ExtendedHypercubeDigraphBase {
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 {
188 298
  public:
189 299

	
190
    typedef ExtendedHypercubeDigraphBase Parent;
300
    typedef ExtendedHypercubeGraphBase Parent;
191 301

	
192
    /// \brief Construct a hypercube digraph with \c dim dimension.
302
    /// \brief Constructs a hypercube graph with \c dim dimensions.
193 303
    ///
194
    /// Construct a hypercube digraph with \c dim dimension.
195
    HypercubeDigraph(int dim) { construct(dim); }
304
    /// Constructs a hypercube graph with \c dim dimensions.
305
    HypercubeGraph(int dim) { construct(dim); }
196 306

	
197
    /// \brief Gives back the number of the dimensions.
307
    /// \brief The number of dimensions.
198 308
    ///
199
    /// Gives back the number of the dimensions.
309
    /// Gives back the number of dimensions.
200 310
    int dimension() const {
201 311
      return Parent::dimension();
202 312
    }
203 313

	
204
    /// \brief Returns true if the n'th bit of the node is one.
314
    /// \brief Returns \c true if the n'th bit of the node is one.
205 315
    ///
206
    /// Returns true if the n'th bit of the node is one.
316
    /// Returns \c true if the n'th bit of the node is one.
207 317
    bool projection(Node node, int n) const {
208 318
      return Parent::projection(node, n);
209 319
    }
210 320

	
211
    /// \brief The dimension id of the arc.
321
    /// \brief The dimension id of an edge.
212 322
    ///
213
    /// It returns the dimension id of the arc. It can
214
    /// be in the \f$ \{0, 1, \dots, dim-1\} \f$ interval.
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.
215 333
    int dimension(Arc arc) const {
216 334
      return Parent::dimension(arc);
217 335
    }
218 336

	
219
    /// \brief Gives back the index of the node.
337
    /// \brief The index of a node.
220 338
    ///
221
    /// Gives back the index of the node. The lower bits of the
222
    /// integer describes the node.
339
    /// Gives back the index of the given node.
340
    /// The lower bits of the integer describes the node.
223 341
    int index(Node node) const {
224 342
      return Parent::index(node);
225 343
    }
226 344

	
227
    /// \brief Gives back the node by its index.
345
    /// \brief Gives back a node by its index.
228 346
    ///
229
    /// Gives back the node by its index.
347
    /// Gives back a node by its index.
230 348
    Node operator()(int ix) const {
231 349
      return Parent::operator()(ix);
232 350
    }
233 351

	
234 352
    /// \brief Number of nodes.
235 353
    int nodeNum() const { return Parent::nodeNum(); }
354
    /// \brief Number of edges.
355
    int edgeNum() const { return Parent::edgeNum(); }
236 356
    /// \brief Number of arcs.
237 357
    int arcNum() const { return Parent::arcNum(); }
238 358

	
239 359
    /// \brief Linear combination map.
240 360
    ///
241
    /// It makes possible to give back a linear combination
242
    /// for each node. This function works like the \c std::accumulate
243
    /// so it accumulates the \c bf binary function with the \c fv
244
    /// first value. The map accumulates only on that dimensions where
245
    /// the node's index is one. The accumulated values should be
246
    /// given by the \c begin and \c end iterators and the length of this
247
    /// range should be equal to the dimension number of the digraph.
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.
248 369
    ///
249 370
    ///\code
250 371
    /// const int DIM = 3;
251
    /// HypercubeDigraph digraph(DIM);
372
    /// HypercubeGraph graph(DIM);
252 373
    /// dim2::Point<double> base[DIM];
253 374
    /// for (int k = 0; k < DIM; ++k) {
254 375
    ///   base[k].x = rnd();
255 376
    ///   base[k].y = rnd();
256 377
    /// }
257
    /// HypercubeDigraph::HyperMap<dim2::Point<double> >
258
    ///   pos(digraph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
378
    /// HypercubeGraph::HyperMap<dim2::Point<double> >
379
    ///   pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
259 380
    ///\endcode
260 381
    ///
261
    /// \see HypercubeDigraph
382
    /// \see HypercubeGraph
262 383
    template <typename T, typename BF = std::plus<T> >
263 384
    class HyperMap {
264 385
    public:
265 386

	
387
      /// \brief The key type of the map
266 388
      typedef Node Key;
389
      /// \brief The value type of the map
267 390
      typedef T Value;
268 391

	
269

	
270 392
      /// \brief Constructor for HyperMap.
271 393
      ///
272
      /// Construct a HyperMap for the given digraph. The accumulated values
273
      /// should be given by the \c begin and \c end iterators and the length
274
      /// of this range should be equal to the dimension number of the digraph.
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.
275 398
      ///
276
      /// This function accumulates the \c bf binary function with
277
      /// the \c fv first value. The map accumulates only on that dimensions
278
      /// where the node's index is one.
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.
279 402
      template <typename It>
280
      HyperMap(const Digraph& digraph, It begin, It end,
281
               T fv = 0.0, const BF& bf = BF())
282
        : _graph(digraph), _values(begin, end), _first_value(fv), _bin_func(bf)
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)
283 406
      {
284
        LEMON_ASSERT(_values.size() == digraph.dimension(),
285
                     "Wrong size of dimension");
407
        LEMON_ASSERT(_values.size() == graph.dimension(),
408
                     "Wrong size of range");
286 409
      }
287 410

	
288
      /// \brief Gives back the partial accumulated value.
411
      /// \brief The partial accumulated value.
289 412
      ///
290 413
      /// Gives back the partial accumulated value.
291
      Value operator[](Key k) const {
414
      Value operator[](const Key& k) const {
292 415
        Value val = _first_value;
293 416
        int id = _graph.index(k);
294 417
        int n = 0;
295 418
        while (id != 0) {
296 419
          if (id & 1) {
297 420
            val = _bin_func(val, _values[n]);
298 421
          }
299 422
          id >>= 1;
300 423
          ++n;
301 424
        }
302 425
        return val;
303 426
      }
304 427

	
305 428
    private:
306
      const Digraph& _graph;
429
      const Graph& _graph;
307 430
      std::vector<T> _values;
308 431
      T _first_value;
309 432
      BF _bin_func;
310 433
    };
311 434

	
312 435
  };
313 436

	
314 437
}
315 438

	
316 439
#endif
Ignore white space 6 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-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,113 +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
void checkHypercubeDigraph(int dim) {
116
  DIGRAPH_TYPEDEFS(HypercubeDigraph);
117

	
118
  HypercubeDigraph G(dim);
119
  checkGraphNodeList(G, 1 << dim);
120
  checkGraphArcList(G, (1 << dim) * dim);
121

	
122
  Node n = G.nodeFromId(dim);
123

	
124
  checkGraphOutArcList(G, n, dim);
125
  for (OutArcIt a(G, n); a != INVALID; ++a)
126
    check(G.source(a) == n &&
127
          G.id(G.target(a)) == G.id(n) ^ (1 << G.dimension(a)),
128
          "Wrong arc");
129

	
130
  checkGraphInArcList(G, n, dim);
131
  for (InArcIt a(G, n); a != INVALID; ++a)
132
    check(G.target(a) == n &&
133
          G.id(G.source(a)) == G.id(n) ^ (1 << G.dimension(a)),
134
          "Wrong arc");
135

	
136
  checkGraphConArcList(G, (1 << dim) * dim);
137

	
138
  checkNodeIds(G);
139
  checkArcIds(G);
140
  checkGraphNodeMap(G);
141
  checkGraphArcMap(G);
142
}
143

	
144

	
145 114
void checkConcepts() {
146 115
  { // Checking digraph components
147 116
    checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
148 117

	
149 118
    checkConcept<IDableDigraphComponent<>,
150 119
      IDableDigraphComponent<> >();
151 120

	
152 121
    checkConcept<IterableDigraphComponent<>,
153 122
      IterableDigraphComponent<> >();
154 123

	
155 124
    checkConcept<MappableDigraphComponent<>,
156 125
      MappableDigraphComponent<> >();
157 126
  }
158 127
  { // Checking skeleton digraph
159 128
    checkConcept<Digraph, Digraph>();
160 129
  }
161 130
  { // Checking ListDigraph
162 131
    checkConcept<Digraph, ListDigraph>();
163 132
    checkConcept<AlterableDigraphComponent<>, ListDigraph>();
164 133
    checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
165 134
    checkConcept<ClearableDigraphComponent<>, ListDigraph>();
166 135
    checkConcept<ErasableDigraphComponent<>, ListDigraph>();
167 136
  }
168 137
  { // Checking SmartDigraph
169 138
    checkConcept<Digraph, SmartDigraph>();
170 139
    checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
171 140
    checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
172 141
    checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
173 142
  }
174 143
  { // Checking FullDigraph
175 144
    checkConcept<Digraph, FullDigraph>();
176 145
  }
177
  { // Checking HypercubeDigraph
178
    checkConcept<Digraph, HypercubeDigraph>();
179
  }
180 146
}
181 147

	
182 148
template <typename Digraph>
183 149
void checkDigraphValidity() {
184 150
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
185 151
  Digraph g;
186 152

	
187 153
  Node
188 154
    n1 = g.addNode(),
189 155
    n2 = g.addNode(),
190 156
    n3 = g.addNode();
191 157

	
192 158
  Arc
193 159
    e1 = g.addArc(n1, n2),
194 160
    e2 = g.addArc(n2, n3);
195 161

	
196 162
  check(g.valid(n1), "Wrong validity check");
197 163
  check(g.valid(e1), "Wrong validity check");
198 164

	
199 165
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
200 166
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
201 167
}
202 168

	
203 169
template <typename Digraph>
... ...
@@ -220,37 +186,31 @@
220 186
  g.erase(n1);
221 187

	
222 188
  check(!g.valid(n1), "Wrong validity check");
223 189
  check(g.valid(n2), "Wrong validity check");
224 190
  check(g.valid(n3), "Wrong validity check");
225 191
  check(!g.valid(e1), "Wrong validity check");
226 192
  check(g.valid(e2), "Wrong validity check");
227 193

	
228 194
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
229 195
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
230 196
}
231 197

	
232 198
void checkDigraphs() {
233 199
  { // Checking ListDigraph
234 200
    checkDigraph<ListDigraph>();
235 201
    checkDigraphValidityErase<ListDigraph>();
236 202
  }
237 203
  { // Checking SmartDigraph
238 204
    checkDigraph<SmartDigraph>();
239 205
    checkDigraphValidity<SmartDigraph>();
240 206
  }
241 207
  { // Checking FullDigraph
242 208
    checkFullDigraph(8);
243 209
  }
244
  { // Checking HypercubeDigraph
245
    checkHypercubeDigraph(1);
246
    checkHypercubeDigraph(2);
247
    checkHypercubeDigraph(3);
248
    checkHypercubeDigraph(4);
249
  }
250 210
}
251 211

	
252 212
int main() {
253 213
  checkDigraphs();
254 214
  checkConcepts();
255 215
  return 0;
256 216
}
Ignore white space 48 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-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
    checkGraphIncEdgeList(G, n, num - 1);    
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
}
Ignore white space 6 line context
... ...
@@ -60,36 +60,37 @@
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
    <$i > $TMP
94 95
    mv $TMP $i
95 96
done
0 comments (0 inline)