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