446 createStructures(); |
450 createStructures(); |
447 for (NodeIt n(_graph); n != INVALID; ++n) { |
451 for (NodeIt n(_graph); n != INVALID; ++n) { |
448 (*_matching)[n] = INVALID; |
452 (*_matching)[n] = INVALID; |
449 (*_status)[n] = UNMATCHED; |
453 (*_status)[n] = UNMATCHED; |
450 } |
454 } |
|
455 _unmatched = _node_num; |
451 for (NodeIt n(_graph); n != INVALID; ++n) { |
456 for (NodeIt n(_graph); n != INVALID; ++n) { |
452 if ((*_matching)[n] == INVALID) { |
457 if ((*_matching)[n] == INVALID) { |
453 for (OutArcIt a(_graph, n); a != INVALID ; ++a) { |
458 for (OutArcIt a(_graph, n); a != INVALID ; ++a) { |
454 Node v = _graph.target(a); |
459 Node v = _graph.target(a); |
455 if ((*_matching)[v] == INVALID && v != n) { |
460 if ((*_matching)[v] == INVALID && v != n) { |
456 (*_matching)[n] = a; |
461 (*_matching)[n] = a; |
457 (*_status)[n] = MATCHED; |
462 (*_status)[n] = MATCHED; |
458 (*_matching)[v] = _graph.oppositeArc(a); |
463 (*_matching)[v] = _graph.oppositeArc(a); |
459 (*_status)[v] = MATCHED; |
464 (*_status)[v] = MATCHED; |
|
465 _unmatched -= 2; |
460 break; |
466 break; |
461 } |
467 } |
462 } |
468 } |
463 } |
469 } |
464 } |
470 } |
489 |
496 |
490 Node v = _graph.v(e); |
497 Node v = _graph.v(e); |
491 if ((*_matching)[v] != INVALID) return false; |
498 if ((*_matching)[v] != INVALID) return false; |
492 (*_matching)[v] = _graph.direct(e, false); |
499 (*_matching)[v] = _graph.direct(e, false); |
493 (*_status)[v] = MATCHED; |
500 (*_status)[v] = MATCHED; |
|
501 |
|
502 _unmatched -= 2; |
494 } |
503 } |
495 } |
504 } |
496 return true; |
505 return true; |
497 } |
506 } |
498 |
507 |
499 /// \brief Start Edmonds' algorithm |
508 /// \brief Start Edmonds' algorithm |
500 /// |
509 /// |
501 /// This function runs the original Edmonds' algorithm. |
510 /// This function runs the original Edmonds' algorithm. If the |
|
511 /// \c decomposition parameter is set to false, then the Gallai-Edmonds |
|
512 /// decomposition is not computed. |
502 /// |
513 /// |
503 /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be |
514 /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be |
504 /// called before using this function. |
515 /// called before using this function. |
505 void startSparse() { |
516 void startSparse(bool decomposition = true) { |
506 for(NodeIt n(_graph); n != INVALID; ++n) { |
517 int _unmatched_limit = decomposition ? 0 : 1; |
|
518 for(NodeIt n(_graph); _unmatched > _unmatched_limit; ++n) { |
507 if ((*_status)[n] == UNMATCHED) { |
519 if ((*_status)[n] == UNMATCHED) { |
508 (*_blossom_rep)[_blossom_set->insert(n)] = n; |
520 (*_blossom_rep)[_blossom_set->insert(n)] = n; |
509 _tree_set->insert(n); |
521 _tree_set->insert(n); |
510 (*_status)[n] = EVEN; |
522 (*_status)[n] = EVEN; |
|
523 --_unmatched; |
511 processSparse(n); |
524 processSparse(n); |
512 } |
525 } |
513 } |
526 } |
514 } |
527 } |
515 |
528 |
516 /// \brief Start Edmonds' algorithm with a heuristic improvement |
529 /// \brief Start Edmonds' algorithm with a heuristic improvement |
517 /// for dense graphs |
530 /// for dense graphs |
518 /// |
531 /// |
519 /// This function runs Edmonds' algorithm with a heuristic of postponing |
532 /// This function runs Edmonds' algorithm with a heuristic of postponing |
520 /// shrinks, therefore resulting in a faster algorithm for dense graphs. |
533 /// shrinks, therefore resulting in a faster algorithm for dense graphs. If |
|
534 /// the \c decomposition parameter is set to false, then the Gallai-Edmonds |
|
535 /// decomposition is not computed. |
521 /// |
536 /// |
522 /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be |
537 /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be |
523 /// called before using this function. |
538 /// called before using this function. |
524 void startDense() { |
539 void startDense(bool decomposition = true) { |
525 for(NodeIt n(_graph); n != INVALID; ++n) { |
540 int _unmatched_limit = decomposition ? 0 : 1; |
|
541 for(NodeIt n(_graph); _unmatched > _unmatched_limit; ++n) { |
526 if ((*_status)[n] == UNMATCHED) { |
542 if ((*_status)[n] == UNMATCHED) { |
527 (*_blossom_rep)[_blossom_set->insert(n)] = n; |
543 (*_blossom_rep)[_blossom_set->insert(n)] = n; |
528 _tree_set->insert(n); |
544 _tree_set->insert(n); |
529 (*_status)[n] = EVEN; |
545 (*_status)[n] = EVEN; |
|
546 --_unmatched; |
530 processDense(n); |
547 processDense(n); |
531 } |
548 } |
532 } |
549 } |
533 } |
550 } |
534 |
551 |
535 |
552 |
536 /// \brief Run Edmonds' algorithm |
553 /// \brief Run Edmonds' algorithm |
537 /// |
554 /// |
538 /// This function runs Edmonds' algorithm. An additional heuristic of |
555 /// This function runs Edmonds' algorithm. An additional heuristic of |
539 /// postponing shrinks is used for relatively dense graphs |
556 /// postponing shrinks is used for relatively dense graphs (for which |
540 /// (for which <tt>m>=2*n</tt> holds). |
557 /// <tt>m>=2*n</tt> holds). If the \c decomposition parameter is set to |
541 void run() { |
558 /// false, then the Gallai-Edmonds decomposition is not computed. In some |
|
559 /// cases, this can speed up the algorithm significantly, especially when a |
|
560 /// maximum matching is computed in a dense graph with odd number of nodes. |
|
561 void run(bool decomposition = true) { |
542 if (countEdges(_graph) < 2 * countNodes(_graph)) { |
562 if (countEdges(_graph) < 2 * countNodes(_graph)) { |
543 greedyInit(); |
563 greedyInit(); |
544 startSparse(); |
564 startSparse(decomposition); |
545 } else { |
565 } else { |
546 init(); |
566 init(); |
547 startDense(); |
567 startDense(decomposition); |
548 } |
568 } |
549 } |
569 } |
550 |
570 |
551 /// @} |
571 /// @} |
552 |
572 |