lemon/grid_graph.h
author Balazs Dezso <deba@inf.elte.hu>
Mon, 20 Oct 2008 12:36:02 +0200
changeset 335 160bf92c7cdc
parent 334 ada5f74d1c9e
child 336 052cecabcb71
permissions -rw-r--r--
Improvement on grid graphs

- The indexing of matrix is changed according to integer points of the plane.
- The graph type does not depend on the UndirGraphExtender.
- Improving documentation.
- Improved image generation.
kpeter@334
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
kpeter@334
     2
 *
kpeter@334
     3
 * This file is a part of LEMON, a generic C++ optimization library.
kpeter@334
     4
 *
kpeter@334
     5
 * Copyright (C) 2003-2008
kpeter@334
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@334
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@334
     8
 *
kpeter@334
     9
 * Permission to use, modify and distribute this software is granted
kpeter@334
    10
 * provided that this copyright notice appears in all copies. For
kpeter@334
    11
 * precise terms see the accompanying LICENSE file.
kpeter@334
    12
 *
kpeter@334
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@334
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@334
    15
 * purpose.
kpeter@334
    16
 *
kpeter@334
    17
 */
kpeter@334
    18
kpeter@334
    19
#ifndef GRID_GRAPH_H
kpeter@334
    20
#define GRID_GRAPH_H
kpeter@334
    21
kpeter@334
    22
#include <lemon/core.h>
deba@335
    23
#include <lemon/bits/graph_extender.h>
deba@335
    24
#include <lemon/dim2.h>
kpeter@334
    25
#include <lemon/assert.h>
kpeter@334
    26
kpeter@334
    27
///\ingroup graphs
kpeter@334
    28
///\file
kpeter@334
    29
///\brief GridGraph class.
kpeter@334
    30
kpeter@334
    31
namespace lemon {
kpeter@334
    32
kpeter@334
    33
  class GridGraphBase {
kpeter@334
    34
kpeter@334
    35
  public:
kpeter@334
    36
kpeter@334
    37
    typedef GridGraphBase Graph;
kpeter@334
    38
kpeter@334
    39
    class Node;
deba@335
    40
    class Edge;
kpeter@334
    41
    class Arc;
kpeter@334
    42
kpeter@334
    43
  public:
kpeter@334
    44
kpeter@334
    45
    GridGraphBase() {}
kpeter@334
    46
kpeter@334
    47
  protected:
kpeter@334
    48
deba@335
    49
    void construct(int width, int height) {
deba@335
    50
       _width = width; _height = height;
deba@335
    51
      _node_num = width * height;
deba@335
    52
      _edge_num = 2 * _node_num - width - height;
deba@335
    53
      _edge_limit = _node_num - _width;
kpeter@334
    54
    }
kpeter@334
    55
kpeter@334
    56
  public:
kpeter@334
    57
kpeter@334
    58
    Node operator()(int i, int j) const {
deba@335
    59
      LEMON_DEBUG(0 <= i && i < _width &&
deba@335
    60
                  0 <= j  && j < _height, "Index out of range");
kpeter@334
    61
      return Node(i + j * _width);
kpeter@334
    62
    }
kpeter@334
    63
deba@335
    64
    int col(Node n) const {
deba@335
    65
      return n._id % _width;
kpeter@334
    66
    }
kpeter@334
    67
deba@335
    68
    int row(Node n) const {
deba@335
    69
      return n._id / _width;
deba@335
    70
    }
deba@335
    71
deba@335
    72
    dim2::Point<int> pos(Node n) const {
deba@335
    73
      return dim2::Point<int>(col(n), row(n));
kpeter@334
    74
    }
kpeter@334
    75
kpeter@334
    76
    int width() const {
kpeter@334
    77
      return _width;
kpeter@334
    78
    }
kpeter@334
    79
kpeter@334
    80
    int height() const {
kpeter@334
    81
      return _height;
kpeter@334
    82
    }
kpeter@334
    83
kpeter@334
    84
    typedef True NodeNumTag;
kpeter@334
    85
    typedef True ArcNumTag;
kpeter@334
    86
deba@335
    87
    int nodeNum() const { return _node_num; }
deba@335
    88
    int edgeNum() const { return _edge_num; }
deba@335
    89
    int arcNum() const { return 2 * _edge_num; }
kpeter@334
    90
deba@335
    91
    Node u(Edge edge) const {
deba@335
    92
      if (edge._id < _edge_limit) {
deba@335
    93
        return edge._id;
kpeter@334
    94
      } else {
deba@335
    95
        return (edge._id - _edge_limit) % (_width - 1) +
deba@335
    96
          (edge._id - _edge_limit) / (_width - 1) * _width;
kpeter@334
    97
      }
kpeter@334
    98
    }
kpeter@334
    99
deba@335
   100
    Node v(Edge edge) const {
deba@335
   101
      if (edge._id < _edge_limit) {
deba@335
   102
        return edge._id + _width;
kpeter@334
   103
      } else {
deba@335
   104
        return (edge._id - _edge_limit) % (_width - 1) +
deba@335
   105
          (edge._id - _edge_limit) / (_width - 1) * _width + 1;
kpeter@334
   106
      }
kpeter@334
   107
    }
kpeter@334
   108
deba@335
   109
    Node source(Arc arc) const {
deba@335
   110
      return (arc._id & 1) == 1 ? u(arc) : v(arc);
deba@335
   111
    }
deba@335
   112
deba@335
   113
    Node target(Arc arc) const {
deba@335
   114
      return (arc._id & 1) == 1 ? v(arc) : u(arc);
deba@335
   115
    }
deba@335
   116
deba@335
   117
    static int id(Node node) { return node._id; }
deba@335
   118
    static int id(Edge edge) { return edge._id; }
deba@335
   119
    static int id(Arc arc) { return arc._id; }
deba@335
   120
deba@335
   121
    int maxNodeId() const { return _node_num - 1; }
deba@335
   122
    int maxEdgeId() const { return _edge_num - 1; }
deba@335
   123
    int maxArcId() const { return 2 * _edge_num - 1; }
kpeter@334
   124
kpeter@334
   125
    static Node nodeFromId(int id) { return Node(id);}
deba@335
   126
    static Edge edgeFromId(int id) { return Edge(id);}
kpeter@334
   127
    static Arc arcFromId(int id) { return Arc(id);}
kpeter@334
   128
deba@335
   129
    typedef True FindEdgeTag;
deba@335
   130
deba@335
   131
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
deba@335
   132
      if (prev != INVALID) return INVALID;
deba@335
   133
      if (v._id > u._id) {
deba@335
   134
        if (v._id - u._id == _width)
deba@335
   135
          return Edge(u._id);
deba@335
   136
        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
deba@335
   137
          return Edge(u._id / _width * (_width - 1) +
deba@335
   138
                      u._id % _width + _edge_limit);
deba@335
   139
        }
deba@335
   140
      } else {
deba@335
   141
        if (u._id - v._id == _width)
deba@335
   142
          return Edge(v._id);
deba@335
   143
        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
deba@335
   144
          return Edge(v._id / _width * (_width - 1) +
deba@335
   145
                      v._id % _width + _edge_limit);
deba@335
   146
        }
deba@335
   147
      }
deba@335
   148
      return INVALID;
deba@335
   149
    }
kpeter@334
   150
kpeter@334
   151
    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
kpeter@334
   152
      if (prev != INVALID) return INVALID;
deba@335
   153
      if (v._id > u._id) {
deba@335
   154
        if (v._id - u._id == _width)
deba@335
   155
          return Arc((u._id << 1) | 1);
deba@335
   156
        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
deba@335
   157
          return Arc(((u._id / _width * (_width - 1) +
deba@335
   158
                       u._id % _width + _edge_limit) << 1) | 1);
deba@335
   159
        }
deba@335
   160
      } else {
deba@335
   161
        if (u._id - v._id == _width)
deba@335
   162
          return Arc(v._id << 1);
deba@335
   163
        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
deba@335
   164
          return Arc((v._id / _width * (_width - 1) +
deba@335
   165
                       v._id % _width + _edge_limit) << 1);
deba@335
   166
        }
kpeter@334
   167
      }
kpeter@334
   168
      return INVALID;
kpeter@334
   169
    }
kpeter@334
   170
kpeter@334
   171
    class Node {
kpeter@334
   172
      friend class GridGraphBase;
kpeter@334
   173
kpeter@334
   174
    protected:
deba@335
   175
      int _id;
deba@335
   176
      Node(int id) : _id(id) {}
kpeter@334
   177
    public:
kpeter@334
   178
      Node() {}
deba@335
   179
      Node (Invalid) : _id(-1) {}
deba@335
   180
      bool operator==(const Node node) const {return _id == node._id;}
deba@335
   181
      bool operator!=(const Node node) const {return _id != node._id;}
deba@335
   182
      bool operator<(const Node node) const {return _id < node._id;}
deba@335
   183
    };
deba@335
   184
deba@335
   185
    class Edge {
deba@335
   186
      friend class GridGraphBase;
deba@335
   187
deba@335
   188
    protected:
deba@335
   189
      int _id;
deba@335
   190
deba@335
   191
      Edge(int id) : _id(id) {}
deba@335
   192
deba@335
   193
    public:
deba@335
   194
      Edge() {}
deba@335
   195
      Edge (Invalid) : _id(-1) {}
deba@335
   196
      bool operator==(const Edge edge) const {return _id == edge._id;}
deba@335
   197
      bool operator!=(const Edge edge) const {return _id != edge._id;}
deba@335
   198
      bool operator<(const Edge edge) const {return _id < edge._id;}
kpeter@334
   199
    };
kpeter@334
   200
kpeter@334
   201
    class Arc {
kpeter@334
   202
      friend class GridGraphBase;
kpeter@334
   203
kpeter@334
   204
    protected:
deba@335
   205
      int _id;
deba@335
   206
deba@335
   207
      Arc(int id) : _id(id) {}
deba@335
   208
kpeter@334
   209
    public:
kpeter@334
   210
      Arc() {}
deba@335
   211
      Arc (Invalid) : _id(-1) {}
deba@335
   212
      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
deba@335
   213
      bool operator==(const Arc arc) const {return _id == arc._id;}
deba@335
   214
      bool operator!=(const Arc arc) const {return _id != arc._id;}
deba@335
   215
      bool operator<(const Arc arc) const {return _id < arc._id;}
kpeter@334
   216
    };
kpeter@334
   217
deba@335
   218
    static bool direction(Arc arc) {
deba@335
   219
      return (arc._id & 1) == 1;
deba@335
   220
    }
deba@335
   221
deba@335
   222
    static Arc direct(Edge edge, bool dir) {
deba@335
   223
      return Arc((edge._id << 1) | (dir ? 1 : 0));
deba@335
   224
    }
deba@335
   225
kpeter@334
   226
    void first(Node& node) const {
deba@335
   227
      node._id = _node_num - 1;
kpeter@334
   228
    }
kpeter@334
   229
kpeter@334
   230
    static void next(Node& node) {
deba@335
   231
      --node._id;
deba@335
   232
    }
deba@335
   233
deba@335
   234
    void first(Edge& edge) const {
deba@335
   235
      edge._id = _edge_num - 1;
deba@335
   236
    }
deba@335
   237
deba@335
   238
    static void next(Edge& edge) {
deba@335
   239
      --edge._id;
kpeter@334
   240
    }
kpeter@334
   241
kpeter@334
   242
    void first(Arc& arc) const {
deba@335
   243
      arc._id = 2 * _edge_num - 1;
kpeter@334
   244
    }
kpeter@334
   245
kpeter@334
   246
    static void next(Arc& arc) {
deba@335
   247
      --arc._id;
kpeter@334
   248
    }
kpeter@334
   249
kpeter@334
   250
    void firstOut(Arc& arc, const Node& node) const {
deba@335
   251
      if (node._id % _width < _width - 1) {
deba@335
   252
        arc._id = (_edge_limit + node._id % _width +
deba@335
   253
                   (node._id / _width) * (_width - 1)) << 1 | 1;
deba@335
   254
        return;
deba@335
   255
      }
deba@335
   256
      if (node._id < _node_num - _width) {
deba@335
   257
        arc._id = node._id << 1 | 1;
deba@335
   258
        return;
deba@335
   259
      }
deba@335
   260
      if (node._id % _width > 0) {
deba@335
   261
        arc._id = (_edge_limit + node._id % _width +
deba@335
   262
                   (node._id / _width) * (_width - 1) - 1) << 1;
deba@335
   263
        return;
deba@335
   264
      }
deba@335
   265
      if (node._id >= _width) {
deba@335
   266
        arc._id = (node._id - _width) << 1;
deba@335
   267
        return;
deba@335
   268
      }
deba@335
   269
      arc._id = -1;
deba@335
   270
    }
deba@335
   271
deba@335
   272
    void nextOut(Arc& arc) const {
deba@335
   273
      int nid = arc._id >> 1;
deba@335
   274
      if ((arc._id & 1) == 1) {
deba@335
   275
        if (nid >= _edge_limit) {
deba@335
   276
          nid = (nid - _edge_limit) % (_width - 1) +
deba@335
   277
            (nid - _edge_limit) / (_width - 1) * _width;
deba@335
   278
          if (nid < _node_num - _width) {
deba@335
   279
            arc._id = nid << 1 | 1;
deba@335
   280
            return;
deba@335
   281
          }
deba@335
   282
        }
deba@335
   283
        if (nid % _width > 0) {
deba@335
   284
          arc._id = (_edge_limit + nid % _width +
deba@335
   285
                     (nid / _width) * (_width - 1) - 1) << 1;
deba@335
   286
          return;
deba@335
   287
        }
deba@335
   288
        if (nid >= _width) {
deba@335
   289
          arc._id = (nid - _width) << 1;
deba@335
   290
          return;
deba@335
   291
        }
kpeter@334
   292
      } else {
deba@335
   293
        if (nid >= _edge_limit) {
deba@335
   294
          nid = (nid - _edge_limit) % (_width - 1) +
deba@335
   295
            (nid - _edge_limit) / (_width - 1) * _width + 1;
deba@335
   296
          if (nid >= _width) {
deba@335
   297
            arc._id = (nid - _width) << 1;
deba@335
   298
            return;
deba@335
   299
          }
deba@335
   300
        }
deba@335
   301
      }
deba@335
   302
      arc._id = -1;
deba@335
   303
    }
deba@335
   304
deba@335
   305
    void firstIn(Arc& arc, const Node& node) const {
deba@335
   306
      if (node._id % _width < _width - 1) {
deba@335
   307
        arc._id = (_edge_limit + node._id % _width +
deba@335
   308
                   (node._id / _width) * (_width - 1)) << 1;
deba@335
   309
        return;
deba@335
   310
      }
deba@335
   311
      if (node._id < _node_num - _width) {
deba@335
   312
        arc._id = node._id << 1;
deba@335
   313
        return;
deba@335
   314
      }
deba@335
   315
      if (node._id % _width > 0) {
deba@335
   316
        arc._id = (_edge_limit + node._id % _width +
deba@335
   317
                   (node._id / _width) * (_width - 1) - 1) << 1 | 1;
deba@335
   318
        return;
deba@335
   319
      }
deba@335
   320
      if (node._id >= _width) {
deba@335
   321
        arc._id = (node._id - _width) << 1 | 1;
deba@335
   322
        return;
deba@335
   323
      }
deba@335
   324
      arc._id = -1;
deba@335
   325
    }
deba@335
   326
deba@335
   327
    void nextIn(Arc& arc) const {
deba@335
   328
      int nid = arc._id >> 1;
deba@335
   329
      if ((arc._id & 1) == 0) {
deba@335
   330
        if (nid >= _edge_limit) {
deba@335
   331
          nid = (nid - _edge_limit) % (_width - 1) +
deba@335
   332
            (nid - _edge_limit) / (_width - 1) * _width;
deba@335
   333
          if (nid < _node_num - _width) {
deba@335
   334
            arc._id = nid << 1;
deba@335
   335
            return;
deba@335
   336
          }
deba@335
   337
        }
deba@335
   338
        if (nid % _width > 0) {
deba@335
   339
          arc._id = (_edge_limit + nid % _width +
deba@335
   340
                     (nid / _width) * (_width - 1) - 1) << 1 | 1;
deba@335
   341
          return;
deba@335
   342
        }
deba@335
   343
        if (nid >= _width) {
deba@335
   344
          arc._id = (nid - _width) << 1 | 1;
deba@335
   345
          return;
deba@335
   346
        }
deba@335
   347
      } else {
deba@335
   348
        if (nid >= _edge_limit) {
deba@335
   349
          nid = (nid - _edge_limit) % (_width - 1) +
deba@335
   350
            (nid - _edge_limit) / (_width - 1) * _width + 1;
deba@335
   351
          if (nid >= _width) {
deba@335
   352
            arc._id = (nid - _width) << 1 | 1;
deba@335
   353
            return;
deba@335
   354
          }
deba@335
   355
        }
deba@335
   356
      }
deba@335
   357
      arc._id = -1;
deba@335
   358
    }
deba@335
   359
deba@335
   360
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
deba@335
   361
      if (node._id % _width < _width - 1) {
deba@335
   362
        edge._id = _edge_limit + node._id % _width +
deba@335
   363
          (node._id / _width) * (_width - 1);
deba@335
   364
        dir = true;
deba@335
   365
        return;
deba@335
   366
      }
deba@335
   367
      if (node._id < _node_num - _width) {
deba@335
   368
        edge._id = node._id;
deba@335
   369
        dir = true;
deba@335
   370
        return;
deba@335
   371
      }
deba@335
   372
      if (node._id % _width > 0) {
deba@335
   373
        edge._id = _edge_limit + node._id % _width +
deba@335
   374
          (node._id / _width) * (_width - 1) - 1;
deba@335
   375
        dir = false;
deba@335
   376
        return;
deba@335
   377
      }
deba@335
   378
      if (node._id >= _width) {
deba@335
   379
        edge._id = node._id - _width;
deba@335
   380
        dir = false;
deba@335
   381
        return;
deba@335
   382
      }
deba@335
   383
      edge._id = -1;
deba@335
   384
      dir = true;
deba@335
   385
    }
deba@335
   386
deba@335
   387
    void nextInc(Edge& edge, bool& dir) const {
deba@335
   388
      int nid = edge._id;
deba@335
   389
      if (dir) {
deba@335
   390
        if (nid >= _edge_limit) {
deba@335
   391
          nid = (nid - _edge_limit) % (_width - 1) +
deba@335
   392
            (nid - _edge_limit) / (_width - 1) * _width;
deba@335
   393
          if (nid < _node_num - _width) {
deba@335
   394
            edge._id = nid;
deba@335
   395
            return;
deba@335
   396
          }
deba@335
   397
        }
deba@335
   398
        if (nid % _width > 0) {
deba@335
   399
          edge._id = _edge_limit + nid % _width +
deba@335
   400
            (nid / _width) * (_width - 1) - 1;
deba@335
   401
          dir = false;
deba@335
   402
          return;
deba@335
   403
        }
deba@335
   404
        if (nid >= _width) {
deba@335
   405
          edge._id = nid - _width;
deba@335
   406
          dir = false;
deba@335
   407
          return;
deba@335
   408
        }
deba@335
   409
      } else {
deba@335
   410
        if (nid >= _edge_limit) {
deba@335
   411
          nid = (nid - _edge_limit) % (_width - 1) +
deba@335
   412
            (nid - _edge_limit) / (_width - 1) * _width + 1;
deba@335
   413
          if (nid >= _width) {
deba@335
   414
            edge._id = nid - _width;
deba@335
   415
            return;
deba@335
   416
          }
deba@335
   417
        }
deba@335
   418
      }
deba@335
   419
      edge._id = -1;
deba@335
   420
      dir = true;
deba@335
   421
    }
deba@335
   422
deba@335
   423
    Arc right(Node n) const {
deba@335
   424
      if (n._id % _width < _width - 1) {
deba@335
   425
        return Arc(((_edge_limit + n._id % _width +
deba@335
   426
                    (n._id / _width) * (_width - 1)) << 1) | 1);
deba@335
   427
      } else {
deba@335
   428
        return INVALID;
kpeter@334
   429
      }
kpeter@334
   430
    }
kpeter@334
   431
deba@335
   432
    Arc left(Node n) const {
deba@335
   433
      if (n._id % _width > 0) {
deba@335
   434
        return Arc((_edge_limit + n._id % _width +
deba@335
   435
                     (n._id / _width) * (_width - 1) - 1) << 1);
kpeter@334
   436
      } else {
deba@335
   437
        return INVALID;
kpeter@334
   438
      }
kpeter@334
   439
    }
kpeter@334
   440
deba@335
   441
    Arc up(Node n) const {
deba@335
   442
      if (n._id < _edge_limit) {
deba@335
   443
        return Arc((n._id << 1) | 1);
kpeter@334
   444
      } else {
deba@335
   445
        return INVALID;
kpeter@334
   446
      }
kpeter@334
   447
    }
kpeter@334
   448
deba@335
   449
    Arc down(Node n) const {
deba@335
   450
      if (n._id >= _width) {
deba@335
   451
        return Arc((n._id - _width) << 1);
kpeter@334
   452
      } else {
deba@335
   453
        return INVALID;
kpeter@334
   454
      }
kpeter@334
   455
    }
kpeter@334
   456
kpeter@334
   457
  private:
kpeter@334
   458
    int _width, _height;
deba@335
   459
    int _node_num, _edge_num;
deba@335
   460
    int _edge_limit;
kpeter@334
   461
  };
kpeter@334
   462
deba@335
   463
deba@335
   464
  typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
kpeter@334
   465
kpeter@334
   466
  /// \ingroup graphs
kpeter@334
   467
  ///
kpeter@334
   468
  /// \brief Grid graph class
kpeter@334
   469
  ///
kpeter@334
   470
  /// This class implements a special graph type. The nodes of the
deba@335
   471
  /// graph can be indexed by two integer \c (i,j) value where \c i is
deba@335
   472
  /// in the \c [0..width()-1] range and j is in the \c
deba@335
   473
  /// [0..height()-1] range.  Two nodes are connected in the graph if
deba@335
   474
  /// the indexes differ exactly on one position and exactly one is
deba@335
   475
  /// the difference. The nodes of the graph be indexed by position
deba@335
   476
  /// with \c operator()() function. The positions of the nodes can be
deba@335
   477
  /// get with \c pos(), \c col() and \c row() members. The outgoing
deba@335
   478
  /// arcs can be retrieved with the \c right(), \c up(), \c left()
deba@335
   479
  /// and \c down() functions, where the bottom-left corner is the
deba@335
   480
  /// origin.
kpeter@334
   481
  ///
kpeter@334
   482
  /// \image html grid_graph.png
deba@335
   483
  /// \image latex grid_graph.eps "Grid digraph" row_num=\textrow_num
kpeter@334
   484
  ///
deba@335
   485
  /// A short example about the basic usage:
kpeter@334
   486
  ///\code
deba@335
   487
  /// GridGraph graph(rows, cols);
deba@335
   488
  /// GridGraph::NodeMap<int> val(graph);
deba@335
   489
  /// for (int i = 0; i < graph.width(); ++i) {
deba@335
   490
  ///   for (int j = 0; j < graph.height(); ++j) {
deba@335
   491
  ///     val[graph(i, j)] = i + j;
kpeter@334
   492
  ///   }
kpeter@334
   493
  /// }
kpeter@334
   494
  ///\endcode
kpeter@334
   495
  ///
deba@335
   496
  /// The graph type is fully conform to the \ref concepts::Graph
deba@335
   497
  /// "Graph" concept, and it also has an important extra feature
deba@335
   498
  /// that its maps are real \ref concepts::ReferenceMap "reference
deba@335
   499
  /// map"s.
kpeter@334
   500
  class GridGraph : public ExtendedGridGraphBase {
kpeter@334
   501
  public:
kpeter@334
   502
kpeter@334
   503
    typedef ExtendedGridGraphBase Parent;
kpeter@334
   504
kpeter@334
   505
    /// \brief Map to get the indices of the nodes as dim2::Point<int>.
kpeter@334
   506
    ///
kpeter@334
   507
    /// Map to get the indices of the nodes as dim2::Point<int>.
kpeter@334
   508
    class IndexMap {
kpeter@334
   509
    public:
deba@335
   510
      /// \brief The key type of the map
kpeter@334
   511
      typedef GridGraph::Node Key;
deba@335
   512
      /// \brief The value type of the map
kpeter@334
   513
      typedef dim2::Point<int> Value;
kpeter@334
   514
deba@335
   515
      /// \brief Constructor
deba@335
   516
      ///
kpeter@334
   517
      /// Constructor
kpeter@334
   518
      IndexMap(const GridGraph& graph) : _graph(graph) {}
kpeter@334
   519
deba@335
   520
      /// \brief The subscript operator
deba@335
   521
      ///
deba@335
   522
      /// The subscript operator.
deba@335
   523
      Value operator[](Key key) const {
deba@335
   524
        return _graph.pos(key);
deba@335
   525
      }
deba@335
   526
deba@335
   527
    private:
deba@335
   528
      const GridGraph& _graph;
deba@335
   529
    };
deba@335
   530
deba@335
   531
    /// \brief Map to get the column of the nodes.
deba@335
   532
    ///
deba@335
   533
    /// Map to get the column of the nodes.
deba@335
   534
    class ColMap {
deba@335
   535
    public:
deba@335
   536
      /// \brief The key type of the map
deba@335
   537
      typedef GridGraph::Node Key;
deba@335
   538
      /// \brief The value type of the map
deba@335
   539
      typedef int Value;
deba@335
   540
deba@335
   541
      /// \brief Constructor
deba@335
   542
      ///
deba@335
   543
      /// Constructor
deba@335
   544
      ColMap(const GridGraph& graph) : _graph(graph) {}
deba@335
   545
deba@335
   546
      /// \brief The subscript operator
deba@335
   547
      ///
deba@335
   548
      /// The subscript operator.
deba@335
   549
      Value operator[](Key key) const {
deba@335
   550
        return _graph.col(key);
kpeter@334
   551
      }
kpeter@334
   552
kpeter@334
   553
    private:
kpeter@334
   554
      const GridGraph& _graph;
kpeter@334
   555
    };
kpeter@334
   556
kpeter@334
   557
    /// \brief Map to get the row of the nodes.
kpeter@334
   558
    ///
kpeter@334
   559
    /// Map to get the row of the nodes.
kpeter@334
   560
    class RowMap {
kpeter@334
   561
    public:
deba@335
   562
      /// \brief The key type of the map
kpeter@334
   563
      typedef GridGraph::Node Key;
deba@335
   564
      /// \brief The value type of the map
kpeter@334
   565
      typedef int Value;
kpeter@334
   566
deba@335
   567
      /// \brief Constructor
deba@335
   568
      ///
kpeter@334
   569
      /// Constructor
kpeter@334
   570
      RowMap(const GridGraph& graph) : _graph(graph) {}
kpeter@334
   571
deba@335
   572
      /// \brief The subscript operator
deba@335
   573
      ///
deba@335
   574
      /// The subscript operator.
deba@335
   575
      Value operator[](Key key) const {
kpeter@334
   576
        return _graph.row(key);
kpeter@334
   577
      }
kpeter@334
   578
kpeter@334
   579
    private:
kpeter@334
   580
      const GridGraph& _graph;
kpeter@334
   581
    };
kpeter@334
   582
kpeter@334
   583
    /// \brief Constructor
kpeter@334
   584
    ///
deba@335
   585
    /// Construct a grid graph with given size.
kpeter@334
   586
    GridGraph(int width, int height) { construct(width, height); }
kpeter@334
   587
kpeter@334
   588
    /// \brief Resize the graph
kpeter@334
   589
    ///
deba@335
   590
    /// Resize the graph. The function will fully destroy and rebuild
deba@335
   591
    /// the graph.  This cause that the maps of the graph will
deba@335
   592
    /// reallocated automatically and the previous values will be
deba@335
   593
    /// lost.
kpeter@334
   594
    void resize(int width, int height) {
kpeter@334
   595
      Parent::notifier(Arc()).clear();
kpeter@334
   596
      Parent::notifier(Edge()).clear();
kpeter@334
   597
      Parent::notifier(Node()).clear();
kpeter@334
   598
      construct(width, height);
kpeter@334
   599
      Parent::notifier(Node()).build();
kpeter@334
   600
      Parent::notifier(Edge()).build();
kpeter@334
   601
      Parent::notifier(Arc()).build();
kpeter@334
   602
    }
kpeter@334
   603
kpeter@334
   604
    /// \brief The node on the given position.
kpeter@334
   605
    ///
kpeter@334
   606
    /// Gives back the node on the given position.
kpeter@334
   607
    Node operator()(int i, int j) const {
kpeter@334
   608
      return Parent::operator()(i, j);
kpeter@334
   609
    }
kpeter@334
   610
deba@335
   611
    /// \brief Gives back the column index of the node.
deba@335
   612
    ///
deba@335
   613
    /// Gives back the column index of the node.
deba@335
   614
    int col(Node n) const {
deba@335
   615
      return Parent::col(n);
deba@335
   616
    }
deba@335
   617
kpeter@334
   618
    /// \brief Gives back the row index of the node.
kpeter@334
   619
    ///
kpeter@334
   620
    /// Gives back the row index of the node.
kpeter@334
   621
    int row(Node n) const {
kpeter@334
   622
      return Parent::row(n);
kpeter@334
   623
    }
kpeter@334
   624
deba@335
   625
    /// \brief Gives back the position of the node.
kpeter@334
   626
    ///
deba@335
   627
    /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
deba@335
   628
    dim2::Point<int> pos(Node n) const {
deba@335
   629
      return Parent::pos(n);
kpeter@334
   630
    }
kpeter@334
   631
deba@335
   632
    /// \brief Gives back the number of the columns.
kpeter@334
   633
    ///
deba@335
   634
    /// Gives back the number of the columns.
kpeter@334
   635
    int width() const {
kpeter@334
   636
      return Parent::width();
kpeter@334
   637
    }
kpeter@334
   638
deba@335
   639
    /// \brief Gives back the number of the rows.
kpeter@334
   640
    ///
deba@335
   641
    /// Gives back the number of the rows.
kpeter@334
   642
    int height() const {
kpeter@334
   643
      return Parent::height();
kpeter@334
   644
    }
kpeter@334
   645
deba@335
   646
    /// \brief Gives back the arc goes right from the node.
deba@335
   647
    ///
deba@335
   648
    /// Gives back the arc goes right from the node. If there is not
deba@335
   649
    /// outgoing arc then it gives back INVALID.
deba@335
   650
    Arc right(Node n) const {
deba@335
   651
      return Parent::right(n);
deba@335
   652
    }
deba@335
   653
deba@335
   654
    /// \brief Gives back the arc goes left from the node.
deba@335
   655
    ///
deba@335
   656
    /// Gives back the arc goes left from the node. If there is not
deba@335
   657
    /// outgoing arc then it gives back INVALID.
deba@335
   658
    Arc left(Node n) const {
deba@335
   659
      return Parent::left(n);
deba@335
   660
    }
deba@335
   661
deba@335
   662
    /// \brief Gives back the arc goes up from the node.
deba@335
   663
    ///
deba@335
   664
    /// Gives back the arc goes up from the node. If there is not
deba@335
   665
    /// outgoing arc then it gives back INVALID.
deba@335
   666
    Arc up(Node n) const {
deba@335
   667
      return Parent::up(n);
deba@335
   668
    }
deba@335
   669
kpeter@334
   670
    /// \brief Gives back the arc goes down from the node.
kpeter@334
   671
    ///
kpeter@334
   672
    /// Gives back the arc goes down from the node. If there is not
deba@335
   673
    /// outgoing arc then it gives back INVALID.
kpeter@334
   674
    Arc down(Node n) const {
deba@335
   675
      return Parent::down(n);
kpeter@334
   676
    }
kpeter@334
   677
deba@335
   678
    /// \brief Index map of the grid graph
kpeter@334
   679
    ///
deba@335
   680
    /// Just returns an IndexMap for the grid graph.
deba@335
   681
    IndexMap indexMap() const {
deba@335
   682
      return IndexMap(*this);
kpeter@334
   683
    }
kpeter@334
   684
deba@335
   685
    /// \brief Row map of the grid graph
kpeter@334
   686
    ///
deba@335
   687
    /// Just returns a RowMap for the grid graph.
deba@335
   688
    RowMap rowMap() const {
deba@335
   689
      return RowMap(*this);
kpeter@334
   690
    }
kpeter@334
   691
deba@335
   692
    /// \brief Column map of the grid graph
kpeter@334
   693
    ///
deba@335
   694
    /// Just returns a ColMap for the grid graph.
deba@335
   695
    ColMap colMap() const {
deba@335
   696
      return ColMap(*this);
kpeter@334
   697
    }
kpeter@334
   698
deba@335
   699
  };
kpeter@334
   700
kpeter@334
   701
}
deba@335
   702
#endif