1 | 1 |
/* -*- C++ -*- |
2 | 2 |
* |
3 | 3 |
* This file is a part of LEMON, a generic C++ optimization library |
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2010 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
10 | 10 |
* provided that this copyright notice appears in all copies. For |
11 | 11 |
* precise terms see the accompanying LICENSE file. |
12 | 12 |
* |
13 | 13 |
* This software is provided "AS IS" with no warranty of any kind, |
14 | 14 |
* express or implied, and with no claim as to its suitability for any |
15 | 15 |
* purpose. |
16 | 16 |
* |
17 | 17 |
*/ |
18 | 18 |
|
19 | 19 |
#ifndef LEMON_MAX_CARDINALITY_SEARCH_H |
20 | 20 |
#define LEMON_MAX_CARDINALITY_SEARCH_H |
21 | 21 |
|
22 | 22 |
|
23 | 23 |
/// \ingroup search |
24 | 24 |
/// \file |
25 | 25 |
/// \brief Maximum cardinality search in undirected digraphs. |
26 | 26 |
|
27 | 27 |
#include <lemon/bin_heap.h> |
28 | 28 |
#include <lemon/bucket_heap.h> |
29 | 29 |
|
30 | 30 |
#include <lemon/error.h> |
31 | 31 |
#include <lemon/maps.h> |
32 | 32 |
|
33 | 33 |
#include <functional> |
34 | 34 |
|
35 | 35 |
namespace lemon { |
36 | 36 |
|
37 | 37 |
/// \brief Default traits class of MaxCardinalitySearch class. |
38 | 38 |
/// |
39 | 39 |
/// Default traits class of MaxCardinalitySearch class. |
40 | 40 |
/// \param Digraph Digraph type. |
41 | 41 |
/// \param CapacityMap Type of capacity map. |
42 | 42 |
template <typename GR, typename CAP> |
43 | 43 |
struct MaxCardinalitySearchDefaultTraits { |
44 | 44 |
/// The digraph type the algorithm runs on. |
45 | 45 |
typedef GR Digraph; |
46 | 46 |
|
47 | 47 |
template <typename CM> |
48 | 48 |
struct CapMapSelector { |
49 | 49 |
|
50 | 50 |
typedef CM CapacityMap; |
51 | 51 |
|
52 | 52 |
static CapacityMap *createCapacityMap(const Digraph& g) { |
53 | 53 |
return new CapacityMap(g); |
54 | 54 |
} |
55 | 55 |
}; |
56 | 56 |
|
57 | 57 |
template <typename CM> |
58 | 58 |
struct CapMapSelector<ConstMap<CM, Const<int, 1> > > { |
59 | 59 |
|
60 | 60 |
typedef ConstMap<CM, Const<int, 1> > CapacityMap; |
61 | 61 |
|
62 | 62 |
static CapacityMap *createCapacityMap(const Digraph&) { |
63 | 63 |
return new CapacityMap; |
64 | 64 |
} |
65 | 65 |
}; |
66 | 66 |
|
67 | 67 |
/// \brief The type of the map that stores the arc capacities. |
68 | 68 |
/// |
69 | 69 |
/// The type of the map that stores the arc capacities. |
70 | 70 |
/// It must meet the \ref concepts::ReadMap "ReadMap" concept. |
71 | 71 |
typedef typename CapMapSelector<CAP>::CapacityMap CapacityMap; |
72 | 72 |
|
73 | 73 |
/// \brief The type of the capacity of the arcs. |
74 | 74 |
typedef typename CapacityMap::Value Value; |
75 | 75 |
|
76 | 76 |
/// \brief Instantiates a CapacityMap. |
77 | 77 |
/// |
78 | 78 |
/// This function instantiates a \ref CapacityMap. |
79 | 79 |
/// \param digraph is the digraph, to which we would like to define |
80 | 80 |
/// the CapacityMap. |
81 | 81 |
static CapacityMap *createCapacityMap(const Digraph& digraph) { |
82 | 82 |
return CapMapSelector<CapacityMap>::createCapacityMap(digraph); |
83 | 83 |
} |
84 | 84 |
|
85 | 85 |
/// \brief The cross reference type used by heap. |
86 | 86 |
/// |
87 | 87 |
/// The cross reference type used by heap. |
88 | 88 |
/// Usually it is \c Digraph::NodeMap<int>. |
89 | 89 |
typedef typename Digraph::template NodeMap<int> HeapCrossRef; |
90 | 90 |
|
91 | 91 |
/// \brief Instantiates a HeapCrossRef. |
92 | 92 |
/// |
93 | 93 |
/// This function instantiates a \ref HeapCrossRef. |
94 | 94 |
/// \param digraph is the digraph, to which we would like to define the |
95 | 95 |
/// HeapCrossRef. |
96 | 96 |
static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) { |
97 | 97 |
return new HeapCrossRef(digraph); |
98 | 98 |
} |
99 | 99 |
|
100 | 100 |
template <typename CapacityMap> |
101 | 101 |
struct HeapSelector { |
102 | 102 |
template <typename Value, typename Ref> |
103 | 103 |
struct Selector { |
104 | 104 |
typedef BinHeap<Value, Ref, std::greater<Value> > Heap; |
105 | 105 |
}; |
106 | 106 |
}; |
107 | 107 |
|
108 | 108 |
template <typename CapacityKey> |
109 | 109 |
struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > { |
110 | 110 |
template <typename Value, typename Ref> |
111 | 111 |
struct Selector { |
112 | 112 |
typedef BucketHeap<Ref, false > Heap; |
113 | 113 |
}; |
114 | 114 |
}; |
115 | 115 |
|
116 | 116 |
/// \brief The heap type used by MaxCardinalitySearch algorithm. |
117 | 117 |
/// |
118 | 118 |
/// The heap type used by MaxCardinalitySearch algorithm. It should |
119 | 119 |
/// maximalize the priorities. The default heap type is |
120 | 120 |
/// the \ref BinHeap, but it is specialized when the |
121 | 121 |
/// CapacityMap is ConstMap<Digraph::Node, Const<int, 1> > |
122 | 122 |
/// to BucketHeap. |
123 | 123 |
/// |
124 | 124 |
/// \sa MaxCardinalitySearch |
125 | 125 |
typedef typename HeapSelector<CapacityMap> |
126 | 126 |
::template Selector<Value, HeapCrossRef> |
127 | 127 |
::Heap Heap; |
128 | 128 |
|
129 | 129 |
/// \brief Instantiates a Heap. |
130 | 130 |
/// |
131 | 131 |
/// This function instantiates a \ref Heap. |
132 | 132 |
/// \param crossref The cross reference of the heap. |
133 | 133 |
static Heap *createHeap(HeapCrossRef& crossref) { |
134 | 134 |
return new Heap(crossref); |
135 | 135 |
} |
136 | 136 |
|
137 | 137 |
/// \brief The type of the map that stores whether a node is processed. |
138 | 138 |
/// |
139 | 139 |
/// The type of the map that stores whether a node is processed. |
140 | 140 |
/// It must meet the \ref concepts::WriteMap "WriteMap" concept. |
141 | 141 |
/// By default it is a NullMap. |
142 | 142 |
typedef NullMap<typename Digraph::Node, bool> ProcessedMap; |
143 | 143 |
|
144 | 144 |
/// \brief Instantiates a ProcessedMap. |
145 | 145 |
/// |
146 | 146 |
/// This function instantiates a \ref ProcessedMap. |
147 | 147 |
/// \param digraph is the digraph, to which |
148 | 148 |
/// we would like to define the \ref ProcessedMap |
149 | 149 |
#ifdef DOXYGEN |
150 | 150 |
static ProcessedMap *createProcessedMap(const Digraph &digraph) |
151 | 151 |
#else |
152 | 152 |
static ProcessedMap *createProcessedMap(const Digraph &) |
153 | 153 |
#endif |
154 | 154 |
{ |
155 | 155 |
return new ProcessedMap(); |
156 | 156 |
} |
157 | 157 |
|
158 | 158 |
/// \brief The type of the map that stores the cardinalities of the nodes. |
159 | 159 |
/// |
160 | 160 |
/// The type of the map that stores the cardinalities of the nodes. |
161 | 161 |
/// It must meet the \ref concepts::WriteMap "WriteMap" concept. |
162 | 162 |
typedef typename Digraph::template NodeMap<Value> CardinalityMap; |
163 | 163 |
|
164 | 164 |
/// \brief Instantiates a CardinalityMap. |
165 | 165 |
/// |
166 | 166 |
/// This function instantiates a \ref CardinalityMap. |
167 | 167 |
/// \param digraph is the digraph, to which we would like to define the \ref |
168 | 168 |
/// CardinalityMap |
169 | 169 |
static CardinalityMap *createCardinalityMap(const Digraph &digraph) { |
170 | 170 |
return new CardinalityMap(digraph); |
171 | 171 |
} |
172 | 172 |
|
173 | 173 |
|
174 | 174 |
}; |
175 | 175 |
|
176 | 176 |
/// \ingroup search |
177 | 177 |
/// |
178 | 178 |
/// \brief Maximum Cardinality Search algorithm class. |
179 | 179 |
/// |
180 | 180 |
/// This class provides an efficient implementation of Maximum Cardinality |
181 | 181 |
/// Search algorithm. The maximum cardinality search first chooses any |
182 | 182 |
/// node of the digraph. Then every time it chooses one unprocessed node |
183 | 183 |
/// with maximum cardinality, i.e the sum of capacities on out arcs to the nodes |
184 | 184 |
/// which were previusly processed. |
185 | 185 |
/// If there is a cut in the digraph the algorithm should choose |
186 | 186 |
/// again any unprocessed node of the digraph. |
187 | 187 |
|
188 | 188 |
/// The arc capacities are passed to the algorithm using a |
189 | 189 |
/// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any |
190 | 190 |
/// kind of capacity. |
191 | 191 |
/// |
192 | 192 |
/// The type of the capacity is determined by the \ref |
193 | 193 |
/// concepts::ReadMap::Value "Value" of the capacity map. |
194 | 194 |
/// |
195 | 195 |
/// It is also possible to change the underlying priority heap. |
196 | 196 |
/// |
197 | 197 |
/// |
198 | 198 |
/// \param GR The digraph type the algorithm runs on. The value of |
199 | 199 |
/// Digraph is not used directly by the search algorithm, it |
200 | 200 |
/// is only passed to \ref MaxCardinalitySearchDefaultTraits. |
201 | 201 |
/// \param CAP This read-only ArcMap determines the capacities of |
202 | 202 |
/// the arcs. It is read once for each arc, so the map may involve in |
203 | 203 |
/// relatively time consuming process to compute the arc capacity if |
204 | 204 |
/// it is necessary. The default map type is \ref |
205 | 205 |
/// ConstMap "ConstMap<concepts::Digraph::Arc, Const<int,1> >". The value |
206 | 206 |
/// of CapacityMap is not used directly by search algorithm, it is only |
207 | 207 |
/// passed to \ref MaxCardinalitySearchDefaultTraits. |
208 | 208 |
/// \param TR Traits class to set various data types used by the |
209 | 209 |
/// algorithm. The default traits class is |
210 | 210 |
/// \ref MaxCardinalitySearchDefaultTraits |
211 | 211 |
/// "MaxCardinalitySearchDefaultTraits<GR, CAP>". |
212 | 212 |
/// See \ref MaxCardinalitySearchDefaultTraits |
213 | 213 |
/// for the documentation of a MaxCardinalitySearch traits class. |
214 | 214 |
|
215 | 215 |
#ifdef DOXYGEN |
216 | 216 |
template <typename GR, typename CAP, typename TR> |
217 | 217 |
#else |
218 | 218 |
template <typename GR, typename CAP = |
219 | 219 |
ConstMap<typename GR::Arc, Const<int,1> >, |
220 | 220 |
typename TR = |
221 | 221 |
MaxCardinalitySearchDefaultTraits<GR, CAP> > |
222 | 222 |
#endif |
223 | 223 |
class MaxCardinalitySearch { |
224 | 224 |
public: |
225 | 225 |
|
226 | 226 |
typedef TR Traits; |
227 | 227 |
///The type of the underlying digraph. |
228 | 228 |
typedef typename Traits::Digraph Digraph; |
229 | 229 |
|
230 | 230 |
///The type of the capacity of the arcs. |
231 | 231 |
typedef typename Traits::CapacityMap::Value Value; |
232 | 232 |
///The type of the map that stores the arc capacities. |
233 | 233 |
typedef typename Traits::CapacityMap CapacityMap; |
234 | 234 |
///The type of the map indicating if a node is processed. |
235 | 235 |
typedef typename Traits::ProcessedMap ProcessedMap; |
236 | 236 |
///The type of the map that stores the cardinalities of the nodes. |
237 | 237 |
typedef typename Traits::CardinalityMap CardinalityMap; |
238 | 238 |
///The cross reference type used for the current heap. |
239 | 239 |
typedef typename Traits::HeapCrossRef HeapCrossRef; |
240 | 240 |
///The heap type used by the algorithm. It maximizes the priorities. |
241 | 241 |
typedef typename Traits::Heap Heap; |
242 | 242 |
private: |
243 | 243 |
// Pointer to the underlying digraph. |
244 | 244 |
const Digraph *_graph; |
245 | 245 |
// Pointer to the capacity map |
246 | 246 |
const CapacityMap *_capacity; |
247 | 247 |
// Indicates if \ref _capacity is locally allocated (\c true) or not. |
248 | 248 |
bool local_capacity; |
249 | 249 |
// Pointer to the map of cardinality. |
250 | 250 |
CardinalityMap *_cardinality; |
251 | 251 |
// Indicates if \ref _cardinality is locally allocated (\c true) or not. |
252 | 252 |
bool local_cardinality; |
253 | 253 |
// Pointer to the map of processed status of the nodes. |
254 | 254 |
ProcessedMap *_processed; |
255 | 255 |
// Indicates if \ref _processed is locally allocated (\c true) or not. |
256 | 256 |
bool local_processed; |
257 | 257 |
// Pointer to the heap cross references. |
258 | 258 |
HeapCrossRef *_heap_cross_ref; |
259 | 259 |
// Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not. |
260 | 260 |
bool local_heap_cross_ref; |
261 | 261 |
// Pointer to the heap. |
262 | 262 |
Heap *_heap; |
263 | 263 |
// Indicates if \ref _heap is locally allocated (\c true) or not. |
264 | 264 |
bool local_heap; |
265 | 265 |
|
266 | 266 |
public : |
267 | 267 |
|
268 | 268 |
typedef MaxCardinalitySearch Create; |
269 | 269 |
|
270 | 270 |
///\name Named template parameters |
271 | 271 |
|
272 | 272 |
///@{ |
273 | 273 |
|
274 | 274 |
template <class T> |
275 | 275 |
struct DefCapacityMapTraits : public Traits { |
276 | 276 |
typedef T CapacityMap; |
277 | 277 |
static CapacityMap *createCapacityMap(const Digraph &) { |
278 | 278 |
LEMON_ASSERT(false,"Uninitialized parameter."); |
279 | 279 |
return 0; |
280 | 280 |
} |
281 | 281 |
}; |
282 | 282 |
/// \brief \ref named-templ-param "Named parameter" for setting |
283 | 283 |
/// CapacityMap type |
284 | 284 |
/// |
285 | 285 |
/// \ref named-templ-param "Named parameter" for setting CapacityMap type |
286 | 286 |
/// for the algorithm. |
287 | 287 |
template <class T> |
288 | 288 |
struct SetCapacityMap |
289 | 289 |
: public MaxCardinalitySearch<Digraph, CapacityMap, |
290 | 290 |
DefCapacityMapTraits<T> > { |
291 | 291 |
typedef MaxCardinalitySearch<Digraph, CapacityMap, |
292 | 292 |
DefCapacityMapTraits<T> > Create; |
293 | 293 |
}; |
294 | 294 |
|
295 | 295 |
template <class T> |
296 | 296 |
struct DefCardinalityMapTraits : public Traits { |
297 | 297 |
typedef T CardinalityMap; |
298 | 298 |
static CardinalityMap *createCardinalityMap(const Digraph &) |
299 | 299 |
{ |
300 | 300 |
LEMON_ASSERT(false,"Uninitialized parameter."); |
301 | 301 |
return 0; |
302 | 302 |
} |
303 | 303 |
}; |
304 | 304 |
/// \brief \ref named-templ-param "Named parameter" for setting |
305 | 305 |
/// CardinalityMap type |
306 | 306 |
/// |
307 | 307 |
/// \ref named-templ-param "Named parameter" for setting CardinalityMap |
308 | 308 |
/// type for the algorithm. |
309 | 309 |
template <class T> |
310 | 310 |
struct SetCardinalityMap |
311 | 311 |
: public MaxCardinalitySearch<Digraph, CapacityMap, |
312 | 312 |
DefCardinalityMapTraits<T> > { |
313 | 313 |
typedef MaxCardinalitySearch<Digraph, CapacityMap, |
314 | 314 |
DefCardinalityMapTraits<T> > Create; |
315 | 315 |
}; |
316 | 316 |
|
317 | 317 |
template <class T> |
318 | 318 |
struct DefProcessedMapTraits : public Traits { |
319 | 319 |
typedef T ProcessedMap; |
320 | 320 |
static ProcessedMap *createProcessedMap(const Digraph &) { |
321 | 321 |
LEMON_ASSERT(false,"Uninitialized parameter."); |
322 | 322 |
return 0; |
323 | 323 |
} |
324 | 324 |
}; |
325 | 325 |
/// \brief \ref named-templ-param "Named parameter" for setting |
326 | 326 |
/// ProcessedMap type |
327 | 327 |
/// |
328 | 328 |
/// \ref named-templ-param "Named parameter" for setting ProcessedMap type |
329 | 329 |
/// for the algorithm. |
330 | 330 |
template <class T> |
331 | 331 |
struct SetProcessedMap |
332 | 332 |
: public MaxCardinalitySearch<Digraph, CapacityMap, |
333 | 333 |
DefProcessedMapTraits<T> > { |
334 | 334 |
typedef MaxCardinalitySearch<Digraph, CapacityMap, |
335 | 335 |
DefProcessedMapTraits<T> > Create; |
336 | 336 |
}; |
337 | 337 |
|
338 | 338 |
template <class H, class CR> |
339 | 339 |
struct DefHeapTraits : public Traits { |
340 | 340 |
typedef CR HeapCrossRef; |
341 | 341 |
typedef H Heap; |
342 | 342 |
static HeapCrossRef *createHeapCrossRef(const Digraph &) { |
343 | 343 |
LEMON_ASSERT(false,"Uninitialized parameter."); |
344 | 344 |
return 0; |
345 | 345 |
} |
346 | 346 |
static Heap *createHeap(HeapCrossRef &) { |
347 | 347 |
LEMON_ASSERT(false,"Uninitialized parameter."); |
348 | 348 |
return 0; |
349 | 349 |
} |
350 | 350 |
}; |
351 | 351 |
/// \brief \ref named-templ-param "Named parameter" for setting heap |
352 | 352 |
/// and cross reference type |
353 | 353 |
/// |
354 | 354 |
/// \ref named-templ-param "Named parameter" for setting heap and cross |
355 | 355 |
/// reference type for the algorithm. |
356 | 356 |
template <class H, class CR = typename Digraph::template NodeMap<int> > |
357 | 357 |
struct SetHeap |
358 | 358 |
: public MaxCardinalitySearch<Digraph, CapacityMap, |
359 | 359 |
DefHeapTraits<H, CR> > { |
360 | 360 |
typedef MaxCardinalitySearch< Digraph, CapacityMap, |
361 | 361 |
DefHeapTraits<H, CR> > Create; |
362 | 362 |
}; |
363 | 363 |
|
364 | 364 |
template <class H, class CR> |
365 | 365 |
struct DefStandardHeapTraits : public Traits { |
366 | 366 |
typedef CR HeapCrossRef; |
367 | 367 |
typedef H Heap; |
368 | 368 |
static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) { |
369 | 369 |
return new HeapCrossRef(digraph); |
370 | 370 |
} |
371 | 371 |
static Heap *createHeap(HeapCrossRef &crossref) { |
372 | 372 |
return new Heap(crossref); |
373 | 373 |
} |
374 | 374 |
}; |
375 | 375 |
|
376 | 376 |
/// \brief \ref named-templ-param "Named parameter" for setting heap and |
377 | 377 |
/// cross reference type with automatic allocation |
378 | 378 |
/// |
379 | 379 |
/// \ref named-templ-param "Named parameter" for setting heap and cross |
380 | 380 |
/// reference type. It can allocate the heap and the cross reference |
381 | 381 |
/// object if the cross reference's constructor waits for the digraph as |
382 | 382 |
/// parameter and the heap's constructor waits for the cross reference. |
383 | 383 |
template <class H, class CR = typename Digraph::template NodeMap<int> > |
384 | 384 |
struct SetStandardHeap |
385 | 385 |
: public MaxCardinalitySearch<Digraph, CapacityMap, |
386 | 386 |
DefStandardHeapTraits<H, CR> > { |
387 | 387 |
typedef MaxCardinalitySearch<Digraph, CapacityMap, |
388 | 388 |
DefStandardHeapTraits<H, CR> > |
389 | 389 |
Create; |
390 | 390 |
}; |
391 | 391 |
|
392 | 392 |
///@} |
393 | 393 |
|
394 | 394 |
|
395 | 395 |
protected: |
396 | 396 |
|
397 | 397 |
MaxCardinalitySearch() {} |
398 | 398 |
|
399 | 399 |
public: |
400 | 400 |
|
401 | 401 |
/// \brief Constructor. |
402 | 402 |
/// |
403 | 403 |
///\param digraph the digraph the algorithm will run on. |
404 | 404 |
///\param capacity the capacity map used by the algorithm. |
405 |
///When no capacity map given, a constant 1 capacity map will |
|
406 |
///be allocated. |
|
407 |
#ifdef DOXYGEN |
|
408 | 405 |
MaxCardinalitySearch(const Digraph& digraph, |
409 |
const CapacityMap& capacity=0 ) : |
|
410 |
#else |
|
411 |
MaxCardinalitySearch(const Digraph& digraph, |
|
412 |
const CapacityMap& capacity=*static_cast<const CapacityMap*>(0) ) : |
|
413 |
|
|
406 |
const CapacityMap& capacity) : |
|
414 | 407 |
_graph(&digraph), |
415 | 408 |
_capacity(&capacity), local_capacity(false), |
416 | 409 |
_cardinality(0), local_cardinality(false), |
417 | 410 |
_processed(0), local_processed(false), |
418 | 411 |
_heap_cross_ref(0), local_heap_cross_ref(false), |
419 | 412 |
_heap(0), local_heap(false) |
420 | 413 |
{ } |
421 | 414 |
|
415 |
/// \brief Constructor. |
|
416 |
/// |
|
417 |
///\param digraph the digraph the algorithm will run on. |
|
418 |
/// |
|
419 |
///A constant 1 capacity map will be allocated. |
|
420 |
MaxCardinalitySearch(const Digraph& digraph) : |
|
421 |
_graph(&digraph), |
|
422 |
_capacity(0), local_capacity(false), |
|
423 |
_cardinality(0), local_cardinality(false), |
|
424 |
_processed(0), local_processed(false), |
|
425 |
_heap_cross_ref(0), local_heap_cross_ref(false), |
|
426 |
_heap(0), local_heap(false) |
|
427 |
{ } |
|
428 |
|
|
422 | 429 |
/// \brief Destructor. |
423 | 430 |
~MaxCardinalitySearch() { |
424 | 431 |
if(local_capacity) delete _capacity; |
425 | 432 |
if(local_cardinality) delete _cardinality; |
426 | 433 |
if(local_processed) delete _processed; |
427 | 434 |
if(local_heap_cross_ref) delete _heap_cross_ref; |
428 | 435 |
if(local_heap) delete _heap; |
429 | 436 |
} |
430 | 437 |
|
431 | 438 |
/// \brief Sets the capacity map. |
432 | 439 |
/// |
433 | 440 |
/// Sets the capacity map. |
434 | 441 |
/// \return <tt> (*this) </tt> |
435 | 442 |
MaxCardinalitySearch &capacityMap(const CapacityMap &m) { |
436 | 443 |
if (local_capacity) { |
437 | 444 |
delete _capacity; |
438 | 445 |
local_capacity=false; |
439 | 446 |
} |
440 | 447 |
_capacity=&m; |
441 | 448 |
return *this; |
442 | 449 |
} |
443 | 450 |
|
444 | 451 |
/// \brief Returns a const reference to the capacity map. |
445 | 452 |
/// |
446 | 453 |
/// Returns a const reference to the capacity map used by |
447 | 454 |
/// the algorithm. |
448 | 455 |
const CapacityMap &capacityMap() const { |
449 | 456 |
return *_capacity; |
450 | 457 |
} |
451 | 458 |
|
452 | 459 |
/// \brief Sets the map storing the cardinalities calculated by the |
453 | 460 |
/// algorithm. |
454 | 461 |
/// |
455 | 462 |
/// Sets the map storing the cardinalities calculated by the algorithm. |
456 | 463 |
/// If you don't use this function before calling \ref run(), |
457 | 464 |
/// it will allocate one. The destuctor deallocates this |
458 | 465 |
/// automatically allocated map, of course. |
459 | 466 |
/// \return <tt> (*this) </tt> |
460 | 467 |
MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) { |
461 | 468 |
if(local_cardinality) { |
462 | 469 |
delete _cardinality; |
463 | 470 |
local_cardinality=false; |
464 | 471 |
} |
465 | 472 |
_cardinality = &m; |
466 | 473 |
return *this; |
467 | 474 |
} |
468 | 475 |
|
469 | 476 |
/// \brief Sets the map storing the processed nodes. |
470 | 477 |
/// |
471 | 478 |
/// Sets the map storing the processed nodes. |
472 | 479 |
/// If you don't use this function before calling \ref run(), |
473 | 480 |
/// it will allocate one. The destuctor deallocates this |
474 | 481 |
/// automatically allocated map, of course. |
475 | 482 |
/// \return <tt> (*this) </tt> |
476 | 483 |
MaxCardinalitySearch &processedMap(ProcessedMap &m) |
477 | 484 |
{ |
478 | 485 |
if(local_processed) { |
479 | 486 |
delete _processed; |
480 | 487 |
local_processed=false; |
481 | 488 |
} |
482 | 489 |
_processed = &m; |
483 | 490 |
return *this; |
484 | 491 |
} |
485 | 492 |
|
486 | 493 |
/// \brief Returns a const reference to the cardinality map. |
487 | 494 |
/// |
488 | 495 |
/// Returns a const reference to the cardinality map used by |
489 | 496 |
/// the algorithm. |
490 | 497 |
const ProcessedMap &processedMap() const { |
491 | 498 |
return *_processed; |
492 | 499 |
} |
493 | 500 |
|
494 | 501 |
/// \brief Sets the heap and the cross reference used by algorithm. |
495 | 502 |
/// |
496 | 503 |
/// Sets the heap and the cross reference used by algorithm. |
497 | 504 |
/// If you don't use this function before calling \ref run(), |
498 | 505 |
/// it will allocate one. The destuctor deallocates this |
499 | 506 |
/// automatically allocated map, of course. |
500 | 507 |
/// \return <tt> (*this) </tt> |
501 | 508 |
MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) { |
502 | 509 |
if(local_heap_cross_ref) { |
503 | 510 |
delete _heap_cross_ref; |
504 | 511 |
local_heap_cross_ref = false; |
505 | 512 |
} |
506 | 513 |
_heap_cross_ref = &cr; |
507 | 514 |
if(local_heap) { |
508 | 515 |
delete _heap; |
509 | 516 |
local_heap = false; |
510 | 517 |
} |
511 | 518 |
_heap = &hp; |
512 | 519 |
return *this; |
513 | 520 |
} |
514 | 521 |
|
515 | 522 |
/// \brief Returns a const reference to the heap. |
516 | 523 |
/// |
517 | 524 |
/// Returns a const reference to the heap used by |
518 | 525 |
/// the algorithm. |
519 | 526 |
const Heap &heap() const { |
520 | 527 |
return *_heap; |
521 | 528 |
} |
522 | 529 |
|
523 | 530 |
/// \brief Returns a const reference to the cross reference. |
524 | 531 |
/// |
525 | 532 |
/// Returns a const reference to the cross reference |
526 | 533 |
/// of the heap. |
527 | 534 |
const HeapCrossRef &heapCrossRef() const { |
528 | 535 |
return *_heap_cross_ref; |
529 | 536 |
} |
530 | 537 |
|
531 | 538 |
private: |
532 | 539 |
|
533 | 540 |
typedef typename Digraph::Node Node; |
534 | 541 |
typedef typename Digraph::NodeIt NodeIt; |
535 | 542 |
typedef typename Digraph::Arc Arc; |
536 | 543 |
typedef typename Digraph::InArcIt InArcIt; |
537 | 544 |
|
538 | 545 |
void create_maps() { |
539 | 546 |
if(!_capacity) { |
540 | 547 |
local_capacity = true; |
541 | 548 |
_capacity = Traits::createCapacityMap(*_graph); |
542 | 549 |
} |
543 | 550 |
if(!_cardinality) { |
544 | 551 |
local_cardinality = true; |
545 | 552 |
_cardinality = Traits::createCardinalityMap(*_graph); |
546 | 553 |
} |
547 | 554 |
if(!_processed) { |
548 | 555 |
local_processed = true; |
549 | 556 |
_processed = Traits::createProcessedMap(*_graph); |
550 | 557 |
} |
551 | 558 |
if (!_heap_cross_ref) { |
552 | 559 |
local_heap_cross_ref = true; |
553 | 560 |
_heap_cross_ref = Traits::createHeapCrossRef(*_graph); |
554 | 561 |
} |
555 | 562 |
if (!_heap) { |
556 | 563 |
local_heap = true; |
557 | 564 |
_heap = Traits::createHeap(*_heap_cross_ref); |
558 | 565 |
} |
559 | 566 |
} |
560 | 567 |
|
561 | 568 |
void finalizeNodeData(Node node, Value capacity) { |
562 | 569 |
_processed->set(node, true); |
563 | 570 |
_cardinality->set(node, capacity); |
564 | 571 |
} |
565 | 572 |
|
566 | 573 |
public: |
567 | 574 |
/// \name Execution control |
568 | 575 |
/// The simplest way to execute the algorithm is to use |
569 | 576 |
/// one of the member functions called \ref run(). |
570 | 577 |
/// \n |
571 | 578 |
/// If you need more control on the execution, |
572 | 579 |
/// first you must call \ref init(), then you can add several source nodes |
573 | 580 |
/// with \ref addSource(). |
574 | 581 |
/// Finally \ref start() will perform the computation. |
575 | 582 |
|
576 | 583 |
///@{ |
577 | 584 |
|
578 | 585 |
/// \brief Initializes the internal data structures. |
579 | 586 |
/// |
580 | 587 |
/// Initializes the internal data structures, and clears the heap. |
581 | 588 |
void init() { |
582 | 589 |
create_maps(); |
583 | 590 |
_heap->clear(); |
584 | 591 |
for (NodeIt it(*_graph) ; it != INVALID ; ++it) { |
585 | 592 |
_processed->set(it, false); |
586 | 593 |
_heap_cross_ref->set(it, Heap::PRE_HEAP); |
587 | 594 |
} |
588 | 595 |
} |
589 | 596 |
|
590 | 597 |
/// \brief Adds a new source node. |
591 | 598 |
/// |
592 | 599 |
/// Adds a new source node to the priority heap. |
593 | 600 |
/// |
594 | 601 |
/// It checks if the node has not yet been added to the heap. |
595 | 602 |
void addSource(Node source, Value capacity = 0) { |
596 | 603 |
if(_heap->state(source) == Heap::PRE_HEAP) { |
597 | 604 |
_heap->push(source, capacity); |
598 | 605 |
} |
599 | 606 |
} |
600 | 607 |
|
601 | 608 |
/// \brief Processes the next node in the priority heap |
602 | 609 |
/// |
603 | 610 |
/// Processes the next node in the priority heap. |
604 | 611 |
/// |
605 | 612 |
/// \return The processed node. |
606 | 613 |
/// |
607 | 614 |
/// \warning The priority heap must not be empty! |
608 | 615 |
Node processNextNode() { |
609 | 616 |
Node node = _heap->top(); |
610 | 617 |
finalizeNodeData(node, _heap->prio()); |
611 | 618 |
_heap->pop(); |
612 | 619 |
|
613 | 620 |
for (InArcIt it(*_graph, node); it != INVALID; ++it) { |
614 | 621 |
Node source = _graph->source(it); |
615 | 622 |
switch (_heap->state(source)) { |
616 | 623 |
case Heap::PRE_HEAP: |
617 | 624 |
_heap->push(source, (*_capacity)[it]); |
618 | 625 |
break; |
619 | 626 |
case Heap::IN_HEAP: |
620 | 627 |
_heap->decrease(source, (*_heap)[source] + (*_capacity)[it]); |
621 | 628 |
break; |
622 | 629 |
case Heap::POST_HEAP: |
623 | 630 |
break; |
624 | 631 |
} |
625 | 632 |
} |
626 | 633 |
return node; |
627 | 634 |
} |
628 | 635 |
|
629 | 636 |
/// \brief Next node to be processed. |
630 | 637 |
/// |
631 | 638 |
/// Next node to be processed. |
632 | 639 |
/// |
633 | 640 |
/// \return The next node to be processed or INVALID if the |
634 | 641 |
/// priority heap is empty. |
635 | 642 |
Node nextNode() { |
636 | 643 |
return !_heap->empty() ? _heap->top() : INVALID; |
637 | 644 |
} |
638 | 645 |
|
639 | 646 |
/// \brief Returns \c false if there are nodes |
640 | 647 |
/// to be processed in the priority heap |
641 | 648 |
/// |
642 | 649 |
/// Returns \c false if there are nodes |
643 | 650 |
/// to be processed in the priority heap |
644 | 651 |
bool emptyQueue() { return _heap->empty(); } |
645 | 652 |
/// \brief Returns the number of the nodes to be processed |
646 | 653 |
/// in the priority heap |
647 | 654 |
/// |
648 | 655 |
/// Returns the number of the nodes to be processed in the priority heap |
649 | 656 |
int emptySize() { return _heap->size(); } |
650 | 657 |
|
651 | 658 |
/// \brief Executes the algorithm. |
652 | 659 |
/// |
653 | 660 |
/// Executes the algorithm. |
654 | 661 |
/// |
655 | 662 |
///\pre init() must be called and at least one node should be added |
656 | 663 |
/// with addSource() before using this function. |
657 | 664 |
/// |
658 | 665 |
/// This method runs the Maximum Cardinality Search algorithm from the |
659 | 666 |
/// source node(s). |
660 | 667 |
void start() { |
661 | 668 |
while ( !_heap->empty() ) processNextNode(); |
662 | 669 |
} |
663 | 670 |
|
664 | 671 |
/// \brief Executes the algorithm until \c dest is reached. |
665 | 672 |
/// |
666 | 673 |
/// Executes the algorithm until \c dest is reached. |
667 | 674 |
/// |
668 | 675 |
/// \pre init() must be called and at least one node should be added |
669 | 676 |
/// with addSource() before using this function. |
670 | 677 |
/// |
671 | 678 |
/// This method runs the %MaxCardinalitySearch algorithm from the source |
672 | 679 |
/// nodes. |
673 | 680 |
void start(Node dest) { |
674 | 681 |
while ( !_heap->empty() && _heap->top()!=dest ) processNextNode(); |
675 | 682 |
if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio()); |
676 | 683 |
} |
677 | 684 |
|
678 | 685 |
/// \brief Executes the algorithm until a condition is met. |
679 | 686 |
/// |
680 | 687 |
/// Executes the algorithm until a condition is met. |
681 | 688 |
/// |
682 | 689 |
/// \pre init() must be called and at least one node should be added |
683 | 690 |
/// with addSource() before using this function. |
684 | 691 |
/// |
685 | 692 |
/// \param nm must be a bool (or convertible) node map. The algorithm |
686 | 693 |
/// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>. |
687 | 694 |
template <typename NodeBoolMap> |
688 | 695 |
void start(const NodeBoolMap &nm) { |
689 | 696 |
while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode(); |
690 | 697 |
if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio()); |
691 | 698 |
} |
692 | 699 |
|
693 | 700 |
/// \brief Runs the maximum cardinality search algorithm from node \c s. |
694 | 701 |
/// |
695 | 702 |
/// This method runs the %MaxCardinalitySearch algorithm from a root |
696 | 703 |
/// node \c s. |
697 | 704 |
/// |
698 | 705 |
///\note d.run(s) is just a shortcut of the following code. |
699 | 706 |
///\code |
700 | 707 |
/// d.init(); |
701 | 708 |
/// d.addSource(s); |
702 | 709 |
/// d.start(); |
703 | 710 |
///\endcode |
704 | 711 |
void run(Node s) { |
705 | 712 |
init(); |
706 | 713 |
addSource(s); |
707 | 714 |
start(); |
708 | 715 |
} |
709 | 716 |
|
710 | 717 |
/// \brief Runs the maximum cardinality search algorithm for the |
711 | 718 |
/// whole digraph. |
712 | 719 |
/// |
713 | 720 |
/// This method runs the %MaxCardinalitySearch algorithm from all |
714 | 721 |
/// unprocessed node of the digraph. |
715 | 722 |
/// |
716 | 723 |
///\note d.run(s) is just a shortcut of the following code. |
717 | 724 |
///\code |
718 | 725 |
/// d.init(); |
719 | 726 |
/// for (NodeIt it(digraph); it != INVALID; ++it) { |
720 | 727 |
/// if (!d.reached(it)) { |
721 | 728 |
/// d.addSource(s); |
722 | 729 |
/// d.start(); |
723 | 730 |
/// } |
724 | 731 |
/// } |
725 | 732 |
///\endcode |
726 | 733 |
void run() { |
727 | 734 |
init(); |
728 | 735 |
for (NodeIt it(*_graph); it != INVALID; ++it) { |
729 | 736 |
if (!reached(it)) { |
730 | 737 |
addSource(it); |
731 | 738 |
start(); |
732 | 739 |
} |
733 | 740 |
} |
734 | 741 |
} |
735 | 742 |
|
736 | 743 |
///@} |
737 | 744 |
|
738 | 745 |
/// \name Query Functions |
739 | 746 |
/// The results of the maximum cardinality search algorithm can be |
740 | 747 |
/// obtained using these functions. |
741 | 748 |
/// \n |
742 | 749 |
/// Before the use of these functions, either run() or start() must be |
743 | 750 |
/// called. |
744 | 751 |
|
745 | 752 |
///@{ |
746 | 753 |
|
747 | 754 |
/// \brief The cardinality of a node. |
748 | 755 |
/// |
749 | 756 |
/// Returns the cardinality of a node. |
750 | 757 |
/// \pre \ref run() must be called before using this function. |
751 | 758 |
/// \warning If node \c v in unreachable from the root the return value |
752 | 759 |
/// of this funcion is undefined. |
753 | 760 |
Value cardinality(Node node) const { return (*_cardinality)[node]; } |
754 | 761 |
|
755 | 762 |
/// \brief The current cardinality of a node. |
756 | 763 |
/// |
757 | 764 |
/// Returns the current cardinality of a node. |
758 | 765 |
/// \pre the given node should be reached but not processed |
759 | 766 |
Value currentCardinality(Node node) const { return (*_heap)[node]; } |
760 | 767 |
|
761 | 768 |
/// \brief Returns a reference to the NodeMap of cardinalities. |
762 | 769 |
/// |
763 | 770 |
/// Returns a reference to the NodeMap of cardinalities. \pre \ref run() |
764 | 771 |
/// must be called before using this function. |
765 | 772 |
const CardinalityMap &cardinalityMap() const { return *_cardinality;} |
766 | 773 |
|
767 | 774 |
/// \brief Checks if a node is reachable from the root. |
768 | 775 |
/// |
769 | 776 |
/// Returns \c true if \c v is reachable from the root. |
770 | 777 |
/// \warning The source nodes are initated as unreached. |
771 | 778 |
/// \pre \ref run() must be called before using this function. |
772 | 779 |
bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; } |
773 | 780 |
|
774 | 781 |
/// \brief Checks if a node is processed. |
775 | 782 |
/// |
776 | 783 |
/// Returns \c true if \c v is processed, i.e. the shortest |
777 | 784 |
/// path to \c v has already found. |
778 | 785 |
/// \pre \ref run() must be called before using this function. |
779 | 786 |
bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; } |
780 | 787 |
|
781 | 788 |
///@} |
782 | 789 |
}; |
783 | 790 |
|
784 | 791 |
} |
785 | 792 |
|
786 | 793 |
#endif |
0 comments (0 inline)