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