1 /* -*- C++ -*- |
1 /* -*- mode: C++; indent-tabs-mode: nil; -*- |
2 * |
2 * |
3 * This file is a part of LEMON, a generic C++ optimization library |
3 * This file is a part of LEMON, a generic C++ optimization library. |
4 * |
4 * |
5 * Copyright (C) 2003-2008 |
5 * Copyright (C) 2003-2010 |
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 * |
8 * |
9 * Permission to use, modify and distribute this software is granted |
9 * Permission to use, modify and distribute this software is granted |
10 * provided that this copyright notice appears in all copies. For |
10 * provided that this copyright notice appears in all copies. For |
29 namespace lemon { |
29 namespace lemon { |
30 |
30 |
31 class StaticDigraphBase { |
31 class StaticDigraphBase { |
32 public: |
32 public: |
33 |
33 |
34 StaticDigraphBase() |
34 StaticDigraphBase() |
35 : built(false), node_num(0), arc_num(0), |
35 : built(false), node_num(0), arc_num(0), |
36 node_first_out(NULL), node_first_in(NULL), |
36 node_first_out(NULL), node_first_in(NULL), |
37 arc_source(NULL), arc_target(NULL), |
37 arc_source(NULL), arc_target(NULL), |
38 arc_next_in(NULL), arc_next_out(NULL) {} |
38 arc_next_in(NULL), arc_next_out(NULL) {} |
39 |
39 |
40 ~StaticDigraphBase() { |
40 ~StaticDigraphBase() { |
41 if (built) { |
41 if (built) { |
42 delete[] node_first_out; |
42 delete[] node_first_out; |
43 delete[] node_first_in; |
43 delete[] node_first_in; |
44 delete[] arc_source; |
44 delete[] arc_source; |
81 static void next(Node& n) { --n.id; } |
81 static void next(Node& n) { --n.id; } |
82 |
82 |
83 void first(Arc& e) const { e.id = arc_num - 1; } |
83 void first(Arc& e) const { e.id = arc_num - 1; } |
84 static void next(Arc& e) { --e.id; } |
84 static void next(Arc& e) { --e.id; } |
85 |
85 |
86 void firstOut(Arc& e, const Node& n) const { |
86 void firstOut(Arc& e, const Node& n) const { |
87 e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? |
87 e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? |
88 node_first_out[n.id] : -1; |
88 node_first_out[n.id] : -1; |
89 } |
89 } |
90 void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; } |
90 void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; } |
91 |
91 |
92 void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; } |
92 void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; } |
111 template <typename Digraph, typename NodeRefMap> |
111 template <typename Digraph, typename NodeRefMap> |
112 class ArcLess { |
112 class ArcLess { |
113 public: |
113 public: |
114 typedef typename Digraph::Arc Arc; |
114 typedef typename Digraph::Arc Arc; |
115 |
115 |
116 ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) |
116 ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) |
117 : digraph(_graph), nodeRef(_nodeRef) {} |
117 : digraph(_graph), nodeRef(_nodeRef) {} |
118 |
118 |
119 bool operator()(const Arc& left, const Arc& right) const { |
119 bool operator()(const Arc& left, const Arc& right) const { |
120 return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)]; |
120 return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)]; |
121 } |
121 } |
122 private: |
122 private: |
123 const Digraph& digraph; |
123 const Digraph& digraph; |
124 const NodeRefMap& nodeRef; |
124 const NodeRefMap& nodeRef; |
125 }; |
125 }; |
126 |
126 |
127 public: |
127 public: |
128 |
128 |
129 typedef True BuildTag; |
129 typedef True BuildTag; |
130 |
130 |
131 void clear() { |
131 void clear() { |
132 if (built) { |
132 if (built) { |
133 delete[] node_first_out; |
133 delete[] node_first_out; |
134 delete[] node_first_in; |
134 delete[] node_first_in; |
135 delete[] arc_source; |
135 delete[] arc_source; |
139 } |
139 } |
140 built = false; |
140 built = false; |
141 node_num = 0; |
141 node_num = 0; |
142 arc_num = 0; |
142 arc_num = 0; |
143 } |
143 } |
144 |
144 |
145 template <typename Digraph, typename NodeRefMap, typename ArcRefMap> |
145 template <typename Digraph, typename NodeRefMap, typename ArcRefMap> |
146 void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) { |
146 void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) { |
147 typedef typename Digraph::Node GNode; |
147 typedef typename Digraph::Node GNode; |
148 typedef typename Digraph::Arc GArc; |
148 typedef typename Digraph::Arc GArc; |
149 |
149 |
181 std::sort(arcs.begin(), arcs.end(), arcLess); |
181 std::sort(arcs.begin(), arcs.end(), arcLess); |
182 for (typename std::vector<GArc>::iterator it = arcs.begin(); |
182 for (typename std::vector<GArc>::iterator it = arcs.begin(); |
183 it != arcs.end(); ++it) { |
183 it != arcs.end(); ++it) { |
184 int target = nodeRef[digraph.target(*it)].id; |
184 int target = nodeRef[digraph.target(*it)].id; |
185 arcRef[*it] = Arc(arc_index); |
185 arcRef[*it] = Arc(arc_index); |
186 arc_source[arc_index] = source; |
186 arc_source[arc_index] = source; |
187 arc_target[arc_index] = target; |
187 arc_target[arc_index] = target; |
188 arc_next_in[arc_index] = node_first_in[target]; |
188 arc_next_in[arc_index] = node_first_in[target]; |
189 node_first_in[target] = arc_index; |
189 node_first_in[target] = arc_index; |
190 arc_next_out[arc_index] = arc_index + 1; |
190 arc_next_out[arc_index] = arc_index + 1; |
191 ++arc_index; |
191 ++arc_index; |
195 node_first_out[source] = arc_index; |
195 node_first_out[source] = arc_index; |
196 } |
196 } |
197 } |
197 } |
198 node_first_out[node_num] = arc_num; |
198 node_first_out[node_num] = arc_num; |
199 } |
199 } |
200 |
200 |
201 template <typename ArcListIterator> |
201 template <typename ArcListIterator> |
202 void build(int n, ArcListIterator first, ArcListIterator last) { |
202 void build(int n, ArcListIterator first, ArcListIterator last) { |
203 built = true; |
203 built = true; |
204 |
204 |
205 node_num = n; |
205 node_num = n; |
210 |
210 |
211 arc_source = new int[arc_num]; |
211 arc_source = new int[arc_num]; |
212 arc_target = new int[arc_num]; |
212 arc_target = new int[arc_num]; |
213 arc_next_out = new int[arc_num]; |
213 arc_next_out = new int[arc_num]; |
214 arc_next_in = new int[arc_num]; |
214 arc_next_in = new int[arc_num]; |
215 |
215 |
216 for (int i = 0; i != node_num; ++i) { |
216 for (int i = 0; i != node_num; ++i) { |
217 node_first_in[i] = -1; |
217 node_first_in[i] = -1; |
218 } |
218 } |
219 |
219 |
220 int arc_index = 0; |
220 int arc_index = 0; |
221 for (int i = 0; i != node_num; ++i) { |
221 for (int i = 0; i != node_num; ++i) { |
222 node_first_out[i] = arc_index; |
222 node_first_out[i] = arc_index; |
223 for ( ; first != last && (*first).first == i; ++first) { |
223 for ( ; first != last && (*first).first == i; ++first) { |
224 int j = (*first).second; |
224 int j = (*first).second; |
280 /// However it only provides build() and clear() functions and does not |
280 /// However it only provides build() and clear() functions and does not |
281 /// support any other modification of the digraph. |
281 /// support any other modification of the digraph. |
282 /// |
282 /// |
283 /// Since this digraph structure is completely static, its nodes and arcs |
283 /// Since this digraph structure is completely static, its nodes and arcs |
284 /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt> |
284 /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt> |
285 /// and <tt>[0..arcNum()-1]</tt>, respectively. |
285 /// and <tt>[0..arcNum()-1]</tt>, respectively. |
286 /// The index of an item is the same as its ID, it can be obtained |
286 /// The index of an item is the same as its ID, it can be obtained |
287 /// using the corresponding \ref index() or \ref concepts::Digraph::id() |
287 /// using the corresponding \ref index() or \ref concepts::Digraph::id() |
288 /// "id()" function. A node or arc with a certain index can be obtained |
288 /// "id()" function. A node or arc with a certain index can be obtained |
289 /// using node() or arc(). |
289 /// using node() or arc(). |
290 /// |
290 /// |
297 /// \sa concepts::Digraph |
297 /// \sa concepts::Digraph |
298 class StaticDigraph : public ExtendedStaticDigraphBase { |
298 class StaticDigraph : public ExtendedStaticDigraphBase { |
299 public: |
299 public: |
300 |
300 |
301 typedef ExtendedStaticDigraphBase Parent; |
301 typedef ExtendedStaticDigraphBase Parent; |
302 |
302 |
303 public: |
303 public: |
304 |
304 |
305 /// \brief Constructor |
305 /// \brief Constructor |
306 /// |
306 /// |
307 /// Default constructor. |
307 /// Default constructor. |
308 StaticDigraph() : Parent() {} |
308 StaticDigraph() : Parent() {} |
309 |
309 |
347 /// kind. It can be called more than once, but in such case, the whole |
347 /// kind. It can be called more than once, but in such case, the whole |
348 /// structure and all maps will be cleared and rebuilt. |
348 /// structure and all maps will be cleared and rebuilt. |
349 /// |
349 /// |
350 /// This method also makes possible to copy a digraph to a StaticDigraph |
350 /// This method also makes possible to copy a digraph to a StaticDigraph |
351 /// structure using \ref DigraphCopy. |
351 /// structure using \ref DigraphCopy. |
352 /// |
352 /// |
353 /// \param digraph An existing digraph to be copied. |
353 /// \param digraph An existing digraph to be copied. |
354 /// \param nodeRef The node references will be copied into this map. |
354 /// \param nodeRef The node references will be copied into this map. |
355 /// Its key type must be \c Digraph::Node and its value type must be |
355 /// Its key type must be \c Digraph::Node and its value type must be |
356 /// \c StaticDigraph::Node. |
356 /// \c StaticDigraph::Node. |
357 /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" |
357 /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" |
368 template <typename Digraph, typename NodeRefMap, typename ArcRefMap> |
368 template <typename Digraph, typename NodeRefMap, typename ArcRefMap> |
369 void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) { |
369 void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) { |
370 if (built) Parent::clear(); |
370 if (built) Parent::clear(); |
371 Parent::build(digraph, nodeRef, arcRef); |
371 Parent::build(digraph, nodeRef, arcRef); |
372 } |
372 } |
373 |
373 |
374 /// \brief Build the digraph from an arc list. |
374 /// \brief Build the digraph from an arc list. |
375 /// |
375 /// |
376 /// This function builds the digraph from the given arc list. |
376 /// This function builds the digraph from the given arc list. |
377 /// It can be called more than once, but in such case, the whole |
377 /// It can be called more than once, but in such case, the whole |
378 /// structure and all maps will be cleared and rebuilt. |
378 /// structure and all maps will be cleared and rebuilt. |
419 protected: |
419 protected: |
420 |
420 |
421 using Parent::fastFirstOut; |
421 using Parent::fastFirstOut; |
422 using Parent::fastNextOut; |
422 using Parent::fastNextOut; |
423 using Parent::fastLastOut; |
423 using Parent::fastLastOut; |
424 |
424 |
425 public: |
425 public: |
426 |
426 |
427 class OutArcIt : public Arc { |
427 class OutArcIt : public Arc { |
428 public: |
428 public: |
429 |
429 |
430 OutArcIt() { } |
430 OutArcIt() { } |
431 |
431 |
432 OutArcIt(Invalid i) : Arc(i) { } |
432 OutArcIt(Invalid i) : Arc(i) { } |
433 |
433 |
434 OutArcIt(const StaticDigraph& digraph, const Node& node) { |
434 OutArcIt(const StaticDigraph& digraph, const Node& node) { |
435 digraph.fastFirstOut(*this, node); |
435 digraph.fastFirstOut(*this, node); |
436 digraph.fastLastOut(last, node); |
436 digraph.fastLastOut(last, node); |
437 if (last == *this) *this = INVALID; |
437 if (last == *this) *this = INVALID; |
438 } |
438 } |
439 |
439 |
440 OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) { |
440 OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) { |
441 if (arc != INVALID) { |
441 if (arc != INVALID) { |
442 digraph.fastLastOut(last, digraph.source(arc)); |
442 digraph.fastLastOut(last, digraph.source(arc)); |
443 } |
443 } |
444 } |
444 } |
445 |
445 |
446 OutArcIt& operator++() { |
446 OutArcIt& operator++() { |
447 StaticDigraph::fastNextOut(*this); |
447 StaticDigraph::fastNextOut(*this); |
448 if (last == *this) *this = INVALID; |
448 if (last == *this) *this = INVALID; |
449 return *this; |
449 return *this; |
450 } |
450 } |
451 |
451 |
452 private: |
452 private: |
453 Arc last; |
453 Arc last; |
454 }; |
454 }; |