3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_FULL_GRAPH_H
20 #define LEMON_FULL_GRAPH_H
24 #include <lemon/bits/base_extender.h>
25 #include <lemon/bits/graph_extender.h>
27 #include <lemon/bits/invalid.h>
28 #include <lemon/bits/utility.h>
33 ///\brief FullGraph and FullUGraph classes.
43 typedef FullGraphBase Graph;
52 void construct(int n) { _nodeNum = n; _edgeNum = n * n; }
56 typedef True NodeNumTag;
57 typedef True EdgeNumTag;
59 Node operator()(int index) const { return Node(index); }
60 int index(const Node& node) const { return node.id; }
62 Edge edge(const Node& u, const Node& v) const {
63 return Edge(*this, u.id, v.id);
66 int nodeNum() const { return _nodeNum; }
67 int edgeNum() const { return _edgeNum; }
69 int maxNodeId() const { return _nodeNum-1; }
70 int maxEdgeId() const { return _edgeNum-1; }
72 Node source(Edge e) const { return e.id % _nodeNum; }
73 Node target(Edge e) const { return e.id / _nodeNum; }
76 static int id(Node v) { return v.id; }
77 static int id(Edge e) { return e.id; }
79 static Node nodeFromId(int id) { return Node(id);}
81 static Edge edgeFromId(int id) { return Edge(id);}
83 typedef True FindEdgeTag;
85 Edge findEdge(Node u,Node v, Edge prev = INVALID) const {
86 return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID;
91 friend class FullGraphBase;
95 Node(int _id) : id(_id) {}
98 Node (Invalid) : id(-1) {}
99 bool operator==(const Node node) const {return id == node.id;}
100 bool operator!=(const Node node) const {return id != node.id;}
101 bool operator<(const Node node) const {return id < node.id;}
107 friend class FullGraphBase;
110 int id; // _nodeNum * target + source;
112 Edge(int _id) : id(_id) {}
114 Edge(const FullGraphBase& _graph, int source, int target)
115 : id(_graph._nodeNum * target+source) {}
118 Edge (Invalid) { id = -1; }
119 bool operator==(const Edge edge) const {return id == edge.id;}
120 bool operator!=(const Edge edge) const {return id != edge.id;}
121 bool operator<(const Edge edge) const {return id < edge.id;}
124 void first(Node& node) const {
125 node.id = _nodeNum-1;
128 static void next(Node& node) {
132 void first(Edge& edge) const {
133 edge.id = _edgeNum-1;
136 static void next(Edge& edge) {
140 void firstOut(Edge& edge, const Node& node) const {
141 edge.id = _edgeNum + node.id - _nodeNum;
144 void nextOut(Edge& edge) const {
146 if (edge.id < 0) edge.id = -1;
149 void firstIn(Edge& edge, const Node& node) const {
150 edge.id = node.id * _nodeNum;
153 void nextIn(Edge& edge) const {
155 if (edge.id % _nodeNum == 0) edge.id = -1;
160 typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
164 /// \brief A full graph class.
166 /// This is a simple and fast directed full graph implementation.
167 /// It is completely static, so you can neither add nor delete either
169 /// Thus it conforms to
170 /// the \ref concept::Graph "Graph" concept
171 /// \sa concept::Graph.
175 /// \author Alpar Juttner
176 class FullGraph : public ExtendedFullGraphBase {
179 typedef ExtendedFullGraphBase Parent;
181 /// \brief Constructor
182 FullGraph() { construct(0); }
184 /// \brief Constructor
186 FullGraph(int n) { construct(n); }
188 /// \brief Resize the graph
190 /// Resize the graph. The function will fully destroy and build the graph.
191 /// This cause that the maps of the graph will reallocated
192 /// automatically and the previous values will be lost.
194 Parent::getNotifier(Edge()).clear();
195 Parent::getNotifier(Node()).clear();
197 Parent::getNotifier(Node()).build();
198 Parent::getNotifier(Edge()).build();
201 /// \brief Returns the node with the given index.
203 /// Returns the node with the given index. Because it is a
204 /// static size graph the node's of the graph can be indiced
205 /// by the range from 0 to \e nodeNum()-1 and the index of
206 /// the node can accessed by the \e index() member.
207 Node operator()(int index) const { return Parent::operator()(index); }
209 /// \brief Returns the index of the node.
211 /// Returns the index of the node. Because it is a
212 /// static size graph the node's of the graph can be indiced
213 /// by the range from 0 to \e nodeNum()-1 and the index of
214 /// the node can accessed by the \e index() member.
215 int index(const Node& node) const { return Parent::index(node); }
217 /// \brief Returns the edge connects the given nodes.
219 /// Returns the edge connects the given nodes.
220 Edge edge(const Node& u, const Node& v) const {
221 return Parent::edge(u, v);
224 /// \brief Number of nodes.
225 int nodeNum() const { return Parent::nodeNum(); }
226 /// \brief Number of edges.
227 int edgeNum() const { return Parent::edgeNum(); }
231 class FullUGraphBase {
236 typedef FullUGraphBase Graph;
245 void construct(int n) { _nodeNum = n; _edgeNum = n * (n - 1) / 2; }
250 Node operator()(int index) const { return Node(index); }
251 int index(const Node& node) const { return node.id; }
253 Edge edge(const Node& u, const Node& v) const {
254 return Edge(u.id * (u.id - 1) / 2 + v.id);
257 typedef True NodeNumTag;
258 typedef True EdgeNumTag;
260 int nodeNum() const { return _nodeNum; }
261 int edgeNum() const { return _edgeNum; }
263 int maxNodeId() const { return _nodeNum-1; }
264 int maxEdgeId() const { return _edgeNum-1; }
266 static Node nodeFromId(int id) { return Node(id);}
267 static Edge edgeFromId(int id) { return Edge(id);}
269 Node source(Edge e) const {
270 /// \todo we may do it faster
271 return Node(((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2);
274 Node target(Edge e) const {
275 int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;;
276 return Node(e.id - (source) * (source - 1) / 2);
279 static int id(Node v) { return v.id; }
280 static int id(Edge e) { return e.id; }
282 Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
283 if (prev.id != -1 || u.id <= v.id) return Edge(-1);
284 return Edge(u.id * (u.id - 1) / 2 + v.id);
287 typedef True FindEdgeTag;
291 friend class FullUGraphBase;
295 Node(int _id) { id = _id;}
298 Node (Invalid) { id = -1; }
299 bool operator==(const Node node) const {return id == node.id;}
300 bool operator!=(const Node node) const {return id != node.id;}
301 bool operator<(const Node node) const {return id < node.id;}
307 friend class FullUGraphBase;
310 int id; // _nodeNum * target + source;
312 Edge(int _id) : id(_id) {}
316 Edge (Invalid) { id = -1; }
317 bool operator==(const Edge edge) const {return id == edge.id;}
318 bool operator!=(const Edge edge) const {return id != edge.id;}
319 bool operator<(const Edge edge) const {return id < edge.id;}
322 void first(Node& node) const {
323 node.id = _nodeNum - 1;
326 static void next(Node& node) {
330 void first(Edge& edge) const {
331 edge.id = _edgeNum - 1;
334 static void next(Edge& edge) {
338 void firstOut(Edge& edge, const Node& node) const {
341 edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
344 /// \todo with specialized iterators we can make faster iterating
345 void nextOut(Edge& edge) const {
346 int src = source(edge).id;
347 int trg = target(edge).id;
349 edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1);
352 void firstIn(Edge& edge, const Node& node) const {
353 int src = node.id + 1;
355 edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
358 void nextIn(Edge& edge) const {
359 int src = source(edge).id;
360 int trg = target(edge).id;
362 edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1);
367 typedef UGraphExtender<UndirGraphExtender<FullUGraphBase> >
368 ExtendedFullUGraphBase;
372 /// \brief An undirected full graph class.
374 /// This is a simple and fast undirected full graph implementation.
375 /// It is completely static, so you can neither add nor delete either
378 /// The main difference beetween the \e FullGraph and \e FullUGraph class
379 /// is that this class conforms to the undirected graph concept and
380 /// it does not contain the loop edges.
384 /// \author Balazs Dezso
385 class FullUGraph : public ExtendedFullUGraphBase {
388 typedef ExtendedFullUGraphBase Parent;
390 /// \brief Constructor
391 FullUGraph() { construct(0); }
393 /// \brief Constructor
394 FullUGraph(int n) { construct(n); }
396 /// \brief Resize the graph
398 /// Resize the graph. The function will fully destroy and build the graph.
399 /// This cause that the maps of the graph will reallocated
400 /// automatically and the previous values will be lost.
402 Parent::getNotifier(Edge()).clear();
403 Parent::getNotifier(UEdge()).clear();
404 Parent::getNotifier(Node()).clear();
406 Parent::getNotifier(Node()).build();
407 Parent::getNotifier(UEdge()).build();
408 Parent::getNotifier(Edge()).build();
411 /// \brief Returns the node with the given index.
413 /// Returns the node with the given index. Because it is a
414 /// static size graph the node's of the graph can be indiced
415 /// by the range from 0 to \e nodeNum()-1 and the index of
416 /// the node can accessed by the \e index() member.
417 Node operator()(int index) const { return Parent::operator()(index); }
419 /// \brief Returns the index of the node.
421 /// Returns the index of the node. Because it is a
422 /// static size graph the node's of the graph can be indiced
423 /// by the range from 0 to \e nodeNum()-1 and the index of
424 /// the node can accessed by the \e index() member.
425 int index(const Node& node) const { return Parent::index(node); }
427 /// \brief Number of nodes.
428 int nodeNum() const { return Parent::nodeNum(); }
429 /// \brief Number of edges.
430 int edgeNum() const { return Parent::edgeNum(); }
431 /// \brief Number of undirected edges.
432 int uEdgeNum() const { return Parent::uEdgeNum(); }
434 /// \brief Returns the edge connects the given nodes.
436 /// Returns the edge connects the given nodes.
437 Edge edge(const Node& u, const Node& v) const {
438 if (Parent::index(u) > Parent::index(v)) {
439 return Parent::direct(Parent::edge(u, v), true);
440 } else if (Parent::index(u) == Parent::index(v)) {
443 return Parent::direct(Parent::edge(v, u), false);
447 /// \brief Returns the undirected edge connects the given nodes.
449 /// Returns the undirected edge connects the given nodes.
450 UEdge uEdge(const Node& u, const Node& v) const {
451 if (Parent::index(u) > Parent::index(v)) {
452 return Parent::edge(u, v);
453 } else if (Parent::index(u) == Parent::index(v)) {
456 return Parent::edge(v, u);
462 class FullBpUGraphBase {
472 FullBpUGraphBase() {}
474 void construct(int aNodeNum, int bNodeNum) {
475 _aNodeNum = aNodeNum;
476 _bNodeNum = bNodeNum;
477 _edgeNum = aNodeNum * bNodeNum;
482 class NodeSetError : public LogicError {
484 virtual const char* what() const throw() {
485 return "lemon::FullBpUGraph::NodeSetError";
490 friend class FullBpUGraphBase;
494 Node(int _id) : id(_id) {}
497 Node(Invalid) { id = -1; }
498 bool operator==(const Node i) const {return id==i.id;}
499 bool operator!=(const Node i) const {return id!=i.id;}
500 bool operator<(const Node i) const {return id<i.id;}
504 friend class FullBpUGraphBase;
508 UEdge(int _id) { id = _id;}
511 UEdge (Invalid) { id = -1; }
512 bool operator==(const UEdge i) const {return id==i.id;}
513 bool operator!=(const UEdge i) const {return id!=i.id;}
514 bool operator<(const UEdge i) const {return id<i.id;}
517 Node aNode(int index) const { return Node(index << 1); }
518 Node bNode(int index) const { return Node((index << 1) + 1); }
520 int aNodeIndex(const Node& node) const { return node.id >> 1; }
521 int bNodeIndex(const Node& node) const { return node.id >> 1; }
523 UEdge uEdge(const Node& u, const Node& v) const {
524 if (((u.id ^ v.id) & 1) != 1) {
526 } else if ((u.id & 1) == 0) {
527 return UEdge((u.id >> 1) * _bNodeNum + (v.id >> 1));
529 return UEdge((v.id >> 1) * _bNodeNum + (u.id >> 1));
533 void firstANode(Node& node) const {
534 node.id = 2 * _aNodeNum - 2;
535 if (node.id < 0) node.id = -1;
537 void nextANode(Node& node) const {
539 if (node.id < 0) node.id = -1;
542 void firstBNode(Node& node) const {
543 node.id = 2 * _bNodeNum - 1;
545 void nextBNode(Node& node) const {
549 void first(Node& node) const {
551 node.id = 2 * _aNodeNum - 2;
553 node.id = 2 * _bNodeNum - 1;
556 void next(Node& node) const {
559 node.id = 2 * _bNodeNum - 1;
563 void first(UEdge& edge) const {
564 edge.id = _edgeNum - 1;
566 void next(UEdge& edge) const {
570 void firstFromANode(UEdge& edge, const Node& node) const {
571 LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
572 edge.id = (node.id >> 1) * _bNodeNum;
574 void nextFromANode(UEdge& edge) const {
576 if (edge.id % _bNodeNum == 0) edge.id = -1;
579 void firstFromBNode(UEdge& edge, const Node& node) const {
580 LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
581 edge.id = (node.id >> 1);
583 void nextFromBNode(UEdge& edge) const {
584 edge.id += _bNodeNum;
585 if (edge.id >= _edgeNum) edge.id = -1;
588 static int id(const Node& node) {
591 static Node nodeFromId(int id) {
594 int maxNodeId() const {
595 return _aNodeNum > _bNodeNum ?
596 _aNodeNum * 2 - 2 : _bNodeNum * 2 - 1;
599 static int id(const UEdge& edge) {
602 static UEdge uEdgeFromId(int id) {
605 int maxUEdgeId() const {
609 static int aNodeId(const Node& node) {
612 static Node fromANodeId(int id) {
613 return Node(id << 1);
615 int maxANodeId() const {
619 static int bNodeId(const Node& node) {
622 static Node fromBNodeId(int id) {
623 return Node((id << 1) + 1);
625 int maxBNodeId() const {
629 Node aNode(const UEdge& edge) const {
630 return Node((edge.id / _bNodeNum) << 1);
632 Node bNode(const UEdge& edge) const {
633 return Node(((edge.id % _bNodeNum) << 1) + 1);
636 static bool aNode(const Node& node) {
637 return (node.id & 1) == 0;
640 static bool bNode(const Node& node) {
641 return (node.id & 1) == 1;
645 typedef True NodeNumTag;
646 int nodeNum() const { return _aNodeNum + _bNodeNum; }
647 int aNodeNum() const { return _aNodeNum; }
648 int bNodeNum() const { return _bNodeNum; }
650 typedef True EdgeNumTag;
651 int uEdgeNum() const { return _edgeNum; }
654 typedef True FindEdgeTag;
655 UEdge findUEdge(Node u, Node v, UEdge prev = INVALID) const {
656 if (prev.id != -1 || ((u.id ^ v.id) & 1) != 1) {
658 } else if ((u.id & 1) == 0) {
659 return UEdge((u.id >> 1) * _bNodeNum + (v.id >> 1));
661 return UEdge((v.id >> 1) * _bNodeNum + (u.id >> 1));
668 typedef BpUGraphExtender<FullBpUGraphBase> ExtendedFullBpUGraphBase;
673 /// \brief An undirected full bipartite graph class.
675 /// This is a simple and fast bipartite undirected full graph implementation.
676 /// It is completely static, so you can neither add nor delete either
679 /// \author Balazs Dezso
681 public ExtendedFullBpUGraphBase {
684 typedef ExtendedFullBpUGraphBase Parent;
687 Parent::construct(0, 0);
690 FullBpUGraph(int aNodeNum, int bNodeNum) {
691 Parent::construct(aNodeNum, bNodeNum);
694 /// \brief Resize the graph
697 void resize(int n, int m) {
698 Parent::getNotifier(Edge()).clear();
699 Parent::getNotifier(UEdge()).clear();
700 Parent::getNotifier(Node()).clear();
701 Parent::getNotifier(ANode()).clear();
702 Parent::getNotifier(BNode()).clear();
704 Parent::getNotifier(ANode()).build();
705 Parent::getNotifier(BNode()).build();
706 Parent::getNotifier(Node()).build();
707 Parent::getNotifier(UEdge()).build();
708 Parent::getNotifier(Edge()).build();
711 /// \brief Number of nodes.
712 int nodeNum() const { return Parent::nodeNum(); }
713 /// \brief Number of A-nodes.
714 int aNodeNum() const { return Parent::aNodeNum(); }
715 /// \brief Number of B-nodes.
716 int bNodeNum() const { return Parent::bNodeNum(); }
717 /// \brief Number of edges.
718 int edgeNum() const { return Parent::edgeNum(); }
719 /// \brief Number of undirected edges.
720 int uEdgeNum() const { return Parent::uEdgeNum(); }
726 /// \brief Returns the A-node with the given index.
728 /// Returns the A-node with the given index. Because it is a
729 /// static size graph the node's of the graph can be indiced
730 /// by the range from 0 to \e aNodeNum()-1 and the index of
731 /// the node can accessed by the \e aNodeIndex() member.
732 Node aNode(int index) const { return Parent::aNode(index); }
734 /// \brief Returns the B-node with the given index.
736 /// Returns the B-node with the given index. Because it is a
737 /// static size graph the node's of the graph can be indiced
738 /// by the range from 0 to \e bNodeNum()-1 and the index of
739 /// the node can accessed by the \e bNodeIndex() member.
740 Node bNode(int index) const { return Parent::bNode(index); }
742 /// \brief Returns the index of the A-node.
744 /// Returns the index of the A-node. Because it is a
745 /// static size graph the node's of the graph can be indiced
746 /// by the range from 0 to \e aNodeNum()-1 and the index of
747 /// the node can accessed by the \e aNodeIndex() member.
748 int aNodeIndex(const Node& node) const { return Parent::aNodeIndex(node); }
750 /// \brief Returns the index of the B-node.
752 /// Returns the index of the B-node. Because it is a
753 /// static size graph the node's of the graph can be indiced
754 /// by the range from 0 to \e bNodeNum()-1 and the index of
755 /// the node can accessed by the \e bNodeIndex() member.
756 int bNodeIndex(const Node& node) const { return Parent::bNodeIndex(node); }
758 /// \brief Returns the edge connects the given nodes.
760 /// Returns the edge connects the given nodes.
761 Edge edge(const Node& u, const Node& v) const {
762 UEdge uedge = Parent::uEdge(u, v);
763 if (uedge != INVALID) {
764 return Parent::direct(uedge, Parent::aNode(u));
770 /// \brief Returns the undirected edge connects the given nodes.
772 /// Returns the undirected edge connects the given nodes.
773 UEdge uEdge(const Node& u, const Node& v) const {
774 return Parent::uEdge(u, v);
781 #endif //LEMON_FULL_GRAPH_H