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: deba@1979: #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: /// \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 > 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 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. deba@1979: /// deba@1979: /// Map to get the indices of the nodes as xy. 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 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(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