| ... | ... |
@@ -213,401 +213,408 @@ |
| 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) {
|
0 comments (0 inline)