deba@365: /* -*- mode: C++; indent-tabs-mode: nil; -*- deba@365: * deba@365: * This file is a part of LEMON, a generic C++ optimization library. deba@365: * alpar@463: * Copyright (C) 2003-2009 deba@365: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@365: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@365: * deba@365: * Permission to use, modify and distribute this software is granted deba@365: * provided that this copyright notice appears in all copies. For deba@365: * precise terms see the accompanying LICENSE file. deba@365: * deba@365: * This software is provided "AS IS" with no warranty of any kind, deba@365: * express or implied, and with no claim as to its suitability for any deba@365: * purpose. deba@365: * deba@365: */ deba@365: deba@365: #ifndef LEMON_FULL_GRAPH_H deba@365: #define LEMON_FULL_GRAPH_H deba@365: deba@365: #include deba@365: #include deba@365: deba@365: ///\ingroup graphs deba@365: ///\file kpeter@366: ///\brief FullGraph and FullDigraph classes. kpeter@366: deba@365: namespace lemon { deba@365: deba@365: class FullDigraphBase { deba@365: public: deba@365: deba@365: typedef FullDigraphBase Graph; deba@365: deba@365: class Node; deba@365: class Arc; deba@365: deba@365: protected: deba@365: deba@365: int _node_num; deba@365: int _arc_num; deba@365: deba@365: FullDigraphBase() {} deba@365: deba@365: void construct(int n) { _node_num = n; _arc_num = n * n; } deba@365: deba@365: public: deba@365: deba@365: typedef True NodeNumTag; deba@365: typedef True ArcNumTag; deba@365: deba@365: Node operator()(int ix) const { return Node(ix); } deba@365: int index(const Node& node) const { return node._id; } deba@365: deba@365: Arc arc(const Node& s, const Node& t) const { deba@365: return Arc(s._id * _node_num + t._id); deba@365: } deba@365: deba@365: int nodeNum() const { return _node_num; } deba@365: int arcNum() const { return _arc_num; } deba@365: deba@365: int maxNodeId() const { return _node_num - 1; } deba@365: int maxArcId() const { return _arc_num - 1; } deba@365: deba@365: Node source(Arc arc) const { return arc._id / _node_num; } deba@365: Node target(Arc arc) const { return arc._id % _node_num; } deba@365: deba@365: static int id(Node node) { return node._id; } deba@365: static int id(Arc arc) { return arc._id; } deba@365: deba@365: static Node nodeFromId(int id) { return Node(id);} deba@365: static Arc arcFromId(int id) { return Arc(id);} deba@365: deba@365: typedef True FindArcTag; deba@365: deba@365: Arc findArc(Node s, Node t, Arc prev = INVALID) const { kpeter@367: return prev == INVALID ? arc(s, t) : INVALID; deba@365: } deba@365: deba@365: class Node { deba@365: friend class FullDigraphBase; deba@365: deba@365: protected: deba@365: int _id; deba@365: Node(int id) : _id(id) {} deba@365: public: deba@365: Node() {} deba@365: Node (Invalid) : _id(-1) {} deba@365: bool operator==(const Node node) const {return _id == node._id;} deba@365: bool operator!=(const Node node) const {return _id != node._id;} deba@365: bool operator<(const Node node) const {return _id < node._id;} deba@365: }; deba@365: deba@365: class Arc { deba@365: friend class FullDigraphBase; deba@365: deba@365: protected: deba@365: int _id; // _node_num * source + target; deba@365: deba@365: Arc(int id) : _id(id) {} deba@365: deba@365: public: deba@365: Arc() { } deba@365: Arc (Invalid) { _id = -1; } deba@365: bool operator==(const Arc arc) const {return _id == arc._id;} deba@365: bool operator!=(const Arc arc) const {return _id != arc._id;} deba@365: bool operator<(const Arc arc) const {return _id < arc._id;} deba@365: }; deba@365: deba@365: void first(Node& node) const { deba@365: node._id = _node_num - 1; deba@365: } deba@365: deba@365: static void next(Node& node) { deba@365: --node._id; deba@365: } deba@365: deba@365: void first(Arc& arc) const { deba@365: arc._id = _arc_num - 1; deba@365: } deba@365: deba@365: static void next(Arc& arc) { deba@365: --arc._id; deba@365: } deba@365: deba@365: void firstOut(Arc& arc, const Node& node) const { deba@365: arc._id = (node._id + 1) * _node_num - 1; deba@365: } deba@365: deba@365: void nextOut(Arc& arc) const { deba@365: if (arc._id % _node_num == 0) arc._id = 0; deba@365: --arc._id; deba@365: } deba@365: deba@365: void firstIn(Arc& arc, const Node& node) const { deba@365: arc._id = _arc_num + node._id - _node_num; deba@365: } deba@365: deba@365: void nextIn(Arc& arc) const { deba@365: arc._id -= _node_num; deba@365: if (arc._id < 0) arc._id = -1; deba@365: } deba@365: deba@365: }; deba@365: deba@365: typedef DigraphExtender ExtendedFullDigraphBase; deba@365: deba@365: /// \ingroup graphs deba@365: /// deba@365: /// \brief A full digraph class. deba@365: /// deba@365: /// This is a simple and fast directed full graph implementation. deba@365: /// From each node go arcs to each node (including the source node), deba@365: /// therefore the number of the arcs in the digraph is the square of kpeter@366: /// the node number. This digraph type is completely static, so you kpeter@366: /// can neither add nor delete either arcs or nodes, and it needs deba@365: /// constant space in memory. deba@365: /// kpeter@366: /// This class conforms to the \ref concepts::Digraph "Digraph" concept deba@365: /// and it also has an important extra feature that its maps are deba@365: /// real \ref concepts::ReferenceMap "reference map"s. kpeter@366: /// kpeter@366: /// The \c FullDigraph and \c FullGraph classes are very similar, kpeter@366: /// but there are two differences. While this class conforms only kpeter@366: /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph kpeter@366: /// class conforms to the \ref concepts::Graph "Graph" concept, kpeter@366: /// moreover \c FullGraph does not contain a loop arc for each kpeter@366: /// node as \c FullDigraph does. deba@365: /// deba@365: /// \sa FullGraph deba@365: class FullDigraph : public ExtendedFullDigraphBase { deba@365: public: deba@365: deba@365: typedef ExtendedFullDigraphBase Parent; deba@365: deba@365: /// \brief Constructor deba@365: FullDigraph() { construct(0); } deba@365: deba@365: /// \brief Constructor deba@365: /// kpeter@366: /// Constructor. deba@365: /// \param n The number of the nodes. deba@365: FullDigraph(int n) { construct(n); } deba@365: kpeter@366: /// \brief Resizes the digraph deba@365: /// kpeter@366: /// Resizes the digraph. The function will fully destroy and kpeter@366: /// rebuild the digraph. This cause that the maps of the digraph will kpeter@366: /// reallocated automatically and the previous values will be lost. deba@365: void resize(int n) { deba@365: Parent::notifier(Arc()).clear(); deba@365: Parent::notifier(Node()).clear(); deba@365: construct(n); deba@365: Parent::notifier(Node()).build(); deba@365: Parent::notifier(Arc()).build(); deba@365: } deba@365: deba@365: /// \brief Returns the node with the given index. deba@365: /// kpeter@366: /// Returns the node with the given index. Since it is a static kpeter@366: /// digraph its nodes can be indexed with integers from the range kpeter@366: /// [0..nodeNum()-1]. kpeter@366: /// \sa index() deba@365: Node operator()(int ix) const { return Parent::operator()(ix); } deba@365: kpeter@366: /// \brief Returns the index of the given node. deba@365: /// kpeter@366: /// Returns the index of the given node. Since it is a static kpeter@366: /// digraph its nodes can be indexed with integers from the range kpeter@366: /// [0..nodeNum()-1]. kpeter@366: /// \sa operator() deba@365: int index(const Node& node) const { return Parent::index(node); } deba@365: kpeter@366: /// \brief Returns the arc connecting the given nodes. deba@365: /// kpeter@366: /// Returns the arc connecting the given nodes. deba@365: Arc arc(const Node& u, const Node& v) const { deba@365: return Parent::arc(u, v); deba@365: } deba@365: deba@365: /// \brief Number of nodes. deba@365: int nodeNum() const { return Parent::nodeNum(); } deba@365: /// \brief Number of arcs. deba@365: int arcNum() const { return Parent::arcNum(); } deba@365: }; deba@365: deba@365: deba@365: class FullGraphBase { deba@365: int _node_num; deba@365: int _edge_num; deba@365: public: deba@365: deba@365: typedef FullGraphBase Graph; deba@365: deba@365: class Node; deba@365: class Arc; deba@365: class Edge; deba@365: deba@365: protected: deba@365: deba@365: FullGraphBase() {} deba@365: deba@365: void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; } deba@365: deba@365: int _uid(int e) const { deba@365: int u = e / _node_num; deba@365: int v = e % _node_num; deba@365: return u < v ? u : _node_num - 2 - u; deba@365: } deba@365: deba@365: int _vid(int e) const { deba@365: int u = e / _node_num; deba@365: int v = e % _node_num; deba@365: return u < v ? v : _node_num - 1 - v; deba@365: } deba@365: deba@365: void _uvid(int e, int& u, int& v) const { deba@365: u = e / _node_num; deba@365: v = e % _node_num; deba@365: if (u >= v) { deba@365: u = _node_num - 2 - u; deba@365: v = _node_num - 1 - v; deba@365: } deba@365: } deba@365: deba@365: void _stid(int a, int& s, int& t) const { deba@365: if ((a & 1) == 1) { deba@365: _uvid(a >> 1, s, t); deba@365: } else { deba@365: _uvid(a >> 1, t, s); deba@365: } deba@365: } deba@365: deba@365: int _eid(int u, int v) const { deba@365: if (u < (_node_num - 1) / 2) { deba@365: return u * _node_num + v; deba@365: } else { deba@365: return (_node_num - 1 - u) * _node_num - v - 1; deba@365: } deba@365: } deba@365: deba@365: public: deba@365: deba@365: Node operator()(int ix) const { return Node(ix); } deba@365: int index(const Node& node) const { return node._id; } deba@365: deba@365: Edge edge(const Node& u, const Node& v) const { deba@365: if (u._id < v._id) { deba@365: return Edge(_eid(u._id, v._id)); deba@365: } else if (u._id != v._id) { deba@365: return Edge(_eid(v._id, u._id)); deba@365: } else { deba@365: return INVALID; deba@365: } deba@365: } deba@365: deba@365: Arc arc(const Node& s, const Node& t) const { deba@365: if (s._id < t._id) { deba@365: return Arc((_eid(s._id, t._id) << 1) | 1); deba@365: } else if (s._id != t._id) { deba@365: return Arc(_eid(t._id, s._id) << 1); deba@365: } else { deba@365: return INVALID; deba@365: } deba@365: } deba@365: deba@365: typedef True NodeNumTag; kpeter@372: typedef True ArcNumTag; deba@365: typedef True EdgeNumTag; deba@365: deba@365: int nodeNum() const { return _node_num; } deba@365: int arcNum() const { return 2 * _edge_num; } deba@365: int edgeNum() const { return _edge_num; } deba@365: deba@365: static int id(Node node) { return node._id; } deba@365: static int id(Arc arc) { return arc._id; } deba@365: static int id(Edge edge) { return edge._id; } deba@365: deba@365: int maxNodeId() const { return _node_num-1; } deba@365: int maxArcId() const { return 2 * _edge_num-1; } deba@365: int maxEdgeId() const { return _edge_num-1; } deba@365: deba@365: static Node nodeFromId(int id) { return Node(id);} deba@365: static Arc arcFromId(int id) { return Arc(id);} deba@365: static Edge edgeFromId(int id) { return Edge(id);} deba@365: deba@365: Node u(Edge edge) const { deba@365: return Node(_uid(edge._id)); deba@365: } deba@365: deba@365: Node v(Edge edge) const { deba@365: return Node(_vid(edge._id)); deba@365: } deba@365: deba@365: Node source(Arc arc) const { deba@365: return Node((arc._id & 1) == 1 ? deba@365: _uid(arc._id >> 1) : _vid(arc._id >> 1)); deba@365: } deba@365: deba@365: Node target(Arc arc) const { deba@365: return Node((arc._id & 1) == 1 ? deba@365: _vid(arc._id >> 1) : _uid(arc._id >> 1)); deba@365: } deba@365: deba@365: typedef True FindEdgeTag; kpeter@372: typedef True FindArcTag; deba@365: deba@365: Edge findEdge(Node u, Node v, Edge prev = INVALID) const { deba@365: return prev != INVALID ? INVALID : edge(u, v); deba@365: } deba@365: deba@365: Arc findArc(Node s, Node t, Arc prev = INVALID) const { deba@365: return prev != INVALID ? INVALID : arc(s, t); deba@365: } deba@365: deba@365: class Node { deba@365: friend class FullGraphBase; deba@365: deba@365: protected: deba@365: int _id; deba@365: Node(int id) : _id(id) {} deba@365: public: deba@365: Node() {} deba@365: Node (Invalid) { _id = -1; } deba@365: bool operator==(const Node node) const {return _id == node._id;} deba@365: bool operator!=(const Node node) const {return _id != node._id;} deba@365: bool operator<(const Node node) const {return _id < node._id;} deba@365: }; deba@365: deba@365: class Edge { deba@365: friend class FullGraphBase; kpeter@366: friend class Arc; deba@365: deba@365: protected: deba@365: int _id; deba@365: deba@365: Edge(int id) : _id(id) {} deba@365: deba@365: public: deba@365: Edge() { } deba@365: Edge (Invalid) { _id = -1; } deba@365: deba@365: bool operator==(const Edge edge) const {return _id == edge._id;} deba@365: bool operator!=(const Edge edge) const {return _id != edge._id;} deba@365: bool operator<(const Edge edge) const {return _id < edge._id;} deba@365: }; deba@365: deba@365: class Arc { deba@365: friend class FullGraphBase; deba@365: deba@365: protected: deba@365: int _id; deba@365: deba@365: Arc(int id) : _id(id) {} deba@365: deba@365: public: deba@365: Arc() { } deba@365: Arc (Invalid) { _id = -1; } deba@365: deba@365: operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); } deba@365: deba@365: bool operator==(const Arc arc) const {return _id == arc._id;} deba@365: bool operator!=(const Arc arc) const {return _id != arc._id;} deba@365: bool operator<(const Arc arc) const {return _id < arc._id;} deba@365: }; deba@365: deba@365: static bool direction(Arc arc) { deba@365: return (arc._id & 1) == 1; deba@365: } deba@365: deba@365: static Arc direct(Edge edge, bool dir) { deba@365: return Arc((edge._id << 1) | (dir ? 1 : 0)); deba@365: } deba@365: deba@365: void first(Node& node) const { deba@365: node._id = _node_num - 1; deba@365: } deba@365: deba@365: static void next(Node& node) { deba@365: --node._id; deba@365: } deba@365: deba@365: void first(Arc& arc) const { deba@365: arc._id = (_edge_num << 1) - 1; deba@365: } deba@365: deba@365: static void next(Arc& arc) { deba@365: --arc._id; deba@365: } deba@365: deba@365: void first(Edge& edge) const { deba@365: edge._id = _edge_num - 1; deba@365: } deba@365: deba@365: static void next(Edge& edge) { deba@365: --edge._id; deba@365: } deba@365: deba@365: void firstOut(Arc& arc, const Node& node) const { deba@365: int s = node._id, t = _node_num - 1; deba@365: if (s < t) { deba@365: arc._id = (_eid(s, t) << 1) | 1; deba@365: } else { deba@365: --t; deba@365: arc._id = (t != -1 ? (_eid(t, s) << 1) : -1); deba@365: } deba@365: } deba@365: deba@365: void nextOut(Arc& arc) const { deba@365: int s, t; deba@365: _stid(arc._id, s, t); deba@365: --t; deba@365: if (s < t) { deba@365: arc._id = (_eid(s, t) << 1) | 1; deba@365: } else { deba@365: if (s == t) --t; deba@365: arc._id = (t != -1 ? (_eid(t, s) << 1) : -1); deba@365: } deba@365: } deba@365: deba@365: void firstIn(Arc& arc, const Node& node) const { deba@365: int s = _node_num - 1, t = node._id; deba@365: if (s > t) { deba@365: arc._id = (_eid(t, s) << 1); deba@365: } else { deba@365: --s; deba@365: arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1); deba@365: } deba@365: } deba@365: deba@365: void nextIn(Arc& arc) const { deba@365: int s, t; deba@365: _stid(arc._id, s, t); deba@365: --s; deba@365: if (s > t) { deba@365: arc._id = (_eid(t, s) << 1); deba@365: } else { deba@365: if (s == t) --s; deba@365: arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1); deba@365: } deba@365: } deba@365: deba@365: void firstInc(Edge& edge, bool& dir, const Node& node) const { deba@365: int u = node._id, v = _node_num - 1; deba@365: if (u < v) { deba@365: edge._id = _eid(u, v); deba@365: dir = true; deba@365: } else { deba@365: --v; deba@365: edge._id = (v != -1 ? _eid(v, u) : -1); deba@365: dir = false; deba@365: } deba@365: } deba@365: deba@365: void nextInc(Edge& edge, bool& dir) const { deba@365: int u, v; deba@365: if (dir) { deba@365: _uvid(edge._id, u, v); deba@365: --v; deba@365: if (u < v) { deba@365: edge._id = _eid(u, v); deba@365: } else { deba@365: --v; deba@365: edge._id = (v != -1 ? _eid(v, u) : -1); deba@365: dir = false; deba@365: } deba@365: } else { deba@365: _uvid(edge._id, v, u); deba@365: --v; deba@365: edge._id = (v != -1 ? _eid(v, u) : -1); deba@365: } deba@365: } deba@365: deba@365: }; deba@365: deba@365: typedef GraphExtender ExtendedFullGraphBase; deba@365: deba@365: /// \ingroup graphs deba@365: /// deba@365: /// \brief An undirected full graph class. deba@365: /// deba@365: /// This is a simple and fast undirected full graph deba@365: /// implementation. From each node go edge to each other node, kpeter@366: /// therefore the number of edges in the graph is \f$n(n-1)/2\f$. kpeter@366: /// This graph type is completely static, so you can neither kpeter@366: /// add nor delete either edges or nodes, and it needs constant deba@365: /// space in memory. deba@365: /// kpeter@366: /// This class conforms to the \ref concepts::Graph "Graph" concept kpeter@366: /// and it also has an important extra feature that its maps are kpeter@366: /// real \ref concepts::ReferenceMap "reference map"s. deba@365: /// kpeter@366: /// The \c FullGraph and \c FullDigraph classes are very similar, kpeter@366: /// but there are two differences. While the \c FullDigraph class kpeter@366: /// conforms only to the \ref concepts::Digraph "Digraph" concept, kpeter@366: /// this class conforms to the \ref concepts::Graph "Graph" concept, kpeter@366: /// moreover \c FullGraph does not contain a loop arc for each kpeter@366: /// node as \c FullDigraph does. deba@365: /// deba@365: /// \sa FullDigraph deba@365: class FullGraph : public ExtendedFullGraphBase { deba@365: public: deba@365: deba@365: typedef ExtendedFullGraphBase Parent; deba@365: deba@365: /// \brief Constructor deba@365: FullGraph() { construct(0); } deba@365: deba@365: /// \brief Constructor deba@365: /// kpeter@366: /// Constructor. deba@365: /// \param n The number of the nodes. deba@365: FullGraph(int n) { construct(n); } deba@365: kpeter@366: /// \brief Resizes the graph deba@365: /// kpeter@366: /// Resizes the graph. The function will fully destroy and kpeter@366: /// rebuild the graph. This cause that the maps of the graph will kpeter@366: /// reallocated automatically and the previous values will be lost. deba@365: void resize(int n) { deba@365: Parent::notifier(Arc()).clear(); deba@365: Parent::notifier(Edge()).clear(); deba@365: Parent::notifier(Node()).clear(); deba@365: construct(n); deba@365: Parent::notifier(Node()).build(); deba@365: Parent::notifier(Edge()).build(); deba@365: Parent::notifier(Arc()).build(); deba@365: } deba@365: deba@365: /// \brief Returns the node with the given index. deba@365: /// kpeter@366: /// Returns the node with the given index. Since it is a static kpeter@366: /// graph its nodes can be indexed with integers from the range kpeter@366: /// [0..nodeNum()-1]. kpeter@366: /// \sa index() deba@365: Node operator()(int ix) const { return Parent::operator()(ix); } deba@365: kpeter@366: /// \brief Returns the index of the given node. deba@365: /// kpeter@366: /// Returns the index of the given node. Since it is a static kpeter@366: /// graph its nodes can be indexed with integers from the range kpeter@366: /// [0..nodeNum()-1]. kpeter@366: /// \sa operator() deba@365: int index(const Node& node) const { return Parent::index(node); } deba@365: kpeter@366: /// \brief Returns the arc connecting the given nodes. deba@365: /// kpeter@366: /// Returns the arc connecting the given nodes. deba@365: Arc arc(const Node& s, const Node& t) const { deba@365: return Parent::arc(s, t); deba@365: } deba@365: deba@365: /// \brief Returns the edge connects the given nodes. deba@365: /// deba@365: /// Returns the edge connects the given nodes. deba@365: Edge edge(const Node& u, const Node& v) const { deba@365: return Parent::edge(u, v); deba@365: } kpeter@366: kpeter@366: /// \brief Number of nodes. kpeter@366: int nodeNum() const { return Parent::nodeNum(); } kpeter@366: /// \brief Number of arcs. kpeter@366: int arcNum() const { return Parent::arcNum(); } kpeter@366: /// \brief Number of edges. kpeter@366: int edgeNum() const { return Parent::edgeNum(); } kpeter@366: deba@365: }; deba@365: deba@365: deba@365: } //namespace lemon deba@365: deba@365: deba@365: #endif //LEMON_FULL_GRAPH_H