1 /* -*- C++ -*- |
|
2 * |
|
3 * This file is a part of LEMON, a generic C++ optimization library |
|
4 * |
|
5 * Copyright (C) 2003-2006 |
|
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
8 * |
|
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. |
|
12 * |
|
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 |
|
15 * purpose. |
|
16 * |
|
17 */ |
|
18 |
|
19 #ifndef LEMON_FULL_UGRAPH_H |
|
20 #define LEMON_FULL_UGRAPH_H |
|
21 |
|
22 #include <cmath> |
|
23 |
|
24 #include <lemon/bits/base_extender.h> |
|
25 #include <lemon/bits/ugraph_extender.h> |
|
26 |
|
27 #include <lemon/bits/invalid.h> |
|
28 #include <lemon/bits/utility.h> |
|
29 |
|
30 |
|
31 ///\ingroup graphs |
|
32 ///\file |
|
33 ///\brief FullUGraph classes. |
|
34 |
|
35 |
|
36 namespace lemon { |
|
37 |
|
38 /// \brief Base of the FullUGrpah. |
|
39 /// |
|
40 /// Base of the FullUGrpah. |
|
41 class FullUGraphBase { |
|
42 int _nodeNum; |
|
43 int _edgeNum; |
|
44 public: |
|
45 |
|
46 typedef FullUGraphBase Graph; |
|
47 |
|
48 class Node; |
|
49 class Edge; |
|
50 |
|
51 public: |
|
52 |
|
53 FullUGraphBase() {} |
|
54 |
|
55 |
|
56 ///Creates a full graph with \c n nodes. |
|
57 void construct(int n) { _nodeNum = n; _edgeNum = n * (n - 1) / 2; } |
|
58 |
|
59 /// \brief Returns the node with the given index. |
|
60 /// |
|
61 /// Returns the node with the given index. Because it is a |
|
62 /// static size graph the node's of the graph can be indiced |
|
63 /// by the range from 0 to \e nodeNum()-1 and the index of |
|
64 /// the node can accessed by the \e index() member. |
|
65 Node operator()(int index) const { return Node(index); } |
|
66 |
|
67 /// \brief Returns the index of the node. |
|
68 /// |
|
69 /// Returns the index of the node. Because it is a |
|
70 /// static size graph the node's of the graph can be indiced |
|
71 /// by the range from 0 to \e nodeNum()-1 and the index of |
|
72 /// the node can accessed by the \e index() member. |
|
73 int index(const Node& node) const { return node.id; } |
|
74 |
|
75 typedef True NodeNumTag; |
|
76 typedef True EdgeNumTag; |
|
77 |
|
78 ///Number of nodes. |
|
79 int nodeNum() const { return _nodeNum; } |
|
80 ///Number of edges. |
|
81 int edgeNum() const { return _edgeNum; } |
|
82 |
|
83 /// Maximum node ID. |
|
84 |
|
85 /// Maximum node ID. |
|
86 ///\sa id(Node) |
|
87 int maxNodeId() const { return _nodeNum-1; } |
|
88 /// Maximum edge ID. |
|
89 |
|
90 /// Maximum edge ID. |
|
91 ///\sa id(Edge) |
|
92 int maxEdgeId() const { return _edgeNum-1; } |
|
93 |
|
94 /// \brief Returns the node from its \c id. |
|
95 /// |
|
96 /// Returns the node from its \c id. If there is not node |
|
97 /// with the given id the effect of the function is undefinied. |
|
98 static Node nodeFromId(int id) { return Node(id);} |
|
99 |
|
100 /// \brief Returns the edge from its \c id. |
|
101 /// |
|
102 /// Returns the edge from its \c id. If there is not edge |
|
103 /// with the given id the effect of the function is undefinied. |
|
104 static Edge edgeFromId(int id) { return Edge(id);} |
|
105 |
|
106 Node source(Edge e) const { |
|
107 /// \todo we may do it faster |
|
108 return Node(((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2); |
|
109 } |
|
110 |
|
111 Node target(Edge e) const { |
|
112 int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;; |
|
113 return Node(e.id - (source) * (source - 1) / 2); |
|
114 } |
|
115 |
|
116 |
|
117 /// \brief Node ID. |
|
118 /// |
|
119 /// The ID of a valid Node is a nonnegative integer not greater than |
|
120 /// \ref maxNodeId(). The range of the ID's is not surely continuous |
|
121 /// and the greatest node ID can be actually less then \ref maxNodeId(). |
|
122 /// |
|
123 /// The ID of the \ref INVALID node is -1. |
|
124 /// \return The ID of the node \c v. |
|
125 |
|
126 static int id(Node v) { return v.id; } |
|
127 |
|
128 /// \brief Edge ID. |
|
129 /// |
|
130 /// The ID of a valid Edge is a nonnegative integer not greater than |
|
131 /// \ref maxEdgeId(). The range of the ID's is not surely continuous |
|
132 /// and the greatest edge ID can be actually less then \ref maxEdgeId(). |
|
133 /// |
|
134 /// The ID of the \ref INVALID edge is -1. |
|
135 ///\return The ID of the edge \c e. |
|
136 static int id(Edge e) { return e.id; } |
|
137 |
|
138 /// \brief Finds an edge between two nodes. |
|
139 /// |
|
140 /// Finds an edge from node \c u to node \c v. |
|
141 /// |
|
142 /// If \c prev is \ref INVALID (this is the default value), then |
|
143 /// It finds the first edge from \c u to \c v. Otherwise it looks for |
|
144 /// the next edge from \c u to \c v after \c prev. |
|
145 /// \return The found edge or INVALID if there is no such an edge. |
|
146 Edge findEdge(Node u, Node v, Edge prev = INVALID) const { |
|
147 if (prev.id != -1 || u.id <= v.id) return Edge(-1); |
|
148 return Edge(u.id * (u.id - 1) / 2 + v.id); |
|
149 } |
|
150 |
|
151 typedef True FindEdgeTag; |
|
152 |
|
153 |
|
154 class Node { |
|
155 friend class FullUGraphBase; |
|
156 |
|
157 protected: |
|
158 int id; |
|
159 Node(int _id) { id = _id;} |
|
160 public: |
|
161 Node() {} |
|
162 Node (Invalid) { id = -1; } |
|
163 bool operator==(const Node node) const {return id == node.id;} |
|
164 bool operator!=(const Node node) const {return id != node.id;} |
|
165 bool operator<(const Node node) const {return id < node.id;} |
|
166 }; |
|
167 |
|
168 |
|
169 |
|
170 class Edge { |
|
171 friend class FullUGraphBase; |
|
172 |
|
173 protected: |
|
174 int id; // _nodeNum * target + source; |
|
175 |
|
176 Edge(int _id) : id(_id) {} |
|
177 |
|
178 public: |
|
179 Edge() { } |
|
180 Edge (Invalid) { id = -1; } |
|
181 bool operator==(const Edge edge) const {return id == edge.id;} |
|
182 bool operator!=(const Edge edge) const {return id != edge.id;} |
|
183 bool operator<(const Edge edge) const {return id < edge.id;} |
|
184 }; |
|
185 |
|
186 void first(Node& node) const { |
|
187 node.id = _nodeNum - 1; |
|
188 } |
|
189 |
|
190 static void next(Node& node) { |
|
191 --node.id; |
|
192 } |
|
193 |
|
194 void first(Edge& edge) const { |
|
195 edge.id = _edgeNum - 1; |
|
196 } |
|
197 |
|
198 static void next(Edge& edge) { |
|
199 --edge.id; |
|
200 } |
|
201 |
|
202 void firstOut(Edge& edge, const Node& node) const { |
|
203 int src = node.id; |
|
204 int trg = 0; |
|
205 edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1); |
|
206 } |
|
207 |
|
208 /// \todo with specialized iterators we can make faster iterating |
|
209 void nextOut(Edge& edge) const { |
|
210 int src = source(edge).id; |
|
211 int trg = target(edge).id; |
|
212 ++trg; |
|
213 edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1); |
|
214 } |
|
215 |
|
216 void firstIn(Edge& edge, const Node& node) const { |
|
217 int src = node.id + 1; |
|
218 int trg = node.id; |
|
219 edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1); |
|
220 } |
|
221 |
|
222 void nextIn(Edge& edge) const { |
|
223 int src = source(edge).id; |
|
224 int trg = target(edge).id; |
|
225 ++src; |
|
226 edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1); |
|
227 } |
|
228 |
|
229 }; |
|
230 |
|
231 typedef UGraphExtender<UndirGraphExtender<FullUGraphBase> > |
|
232 ExtendedFullUGraphBase; |
|
233 |
|
234 /// \ingroup graphs |
|
235 /// |
|
236 /// \brief An undirected full graph class. |
|
237 /// |
|
238 /// This is a simple and fast undirected full graph implementation. |
|
239 /// It is completely static, so you can neither add nor delete either |
|
240 /// edges or nodes. |
|
241 /// |
|
242 /// The main difference beetween the \e FullGraph and \e FullUGraph class |
|
243 /// is that this class conforms to the undirected graph concept and |
|
244 /// it does not contain the loop edges. |
|
245 /// |
|
246 /// \sa FullUGraphBase |
|
247 /// \sa FullGraph |
|
248 /// |
|
249 /// \author Balazs Dezso |
|
250 class FullUGraph : public ExtendedFullUGraphBase { |
|
251 public: |
|
252 |
|
253 typedef ExtendedFullUGraphBase Parent; |
|
254 |
|
255 /// \brief Constructor |
|
256 FullUGraph() { construct(0); } |
|
257 |
|
258 /// \brief Constructor |
|
259 FullUGraph(int n) { construct(n); } |
|
260 |
|
261 /// \brief Resize the graph |
|
262 /// |
|
263 /// Resize the graph. The function will fully destroy and build the graph. |
|
264 /// This cause that the maps of the graph will reallocated |
|
265 /// automatically and the previous values will be lost. |
|
266 void resize(int n) { |
|
267 Parent::getNotifier(Edge()).clear(); |
|
268 Parent::getNotifier(UEdge()).clear(); |
|
269 Parent::getNotifier(Node()).clear(); |
|
270 construct(n); |
|
271 Parent::getNotifier(Node()).build(); |
|
272 Parent::getNotifier(UEdge()).build(); |
|
273 Parent::getNotifier(Edge()).build(); |
|
274 } |
|
275 }; |
|
276 |
|
277 } //namespace lemon |
|
278 |
|
279 |
|
280 #endif //LEMON_FULL_GRAPH_H |
|