lemon/grid_graph.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 17 Apr 2009 18:04:36 +0200
changeset 609 e6927fe719e6
parent 360 75cf49ce5390
child 559 c5fd2d996909
permissions -rw-r--r--
Support >= and <= constraints in NetworkSimplex (#219, #234)

By default the same inequality constraints are supported as by
Circulation (the GEQ form), but the LEQ form can also be selected
using the problemType() function.

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