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