deba@1979: /* -*- C++ -*-
deba@1979:  *
deba@1979:  * This file is a part of LEMON, a generic C++ optimization library
deba@1979:  *
deba@1979:  * Copyright (C) 2003-2006
deba@1979:  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1979:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1979:  *
deba@1979:  * Permission to use, modify and distribute this software is granted
deba@1979:  * provided that this copyright notice appears in all copies. For
deba@1979:  * precise terms see the accompanying LICENSE file.
deba@1979:  *
deba@1979:  * This software is provided "AS IS" with no warranty of any kind,
deba@1979:  * express or implied, and with no claim as to its suitability for any
deba@1979:  * purpose.
deba@1979:  *
deba@1979:  */
deba@1979: 
deba@1979: #ifndef GRID_UGRAPH_H
deba@1979: #define GRID_UGRAPH_H
deba@1979: 
deba@1979: #include <iostream>
deba@1993: #include <lemon/bits/invalid.h>
deba@1993: #include <lemon/bits/utility.h>
deba@1979: 
deba@1999: #include <lemon/bits/base_extender.h>
deba@2116: #include <lemon/bits/graph_extender.h>
deba@1979: 
deba@1979: #include <lemon/xy.h>
deba@1979: 
deba@1979: ///\ingroup graphs
deba@1979: ///\file
deba@1979: ///\brief GridUGraph class.
deba@1979: 
deba@1979: namespace lemon {
deba@1979: 
deba@1979:   /// \brief Base graph for GridUGraph.
deba@1979:   ///
deba@1979:   /// Base graph for grid graph. It describes some member functions
deba@1979:   /// which can be used in the GridUGraph.
deba@1979:   ///
deba@1979:   /// \warning Always use the GridUGraph instead of this.
deba@1979:   /// \see GridUGraph
deba@1979:   class GridUGraphBase {
deba@1979: 
deba@1979:   public:
deba@1979: 
deba@1979:     typedef GridUGraphBase UGraph;
deba@1979: 
deba@1979:     class Node;
deba@1979:     class Edge;
deba@1979: 
deba@1979:   public:
deba@1979: 
deba@1979:     GridUGraphBase() {}
deba@1979: 
deba@1979:   protected:
deba@1979: 
deba@1979:     /// \brief Creates a grid graph with the given size.
deba@1979:     ///
deba@1979:     /// Creates a grid graph with the given size.
deba@1979:     void construct(int width, int height) {
deba@1979:       _height = height; _width = width;
deba@1979:       _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height;
deba@1979:       _edgeLimit = _nodeNum - width;
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the edge goes down from the node.
deba@1979:     ///
deba@1979:     /// Gives back the edge goes down from the node. If there is not
deba@1979:     /// outgoing edge then it gives back INVALID.
deba@1979:     Edge _down(Node n) const {
deba@1979:       if (n.id < _nodeNum - _width) {
deba@1979: 	return Edge(n.id);
deba@1979:       } else {
deba@1979: 	return INVALID;
deba@1979:       }
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the edge comes from up into the node.
deba@1979:     ///
deba@1979:     /// Gives back the edge comes from up into the node. If there is not
deba@1979:     /// incoming edge then it gives back INVALID.
deba@1979:     Edge _up(Node n) const {
deba@1979:       if (n.id >= _width) {
deba@1979: 	return Edge(n.id - _width);
deba@1979:       } else {
deba@1979: 	return INVALID;
deba@1979:       }
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the edge goes right from the node.
deba@1979:     ///
deba@1979:     /// Gives back the edge goes right from the node. If there is not
deba@1979:     /// outgoing edge then it gives back INVALID.
deba@1979:     Edge _right(Node n) const {
deba@1979:       if (n.id % _width < _width - 1) {
deba@1979: 	return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1);
deba@1979:       } else {
deba@1979: 	return INVALID;
deba@1979:       }
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the edge comes from left into the node.
deba@1979:     ///
deba@1979:     /// Gives back the edge comes left up into the node. If there is not
deba@1979:     /// incoming edge then it gives back INVALID.
deba@1979:     Edge _left(Node n) const {
deba@1979:       if (n.id % _width > 0) {
deba@1979: 	return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1) - 1;
deba@1979:       } else {
deba@1979: 	return INVALID;
deba@1979:       }
deba@1979:     }
deba@1979: 
deba@1979:   public:
deba@1979: 
deba@1979:     class IndexError : public RuntimeError {
deba@1979:     public:
deba@1979:       virtual const char* exceptionName() const {
deba@1979:         return "lemon::GridUGraph::IndexError";
deba@1979:       }  
deba@1979:     };
deba@1979: 
deba@1979:     
deba@1979:     /// \brief The node on the given position.
deba@1979:     /// 
deba@1979:     /// Gives back the node on the given position.
deba@1979:     Node operator()(int i, int j) const {
deba@1986:       LEMON_ASSERT(0 <= i && i < width() && 0 <= j  && 
deba@1986:                    j < height(), IndexError());
deba@1979:       return Node(i + j * _width);
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the row index of the node.
deba@1979:     ///
deba@1979:     /// Gives back the row index of the node.
deba@1979:     int row(Node n) const {
deba@1979:       return n.id / _width;
deba@1979:     }
deba@1979:     
deba@1979:     /// \brief Gives back the coloumn index of the node.
deba@1979:     ///
deba@1979:     /// Gives back the coloumn index of the node.
deba@1979:     int col(Node n) const {
deba@1979:       return n.id % _width;    
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the width of the graph.
deba@1979:     ///
deba@1979:     /// Gives back the width of the graph.
deba@1979:     int width() const {
deba@1979:       return _width;
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the height of the graph.
deba@1979:     ///
deba@1979:     /// Gives back the height of the graph.
deba@1979:     int height() const {
deba@1979:       return _height;
deba@1979:     }
deba@1979: 
deba@1979:     typedef True NodeNumTag;
deba@1979:     typedef True EdgeNumTag;
deba@1979: 
deba@1979:     ///Number of nodes.
deba@1979:     int nodeNum() const { return _nodeNum; }
deba@1979:     ///Number of edges.
deba@1979:     int edgeNum() const { return _edgeNum; }
deba@1979: 
deba@1979:     /// Maximum node ID.
deba@1979:     
deba@1979:     /// Maximum node ID.
deba@1979:     ///\sa id(Node)
deba@1979:     int maxNodeId() const { return nodeNum() - 1; }
deba@1979:     /// Maximum edge ID.
deba@1979:     
deba@1979:     /// Maximum edge ID.
deba@1979:     ///\sa id(Edge)
deba@1979:     int maxEdgeId() const { return edgeNum() - 1; }
deba@1979: 
deba@1979:     /// \brief Gives back the source node of an edge.
deba@1979:     ///    
deba@1979:     /// Gives back the source node of an edge.
deba@1979:     Node source(Edge e) const {
deba@1979:       if (e.id < _edgeLimit) {
deba@1979: 	return e.id;
deba@1979:       } else {
deba@1979: 	return (e.id - _edgeLimit) % (_width - 1) +
deba@1979: 	  (e.id - _edgeLimit) / (_width - 1) * _width;
deba@1979:       }
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the target node of an edge.
deba@1979:     ///    
deba@1979:     /// Gives back the target node of an edge.
deba@1979:     Node target(Edge e) const {
deba@1979:       if (e.id < _edgeLimit) {
deba@1979: 	return e.id + _width;
deba@1979:       } else {
deba@1979: 	return (e.id - _edgeLimit) % (_width - 1) +
deba@1979: 	  (e.id - _edgeLimit) / (_width - 1) * _width + 1;
deba@1979:       }
deba@1979:     }
deba@1979: 
deba@1979:     /// Node ID.
deba@1979:     
deba@1979:     /// The ID of a valid Node is a nonnegative integer not greater than
deba@1979:     /// \ref maxNodeId(). The range of the ID's is not surely continuous
deba@1979:     /// and the greatest node ID can be actually less then \ref maxNodeId().
deba@1979:     ///
deba@1979:     /// The ID of the \ref INVALID node is -1.
deba@1979:     ///\return The ID of the node \c v. 
deba@1979: 
deba@1979:     static int id(Node v) { return v.id; }
deba@1979:     /// Edge ID.
deba@1979:     
deba@1979:     /// The ID of a valid Edge is a nonnegative integer not greater than
deba@1979:     /// \ref maxEdgeId(). The range of the ID's is not surely continuous
deba@1979:     /// and the greatest edge ID can be actually less then \ref maxEdgeId().
deba@1979:     ///
deba@1979:     /// The ID of the \ref INVALID edge is -1.
deba@1979:     ///\return The ID of the edge \c e. 
deba@1979:     static int id(Edge e) { return e.id; }
deba@1979: 
deba@1979:     static Node nodeFromId(int id) { return Node(id);}
deba@1979:     
deba@1979:     static Edge edgeFromId(int id) { return Edge(id);}
deba@1979: 
deba@1979:     typedef True FindEdgeTag;
deba@1979: 
deba@1979:     /// Finds an edge between two nodes.
deba@1979:     
deba@1979:     /// Finds an edge from node \c u to node \c v.
deba@1979:     ///
deba@1979:     /// If \c prev is \ref INVALID (this is the default value), then
deba@1979:     /// It finds the first edge from \c u to \c v. Otherwise it looks for
deba@1979:     /// the next edge from \c u to \c v after \c prev.
deba@1979:     /// \return The found edge or INVALID if there is no such an edge.
deba@1979:     Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
deba@1979:       if (prev != INVALID) return INVALID;
deba@1979:       if (v.id - u.id == _width) return Edge(u.id);
deba@1979:       if (v.id - u.id == 1 && u.id % _width < _width - 1) {
deba@1979: 	return Edge(u.id / _width * (_width - 1) +
deba@1979: 		    u.id % _width + _edgeLimit);
deba@1979:       }
deba@1979:       return INVALID;
deba@1979:     }
deba@1979:     
deba@1979:       
deba@1979:     class Node {
deba@1979:       friend class GridUGraphBase;
deba@1979: 
deba@1979:     protected:
deba@1979:       int id;
deba@1979:       Node(int _id) { id = _id;}
deba@1979:     public:
deba@1979:       Node() {}
deba@1979:       Node (Invalid) { id = -1; }
deba@1979:       bool operator==(const Node node) const {return id == node.id;}
deba@1979:       bool operator!=(const Node node) const {return id != node.id;}
deba@1979:       bool operator<(const Node node) const {return id < node.id;}
deba@1979:     };
deba@1979:     
deba@1979: 
deba@1979: 
deba@1979:     class Edge {
deba@1979:       friend class GridUGraphBase;
deba@1979:       
deba@1979:     protected:
deba@1979:       int id; 
deba@1979: 
deba@1979:       Edge(int _id) : id(_id) {}
deba@1979: 
deba@1979:     public:
deba@1979:       Edge() { }
deba@1979:       Edge (Invalid) { id = -1; }
deba@1979:       bool operator==(const Edge edge) const {return id == edge.id;}
deba@1979:       bool operator!=(const Edge edge) const {return id != edge.id;}
deba@1979:       bool operator<(const Edge edge) const {return id < edge.id;}
deba@1979:     };
deba@1979: 
deba@1979:     void first(Node& node) const {
deba@1979:       node.id = nodeNum() - 1;
deba@1979:     }
deba@1979: 
deba@1979:     static void next(Node& node) {
deba@1979:       --node.id;
deba@1979:     }
deba@1979: 
deba@1979:     void first(Edge& edge) const {
deba@1979:       edge.id = edgeNum() - 1;
deba@1979:     }
deba@1979: 
deba@1979:     static void next(Edge& edge) {
deba@1979:       --edge.id;
deba@1979:     }
deba@1979: 
deba@1979:     void firstOut(Edge& edge, const Node& node) const {
deba@1979:       if (node.id < _nodeNum - _width) {
deba@1979: 	edge.id = node.id;
deba@1979:       } else if (node.id % _width < _width - 1) {
deba@1979: 	edge.id = _edgeLimit + node.id % _width +
deba@1979: 	  (node.id / _width) * (_width - 1);
deba@1979:       } else {
deba@1979: 	edge.id = -1;
deba@1979:       }
deba@1979:     }
deba@1979: 
deba@1979:     void nextOut(Edge& edge) const {
deba@1979:       if (edge.id >= _edgeLimit) {
deba@1979: 	edge.id = -1;
deba@1979:       } else if (edge.id % _width < _width - 1) {
deba@1979: 	edge.id = _edgeLimit + edge.id % _width +
deba@1979: 	  (edge.id / _width) * (_width - 1);
deba@1979:       } else {
deba@1979: 	edge.id = -1;
deba@1979:       }
deba@1979:     }
deba@1979: 
deba@1979:     void firstIn(Edge& edge, const Node& node) const {
deba@1979:       if (node.id >= _width) {
deba@1979: 	edge.id = node.id - _width;
deba@1979:       } else if (node.id % _width > 0) {
deba@1979: 	edge.id = _edgeLimit + node.id % _width +
deba@1979: 	  (node.id / _width) * (_width - 1) - 1;
deba@1979:       } else {
deba@1979: 	edge.id = -1;
deba@1979:       }
deba@1979:     }
deba@1979:     
deba@1979:     void nextIn(Edge& edge) const {
deba@1979:       if (edge.id >= _edgeLimit) {
deba@1979: 	edge.id = -1;
deba@1979:       } else if (edge.id % _width > 0) {
deba@1979: 	edge.id = _edgeLimit + edge.id % _width +
deba@1979: 	  (edge.id / _width + 1) * (_width - 1) - 1;
deba@1979:       } else {
deba@1979: 	edge.id = -1;
deba@1979:       }
deba@1979:     }
deba@1979: 
deba@1979:   private:
deba@1979:     int _width, _height;
deba@1979:     int _nodeNum, _edgeNum;
deba@1979:     int _edgeLimit;
deba@1979:   };
deba@1979: 
deba@1979: 
deba@2076:   typedef UGraphExtender<UndirGraphExtender<GridUGraphBase> > 
deba@2076:   ExtendedGridUGraphBase;
deba@1979: 
deba@1979:   /// \ingroup graphs
deba@1979:   ///
deba@1979:   /// \brief Grid graph class
deba@1979:   ///
deba@1979:   /// This class implements a special graph type. The nodes of the
deba@1979:   /// graph can be indiced by two integer \c (i,j) value where \c i
deba@1979:   /// is in the \c [0,width) range and j is in the [0, height) range.
deba@1979:   /// Two nodes are connected in the graph if the indices differ only
deba@1979:   /// on one position and only one is the difference. 
deba@1979:   ///
deba@1979:   /// The graph can be indiced in the following way:
deba@1979:   ///\code
deba@1979:   /// GridUGraph graph(w, h);
deba@1979:   /// GridUGraph::NodeMap<int> val(graph); 
deba@1979:   /// for (int i = 0; i < graph.width(); ++i) {
deba@1979:   ///   for (int j = 0; j < graph.height(); ++j) {
deba@1979:   ///     val[graph(i, j)] = i + j;
deba@1979:   ///   }
deba@1979:   /// }
deba@1979:   ///\endcode
deba@1979:   ///
deba@2037:   /// The graph type is fully conform to the \ref concept::UGraph
deba@2037:   /// "Undirected Graph" concept.
deba@1979:   ///
deba@1979:   /// \author Balazs Dezso
deba@1979:   /// \see GridUGraphBase
deba@1979:   class GridUGraph : public ExtendedGridUGraphBase {
deba@1979:   public:
deba@1979: 
deba@1979:     typedef ExtendedGridUGraphBase Parent;
deba@1979: 
deba@1979:     /// \brief Map to get the indices of the nodes as xy<int>.
deba@1979:     ///
deba@1979:     /// Map to get the indices of the nodes as xy<int>.
deba@1979:     class IndexMap {
deba@1979:     public:
deba@1979:       /// \brief The key type of the map
deba@1979:       typedef GridUGraph::Node Key;
deba@1979:       /// \brief The value type of the map
deba@1979:       typedef xy<int> Value;
deba@1979: 
deba@1979:       /// \brief Constructor
deba@1979:       ///
deba@1979:       /// Constructor
deba@1979:       IndexMap(const GridUGraph& _graph) : graph(_graph) {}
deba@1979: 
deba@1979:       /// \brief The subscript operator
deba@1979:       ///
deba@1979:       /// The subscript operator.
deba@1979:       Value operator[](Key key) const {
deba@1979: 	return xy<int>(graph.row(key), graph.col(key));
deba@1979:       }
deba@1979: 
deba@1979:     private:
deba@1979:       const GridUGraph& graph;
deba@1979:     };
deba@1979: 
deba@1979:     /// \brief Map to get the row of the nodes.
deba@1979:     ///
deba@1979:     /// Map to get the row of the nodes.
deba@1979:     class RowMap {
deba@1979:     public:
deba@1979:       /// \brief The key type of the map
deba@1979:       typedef GridUGraph::Node Key;
deba@1979:       /// \brief The value type of the map
deba@1979:       typedef int Value;
deba@1979: 
deba@1979:       /// \brief Constructor
deba@1979:       ///
deba@1979:       /// Constructor
deba@1979:       RowMap(const GridUGraph& _graph) : graph(_graph) {}
deba@1979: 
deba@1979:       /// \brief The subscript operator
deba@1979:       ///
deba@1979:       /// The subscript operator.
deba@1979:       Value operator[](Key key) const {
deba@1979: 	return graph.row(key);
deba@1979:       }
deba@1979: 
deba@1979:     private:
deba@1979:       const GridUGraph& graph;
deba@1979:     };
deba@1979: 
deba@1979:     /// \brief Map to get the column of the nodes.
deba@1979:     ///
deba@1979:     /// Map to get the column of the nodes.
deba@1979:     class ColMap {
deba@1979:     public:
deba@1979:       /// \brief The key type of the map
deba@1979:       typedef GridUGraph::Node Key;
deba@1979:       /// \brief The value type of the map
deba@1979:       typedef int Value;
deba@1979: 
deba@1979:       /// \brief Constructor
deba@1979:       ///
deba@1979:       /// Constructor
deba@1979:       ColMap(const GridUGraph& _graph) : graph(_graph) {}
deba@1979: 
deba@1979:       /// \brief The subscript operator
deba@1979:       ///
deba@1979:       /// The subscript operator.
deba@1979:       Value operator[](Key key) const {
deba@1979: 	return graph.col(key);
deba@1979:       }
deba@1979: 
deba@1979:     private:
deba@1979:       const GridUGraph& graph;
deba@1979:     };
deba@1979: 
deba@1979:     /// \brief Constructor
deba@1979:     ///
deba@1979:     /// 
deba@1979:     GridUGraph(int n, int m) { construct(n, m); }
deba@1979: 
deba@1979:     /// \brief Resize the graph
deba@1979:     ///
deba@1979:     void resize(int n, int m) {
deba@1979:       Parent::getNotifier(Edge()).clear();
deba@1979:       Parent::getNotifier(UEdge()).clear();
deba@1979:       Parent::getNotifier(Node()).clear();
deba@1979:       construct(n, m);
deba@1979:       Parent::getNotifier(Node()).build();
deba@1979:       Parent::getNotifier(UEdge()).build();
deba@1979:       Parent::getNotifier(Edge()).build();
deba@1979:     }
deba@1979:     
deba@1979:     /// \brief Gives back the edge goes down from the node.
deba@1979:     ///
deba@1979:     /// Gives back the edge goes down from the node. If there is not
deba@1979:     /// outgoing edge then it gives back INVALID.
deba@1979:     Edge down(Node n) const {
deba@1979:       UEdge ue = _down(n);
deba@1979:       return ue != INVALID ? direct(ue, true) : INVALID;
deba@1979:     }
deba@1979:     
deba@1979:     /// \brief Gives back the edge goes up from the node.
deba@1979:     ///
deba@1979:     /// Gives back the edge goes up from the node. If there is not
deba@1979:     /// outgoing edge then it gives back INVALID.
deba@1979:     Edge up(Node n) const {
deba@1979:       UEdge ue = _up(n);
deba@1979:       return ue != INVALID ? direct(ue, false) : INVALID;
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the edge goes right from the node.
deba@1979:     ///
deba@1979:     /// Gives back the edge goes right from the node. If there is not
deba@1979:     /// outgoing edge then it gives back INVALID.
deba@1979:     Edge right(Node n) const {
deba@1979:       UEdge ue = _right(n);
deba@1979:       return ue != INVALID ? direct(ue, true) : INVALID;
deba@1979:     }
deba@1979: 
deba@1979:     /// \brief Gives back the edge goes left from the node.
deba@1979:     ///
deba@1979:     /// Gives back the edge goes left from the node. If there is not
deba@1979:     /// outgoing edge then it gives back INVALID.
deba@1979:     Edge left(Node n) const {
deba@1979:       UEdge ue = _left(n);
deba@1979:       return ue != INVALID ? direct(ue, false) : INVALID;
deba@1979:     }
deba@1979:     
deba@1979:   };
deba@1979: 
deba@1979:   /// \brief Index map of the grid graph
deba@1979:   ///
deba@1979:   /// Just returns an IndexMap for the grid graph.
deba@1979:   GridUGraph::IndexMap indexMap(const GridUGraph& graph) {
deba@1979:     return GridUGraph::IndexMap(graph);
deba@1979:   }
deba@1979: 
deba@1979:   /// \brief Row map of the grid graph
deba@1979:   ///
deba@1979:   /// Just returns a RowMap for the grid graph.
deba@1979:   GridUGraph::RowMap rowMap(const GridUGraph& graph) {
deba@1979:     return GridUGraph::RowMap(graph);
deba@1979:   }
deba@1979: 
deba@1979:   /// \brief Column map of the grid graph
deba@1979:   ///
deba@1979:   /// Just returns a ColMap for the grid graph.
deba@1979:   GridUGraph::ColMap colMap(const GridUGraph& graph) {
deba@1979:     return GridUGraph::ColMap(graph);
deba@1979:   }
deba@1979: }
deba@1979: #endif