00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef GRID_GRAPH_H
00018 #define GRID_GRAPH_H
00019
00020 #include <iostream>
00021 #include <lemon/invalid.h>
00022 #include <lemon/utility.h>
00023
00024 #include <lemon/bits/iterable_graph_extender.h>
00025 #include <lemon/bits/alteration_notifier.h>
00026 #include <lemon/bits/default_map.h>
00027
00028 #include <lemon/bits/undir_graph_extender.h>
00029
00030 namespace lemon {
00031
00032 class GridGraphBase {
00033
00034 public:
00035
00036 typedef GridGraphBase Graph;
00037
00038 class Node;
00039 class Edge;
00040
00041 public:
00042
00043 GridGraphBase() {}
00044
00045 protected:
00046
00050 void construct(int height, int width) {
00051 _height = height; _width = width;
00052 _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height;
00053 _edgeLimit = _nodeNum - width;
00054 }
00055
00056 public:
00057
00061 Node operator()(int i, int j) const {
00062 return Node(i * _width + j);
00063 }
00064
00068 int row(Node n) const {
00069 return n.id / _width;
00070 }
00071
00075 int col(Node node) const {
00076 return n.id % _width;
00077 }
00078
00082 int width() const {
00083 return _width;
00084 }
00085
00089 int height() const {
00090 return _height;
00091 }
00092
00093 typedef True NodeNumTag;
00094 typedef True EdgeNumTag;
00095
00097 int nodeNum() const { return _nodeNum; }
00099 int edgeNum() const { return _edgeNum; }
00100
00102
00105 int maxId(Node = INVALID) const { return nodeNum() - 1; }
00107
00110 int maxId(Edge = INVALID) const { return edgeNum() - 1; }
00111
00115 Node source(Edge e) const {
00116 if (e.id < _edgeLimit) {
00117 return e.id;
00118 } else {
00119 return (e.id - _edgeLimit) % (_width - 1) +
00120 (e.id - _edgeLimit) / (_width - 1) * _width;
00121 }
00122 }
00123
00127 Node target(Edge e) const {
00128 if (e.id < _edgeLimit) {
00129 return e.id + _width;
00130 } else {
00131 return (e.id - _edgeLimit) % (_width - 1) +
00132 (e.id - _edgeLimit) / (_width - 1) * _width + 1;
00133 }
00134 }
00135
00137
00144
00145 static int id(Node v) { return v.id; }
00147
00154 static int id(Edge e) { return e.id; }
00155
00156 static Node fromId(int id, Node) { return Node(id);}
00157
00158 static Edge fromId(int id, Edge) { return Edge(id);}
00159
00160 typedef True FindEdgeTag;
00161
00163
00170 Edge findEdge(Node u, Node v, Edge prev = INVALID) {
00171 if (prev != INVALID) return INVALID;
00172 if (v.id - u.id == _width) return Edge(u.id);
00173 if (v.id - u.id == 1 && u.id % _width < _width - 1) {
00174 return Edge(u.id / _width * (_width - 1) +
00175 u.id % _width + _edgeLimit);
00176 }
00177 return INVALID;
00178 }
00179
00180
00181 class Node {
00182 friend class GridGraphBase;
00183
00184 protected:
00185 int id;
00186 Node(int _id) { id = _id;}
00187 public:
00188 Node() {}
00189 Node (Invalid) { id = -1; }
00190 bool operator==(const Node node) const {return id == node.id;}
00191 bool operator!=(const Node node) const {return id != node.id;}
00192 bool operator<(const Node node) const {return id < node.id;}
00193 };
00194
00195
00196
00197 class Edge {
00198 friend class GridGraphBase;
00199
00200 protected:
00201 int id;
00202
00203 Edge(int _id) : id(_id) {}
00204
00205 public:
00206 Edge() { }
00207 Edge (Invalid) { id = -1; }
00208 bool operator==(const Edge edge) const {return id == edge.id;}
00209 bool operator!=(const Edge edge) const {return id != edge.id;}
00210 bool operator<(const Edge edge) const {return id < edge.id;}
00211 };
00212
00213 void first(Node& node) const {
00214 node.id = nodeNum() - 1;
00215 }
00216
00217 static void next(Node& node) {
00218 --node.id;
00219 }
00220
00221 void first(Edge& edge) const {
00222 edge.id = edgeNum() - 1;
00223 }
00224
00225 static void next(Edge& edge) {
00226 --edge.id;
00227 }
00228
00229 void firstOut(Edge& edge, const Node& node) const {
00230 if (node.id < _nodeNum - _width) {
00231 edge.id = node.id;
00232 } else if (node.id % _width < _width - 1) {
00233 edge.id = _edgeLimit + node.id % _width +
00234 (node.id / _width) * (_width - 1);
00235 } else {
00236 edge.id = -1;
00237 }
00238 }
00239
00240 void nextOut(Edge& edge) const {
00241 if (edge.id >= _edgeLimit) {
00242 edge.id = -1;
00243 } else if (edge.id % _width < _width - 1) {
00244 edge.id = _edgeLimit + edge.id % _width +
00245 (edge.id / _width) * (_width - 1);
00246 } else {
00247 edge.id = -1;
00248 }
00249 }
00250
00251 void firstIn(Edge& edge, const Node& node) const {
00252 if (node.id >= _width) {
00253 edge.id = node.id - _width;
00254 } else if (node.id % _width > 0) {
00255 edge.id = _edgeLimit + node.id % _width +
00256 (node.id / _width) * (_width - 1) - 1;
00257 } else {
00258 edge.id = -1;
00259 }
00260 }
00261
00262 void nextIn(Edge& edge) const {
00263 if (edge.id >= _edgeLimit) {
00264 edge.id = -1;
00265 } else if (edge.id % _width > 0) {
00266 edge.id = _edgeLimit + edge.id % _width +
00267 (edge.id / _width + 1) * (_width - 1) - 1;
00268 } else {
00269 edge.id = -1;
00270 }
00271 }
00272
00273 private:
00274 int _width, _height;
00275 int _nodeNum, _edgeNum;
00276 int _edgeLimit;
00277 };
00278
00279
00280 typedef UndirGraphExtender<GridGraphBase>
00281 UndirGridGraphBase;
00282 typedef AlterableUndirGraphExtender<UndirGridGraphBase>
00283 AlterableGridGraphBase;
00284 typedef IterableUndirGraphExtender<AlterableGridGraphBase>
00285 IterableGridGraphBase;
00286 typedef MappableUndirGraphExtender<IterableGridGraphBase>
00287 MappableGridGraphBase;
00288
00314 class GridGraph : public MappableGridGraphBase {
00315 public:
00316
00317 GridGraph(int m, int n) { construct(m, n); }
00318 };
00319 }
00320 #endif