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