1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
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_COMPACT_GRAPH_H
20 #define LEMON_COMPACT_GRAPH_H
24 ///\brief CompactDigraph class.
26 #include <lemon/core.h>
27 #include <lemon/bits/graph_extender.h>
33 class CompactDigraphBase {
38 : built(false), node_num(0), arc_num(0),
42 ~CompactDigraphBase() {
44 delete[] node_first_out;
50 friend class CompactDigraphBase;
53 Node(int _id) : id(_id) {}
56 Node (Invalid) : id(-1) {}
57 bool operator==(const Node& node) const { return id == node.id; }
58 bool operator!=(const Node& node) const { return id != node.id; }
59 bool operator<(const Node& node) const { return id < node.id; }
63 friend class CompactDigraphBase;
67 Arc(int _id, int _source) : id(_id), source(_source) {}
70 Arc (Invalid) : id(-1), source(-1) {}
71 bool operator==(const Arc& arc) const { return id == arc.id; }
72 bool operator!=(const Arc& arc) const { return id != arc.id; }
73 bool operator<(const Arc& arc) const { return id < arc.id; }
76 Node source(const Arc& e) const { return Node(e.source); }
77 Node target(const Arc& e) const { return Node(arc_target[e.id]); }
79 void first(Node& n) const { n.id = node_num - 1; }
80 static void next(Node& n) { --n.id; }
84 void nextSource(Arc& e) const {
85 if (e.id == -1) return;
86 int last = node_first_out[e.source] - 1;
87 while (e.id == last) {
89 last = node_first_out[e.source] - 1;
95 void first(Arc& e) const {
97 e.source = node_num - 1;
100 void next(Arc& e) const {
105 void firstOut(Arc& e, const Node& n) const {
107 e.id = node_first_out[n.id];
108 if (e.id == node_first_out[n.id + 1]) e = INVALID;
110 void nextOut(Arc& e) const {
112 if (e.id == node_first_out[e.source + 1]) e = INVALID;
115 void firstIn(Arc& e, const Node& n) const {
117 while(e != INVALID && target(e) != n) {
121 void nextIn(Arc& e) const {
122 Node arcTarget = target(e);
125 } while(e != INVALID && target(e) != arcTarget);
128 static int id(const Node& n) { return n.id; }
129 static Node nodeFromId(int id) { return Node(id); }
130 int maxNodeId() const { return node_num - 1; }
132 static int id(const Arc& e) { return e.id; }
133 Arc arcFromId(int id) const {
134 int *l = std::upper_bound(node_first_out, node_first_out + node_num, id) - 1;
135 int src = l - node_first_out;
138 int maxArcId() const { return arc_num - 1; }
140 typedef True NodeNumTag;
141 typedef True ArcNumTag;
143 int nodeNum() const { return node_num; }
144 int arcNum() const { return arc_num; }
148 template <typename Digraph, typename NodeRefMap>
151 typedef typename Digraph::Arc Arc;
153 ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
154 : digraph(_graph), nodeRef(_nodeRef) {}
156 bool operator()(const Arc& left, const Arc& right) const {
157 return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
160 const Digraph& digraph;
161 const NodeRefMap& nodeRef;
166 typedef True BuildTag;
170 delete[] node_first_out;
178 template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
179 void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
180 typedef typename Digraph::Node GNode;
181 typedef typename Digraph::Arc GArc;
185 node_num = countNodes(digraph);
186 arc_num = countArcs(digraph);
188 node_first_out = new int[node_num + 1];
190 arc_target = new int[arc_num];
193 for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
194 nodeRef[n] = Node(node_index);
198 ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
201 for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
202 int source = nodeRef[n].id;
203 std::vector<GArc> arcs;
204 for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
208 node_first_out[source] = arc_index;
209 std::sort(arcs.begin(), arcs.end(), arcLess);
210 for (typename std::vector<GArc>::iterator it = arcs.begin();
211 it != arcs.end(); ++it) {
212 int target = nodeRef[digraph.target(*it)].id;
213 arcRef[*it] = Arc(arc_index, source);
214 arc_target[arc_index] = target;
218 node_first_out[source] = arc_index;
221 node_first_out[node_num] = arc_num;
224 template <typename ArcListIterator>
225 void build(int n, ArcListIterator first, ArcListIterator last) {
229 arc_num = static_cast<int>(std::distance(first, last));
231 node_first_out = new int[node_num + 1];
233 arc_target = new int[arc_num];
236 for (int i = 0; i != node_num; ++i) {
237 node_first_out[i] = arc_index;
238 for ( ; first != last && (*first).first == i; ++first) {
239 int j = (*first).second;
240 LEMON_ASSERT(j >= 0 && j < node_num,
241 "Wrong arc list for CompactDigraph::build()");
242 arc_target[arc_index] = j;
246 LEMON_ASSERT(first == last,
247 "Wrong arc list for CompactDigraph::build()");
248 node_first_out[node_num] = arc_num;
259 typedef DigraphExtender<CompactDigraphBase> ExtendedCompactDigraphBase;
264 /// \brief A static directed graph class.
266 /// \ref CompactDigraph is a highly efficient digraph implementation
267 /// similar to \ref StaticDigraph. It is more memory efficient but does
268 /// not provide efficient iteration over incoming arcs.
270 /// It stores only one \c int values for each node and one \c int value
271 /// for each arc. Its \ref InArcIt implementation is inefficient and
272 /// provided only for compatibility with the \ref concepts::Digraph "Digraph concept".
274 /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
275 /// Most of its member functions and nested classes are documented
276 /// only in the concept class.
278 /// \sa concepts::Digraph
279 class CompactDigraph : public ExtendedCompactDigraphBase {
282 /// Graphs are \e not copy constructible. Use DigraphCopy instead.
283 CompactDigraph(const CompactDigraph &) : ExtendedCompactDigraphBase() {};
284 /// \brief Assignment of a graph to another one is \e not allowed.
285 /// Use DigraphCopy instead.
286 void operator=(const CompactDigraph&) {}
290 typedef ExtendedCompactDigraphBase Parent;
294 /// \brief Constructor
296 /// Default constructor.
297 CompactDigraph() : Parent() {}
299 /// \brief The node with the given index.
301 /// This function returns the node with the given index.
303 static Node node(int ix) { return Parent::nodeFromId(ix); }
305 /// \brief The arc with the given index.
307 /// This function returns the arc with the given index.
309 Arc arc(int ix) { return arcFromId(ix); }
311 /// \brief The index of the given node.
313 /// This function returns the index of the the given node.
315 static int index(Node node) { return Parent::id(node); }
317 /// \brief The index of the given arc.
319 /// This function returns the index of the the given arc.
321 static int index(Arc arc) { return Parent::id(arc); }
323 /// \brief Number of nodes.
325 /// This function returns the number of nodes.
326 int nodeNum() const { return node_num; }
328 /// \brief Number of arcs.
330 /// This function returns the number of arcs.
331 int arcNum() const { return arc_num; }
333 /// \brief Build the digraph copying another digraph.
335 /// This function builds the digraph copying another digraph of any
336 /// kind. It can be called more than once, but in such case, the whole
337 /// structure and all maps will be cleared and rebuilt.
339 /// This method also makes possible to copy a digraph to a CompactDigraph
340 /// structure using \ref DigraphCopy.
342 /// \param digraph An existing digraph to be copied.
343 /// \param nodeRef The node references will be copied into this map.
344 /// Its key type must be \c Digraph::Node and its value type must be
345 /// \c CompactDigraph::Node.
346 /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
348 /// \param arcRef The arc references will be copied into this map.
349 /// Its key type must be \c Digraph::Arc and its value type must be
350 /// \c CompactDigraph::Arc.
351 /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
353 /// \note If you do not need the arc references, then you could use
354 /// \ref NullMap for the last parameter. However the node references
355 /// are required by the function itself, thus they must be readable
357 template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
358 void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
359 if (built) Parent::clear();
360 Parent::build(digraph, nodeRef, arcRef);
363 /// \brief Build the digraph from an arc list.
365 /// This function builds the digraph from the given arc list.
366 /// It can be called more than once, but in such case, the whole
367 /// structure and all maps will be cleared and rebuilt.
369 /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
370 /// specified by STL compatible itartors whose \c value_type must be
371 /// <tt>std::pair<int,int></tt>.
372 /// Each arc must be specified by a pair of integer indices
373 /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
374 /// non-decreasing order with respect to their first values.</i>
375 /// If the k-th pair in the list is <tt>(i,j)</tt>, then
376 /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
378 /// \param n The number of nodes.
379 /// \param begin An iterator pointing to the beginning of the arc list.
380 /// \param end An iterator pointing to the end of the arc list.
382 /// For example, a simple digraph can be constructed like this.
384 /// std::vector<std::pair<int,int> > arcs;
385 /// arcs.push_back(std::make_pair(0,1));
386 /// arcs.push_back(std::make_pair(0,2));
387 /// arcs.push_back(std::make_pair(1,3));
388 /// arcs.push_back(std::make_pair(1,2));
389 /// arcs.push_back(std::make_pair(3,0));
390 /// CompactDigraph gr;
391 /// gr.build(4, arcs.begin(), arcs.end());
393 template <typename ArcListIterator>
394 void build(int n, ArcListIterator begin, ArcListIterator end) {
395 if (built) Parent::clear();
396 CompactDigraphBase::build(n, begin, end);
397 notifier(Node()).build();
398 notifier(Arc()).build();
401 /// \brief Clear the digraph.
403 /// This function erases all nodes and arcs from the digraph.
410 Node baseNode(const OutArcIt &arc) const {
411 return Parent::source(static_cast<const Arc&>(arc));
414 Node runningNode(const OutArcIt &arc) const {
415 return Parent::target(static_cast<const Arc&>(arc));
418 Node baseNode(const InArcIt &arc) const {
419 return Parent::target(static_cast<const Arc&>(arc));
422 Node runningNode(const InArcIt &arc) const {
423 return Parent::source(static_cast<const Arc&>(arc));