lemon/grid_graph.h
author alpar
Tue, 08 Nov 2005 10:10:09 +0000
changeset 1779 f6cafba4dbf2
parent 1693 269f0cbfbcc8
child 1791 62e7d237e1fb
permissions -rw-r--r--
Obsolete bug removed
     1 /* -*- C++ -*-
     2  * lemon/grid_graph.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef GRID_GRAPH_H
    18 #define GRID_GRAPH_H
    19 
    20 #include <iostream>
    21 #include <lemon/invalid.h>
    22 #include <lemon/utility.h>
    23 
    24 #include <lemon/bits/iterable_graph_extender.h>
    25 #include <lemon/bits/alteration_notifier.h>
    26 #include <lemon/bits/static_map.h>
    27 
    28 #include <lemon/bits/undir_graph_extender.h>
    29 
    30 #include <lemon/xy.h>
    31 
    32 ///\ingroup graphs
    33 ///\file
    34 ///\brief GridGraph class.
    35 
    36 namespace lemon {
    37 
    38   /// \brief Base graph for GridGraph.
    39   ///
    40   /// Base graph for grid graph. It describes some member functions
    41   /// which can be used in the GridGraph.
    42   ///
    43   /// \warning Always use the GridGraph instead of this.
    44   /// \see GridGraph
    45   class GridGraphBase {
    46 
    47   public:
    48 
    49     typedef GridGraphBase Graph;
    50 
    51     class Node;
    52     class Edge;
    53 
    54   public:
    55 
    56     GridGraphBase() {}
    57 
    58   protected:
    59 
    60     /// \brief Creates a grid graph with the given size.
    61     ///
    62     /// Creates a grid graph with the given size.
    63     void construct(int width, int height) {
    64       _height = height; _width = width;
    65       _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height;
    66       _edgeLimit = _nodeNum - width;
    67     }
    68 
    69     /// \brief Gives back the edge goes down from the node.
    70     ///
    71     /// Gives back the edge goes down from the node. If there is not
    72     /// outgoing edge then it gives back INVALID.
    73     Edge _down(Node n) const {
    74       if (n.id < _nodeNum - _width) {
    75 	return Edge(n.id);
    76       } else {
    77 	return INVALID;
    78       }
    79     }
    80 
    81     /// \brief Gives back the edge comes from up into the node.
    82     ///
    83     /// Gives back the edge comes from up into the node. If there is not
    84     /// incoming edge then it gives back INVALID.
    85     Edge _up(Node n) const {
    86       if (n.id >= _width) {
    87 	return Edge(n.id - _width);
    88       } else {
    89 	return INVALID;
    90       }
    91     }
    92 
    93     /// \brief Gives back the edge goes right from the node.
    94     ///
    95     /// Gives back the edge goes right from the node. If there is not
    96     /// outgoing edge then it gives back INVALID.
    97     Edge _right(Node n) const {
    98       if (n.id % _width < _width - 1) {
    99 	return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1);
   100       } else {
   101 	return INVALID;
   102       }
   103     }
   104 
   105     /// \brief Gives back the edge comes from left into the node.
   106     ///
   107     /// Gives back the edge comes left up into the node. If there is not
   108     /// incoming edge then it gives back INVALID.
   109     Edge _left(Node n) const {
   110       if (n.id % _width > 0) {
   111 	return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1) - 1;
   112       } else {
   113 	return INVALID;
   114       }
   115     }
   116 
   117 
   118   public:
   119     
   120     /// \brief The node on the given position.
   121     /// 
   122     /// Gives back the node on the given position.
   123     Node operator()(int i, int j) const {
   124       return Node(i + j * _width);
   125     }
   126 
   127     /// \brief Gives back the row index of the node.
   128     ///
   129     /// Gives back the row index of the node.
   130     int row(Node n) const {
   131       return n.id / _width;
   132     }
   133     
   134     /// \brief Gives back the coloumn index of the node.
   135     ///
   136     /// Gives back the coloumn index of the node.
   137     int col(Node n) const {
   138       return n.id % _width;    
   139     }
   140 
   141     /// \brief Gives back the width of the graph.
   142     ///
   143     /// Gives back the width of the graph.
   144     int width() const {
   145       return _width;
   146     }
   147 
   148     /// \brief Gives back the height of the graph.
   149     ///
   150     /// Gives back the height of the graph.
   151     int height() const {
   152       return _height;
   153     }
   154 
   155     typedef True NodeNumTag;
   156     typedef True EdgeNumTag;
   157 
   158     ///Number of nodes.
   159     int nodeNum() const { return _nodeNum; }
   160     ///Number of edges.
   161     int edgeNum() const { return _edgeNum; }
   162 
   163     /// Maximum node ID.
   164     
   165     /// Maximum node ID.
   166     ///\sa id(Node)
   167     int maxId(Node = INVALID) const { return nodeNum() - 1; }
   168     /// Maximum edge ID.
   169     
   170     /// Maximum edge ID.
   171     ///\sa id(Edge)
   172     int maxId(Edge = INVALID) const { return edgeNum() - 1; }
   173 
   174     /// \brief Gives back the source node of an edge.
   175     ///    
   176     /// Gives back the source node of an edge.
   177     Node source(Edge e) const {
   178       if (e.id < _edgeLimit) {
   179 	return e.id;
   180       } else {
   181 	return (e.id - _edgeLimit) % (_width - 1) +
   182 	  (e.id - _edgeLimit) / (_width - 1) * _width;
   183       }
   184     }
   185 
   186     /// \brief Gives back the target node of an edge.
   187     ///    
   188     /// Gives back the target node of an edge.
   189     Node target(Edge e) const {
   190       if (e.id < _edgeLimit) {
   191 	return e.id + _width;
   192       } else {
   193 	return (e.id - _edgeLimit) % (_width - 1) +
   194 	  (e.id - _edgeLimit) / (_width - 1) * _width + 1;
   195       }
   196     }
   197 
   198     /// Node ID.
   199     
   200     /// The ID of a valid Node is a nonnegative integer not greater than
   201     /// \ref maxNodeId(). The range of the ID's is not surely continuous
   202     /// and the greatest node ID can be actually less then \ref maxNodeId().
   203     ///
   204     /// The ID of the \ref INVALID node is -1.
   205     ///\return The ID of the node \c v. 
   206 
   207     static int id(Node v) { return v.id; }
   208     /// Edge ID.
   209     
   210     /// The ID of a valid Edge is a nonnegative integer not greater than
   211     /// \ref maxEdgeId(). The range of the ID's is not surely continuous
   212     /// and the greatest edge ID can be actually less then \ref maxEdgeId().
   213     ///
   214     /// The ID of the \ref INVALID edge is -1.
   215     ///\return The ID of the edge \c e. 
   216     static int id(Edge e) { return e.id; }
   217 
   218     static Node fromId(int id, Node) { return Node(id);}
   219     
   220     static Edge fromId(int id, Edge) { return Edge(id);}
   221 
   222     typedef True FindEdgeTag;
   223 
   224     /// Finds an edge between two nodes.
   225     
   226     /// Finds an edge from node \c u to node \c v.
   227     ///
   228     /// If \c prev is \ref INVALID (this is the default value), then
   229     /// It finds the first edge from \c u to \c v. Otherwise it looks for
   230     /// the next edge from \c u to \c v after \c prev.
   231     /// \return The found edge or INVALID if there is no such an edge.
   232     Edge findEdge(Node u, Node v, Edge prev = INVALID) {
   233       if (prev != INVALID) return INVALID;
   234       if (v.id - u.id == _width) return Edge(u.id);
   235       if (v.id - u.id == 1 && u.id % _width < _width - 1) {
   236 	return Edge(u.id / _width * (_width - 1) +
   237 		    u.id % _width + _edgeLimit);
   238       }
   239       return INVALID;
   240     }
   241     
   242       
   243     class Node {
   244       friend class GridGraphBase;
   245 
   246     protected:
   247       int id;
   248       Node(int _id) { id = _id;}
   249     public:
   250       Node() {}
   251       Node (Invalid) { id = -1; }
   252       bool operator==(const Node node) const {return id == node.id;}
   253       bool operator!=(const Node node) const {return id != node.id;}
   254       bool operator<(const Node node) const {return id < node.id;}
   255     };
   256     
   257 
   258 
   259     class Edge {
   260       friend class GridGraphBase;
   261       
   262     protected:
   263       int id; 
   264 
   265       Edge(int _id) : id(_id) {}
   266 
   267     public:
   268       Edge() { }
   269       Edge (Invalid) { id = -1; }
   270       bool operator==(const Edge edge) const {return id == edge.id;}
   271       bool operator!=(const Edge edge) const {return id != edge.id;}
   272       bool operator<(const Edge edge) const {return id < edge.id;}
   273     };
   274 
   275     void first(Node& node) const {
   276       node.id = nodeNum() - 1;
   277     }
   278 
   279     static void next(Node& node) {
   280       --node.id;
   281     }
   282 
   283     void first(Edge& edge) const {
   284       edge.id = edgeNum() - 1;
   285     }
   286 
   287     static void next(Edge& edge) {
   288       --edge.id;
   289     }
   290 
   291     void firstOut(Edge& edge, const Node& node) const {
   292       if (node.id < _nodeNum - _width) {
   293 	edge.id = node.id;
   294       } else if (node.id % _width < _width - 1) {
   295 	edge.id = _edgeLimit + node.id % _width +
   296 	  (node.id / _width) * (_width - 1);
   297       } else {
   298 	edge.id = -1;
   299       }
   300     }
   301 
   302     void nextOut(Edge& edge) const {
   303       if (edge.id >= _edgeLimit) {
   304 	edge.id = -1;
   305       } else if (edge.id % _width < _width - 1) {
   306 	edge.id = _edgeLimit + edge.id % _width +
   307 	  (edge.id / _width) * (_width - 1);
   308       } else {
   309 	edge.id = -1;
   310       }
   311     }
   312 
   313     void firstIn(Edge& edge, const Node& node) const {
   314       if (node.id >= _width) {
   315 	edge.id = node.id - _width;
   316       } else if (node.id % _width > 0) {
   317 	edge.id = _edgeLimit + node.id % _width +
   318 	  (node.id / _width) * (_width - 1) - 1;
   319       } else {
   320 	edge.id = -1;
   321       }
   322     }
   323     
   324     void nextIn(Edge& edge) const {
   325       if (edge.id >= _edgeLimit) {
   326 	edge.id = -1;
   327       } else if (edge.id % _width > 0) {
   328 	edge.id = _edgeLimit + edge.id % _width +
   329 	  (edge.id / _width + 1) * (_width - 1) - 1;
   330       } else {
   331 	edge.id = -1;
   332       }
   333     }
   334 
   335   private:
   336     int _width, _height;
   337     int _nodeNum, _edgeNum;
   338     int _edgeLimit;
   339   };
   340 
   341 
   342   typedef StaticMappableUndirGraphExtender<
   343     IterableUndirGraphExtender<
   344     AlterableUndirGraphExtender<
   345     UndirGraphExtender<GridGraphBase> > > > ExtendedGridGraphBase;
   346 
   347   /// \ingroup graphs
   348   ///
   349   /// \brief Grid graph class
   350   ///
   351   /// This class implements a special graph type. The nodes of the
   352   /// graph can be indiced by two integer \c (i,j) value where \c i
   353   /// is in the \c [0,height) range and j is in the [0, width) range.
   354   /// Two nodes are connected in the graph if the indices differ only
   355   /// on one position and only one is the difference. 
   356   ///
   357   /// The graph can be indiced in the following way:
   358   /// \code
   359   /// GridGraph graph(h, w);
   360   /// GridGraph::NodeMap<int> val(graph); 
   361   /// for (int i = 0; i < graph.height(); ++i) {
   362   ///   for (int j = 0; j < graph.width(); ++j) {
   363   ///     val[graph(i, j)] = i + j;
   364   ///   }
   365   /// }
   366   /// \endcode
   367   ///
   368   /// The graph type is fully conform to the \ref concept::UndirGraph
   369   /// "Undirected Graph" concept.
   370   ///
   371   /// \author Balazs Dezso
   372   /// \see GridGraphBase
   373   class GridGraph : public ExtendedGridGraphBase {
   374   public:
   375 
   376     /// \brief Map to get the indices of the nodes as xy<int>.
   377     ///
   378     /// Map to get the indices of the nodes as xy<int>.
   379     class IndexMap {
   380     public:
   381       typedef True NeedCopy;
   382       /// \brief The key type of the map
   383       typedef GridGraph::Node Key;
   384       /// \brief The value type of the map
   385       typedef xy<int> Value;
   386 
   387       /// \brief Constructor
   388       ///
   389       /// Constructor
   390       IndexMap(const GridGraph& _graph) : graph(_graph) {}
   391 
   392       /// \brief The subscript operator
   393       ///
   394       /// The subscript operator.
   395       Value operator[](Key key) const {
   396 	return xy<int>(graph.row(key), graph.col(key));
   397       }
   398 
   399     private:
   400       const GridGraph& graph;
   401     };
   402 
   403     /// \brief Map to get the row of the nodes.
   404     ///
   405     /// Map to get the row of the nodes.
   406     class RowMap {
   407     public:
   408       typedef True NeedCopy;
   409       /// \brief The key type of the map
   410       typedef GridGraph::Node Key;
   411       /// \brief The value type of the map
   412       typedef int Value;
   413 
   414       /// \brief Constructor
   415       ///
   416       /// Constructor
   417       RowMap(const GridGraph& _graph) : graph(_graph) {}
   418 
   419       /// \brief The subscript operator
   420       ///
   421       /// The subscript operator.
   422       Value operator[](Key key) const {
   423 	return graph.row(key);
   424       }
   425 
   426     private:
   427       const GridGraph& graph;
   428     };
   429 
   430     /// \brief Map to get the column of the nodes.
   431     ///
   432     /// Map to get the column of the nodes.
   433     class ColMap {
   434     public:
   435       typedef True NeedCopy;
   436       /// \brief The key type of the map
   437       typedef GridGraph::Node Key;
   438       /// \brief The value type of the map
   439       typedef int Value;
   440 
   441       /// \brief Constructor
   442       ///
   443       /// Constructor
   444       ColMap(const GridGraph& _graph) : graph(_graph) {}
   445 
   446       /// \brief The subscript operator
   447       ///
   448       /// The subscript operator.
   449       Value operator[](Key key) const {
   450 	return graph.col(key);
   451       }
   452 
   453     private:
   454       const GridGraph& graph;
   455     };
   456 
   457     GridGraph(int n, int m) { construct(n, m); }
   458     
   459     /// \brief Gives back the edge goes down from the node.
   460     ///
   461     /// Gives back the edge goes down from the node. If there is not
   462     /// outgoing edge then it gives back INVALID.
   463     Edge down(Node n) const {
   464       UndirEdge ue = _down(n);
   465       return ue != INVALID ? direct(ue, true) : INVALID;
   466     }
   467     
   468     /// \brief Gives back the edge goes up from the node.
   469     ///
   470     /// Gives back the edge goes up from the node. If there is not
   471     /// outgoing edge then it gives back INVALID.
   472     Edge up(Node n) const {
   473       UndirEdge ue = _up(n);
   474       return ue != INVALID ? direct(ue, false) : INVALID;
   475     }
   476 
   477     /// \brief Gives back the edge goes right from the node.
   478     ///
   479     /// Gives back the edge goes right from the node. If there is not
   480     /// outgoing edge then it gives back INVALID.
   481     Edge right(Node n) const {
   482       UndirEdge ue = _right(n);
   483       return ue != INVALID ? direct(ue, true) : INVALID;
   484     }
   485 
   486     /// \brief Gives back the edge goes left from the node.
   487     ///
   488     /// Gives back the edge goes left from the node. If there is not
   489     /// outgoing edge then it gives back INVALID.
   490     Edge left(Node n) const {
   491       UndirEdge ue = _left(n);
   492       return ue != INVALID ? direct(ue, false) : INVALID;
   493     }
   494     
   495   };
   496 
   497   /// \brief Index map of the grid graph
   498   ///
   499   /// Just returns an IndexMap for the grid graph.
   500   GridGraph::IndexMap indexMap(const GridGraph& graph) {
   501     return GridGraph::IndexMap(graph);
   502   }
   503 
   504   /// \brief Row map of the grid graph
   505   ///
   506   /// Just returns an RowMap for the grid graph.
   507   GridGraph::RowMap rowMap(const GridGraph& graph) {
   508     return GridGraph::RowMap(graph);
   509   }
   510 
   511   /// \brief Coloumn map of the grid graph
   512   ///
   513   /// Just returns an ColMap for the grid graph.
   514   GridGraph::ColMap colMap(const GridGraph& graph) {
   515     return GridGraph::ColMap(graph);
   516   }
   517 }
   518 #endif