gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Fixes and improvements related to GridGraph
0 2 0
default
2 files changed with 9 insertions and 8 deletions:
↑ Collapse diff ↑
Ignore white space 384 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 GRID_GRAPH_H
20 20
#define GRID_GRAPH_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/bits/graph_extender.h>
24 24
#include <lemon/dim2.h>
25 25
#include <lemon/assert.h>
26 26

	
27 27
///\ingroup graphs
28 28
///\file
29 29
///\brief GridGraph class.
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  class GridGraphBase {
34 34

	
35 35
  public:
36 36

	
37 37
    typedef GridGraphBase Graph;
38 38

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

	
43 43
  public:
44 44

	
45 45
    GridGraphBase() {}
46 46

	
47 47
  protected:
48 48

	
49 49
    void construct(int width, int height) {
50 50
       _width = width; _height = height;
51 51
      _node_num = width * height;
52 52
      _edge_num = 2 * _node_num - width - height;
53 53
      _edge_limit = _node_num - _width;
54 54
    }
55 55

	
56 56
  public:
57 57

	
58 58
    Node operator()(int i, int j) const {
59 59
      LEMON_DEBUG(0 <= i && i < _width &&
60 60
                  0 <= j  && j < _height, "Index out of range");
61 61
      return Node(i + j * _width);
62 62
    }
63 63

	
64 64
    int col(Node n) const {
65 65
      return n._id % _width;
66 66
    }
67 67

	
68 68
    int row(Node n) const {
69 69
      return n._id / _width;
70 70
    }
71 71

	
72 72
    dim2::Point<int> pos(Node n) const {
73 73
      return dim2::Point<int>(col(n), row(n));
74 74
    }
75 75

	
76 76
    int width() const {
77 77
      return _width;
78 78
    }
79 79

	
80 80
    int height() const {
81 81
      return _height;
82 82
    }
83 83

	
84 84
    typedef True NodeNumTag;
85 85
    typedef True ArcNumTag;
86 86

	
87 87
    int nodeNum() const { return _node_num; }
88 88
    int edgeNum() const { return _edge_num; }
89 89
    int arcNum() const { return 2 * _edge_num; }
90 90

	
91 91
    Node u(Edge edge) const {
92 92
      if (edge._id < _edge_limit) {
93 93
        return edge._id;
94 94
      } else {
95 95
        return (edge._id - _edge_limit) % (_width - 1) +
96 96
          (edge._id - _edge_limit) / (_width - 1) * _width;
97 97
      }
98 98
    }
99 99

	
100 100
    Node v(Edge edge) const {
101 101
      if (edge._id < _edge_limit) {
102 102
        return edge._id + _width;
103 103
      } else {
104 104
        return (edge._id - _edge_limit) % (_width - 1) +
105 105
          (edge._id - _edge_limit) / (_width - 1) * _width + 1;
106 106
      }
107 107
    }
108 108

	
109 109
    Node source(Arc arc) const {
110 110
      return (arc._id & 1) == 1 ? u(arc) : v(arc);
111 111
    }
112 112

	
113 113
    Node target(Arc arc) const {
114 114
      return (arc._id & 1) == 1 ? v(arc) : u(arc);
115 115
    }
116 116

	
117 117
    static int id(Node node) { return node._id; }
118 118
    static int id(Edge edge) { return edge._id; }
119 119
    static int id(Arc arc) { return arc._id; }
120 120

	
121 121
    int maxNodeId() const { return _node_num - 1; }
122 122
    int maxEdgeId() const { return _edge_num - 1; }
123 123
    int maxArcId() const { return 2 * _edge_num - 1; }
124 124

	
125 125
    static Node nodeFromId(int id) { return Node(id);}
126 126
    static Edge edgeFromId(int id) { return Edge(id);}
127 127
    static Arc arcFromId(int id) { return Arc(id);}
128 128

	
129 129
    typedef True FindEdgeTag;
130 130

	
131 131
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
132 132
      if (prev != INVALID) return INVALID;
133 133
      if (v._id > u._id) {
134 134
        if (v._id - u._id == _width)
135 135
          return Edge(u._id);
136 136
        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
137 137
          return Edge(u._id / _width * (_width - 1) +
138 138
                      u._id % _width + _edge_limit);
139 139
        }
140 140
      } else {
141 141
        if (u._id - v._id == _width)
142 142
          return Edge(v._id);
143 143
        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
144 144
          return Edge(v._id / _width * (_width - 1) +
145 145
                      v._id % _width + _edge_limit);
146 146
        }
147 147
      }
148 148
      return INVALID;
149 149
    }
150 150

	
151 151
    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
152 152
      if (prev != INVALID) return INVALID;
153 153
      if (v._id > u._id) {
154 154
        if (v._id - u._id == _width)
155 155
          return Arc((u._id << 1) | 1);
156 156
        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
157 157
          return Arc(((u._id / _width * (_width - 1) +
158 158
                       u._id % _width + _edge_limit) << 1) | 1);
159 159
        }
160 160
      } else {
161 161
        if (u._id - v._id == _width)
162 162
          return Arc(v._id << 1);
163 163
        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
164 164
          return Arc((v._id / _width * (_width - 1) +
165 165
                       v._id % _width + _edge_limit) << 1);
166 166
        }
167 167
      }
168 168
      return INVALID;
169 169
    }
170 170

	
171 171
    class Node {
172 172
      friend class GridGraphBase;
173 173

	
174 174
    protected:
175 175
      int _id;
176 176
      Node(int id) : _id(id) {}
177 177
    public:
178 178
      Node() {}
179 179
      Node (Invalid) : _id(-1) {}
180 180
      bool operator==(const Node node) const {return _id == node._id;}
181 181
      bool operator!=(const Node node) const {return _id != node._id;}
182 182
      bool operator<(const Node node) const {return _id < node._id;}
183 183
    };
184 184

	
185 185
    class Edge {
186 186
      friend class GridGraphBase;
187
      friend class Arc;
187 188

	
188 189
    protected:
189 190
      int _id;
190 191

	
191 192
      Edge(int id) : _id(id) {}
192 193

	
193 194
    public:
194 195
      Edge() {}
195 196
      Edge (Invalid) : _id(-1) {}
196 197
      bool operator==(const Edge edge) const {return _id == edge._id;}
197 198
      bool operator!=(const Edge edge) const {return _id != edge._id;}
198 199
      bool operator<(const Edge edge) const {return _id < edge._id;}
199 200
    };
200 201

	
201 202
    class Arc {
202 203
      friend class GridGraphBase;
203 204

	
204 205
    protected:
205 206
      int _id;
206 207

	
207 208
      Arc(int id) : _id(id) {}
208 209

	
209 210
    public:
210 211
      Arc() {}
211 212
      Arc (Invalid) : _id(-1) {}
212 213
      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
213 214
      bool operator==(const Arc arc) const {return _id == arc._id;}
214 215
      bool operator!=(const Arc arc) const {return _id != arc._id;}
215 216
      bool operator<(const Arc arc) const {return _id < arc._id;}
216 217
    };
217 218

	
218 219
    static bool direction(Arc arc) {
219 220
      return (arc._id & 1) == 1;
220 221
    }
221 222

	
222 223
    static Arc direct(Edge edge, bool dir) {
223 224
      return Arc((edge._id << 1) | (dir ? 1 : 0));
224 225
    }
225 226

	
226 227
    void first(Node& node) const {
227 228
      node._id = _node_num - 1;
228 229
    }
229 230

	
230 231
    static void next(Node& node) {
231 232
      --node._id;
232 233
    }
233 234

	
234 235
    void first(Edge& edge) const {
235 236
      edge._id = _edge_num - 1;
236 237
    }
237 238

	
238 239
    static void next(Edge& edge) {
239 240
      --edge._id;
240 241
    }
241 242

	
242 243
    void first(Arc& arc) const {
243 244
      arc._id = 2 * _edge_num - 1;
244 245
    }
245 246

	
246 247
    static void next(Arc& arc) {
247 248
      --arc._id;
248 249
    }
249 250

	
250 251
    void firstOut(Arc& arc, const Node& node) const {
251 252
      if (node._id % _width < _width - 1) {
252 253
        arc._id = (_edge_limit + node._id % _width +
253 254
                   (node._id / _width) * (_width - 1)) << 1 | 1;
254 255
        return;
255 256
      }
256 257
      if (node._id < _node_num - _width) {
257 258
        arc._id = node._id << 1 | 1;
258 259
        return;
259 260
      }
260 261
      if (node._id % _width > 0) {
261 262
        arc._id = (_edge_limit + node._id % _width +
262 263
                   (node._id / _width) * (_width - 1) - 1) << 1;
263 264
        return;
264 265
      }
265 266
      if (node._id >= _width) {
266 267
        arc._id = (node._id - _width) << 1;
267 268
        return;
268 269
      }
269 270
      arc._id = -1;
270 271
    }
271 272

	
272 273
    void nextOut(Arc& arc) const {
273 274
      int nid = arc._id >> 1;
274 275
      if ((arc._id & 1) == 1) {
275 276
        if (nid >= _edge_limit) {
276 277
          nid = (nid - _edge_limit) % (_width - 1) +
277 278
            (nid - _edge_limit) / (_width - 1) * _width;
278 279
          if (nid < _node_num - _width) {
279 280
            arc._id = nid << 1 | 1;
280 281
            return;
281 282
          }
282 283
        }
283 284
        if (nid % _width > 0) {
284 285
          arc._id = (_edge_limit + nid % _width +
285 286
                     (nid / _width) * (_width - 1) - 1) << 1;
286 287
          return;
287 288
        }
288 289
        if (nid >= _width) {
289 290
          arc._id = (nid - _width) << 1;
290 291
          return;
291 292
        }
292 293
      } else {
293 294
        if (nid >= _edge_limit) {
294 295
          nid = (nid - _edge_limit) % (_width - 1) +
295 296
            (nid - _edge_limit) / (_width - 1) * _width + 1;
296 297
          if (nid >= _width) {
297 298
            arc._id = (nid - _width) << 1;
298 299
            return;
299 300
          }
300 301
        }
301 302
      }
302 303
      arc._id = -1;
303 304
    }
304 305

	
305 306
    void firstIn(Arc& arc, const Node& node) const {
306 307
      if (node._id % _width < _width - 1) {
307 308
        arc._id = (_edge_limit + node._id % _width +
308 309
                   (node._id / _width) * (_width - 1)) << 1;
309 310
        return;
310 311
      }
311 312
      if (node._id < _node_num - _width) {
312 313
        arc._id = node._id << 1;
313 314
        return;
314 315
      }
315 316
      if (node._id % _width > 0) {
316 317
        arc._id = (_edge_limit + node._id % _width +
317 318
                   (node._id / _width) * (_width - 1) - 1) << 1 | 1;
318 319
        return;
319 320
      }
320 321
      if (node._id >= _width) {
321 322
        arc._id = (node._id - _width) << 1 | 1;
322 323
        return;
323 324
      }
324 325
      arc._id = -1;
325 326
    }
326 327

	
327 328
    void nextIn(Arc& arc) const {
328 329
      int nid = arc._id >> 1;
329 330
      if ((arc._id & 1) == 0) {
330 331
        if (nid >= _edge_limit) {
331 332
          nid = (nid - _edge_limit) % (_width - 1) +
332 333
            (nid - _edge_limit) / (_width - 1) * _width;
333 334
          if (nid < _node_num - _width) {
334 335
            arc._id = nid << 1;
335 336
            return;
336 337
          }
337 338
        }
338 339
        if (nid % _width > 0) {
339 340
          arc._id = (_edge_limit + nid % _width +
340 341
                     (nid / _width) * (_width - 1) - 1) << 1 | 1;
341 342
          return;
342 343
        }
343 344
        if (nid >= _width) {
344 345
          arc._id = (nid - _width) << 1 | 1;
345 346
          return;
346 347
        }
347 348
      } else {
348 349
        if (nid >= _edge_limit) {
349 350
          nid = (nid - _edge_limit) % (_width - 1) +
350 351
            (nid - _edge_limit) / (_width - 1) * _width + 1;
351 352
          if (nid >= _width) {
352 353
            arc._id = (nid - _width) << 1 | 1;
353 354
            return;
354 355
          }
355 356
        }
356 357
      }
357 358
      arc._id = -1;
358 359
    }
359 360

	
360 361
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
361 362
      if (node._id % _width < _width - 1) {
362 363
        edge._id = _edge_limit + node._id % _width +
363 364
          (node._id / _width) * (_width - 1);
364 365
        dir = true;
365 366
        return;
366 367
      }
367 368
      if (node._id < _node_num - _width) {
368 369
        edge._id = node._id;
369 370
        dir = true;
370 371
        return;
371 372
      }
372 373
      if (node._id % _width > 0) {
373 374
        edge._id = _edge_limit + node._id % _width +
374 375
          (node._id / _width) * (_width - 1) - 1;
375 376
        dir = false;
376 377
        return;
377 378
      }
378 379
      if (node._id >= _width) {
379 380
        edge._id = node._id - _width;
380 381
        dir = false;
381 382
        return;
382 383
      }
383 384
      edge._id = -1;
384 385
      dir = true;
385 386
    }
386 387

	
387 388
    void nextInc(Edge& edge, bool& dir) const {
388 389
      int nid = edge._id;
389 390
      if (dir) {
390 391
        if (nid >= _edge_limit) {
391 392
          nid = (nid - _edge_limit) % (_width - 1) +
392 393
            (nid - _edge_limit) / (_width - 1) * _width;
393 394
          if (nid < _node_num - _width) {
394 395
            edge._id = nid;
395 396
            return;
396 397
          }
397 398
        }
398 399
        if (nid % _width > 0) {
399 400
          edge._id = _edge_limit + nid % _width +
400 401
            (nid / _width) * (_width - 1) - 1;
401 402
          dir = false;
402 403
          return;
403 404
        }
404 405
        if (nid >= _width) {
405 406
          edge._id = nid - _width;
406 407
          dir = false;
407 408
          return;
408 409
        }
409 410
      } else {
410 411
        if (nid >= _edge_limit) {
411 412
          nid = (nid - _edge_limit) % (_width - 1) +
412 413
            (nid - _edge_limit) / (_width - 1) * _width + 1;
413 414
          if (nid >= _width) {
414 415
            edge._id = nid - _width;
415 416
            return;
416 417
          }
417 418
        }
418 419
      }
419 420
      edge._id = -1;
420 421
      dir = true;
421 422
    }
422 423

	
423 424
    Arc right(Node n) const {
424 425
      if (n._id % _width < _width - 1) {
425 426
        return Arc(((_edge_limit + n._id % _width +
426 427
                    (n._id / _width) * (_width - 1)) << 1) | 1);
427 428
      } else {
428 429
        return INVALID;
429 430
      }
430 431
    }
431 432

	
432 433
    Arc left(Node n) const {
433 434
      if (n._id % _width > 0) {
434 435
        return Arc((_edge_limit + n._id % _width +
435 436
                     (n._id / _width) * (_width - 1) - 1) << 1);
436 437
      } else {
437 438
        return INVALID;
438 439
      }
439 440
    }
440 441

	
441 442
    Arc up(Node n) const {
442 443
      if (n._id < _edge_limit) {
443 444
        return Arc((n._id << 1) | 1);
444 445
      } else {
445 446
        return INVALID;
446 447
      }
447 448
    }
448 449

	
449 450
    Arc down(Node n) const {
450 451
      if (n._id >= _width) {
451 452
        return Arc((n._id - _width) << 1);
452 453
      } else {
453 454
        return INVALID;
454 455
      }
455 456
    }
456 457

	
457 458
  private:
458 459
    int _width, _height;
459 460
    int _node_num, _edge_num;
460 461
    int _edge_limit;
461 462
  };
462 463

	
463 464

	
464 465
  typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
465 466

	
466 467
  /// \ingroup graphs
467 468
  ///
468 469
  /// \brief Grid graph class
469 470
  ///
470 471
  /// This class implements a special graph type. The nodes of the
471 472
  /// graph can be indexed by two integer \c (i,j) value where \c i is
472 473
  /// in the \c [0..width()-1] range and j is in the \c
473 474
  /// [0..height()-1] range.  Two nodes are connected in the graph if
474 475
  /// the indexes differ exactly on one position and exactly one is
475
  /// the difference. The nodes of the graph be indexed by position
476
  /// with \c operator()() function. The positions of the nodes can be
476
  /// the difference. The nodes of the graph can be indexed by position
477
  /// with the \c operator()() function. The positions of the nodes can be
477 478
  /// get with \c pos(), \c col() and \c row() members. The outgoing
478 479
  /// arcs can be retrieved with the \c right(), \c up(), \c left()
479 480
  /// and \c down() functions, where the bottom-left corner is the
480 481
  /// origin.
481 482
  ///
482 483
  /// \image html grid_graph.png
483
  /// \image latex grid_graph.eps "Grid digraph" row_num=\textrow_num
484
  /// \image latex grid_graph.eps "Grid graph" row_num=\textrow_num
484 485
  ///
485 486
  /// A short example about the basic usage:
486 487
  ///\code
487 488
  /// GridGraph graph(rows, cols);
488 489
  /// GridGraph::NodeMap<int> val(graph);
489 490
  /// for (int i = 0; i < graph.width(); ++i) {
490 491
  ///   for (int j = 0; j < graph.height(); ++j) {
491 492
  ///     val[graph(i, j)] = i + j;
492 493
  ///   }
493 494
  /// }
494 495
  ///\endcode
495 496
  ///
496
  /// The graph type is fully conform to the \ref concepts::Graph
497
  /// This graph type is fully conform to the \ref concepts::Graph
497 498
  /// "Graph" concept, and it also has an important extra feature
498
  /// that its maps are real \ref concepts::ReferenceMap "reference
499
  /// map"s.
499
  /// that its maps are real \ref concepts::ReferenceMap
500
  /// "reference map"s.
500 501
  class GridGraph : public ExtendedGridGraphBase {
501 502
  public:
502 503

	
503 504
    typedef ExtendedGridGraphBase Parent;
504 505

	
505 506
    /// \brief Map to get the indices of the nodes as dim2::Point<int>.
506 507
    ///
507 508
    /// Map to get the indices of the nodes as dim2::Point<int>.
508 509
    class IndexMap {
509 510
    public:
510 511
      /// \brief The key type of the map
511 512
      typedef GridGraph::Node Key;
512 513
      /// \brief The value type of the map
513 514
      typedef dim2::Point<int> Value;
514 515

	
515 516
      /// \brief Constructor
516 517
      ///
517 518
      /// Constructor
518 519
      IndexMap(const GridGraph& graph) : _graph(graph) {}
519 520

	
520 521
      /// \brief The subscript operator
521 522
      ///
522 523
      /// The subscript operator.
523 524
      Value operator[](Key key) const {
524 525
        return _graph.pos(key);
525 526
      }
526 527

	
527 528
    private:
528 529
      const GridGraph& _graph;
529 530
    };
530 531

	
531 532
    /// \brief Map to get the column of the nodes.
532 533
    ///
533 534
    /// Map to get the column of the nodes.
534 535
    class ColMap {
535 536
    public:
536 537
      /// \brief The key type of the map
537 538
      typedef GridGraph::Node Key;
538 539
      /// \brief The value type of the map
539 540
      typedef int Value;
540 541

	
541 542
      /// \brief Constructor
542 543
      ///
543 544
      /// Constructor
544 545
      ColMap(const GridGraph& graph) : _graph(graph) {}
545 546

	
546 547
      /// \brief The subscript operator
547 548
      ///
548 549
      /// The subscript operator.
549 550
      Value operator[](Key key) const {
550 551
        return _graph.col(key);
551 552
      }
552 553

	
553 554
    private:
554 555
      const GridGraph& _graph;
555 556
    };
556 557

	
557 558
    /// \brief Map to get the row of the nodes.
558 559
    ///
559 560
    /// Map to get the row of the nodes.
560 561
    class RowMap {
561 562
    public:
562 563
      /// \brief The key type of the map
563 564
      typedef GridGraph::Node Key;
564 565
      /// \brief The value type of the map
565 566
      typedef int Value;
566 567

	
567 568
      /// \brief Constructor
568 569
      ///
569 570
      /// Constructor
570 571
      RowMap(const GridGraph& graph) : _graph(graph) {}
571 572

	
572 573
      /// \brief The subscript operator
573 574
      ///
574 575
      /// The subscript operator.
575 576
      Value operator[](Key key) const {
576 577
        return _graph.row(key);
577 578
      }
578 579

	
579 580
    private:
580 581
      const GridGraph& _graph;
581 582
    };
582 583

	
583 584
    /// \brief Constructor
584 585
    ///
585 586
    /// Construct a grid graph with given size.
586 587
    GridGraph(int width, int height) { construct(width, height); }
587 588

	
588 589
    /// \brief Resize the graph
589 590
    ///
590 591
    /// Resize the graph. The function will fully destroy and rebuild
591 592
    /// the graph.  This cause that the maps of the graph will
592 593
    /// reallocated automatically and the previous values will be
593 594
    /// lost.
594 595
    void resize(int width, int height) {
595 596
      Parent::notifier(Arc()).clear();
596 597
      Parent::notifier(Edge()).clear();
597 598
      Parent::notifier(Node()).clear();
598 599
      construct(width, height);
599 600
      Parent::notifier(Node()).build();
600 601
      Parent::notifier(Edge()).build();
601 602
      Parent::notifier(Arc()).build();
602 603
    }
603 604

	
604 605
    /// \brief The node on the given position.
605 606
    ///
606 607
    /// Gives back the node on the given position.
607 608
    Node operator()(int i, int j) const {
608 609
      return Parent::operator()(i, j);
609 610
    }
610 611

	
611 612
    /// \brief Gives back the column index of the node.
612 613
    ///
613 614
    /// Gives back the column index of the node.
614 615
    int col(Node n) const {
615 616
      return Parent::col(n);
616 617
    }
617 618

	
618 619
    /// \brief Gives back the row index of the node.
619 620
    ///
620 621
    /// Gives back the row index of the node.
621 622
    int row(Node n) const {
622 623
      return Parent::row(n);
623 624
    }
624 625

	
625 626
    /// \brief Gives back the position of the node.
626 627
    ///
627 628
    /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
628 629
    dim2::Point<int> pos(Node n) const {
629 630
      return Parent::pos(n);
630 631
    }
631 632

	
632 633
    /// \brief Gives back the number of the columns.
633 634
    ///
634 635
    /// Gives back the number of the columns.
635 636
    int width() const {
636 637
      return Parent::width();
637 638
    }
638 639

	
639 640
    /// \brief Gives back the number of the rows.
640 641
    ///
641 642
    /// Gives back the number of the rows.
642 643
    int height() const {
643 644
      return Parent::height();
644 645
    }
645 646

	
646 647
    /// \brief Gives back the arc goes right from the node.
647 648
    ///
648 649
    /// Gives back the arc goes right from the node. If there is not
649 650
    /// outgoing arc then it gives back INVALID.
650 651
    Arc right(Node n) const {
651 652
      return Parent::right(n);
652 653
    }
653 654

	
654 655
    /// \brief Gives back the arc goes left from the node.
655 656
    ///
656 657
    /// Gives back the arc goes left from the node. If there is not
657 658
    /// outgoing arc then it gives back INVALID.
658 659
    Arc left(Node n) const {
659 660
      return Parent::left(n);
660 661
    }
661 662

	
662 663
    /// \brief Gives back the arc goes up from the node.
663 664
    ///
664 665
    /// Gives back the arc goes up from the node. If there is not
665 666
    /// outgoing arc then it gives back INVALID.
666 667
    Arc up(Node n) const {
667 668
      return Parent::up(n);
668 669
    }
669 670

	
670 671
    /// \brief Gives back the arc goes down from the node.
671 672
    ///
672 673
    /// Gives back the arc goes down from the node. If there is not
673 674
    /// outgoing arc then it gives back INVALID.
674 675
    Arc down(Node n) const {
675 676
      return Parent::down(n);
676 677
    }
677 678

	
678 679
    /// \brief Index map of the grid graph
679 680
    ///
680 681
    /// Just returns an IndexMap for the grid graph.
681 682
    IndexMap indexMap() const {
682 683
      return IndexMap(*this);
683 684
    }
684 685

	
685 686
    /// \brief Row map of the grid graph
686 687
    ///
687 688
    /// Just returns a RowMap for the grid graph.
688 689
    RowMap rowMap() const {
689 690
      return RowMap(*this);
690 691
    }
691 692

	
Ignore white space 6 line context
... ...
@@ -3,294 +3,294 @@
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 24

	
25 25
#include "test_tools.h"
26 26
#include "graph_test.h"
27 27

	
28 28
using namespace lemon;
29 29
using namespace lemon::concepts;
30 30

	
31 31
template <class Graph>
32 32
void checkGraph() {
33 33
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
34 34

	
35 35
  Graph G;
36 36
  checkGraphNodeList(G, 0);
37 37
  checkGraphEdgeList(G, 0);
38 38

	
39 39
  Node
40 40
    n1 = G.addNode(),
41 41
    n2 = G.addNode(),
42 42
    n3 = G.addNode();
43 43
  checkGraphNodeList(G, 3);
44 44
  checkGraphEdgeList(G, 0);
45 45

	
46 46
  Edge e1 = G.addEdge(n1, n2);
47 47
  check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
48 48
        "Wrong edge");
49 49
  checkGraphNodeList(G, 3);
50 50
  checkGraphArcList(G, 2);
51 51
  checkGraphEdgeList(G, 1);
52 52

	
53 53
  checkGraphOutArcList(G, n1, 1);
54 54
  checkGraphOutArcList(G, n2, 1);
55 55
  checkGraphOutArcList(G, n3, 0);
56 56

	
57 57
  checkGraphInArcList(G, n1, 1);
58 58
  checkGraphInArcList(G, n2, 1);
59 59
  checkGraphInArcList(G, n3, 0);
60 60

	
61 61
  checkGraphIncEdgeList(G, n1, 1);
62 62
  checkGraphIncEdgeList(G, n2, 1);
63 63
  checkGraphIncEdgeList(G, n3, 0);
64 64

	
65 65
  checkGraphConArcList(G, 2);
66 66
  checkGraphConEdgeList(G, 1);
67 67

	
68 68
  Edge e2 = G.addEdge(n2, n1), e3 = G.addEdge(n2, n3);
69 69
  checkGraphNodeList(G, 3);
70 70
  checkGraphArcList(G, 6);
71 71
  checkGraphEdgeList(G, 3);
72 72

	
73 73
  checkGraphOutArcList(G, n1, 2);
74 74
  checkGraphOutArcList(G, n2, 3);
75 75
  checkGraphOutArcList(G, n3, 1);
76 76

	
77 77
  checkGraphInArcList(G, n1, 2);
78 78
  checkGraphInArcList(G, n2, 3);
79 79
  checkGraphInArcList(G, n3, 1);
80 80

	
81 81
  checkGraphIncEdgeList(G, n1, 2);
82 82
  checkGraphIncEdgeList(G, n2, 3);
83 83
  checkGraphIncEdgeList(G, n3, 1);
84 84

	
85 85
  checkGraphConArcList(G, 6);
86 86
  checkGraphConEdgeList(G, 3);
87 87

	
88 88
  checkArcDirections(G);
89 89

	
90 90
  checkNodeIds(G);
91 91
  checkArcIds(G);
92 92
  checkEdgeIds(G);
93 93
  checkGraphNodeMap(G);
94 94
  checkGraphArcMap(G);
95 95
  checkGraphEdgeMap(G);
96 96
}
97 97

	
98 98
void checkConcepts() {
99 99
  { // Checking graph components
100 100
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
101 101

	
102 102
    checkConcept<IDableGraphComponent<>,
103 103
      IDableGraphComponent<> >();
104 104

	
105 105
    checkConcept<IterableGraphComponent<>,
106 106
      IterableGraphComponent<> >();
107 107

	
108 108
    checkConcept<MappableGraphComponent<>,
109 109
      MappableGraphComponent<> >();
110 110
  }
111 111
  { // Checking skeleton graph
112 112
    checkConcept<Graph, Graph>();
113 113
  }
114 114
  { // Checking ListGraph
115 115
    checkConcept<Graph, ListGraph>();
116 116
    checkConcept<AlterableGraphComponent<>, ListGraph>();
117 117
    checkConcept<ExtendableGraphComponent<>, ListGraph>();
118 118
    checkConcept<ClearableGraphComponent<>, ListGraph>();
119 119
    checkConcept<ErasableGraphComponent<>, ListGraph>();
120 120
  }
121 121
  { // Checking SmartGraph
122 122
    checkConcept<Graph, SmartGraph>();
123 123
    checkConcept<AlterableGraphComponent<>, SmartGraph>();
124 124
    checkConcept<ExtendableGraphComponent<>, SmartGraph>();
125 125
    checkConcept<ClearableGraphComponent<>, SmartGraph>();
126 126
  }
127 127
//  { // Checking FullGraph
128 128
//    checkConcept<Graph, FullGraph>();
129 129
//    checkGraphIterators<FullGraph>();
130 130
//  }
131 131
  { // Checking GridGraph
132 132
    checkConcept<Graph, GridGraph>();
133 133
  }
134 134
}
135 135

	
136 136
template <typename Graph>
137 137
void checkGraphValidity() {
138 138
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
139 139
  Graph g;
140 140

	
141 141
  Node
142 142
    n1 = g.addNode(),
143 143
    n2 = g.addNode(),
144 144
    n3 = g.addNode();
145 145

	
146 146
  Edge
147 147
    e1 = g.addEdge(n1, n2),
148 148
    e2 = g.addEdge(n2, n3);
149 149

	
150 150
  check(g.valid(n1), "Wrong validity check");
151 151
  check(g.valid(e1), "Wrong validity check");
152 152
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
153 153

	
154 154
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
155 155
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
156 156
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
157 157
}
158 158

	
159 159
template <typename Graph>
160 160
void checkGraphValidityErase() {
161 161
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
162 162
  Graph g;
163 163

	
164 164
  Node
165 165
    n1 = g.addNode(),
166 166
    n2 = g.addNode(),
167 167
    n3 = g.addNode();
168 168

	
169 169
  Edge
170 170
    e1 = g.addEdge(n1, n2),
171 171
    e2 = g.addEdge(n2, n3);
172 172

	
173 173
  check(g.valid(n1), "Wrong validity check");
174 174
  check(g.valid(e1), "Wrong validity check");
175 175
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
176 176

	
177 177
  g.erase(n1);
178 178

	
179 179
  check(!g.valid(n1), "Wrong validity check");
180 180
  check(g.valid(n2), "Wrong validity check");
181 181
  check(g.valid(n3), "Wrong validity check");
182 182
  check(!g.valid(e1), "Wrong validity check");
183 183
  check(g.valid(e2), "Wrong validity check");
184 184

	
185 185
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
186 186
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
187 187
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
188 188
}
189 189

	
190 190
void checkGridGraph(int width, int height) {
191 191
  typedef GridGraph Graph;
192 192
  GRAPH_TYPEDEFS(Graph);
193 193
  Graph G(width, height);
194 194

	
195
  check(G.width() == width, "Wrong row number");
196
  check(G.height() == height, "Wrong column number");
195
  check(G.width() == width, "Wrong column number");
196
  check(G.height() == height, "Wrong row number");
197 197

	
198 198
  for (int i = 0; i < width; ++i) {
199 199
    for (int j = 0; j < height; ++j) {
200 200
      check(G.col(G(i, j)) == i, "Wrong column");
201 201
      check(G.row(G(i, j)) == j, "Wrong row");
202 202
      check(G.pos(G(i, j)).x == i, "Wrong column");
203 203
      check(G.pos(G(i, j)).y == j, "Wrong row");
204 204
    }
205 205
  }
206 206

	
207 207
  for (int j = 0; j < height; ++j) {
208 208
    for (int i = 0; i < width - 1; ++i) {
209 209
      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
210 210
      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
211 211
    }
212 212
    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
213 213
  }
214 214

	
215 215
  for (int j = 0; j < height; ++j) {
216 216
    for (int i = 1; i < width; ++i) {
217 217
      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
218 218
      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
219 219
    }
220 220
    check(G.left(G(0, j)) == INVALID, "Wrong left");
221 221
  }
222 222

	
223 223
  for (int i = 0; i < width; ++i) {
224 224
    for (int j = 0; j < height - 1; ++j) {
225 225
      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
226 226
      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
227 227
    }
228 228
    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
229 229
  }
230 230

	
231 231
  for (int i = 0; i < width; ++i) {
232 232
    for (int j = 1; j < height; ++j) {
233 233
      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
234 234
      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
235 235
    }
236 236
    check(G.down(G(i, 0)) == INVALID, "Wrong down");
237 237
  }
238 238

	
239 239
  checkGraphNodeList(G, width * height);
240 240
  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
241 241
  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
242 242

	
243 243
  for (NodeIt n(G); n != INVALID; ++n) {
244 244
    int nb = 4;
245 245
    if (G.col(n) == 0) --nb;
246 246
    if (G.col(n) == width - 1) --nb;
247 247
    if (G.row(n) == 0) --nb;
248 248
    if (G.row(n) == height - 1) --nb;
249 249

	
250 250
    checkGraphOutArcList(G, n, nb);
251 251
    checkGraphInArcList(G, n, nb);
252 252
    checkGraphIncEdgeList(G, n, nb);
253 253
  }
254 254

	
255 255
  checkArcDirections(G);
256 256

	
257 257
  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
258 258
  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
259 259

	
260 260
  checkNodeIds(G);
261 261
  checkArcIds(G);
262 262
  checkEdgeIds(G);
263 263
  checkGraphNodeMap(G);
264 264
  checkGraphArcMap(G);
265 265
  checkGraphEdgeMap(G);
266 266

	
267 267
}
268 268

	
269 269
void checkGraphs() {
270 270
  { // Checking ListGraph
271 271
    checkGraph<ListGraph>();
272 272
    checkGraphValidityErase<ListGraph>();
273 273
  }
274 274
  { // Checking SmartGraph
275 275
    checkGraph<SmartGraph>();
276 276
    checkGraphValidity<SmartGraph>();
277 277
  }
278 278
//   { // Checking FullGraph
279 279
//     FullGraph g(5);
280 280
//     checkGraphNodeList(g, 5);
281 281
//     checkGraphEdgeList(g, 10);
282 282
//   }
283 283
  { // Checking GridGraph
284 284
    checkGridGraph(5, 8);
285 285
    checkGridGraph(8, 5);
286 286
    checkGridGraph(5, 5);
287 287
    checkGridGraph(0, 0);
288 288
    checkGridGraph(1, 1);
289 289
  }
290 290
}
291 291

	
292 292
int main() {
293 293
  checkConcepts();
294 294
  checkGraphs();
295 295
  return 0;
296 296
}
0 comments (0 inline)