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 deba@1993: #include deba@1993: #include deba@1979: deba@1999: #include deba@2116: #include deba@1979: alpar@2207: #include deba@1979: deba@1979: ///\ingroup graphs deba@1979: ///\file deba@1979: ///\brief GridUGraph class. deba@1979: deba@1979: namespace lemon { deba@1979: 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: 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: 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: 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: 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: 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: alpar@2151: virtual const char* what() const throw() { deba@1979: return "lemon::GridUGraph::IndexError"; deba@1979: } deba@1979: }; deba@1979: deba@1979: 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: int row(Node n) const { deba@1979: return n.id / _width; deba@1979: } deba@1979: deba@1979: int col(Node n) const { deba@1979: return n.id % _width; deba@1979: } deba@1979: deba@1979: int width() const { deba@1979: return _width; deba@1979: } deba@1979: 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: int nodeNum() const { return _nodeNum; } deba@1979: int edgeNum() const { return _edgeNum; } deba@1979: deba@1979: int maxNodeId() const { return nodeNum() - 1; } deba@1979: int maxEdgeId() const { return edgeNum() - 1; } deba@1979: 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: 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: static int id(Node v) { return v.id; } 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: 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 > 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@2223: /// \image html grid_ugraph.png deba@2223: /// \image latex grid_ugraph.eps "Grid graph" width=\textwidth deba@2223: /// deba@1979: /// The graph can be indiced in the following way: deba@1979: ///\code deba@1979: /// GridUGraph graph(w, h); deba@1979: /// GridUGraph::NodeMap 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: /// alpar@2260: /// The graph type is fully conform to the \ref concepts::UGraph alpar@2256: /// "Undirected Graph" concept, and it also has an alpar@2256: ///important extra feature that alpar@2260: ///its maps are real \ref concepts::ReferenceMap "reference map"s. alpar@2256: /// deba@1979: /// deba@1979: /// \author Balazs Dezso deba@1979: class GridUGraph : public ExtendedGridUGraphBase { deba@1979: public: deba@1979: deba@1979: typedef ExtendedGridUGraphBase Parent; deba@1979: alpar@2207: /// \brief Map to get the indices of the nodes as dim2::Point. deba@1979: /// alpar@2207: /// Map to get the indices of the nodes as dim2::Point. 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 alpar@2207: typedef dim2::Point 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 { alpar@2207: return dim2::Point(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@2384: Parent::notifier(Edge()).clear(); deba@2384: Parent::notifier(UEdge()).clear(); deba@2384: Parent::notifier(Node()).clear(); deba@1979: construct(n, m); deba@2384: Parent::notifier(Node()).build(); deba@2384: Parent::notifier(UEdge()).build(); deba@2384: Parent::notifier(Edge()).build(); deba@1979: } deba@1979: deba@2223: /// \brief The node on the given position. deba@2223: /// deba@2223: /// Gives back the node on the given position. deba@2223: Node operator()(int i, int j) const { deba@2223: return Parent::operator()(i, j); deba@2223: } deba@2223: deba@2223: /// \brief Gives back the row index of the node. deba@2223: /// deba@2223: /// Gives back the row index of the node. deba@2223: int row(Node n) const { deba@2223: return Parent::row(n); deba@2223: } deba@2223: deba@2223: /// \brief Gives back the coloumn index of the node. deba@2223: /// deba@2223: /// Gives back the coloumn index of the node. deba@2223: int col(Node n) const { deba@2223: return Parent::col(n); deba@2223: } deba@2223: deba@2223: /// \brief Gives back the width of the graph. deba@2223: /// deba@2223: /// Gives back the width of the graph. deba@2223: int width() const { deba@2223: return Parent::width(); deba@2223: } deba@2223: deba@2223: /// \brief Gives back the height of the graph. deba@2223: /// deba@2223: /// Gives back the height of the graph. deba@2223: int height() const { deba@2223: return Parent::height(); deba@2223: } deba@2223: 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