Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

grid_graph.h

00001 /* -*- C++ -*-
00002  * lemon/grid_graph.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00006  *
00007  * Permission to use, modify and distribute this software is granted
00008  * provided that this copyright notice appears in all copies. For
00009  * precise terms see the accompanying LICENSE file.
00010  *
00011  * This software is provided "AS IS" with no warranty of any kind,
00012  * express or implied, and with no claim as to its suitability for any
00013  * purpose.
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

Generated on Sat Aug 27 14:14:52 2005 for LEMON by  doxygen 1.4.4