| 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@735 |    473 |   /// GridGraph implements a special graph type. The nodes of the
 | 
| kpeter@735 |    474 |   /// graph can be indexed by two integer values \c (i,j) where \c i is
 | 
| kpeter@735 |    475 |   /// in the range <tt>[0..width()-1]</tt> and j is in the range
 | 
| kpeter@735 |    476 |   /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
 | 
| kpeter@735 |    477 |   /// the indices differ exactly on one position and the difference is
 | 
| kpeter@735 |    478 |   /// also exactly one. The nodes of the graph can be obtained by position
 | 
| kpeter@735 |    479 |   /// using the \c operator()() function and the indices of the nodes can
 | 
| kpeter@735 |    480 |   /// be obtained using \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@735 |    485 |   /// This class is completely static and it needs constant memory space.
 | 
| kpeter@735 |    486 |   /// Thus you can neither add nor delete nodes or edges, however
 | 
| kpeter@735 |    487 |   /// the structure can be resized using resize().
 | 
| kpeter@735 |    488 |   ///
 | 
| kpeter@334 |    489 |   /// \image html grid_graph.png
 | 
| deba@338 |    490 |   /// \image latex grid_graph.eps "Grid graph" width=\textwidth
 | 
| kpeter@334 |    491 |   ///
 | 
| deba@335 |    492 |   /// A short example about the basic usage:
 | 
| kpeter@334 |    493 |   ///\code
 | 
| deba@335 |    494 |   /// GridGraph graph(rows, cols);
 | 
| deba@335 |    495 |   /// GridGraph::NodeMap<int> val(graph);
 | 
| deba@335 |    496 |   /// for (int i = 0; i < graph.width(); ++i) {
 | 
| deba@335 |    497 |   ///   for (int j = 0; j < graph.height(); ++j) {
 | 
| deba@335 |    498 |   ///     val[graph(i, j)] = i + j;
 | 
| kpeter@334 |    499 |   ///   }
 | 
| kpeter@334 |    500 |   /// }
 | 
| kpeter@334 |    501 |   ///\endcode
 | 
| kpeter@334 |    502 |   ///
 | 
| kpeter@735 |    503 |   /// This type fully conforms to the \ref concepts::Graph "Graph concept".
 | 
| kpeter@735 |    504 |   /// Most of its member functions and nested classes are documented
 | 
| kpeter@735 |    505 |   /// only in the concept class.
 | 
| kpeter@787 |    506 |   ///
 | 
| kpeter@787 |    507 |   /// This class provides constant time counting for nodes, edges and arcs.
 | 
| kpeter@334 |    508 |   class GridGraph : public ExtendedGridGraphBase {
 | 
| kpeter@617 |    509 |     typedef ExtendedGridGraphBase Parent;
 | 
| kpeter@617 |    510 | 
 | 
| kpeter@334 |    511 |   public:
 | 
| kpeter@334 |    512 | 
 | 
| kpeter@735 |    513 |     /// \brief Map to get the indices of the nodes as \ref dim2::Point
 | 
| kpeter@735 |    514 |     /// "dim2::Point<int>".
 | 
| kpeter@334 |    515 |     ///
 | 
| kpeter@735 |    516 |     /// Map to get the indices of the nodes as \ref dim2::Point
 | 
| kpeter@735 |    517 |     /// "dim2::Point<int>".
 | 
| kpeter@334 |    518 |     class IndexMap {
 | 
| kpeter@334 |    519 |     public:
 | 
| deba@335 |    520 |       /// \brief The key type of the map
 | 
| kpeter@334 |    521 |       typedef GridGraph::Node Key;
 | 
| deba@335 |    522 |       /// \brief The value type of the map
 | 
| kpeter@334 |    523 |       typedef dim2::Point<int> Value;
 | 
| kpeter@334 |    524 | 
 | 
| deba@335 |    525 |       /// \brief Constructor
 | 
| kpeter@334 |    526 |       IndexMap(const GridGraph& graph) : _graph(graph) {}
 | 
| kpeter@334 |    527 | 
 | 
| deba@335 |    528 |       /// \brief The subscript operator
 | 
| deba@335 |    529 |       Value operator[](Key key) const {
 | 
| deba@335 |    530 |         return _graph.pos(key);
 | 
| deba@335 |    531 |       }
 | 
| deba@335 |    532 | 
 | 
| deba@335 |    533 |     private:
 | 
| deba@335 |    534 |       const GridGraph& _graph;
 | 
| deba@335 |    535 |     };
 | 
| deba@335 |    536 | 
 | 
| deba@335 |    537 |     /// \brief Map to get the column of the nodes.
 | 
| deba@335 |    538 |     ///
 | 
| deba@335 |    539 |     /// Map to get the column of the nodes.
 | 
| deba@335 |    540 |     class ColMap {
 | 
| deba@335 |    541 |     public:
 | 
| deba@335 |    542 |       /// \brief The key type of the map
 | 
| deba@335 |    543 |       typedef GridGraph::Node Key;
 | 
| deba@335 |    544 |       /// \brief The value type of the map
 | 
| deba@335 |    545 |       typedef int Value;
 | 
| deba@335 |    546 | 
 | 
| deba@335 |    547 |       /// \brief Constructor
 | 
| deba@335 |    548 |       ColMap(const GridGraph& graph) : _graph(graph) {}
 | 
| deba@335 |    549 | 
 | 
| deba@335 |    550 |       /// \brief The subscript operator
 | 
| deba@335 |    551 |       Value operator[](Key key) const {
 | 
| deba@335 |    552 |         return _graph.col(key);
 | 
| kpeter@334 |    553 |       }
 | 
| kpeter@334 |    554 | 
 | 
| kpeter@334 |    555 |     private:
 | 
| kpeter@334 |    556 |       const GridGraph& _graph;
 | 
| kpeter@334 |    557 |     };
 | 
| kpeter@334 |    558 | 
 | 
| kpeter@334 |    559 |     /// \brief Map to get the row of the nodes.
 | 
| kpeter@334 |    560 |     ///
 | 
| kpeter@334 |    561 |     /// Map to get the row of the nodes.
 | 
| kpeter@334 |    562 |     class RowMap {
 | 
| kpeter@334 |    563 |     public:
 | 
| deba@335 |    564 |       /// \brief The key type of the map
 | 
| kpeter@334 |    565 |       typedef GridGraph::Node Key;
 | 
| deba@335 |    566 |       /// \brief The value type of the map
 | 
| kpeter@334 |    567 |       typedef int Value;
 | 
| kpeter@334 |    568 | 
 | 
| deba@335 |    569 |       /// \brief Constructor
 | 
| kpeter@334 |    570 |       RowMap(const GridGraph& graph) : _graph(graph) {}
 | 
| kpeter@334 |    571 | 
 | 
| deba@335 |    572 |       /// \brief The subscript operator
 | 
| deba@335 |    573 |       Value operator[](Key key) const {
 | 
| kpeter@334 |    574 |         return _graph.row(key);
 | 
| kpeter@334 |    575 |       }
 | 
| kpeter@334 |    576 | 
 | 
| kpeter@334 |    577 |     private:
 | 
| kpeter@334 |    578 |       const GridGraph& _graph;
 | 
| kpeter@334 |    579 |     };
 | 
| kpeter@334 |    580 | 
 | 
| kpeter@334 |    581 |     /// \brief Constructor
 | 
| kpeter@334 |    582 |     ///
 | 
| kpeter@735 |    583 |     /// Construct a grid graph with the given size.
 | 
| kpeter@334 |    584 |     GridGraph(int width, int height) { construct(width, height); }
 | 
| kpeter@334 |    585 | 
 | 
| kpeter@735 |    586 |     /// \brief Resizes the graph
 | 
| kpeter@334 |    587 |     ///
 | 
| kpeter@735 |    588 |     /// This function resizes the graph. It fully destroys and
 | 
| kpeter@735 |    589 |     /// rebuilds the structure, therefore the maps of the graph will be
 | 
| kpeter@735 |    590 |     /// reallocated automatically and the previous values will be lost.
 | 
| kpeter@334 |    591 |     void resize(int width, int height) {
 | 
| kpeter@334 |    592 |       Parent::notifier(Arc()).clear();
 | 
| kpeter@334 |    593 |       Parent::notifier(Edge()).clear();
 | 
| kpeter@334 |    594 |       Parent::notifier(Node()).clear();
 | 
| kpeter@334 |    595 |       construct(width, height);
 | 
| kpeter@334 |    596 |       Parent::notifier(Node()).build();
 | 
| kpeter@334 |    597 |       Parent::notifier(Edge()).build();
 | 
| kpeter@334 |    598 |       Parent::notifier(Arc()).build();
 | 
| kpeter@334 |    599 |     }
 | 
| kpeter@334 |    600 | 
 | 
| kpeter@334 |    601 |     /// \brief The node on the given position.
 | 
| kpeter@334 |    602 |     ///
 | 
| kpeter@334 |    603 |     /// Gives back the node on the given position.
 | 
| kpeter@334 |    604 |     Node operator()(int i, int j) const {
 | 
| kpeter@334 |    605 |       return Parent::operator()(i, j);
 | 
| kpeter@334 |    606 |     }
 | 
| kpeter@334 |    607 | 
 | 
| kpeter@735 |    608 |     /// \brief The column index of the node.
 | 
| deba@335 |    609 |     ///
 | 
| deba@335 |    610 |     /// Gives back the column index of the node.
 | 
| deba@335 |    611 |     int col(Node n) const {
 | 
| deba@335 |    612 |       return Parent::col(n);
 | 
| deba@335 |    613 |     }
 | 
| deba@335 |    614 | 
 | 
| kpeter@735 |    615 |     /// \brief The row index of the node.
 | 
| kpeter@334 |    616 |     ///
 | 
| kpeter@334 |    617 |     /// Gives back the row index of the node.
 | 
| kpeter@334 |    618 |     int row(Node n) const {
 | 
| kpeter@334 |    619 |       return Parent::row(n);
 | 
| kpeter@334 |    620 |     }
 | 
| kpeter@334 |    621 | 
 | 
| kpeter@735 |    622 |     /// \brief The position of the node.
 | 
| kpeter@334 |    623 |     ///
 | 
| deba@335 |    624 |     /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
 | 
| deba@335 |    625 |     dim2::Point<int> pos(Node n) const {
 | 
| deba@335 |    626 |       return Parent::pos(n);
 | 
| kpeter@334 |    627 |     }
 | 
| kpeter@334 |    628 | 
 | 
| kpeter@735 |    629 |     /// \brief The number of the columns.
 | 
| kpeter@334 |    630 |     ///
 | 
| deba@335 |    631 |     /// Gives back the number of the columns.
 | 
| kpeter@334 |    632 |     int width() const {
 | 
| kpeter@334 |    633 |       return Parent::width();
 | 
| kpeter@334 |    634 |     }
 | 
| kpeter@334 |    635 | 
 | 
| kpeter@735 |    636 |     /// \brief The number of the rows.
 | 
| kpeter@334 |    637 |     ///
 | 
| deba@335 |    638 |     /// Gives back the number of the rows.
 | 
| kpeter@334 |    639 |     int height() const {
 | 
| kpeter@334 |    640 |       return Parent::height();
 | 
| kpeter@334 |    641 |     }
 | 
| kpeter@334 |    642 | 
 | 
| kpeter@735 |    643 |     /// \brief The arc goes right from the node.
 | 
| deba@335 |    644 |     ///
 | 
| deba@335 |    645 |     /// Gives back the arc goes right from the node. If there is not
 | 
| deba@335 |    646 |     /// outgoing arc then it gives back INVALID.
 | 
| deba@335 |    647 |     Arc right(Node n) const {
 | 
| deba@335 |    648 |       return Parent::right(n);
 | 
| deba@335 |    649 |     }
 | 
| deba@335 |    650 | 
 | 
| kpeter@735 |    651 |     /// \brief The arc goes left from the node.
 | 
| deba@335 |    652 |     ///
 | 
| deba@335 |    653 |     /// Gives back the arc goes left from the node. If there is not
 | 
| deba@335 |    654 |     /// outgoing arc then it gives back INVALID.
 | 
| deba@335 |    655 |     Arc left(Node n) const {
 | 
| deba@335 |    656 |       return Parent::left(n);
 | 
| deba@335 |    657 |     }
 | 
| deba@335 |    658 | 
 | 
| kpeter@735 |    659 |     /// \brief The arc goes up from the node.
 | 
| deba@335 |    660 |     ///
 | 
| deba@335 |    661 |     /// Gives back the arc goes up from the node. If there is not
 | 
| deba@335 |    662 |     /// outgoing arc then it gives back INVALID.
 | 
| deba@335 |    663 |     Arc up(Node n) const {
 | 
| deba@335 |    664 |       return Parent::up(n);
 | 
| deba@335 |    665 |     }
 | 
| deba@335 |    666 | 
 | 
| kpeter@735 |    667 |     /// \brief The arc goes down from the node.
 | 
| kpeter@334 |    668 |     ///
 | 
| kpeter@334 |    669 |     /// Gives back the arc goes down from the node. If there is not
 | 
| deba@335 |    670 |     /// outgoing arc then it gives back INVALID.
 | 
| kpeter@334 |    671 |     Arc down(Node n) const {
 | 
| deba@335 |    672 |       return Parent::down(n);
 | 
| kpeter@334 |    673 |     }
 | 
| kpeter@334 |    674 | 
 | 
| deba@335 |    675 |     /// \brief Index map of the grid graph
 | 
| kpeter@334 |    676 |     ///
 | 
| deba@335 |    677 |     /// Just returns an IndexMap for the grid graph.
 | 
| deba@335 |    678 |     IndexMap indexMap() const {
 | 
| deba@335 |    679 |       return IndexMap(*this);
 | 
| kpeter@334 |    680 |     }
 | 
| kpeter@334 |    681 | 
 | 
| deba@335 |    682 |     /// \brief Row map of the grid graph
 | 
| kpeter@334 |    683 |     ///
 | 
| deba@335 |    684 |     /// Just returns a RowMap for the grid graph.
 | 
| deba@335 |    685 |     RowMap rowMap() const {
 | 
| deba@335 |    686 |       return RowMap(*this);
 | 
| kpeter@334 |    687 |     }
 | 
| kpeter@334 |    688 | 
 | 
| deba@335 |    689 |     /// \brief Column map of the grid graph
 | 
| kpeter@334 |    690 |     ///
 | 
| deba@335 |    691 |     /// Just returns a ColMap for the grid graph.
 | 
| deba@335 |    692 |     ColMap colMap() const {
 | 
| deba@335 |    693 |       return ColMap(*this);
 | 
| kpeter@334 |    694 |     }
 | 
| kpeter@334 |    695 | 
 | 
| deba@335 |    696 |   };
 | 
| kpeter@334 |    697 | 
 | 
| kpeter@334 |    698 | }
 | 
| deba@335 |    699 | #endif
 |