gravatar
deba@inf.elte.hu
deba@inf.elte.hu
General improvements in weighted matching algorithms (#314) - Fix include guard - Uniform handling of MATCHED and UNMATCHED blossoms - Prefer operations which decrease the number of trees - Fix improper use of '/=' The solved problems did not cause wrong solution.
0 1 0
default
1 file changed with 231 insertions and 350 deletions:
↑ Collapse diff ↑
Ignore white space 48 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
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
#ifndef LEMON_MAX_MATCHING_H
20
#define LEMON_MAX_MATCHING_H
19
#ifndef LEMON_MATCHING_H
20
#define LEMON_MATCHING_H
21 21

	
22 22
#include <vector>
23 23
#include <queue>
24 24
#include <set>
25 25
#include <limits>
26 26

	
27 27
#include <lemon/core.h>
28 28
#include <lemon/unionfind.h>
29 29
#include <lemon/bin_heap.h>
30 30
#include <lemon/maps.h>
31 31

	
32 32
///\ingroup matching
33 33
///\file
34 34
///\brief Maximum matching algorithms in general graphs.
35 35

	
36 36
namespace lemon {
37 37

	
38 38
  /// \ingroup matching
39 39
  ///
40 40
  /// \brief Maximum cardinality matching in general graphs
41 41
  ///
42 42
  /// This class implements Edmonds' alternating forest matching algorithm
43 43
  /// for finding a maximum cardinality matching in a general undirected graph.
44
  /// It can be started from an arbitrary initial matching 
44
  /// It can be started from an arbitrary initial matching
45 45
  /// (the default is the empty one).
46 46
  ///
47 47
  /// The dual solution of the problem is a map of the nodes to
48 48
  /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
49 49
  /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
50 50
  /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
51 51
  /// with factor-critical components, the nodes in \c ODD/A form the
52 52
  /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having
53 53
  /// a perfect matching. The number of the factor-critical components
54 54
  /// minus the number of barrier nodes is a lower bound on the
55 55
  /// unmatched nodes, and the matching is optimal if and only if this bound is
56 56
  /// tight. This decomposition can be obtained using \ref status() or
57 57
  /// \ref statusMap() after running the algorithm.
58 58
  ///
59 59
  /// \tparam GR The undirected graph type the algorithm runs on.
60 60
  template <typename GR>
61 61
  class MaxMatching {
62 62
  public:
63 63

	
64 64
    /// The graph type of the algorithm
65 65
    typedef GR Graph;
66 66
    /// The type of the matching map
67 67
    typedef typename Graph::template NodeMap<typename Graph::Arc>
68 68
    MatchingMap;
69 69

	
70 70
    ///\brief Status constants for Gallai-Edmonds decomposition.
71 71
    ///
72
    ///These constants are used for indicating the Gallai-Edmonds 
72
    ///These constants are used for indicating the Gallai-Edmonds
73 73
    ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
74 74
    ///induce a subgraph with factor-critical components, the nodes with
75 75
    ///status \c ODD (or \c A) form the canonical barrier, and the nodes
76
    ///with status \c MATCHED (or \c C) induce a subgraph having a 
76
    ///with status \c MATCHED (or \c C) induce a subgraph having a
77 77
    ///perfect matching.
78 78
    enum Status {
79 79
      EVEN = 1,       ///< = 1. (\c D is an alias for \c EVEN.)
80 80
      D = 1,
81 81
      MATCHED = 0,    ///< = 0. (\c C is an alias for \c MATCHED.)
82 82
      C = 0,
83 83
      ODD = -1,       ///< = -1. (\c A is an alias for \c ODD.)
84 84
      A = -1,
85 85
      UNMATCHED = -2  ///< = -2.
86 86
    };
87 87

	
88 88
    /// The type of the status map
89 89
    typedef typename Graph::template NodeMap<Status> StatusMap;
90 90

	
91 91
  private:
92 92

	
93 93
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
94 94

	
95 95
    typedef UnionFindEnum<IntNodeMap> BlossomSet;
96 96
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
97 97
    typedef RangeMap<Node> NodeIntMap;
98 98
    typedef MatchingMap EarMap;
99 99
    typedef std::vector<Node> NodeQueue;
100 100

	
... ...
@@ -491,219 +491,219 @@
491 491
          (*_matching)[v] = _graph.direct(e, false);
492 492
          (*_status)[v] = MATCHED;
493 493
        }
494 494
      }
495 495
      return true;
496 496
    }
497 497

	
498 498
    /// \brief Start Edmonds' algorithm
499 499
    ///
500 500
    /// This function runs the original Edmonds' algorithm.
501 501
    ///
502 502
    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
503 503
    /// called before using this function.
504 504
    void startSparse() {
505 505
      for(NodeIt n(_graph); n != INVALID; ++n) {
506 506
        if ((*_status)[n] == UNMATCHED) {
507 507
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
508 508
          _tree_set->insert(n);
509 509
          (*_status)[n] = EVEN;
510 510
          processSparse(n);
511 511
        }
512 512
      }
513 513
    }
514 514

	
515
    /// \brief Start Edmonds' algorithm with a heuristic improvement 
515
    /// \brief Start Edmonds' algorithm with a heuristic improvement
516 516
    /// for dense graphs
517 517
    ///
518 518
    /// This function runs Edmonds' algorithm with a heuristic of postponing
519 519
    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
520 520
    ///
521 521
    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
522 522
    /// called before using this function.
523 523
    void startDense() {
524 524
      for(NodeIt n(_graph); n != INVALID; ++n) {
525 525
        if ((*_status)[n] == UNMATCHED) {
526 526
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
527 527
          _tree_set->insert(n);
528 528
          (*_status)[n] = EVEN;
529 529
          processDense(n);
530 530
        }
531 531
      }
532 532
    }
533 533

	
534 534

	
535 535
    /// \brief Run Edmonds' algorithm
536 536
    ///
537
    /// This function runs Edmonds' algorithm. An additional heuristic of 
538
    /// postponing shrinks is used for relatively dense graphs 
537
    /// This function runs Edmonds' algorithm. An additional heuristic of
538
    /// postponing shrinks is used for relatively dense graphs
539 539
    /// (for which <tt>m>=2*n</tt> holds).
540 540
    void run() {
541 541
      if (countEdges(_graph) < 2 * countNodes(_graph)) {
542 542
        greedyInit();
543 543
        startSparse();
544 544
      } else {
545 545
        init();
546 546
        startDense();
547 547
      }
548 548
    }
549 549

	
550 550
    /// @}
551 551

	
552 552
    /// \name Primal Solution
553 553
    /// Functions to get the primal solution, i.e. the maximum matching.
554 554

	
555 555
    /// @{
556 556

	
557 557
    /// \brief Return the size (cardinality) of the matching.
558 558
    ///
559
    /// This function returns the size (cardinality) of the current matching. 
559
    /// This function returns the size (cardinality) of the current matching.
560 560
    /// After run() it returns the size of the maximum matching in the graph.
561 561
    int matchingSize() const {
562 562
      int size = 0;
563 563
      for (NodeIt n(_graph); n != INVALID; ++n) {
564 564
        if ((*_matching)[n] != INVALID) {
565 565
          ++size;
566 566
        }
567 567
      }
568 568
      return size / 2;
569 569
    }
570 570

	
571 571
    /// \brief Return \c true if the given edge is in the matching.
572 572
    ///
573
    /// This function returns \c true if the given edge is in the current 
573
    /// This function returns \c true if the given edge is in the current
574 574
    /// matching.
575 575
    bool matching(const Edge& edge) const {
576 576
      return edge == (*_matching)[_graph.u(edge)];
577 577
    }
578 578

	
579 579
    /// \brief Return the matching arc (or edge) incident to the given node.
580 580
    ///
581 581
    /// This function returns the matching arc (or edge) incident to the
582
    /// given node in the current matching or \c INVALID if the node is 
582
    /// given node in the current matching or \c INVALID if the node is
583 583
    /// not covered by the matching.
584 584
    Arc matching(const Node& n) const {
585 585
      return (*_matching)[n];
586 586
    }
587 587

	
588 588
    /// \brief Return a const reference to the matching map.
589 589
    ///
590 590
    /// This function returns a const reference to a node map that stores
591 591
    /// the matching arc (or edge) incident to each node.
592 592
    const MatchingMap& matchingMap() const {
593 593
      return *_matching;
594 594
    }
595 595

	
596 596
    /// \brief Return the mate of the given node.
597 597
    ///
598
    /// This function returns the mate of the given node in the current 
598
    /// This function returns the mate of the given node in the current
599 599
    /// matching or \c INVALID if the node is not covered by the matching.
600 600
    Node mate(const Node& n) const {
601 601
      return (*_matching)[n] != INVALID ?
602 602
        _graph.target((*_matching)[n]) : INVALID;
603 603
    }
604 604

	
605 605
    /// @}
606 606

	
607 607
    /// \name Dual Solution
608
    /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
608
    /// Functions to get the dual solution, i.e. the Gallai-Edmonds
609 609
    /// decomposition.
610 610

	
611 611
    /// @{
612 612

	
613 613
    /// \brief Return the status of the given node in the Edmonds-Gallai
614 614
    /// decomposition.
615 615
    ///
616 616
    /// This function returns the \ref Status "status" of the given node
617 617
    /// in the Edmonds-Gallai decomposition.
618 618
    Status status(const Node& n) const {
619 619
      return (*_status)[n];
620 620
    }
621 621

	
622 622
    /// \brief Return a const reference to the status map, which stores
623 623
    /// the Edmonds-Gallai decomposition.
624 624
    ///
625 625
    /// This function returns a const reference to a node map that stores the
626 626
    /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
627 627
    const StatusMap& statusMap() const {
628 628
      return *_status;
629 629
    }
630 630

	
631 631
    /// \brief Return \c true if the given node is in the barrier.
632 632
    ///
633 633
    /// This function returns \c true if the given node is in the barrier.
634 634
    bool barrier(const Node& n) const {
635 635
      return (*_status)[n] == ODD;
636 636
    }
637 637

	
638 638
    /// @}
639 639

	
640 640
  };
641 641

	
642 642
  /// \ingroup matching
643 643
  ///
644 644
  /// \brief Weighted matching in general graphs
645 645
  ///
646 646
  /// This class provides an efficient implementation of Edmond's
647 647
  /// maximum weighted matching algorithm. The implementation is based
648 648
  /// on extensive use of priority queues and provides
649 649
  /// \f$O(nm\log n)\f$ time complexity.
650 650
  ///
651
  /// The maximum weighted matching problem is to find a subset of the 
652
  /// edges in an undirected graph with maximum overall weight for which 
651
  /// The maximum weighted matching problem is to find a subset of the
652
  /// edges in an undirected graph with maximum overall weight for which
653 653
  /// each node has at most one incident edge.
654 654
  /// It can be formulated with the following linear program.
655 655
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
656 656
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
657 657
      \quad \forall B\in\mathcal{O}\f] */
658 658
  /// \f[x_e \ge 0\quad \forall e\in E\f]
659 659
  /// \f[\max \sum_{e\in E}x_ew_e\f]
660 660
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
661 661
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
662 662
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
663 663
  /// subsets of the nodes.
664 664
  ///
665 665
  /// The algorithm calculates an optimal matching and a proof of the
666 666
  /// optimality. The solution of the dual problem can be used to check
667 667
  /// the result of the algorithm. The dual linear problem is the
668 668
  /// following.
669 669
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
670 670
      z_B \ge w_{uv} \quad \forall uv\in E\f] */
671 671
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
672 672
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
673 673
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
674 674
      \frac{\vert B \vert - 1}{2}z_B\f] */
675 675
  ///
676
  /// The algorithm can be executed with the run() function. 
676
  /// The algorithm can be executed with the run() function.
677 677
  /// After it the matching (the primal solution) and the dual solution
678
  /// can be obtained using the query functions and the 
679
  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
680
  /// which is able to iterate on the nodes of a blossom. 
678
  /// can be obtained using the query functions and the
679
  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
680
  /// which is able to iterate on the nodes of a blossom.
681 681
  /// If the value type is integer, then the dual solution is multiplied
682 682
  /// by \ref MaxWeightedMatching::dualScale "4".
683 683
  ///
684 684
  /// \tparam GR The undirected graph type the algorithm runs on.
685
  /// \tparam WM The type edge weight map. The default type is 
685
  /// \tparam WM The type edge weight map. The default type is
686 686
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
687 687
#ifdef DOXYGEN
688 688
  template <typename GR, typename WM>
689 689
#else
690 690
  template <typename GR,
691 691
            typename WM = typename GR::template EdgeMap<int> >
692 692
#endif
693 693
  class MaxWeightedMatching {
694 694
  public:
695 695

	
696 696
    /// The graph type of the algorithm
697 697
    typedef GR Graph;
698 698
    /// The type of the edge weight map
699 699
    typedef WM WeightMap;
700 700
    /// The value type of the edge weights
701 701
    typedef typename WeightMap::Value Value;
702 702

	
703 703
    /// The type of the matching map
704 704
    typedef typename Graph::template NodeMap<typename Graph::Arc>
705 705
    MatchingMap;
706 706

	
707 707
    /// \brief Scaling factor for dual solution
708 708
    ///
709 709
    /// Scaling factor for dual solution. It is equal to 4 or 1
... ...
@@ -724,49 +724,49 @@
724 724

	
725 725
      BlossomVariable(int _begin, int _end, Value _value)
726 726
        : begin(_begin), end(_end), value(_value) {}
727 727

	
728 728
    };
729 729

	
730 730
    typedef std::vector<BlossomVariable> BlossomPotential;
731 731

	
732 732
    const Graph& _graph;
733 733
    const WeightMap& _weight;
734 734

	
735 735
    MatchingMap* _matching;
736 736

	
737 737
    NodePotential* _node_potential;
738 738

	
739 739
    BlossomPotential _blossom_potential;
740 740
    BlossomNodeList _blossom_node_list;
741 741

	
742 742
    int _node_num;
743 743
    int _blossom_num;
744 744

	
745 745
    typedef RangeMap<int> IntIntMap;
746 746

	
747 747
    enum Status {
748
      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
748
      EVEN = -1, MATCHED = 0, ODD = 1
749 749
    };
750 750

	
751 751
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
752 752
    struct BlossomData {
753 753
      int tree;
754 754
      Status status;
755 755
      Arc pred, next;
756 756
      Value pot, offset;
757 757
      Node base;
758 758
    };
759 759

	
760 760
    IntNodeMap *_blossom_index;
761 761
    BlossomSet *_blossom_set;
762 762
    RangeMap<BlossomData>* _blossom_data;
763 763

	
764 764
    IntNodeMap *_node_index;
765 765
    IntArcMap *_node_heap_index;
766 766

	
767 767
    struct NodeData {
768 768

	
769 769
      NodeData(IntArcMap& node_heap_index)
770 770
        : heap(node_heap_index) {}
771 771

	
772 772
      int blossom;
... ...
@@ -823,51 +823,48 @@
823 823

	
824 824
      if (!_tree_set) {
825 825
        _tree_set_index = new IntIntMap(_blossom_num);
826 826
        _tree_set = new TreeSet(*_tree_set_index);
827 827
      }
828 828
      if (!_delta1) {
829 829
        _delta1_index = new IntNodeMap(_graph);
830 830
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
831 831
      }
832 832
      if (!_delta2) {
833 833
        _delta2_index = new IntIntMap(_blossom_num);
834 834
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
835 835
      }
836 836
      if (!_delta3) {
837 837
        _delta3_index = new IntEdgeMap(_graph);
838 838
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
839 839
      }
840 840
      if (!_delta4) {
841 841
        _delta4_index = new IntIntMap(_blossom_num);
842 842
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
843 843
      }
844 844
    }
845 845

	
846 846
    void destroyStructures() {
847
      _node_num = countNodes(_graph);
848
      _blossom_num = _node_num * 3 / 2;
849

	
850 847
      if (_matching) {
851 848
        delete _matching;
852 849
      }
853 850
      if (_node_potential) {
854 851
        delete _node_potential;
855 852
      }
856 853
      if (_blossom_set) {
857 854
        delete _blossom_index;
858 855
        delete _blossom_set;
859 856
        delete _blossom_data;
860 857
      }
861 858

	
862 859
      if (_node_index) {
863 860
        delete _node_index;
864 861
        delete _node_heap_index;
865 862
        delete _node_data;
866 863
      }
867 864

	
868 865
      if (_tree_set) {
869 866
        delete _tree_set_index;
870 867
        delete _tree_set;
871 868
      }
872 869
      if (_delta1) {
873 870
        delete _delta1_index;
... ...
@@ -901,453 +898,348 @@
901 898
           n != INVALID; ++n) {
902 899

	
903 900
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
904 901
        int ni = (*_node_index)[n];
905 902

	
906 903
        (*_node_data)[ni].heap.clear();
907 904
        (*_node_data)[ni].heap_index.clear();
908 905

	
909 906
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
910 907

	
911 908
        _delta1->push(n, (*_node_data)[ni].pot);
912 909

	
913 910
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
914 911
          Node v = _graph.source(e);
915 912
          int vb = _blossom_set->find(v);
916 913
          int vi = (*_node_index)[v];
917 914

	
918 915
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
919 916
            dualScale * _weight[e];
920 917

	
921 918
          if ((*_blossom_data)[vb].status == EVEN) {
922 919
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
923 920
              _delta3->push(e, rw / 2);
924 921
            }
925
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
926
            if (_delta3->state(e) != _delta3->IN_HEAP) {
927
              _delta3->push(e, rw);
928
            }
929 922
          } else {
930 923
            typename std::map<int, Arc>::iterator it =
931 924
              (*_node_data)[vi].heap_index.find(tree);
932 925

	
933 926
            if (it != (*_node_data)[vi].heap_index.end()) {
934 927
              if ((*_node_data)[vi].heap[it->second] > rw) {
935 928
                (*_node_data)[vi].heap.replace(it->second, e);
936 929
                (*_node_data)[vi].heap.decrease(e, rw);
937 930
                it->second = e;
938 931
              }
939 932
            } else {
940 933
              (*_node_data)[vi].heap.push(e, rw);
941 934
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
942 935
            }
943 936

	
944 937
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
945 938
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
946 939

	
947 940
              if ((*_blossom_data)[vb].status == MATCHED) {
948 941
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
949 942
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
950 943
                               (*_blossom_data)[vb].offset);
951 944
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
952
                           (*_blossom_data)[vb].offset){
953
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
954
                                   (*_blossom_data)[vb].offset);
955
                }
956
              }
957
            }
958
          }
959
        }
960
      }
961
      (*_blossom_data)[blossom].offset = 0;
962
    }
963

	
964
    void matchedToOdd(int blossom) {
965
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
966
        _delta2->erase(blossom);
967
      }
968
      (*_blossom_data)[blossom].offset += _delta_sum;
969
      if (!_blossom_set->trivial(blossom)) {
970
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
971
                     (*_blossom_data)[blossom].offset);
972
      }
973
    }
974

	
975
    void evenToMatched(int blossom, int tree) {
976
      if (!_blossom_set->trivial(blossom)) {
977
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
978
      }
979

	
980
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
981
           n != INVALID; ++n) {
982
        int ni = (*_node_index)[n];
983
        (*_node_data)[ni].pot -= _delta_sum;
984

	
985
        _delta1->erase(n);
986

	
987
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
988
          Node v = _graph.source(e);
989
          int vb = _blossom_set->find(v);
990
          int vi = (*_node_index)[v];
991

	
992
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
993
            dualScale * _weight[e];
994

	
995
          if (vb == blossom) {
996
            if (_delta3->state(e) == _delta3->IN_HEAP) {
997
              _delta3->erase(e);
998
            }
999
          } else if ((*_blossom_data)[vb].status == EVEN) {
1000

	
1001
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1002
              _delta3->erase(e);
1003
            }
1004

	
1005
            int vt = _tree_set->find(vb);
1006

	
1007
            if (vt != tree) {
1008

	
1009
              Arc r = _graph.oppositeArc(e);
1010

	
1011
              typename std::map<int, Arc>::iterator it =
1012
                (*_node_data)[ni].heap_index.find(vt);
1013

	
1014
              if (it != (*_node_data)[ni].heap_index.end()) {
1015
                if ((*_node_data)[ni].heap[it->second] > rw) {
1016
                  (*_node_data)[ni].heap.replace(it->second, r);
1017
                  (*_node_data)[ni].heap.decrease(r, rw);
1018
                  it->second = r;
1019
                }
1020
              } else {
1021
                (*_node_data)[ni].heap.push(r, rw);
1022
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1023
              }
1024

	
1025
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1026
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1027

	
1028
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1029
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1030
                               (*_blossom_data)[blossom].offset);
1031
                } else if ((*_delta2)[blossom] >
1032
                           _blossom_set->classPrio(blossom) -
1033
                           (*_blossom_data)[blossom].offset){
1034
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1035
                                   (*_blossom_data)[blossom].offset);
1036
                }
1037
              }
1038
            }
1039

	
1040
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1041
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1042
              _delta3->erase(e);
1043
            }
1044
          } else {
1045

	
1046
            typename std::map<int, Arc>::iterator it =
1047
              (*_node_data)[vi].heap_index.find(tree);
1048

	
1049
            if (it != (*_node_data)[vi].heap_index.end()) {
1050
              (*_node_data)[vi].heap.erase(it->second);
1051
              (*_node_data)[vi].heap_index.erase(it);
1052
              if ((*_node_data)[vi].heap.empty()) {
1053
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1054
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1055
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
1056
              }
1057

	
1058
              if ((*_blossom_data)[vb].status == MATCHED) {
1059
                if (_blossom_set->classPrio(vb) ==
1060
                    std::numeric_limits<Value>::max()) {
1061
                  _delta2->erase(vb);
1062
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
1063
                           (*_blossom_data)[vb].offset) {
1064
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
1065
                                   (*_blossom_data)[vb].offset);
1066
                }
1067
              }
1068
            }
1069
          }
1070
        }
1071
      }
1072
    }
1073

	
1074
    void oddToMatched(int blossom) {
1075
      (*_blossom_data)[blossom].offset -= _delta_sum;
1076

	
1077
      if (_blossom_set->classPrio(blossom) !=
1078
          std::numeric_limits<Value>::max()) {
1079
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1080
                       (*_blossom_data)[blossom].offset);
1081
      }
1082

	
1083
      if (!_blossom_set->trivial(blossom)) {
1084
        _delta4->erase(blossom);
1085
      }
1086
    }
1087

	
1088
    void oddToEven(int blossom, int tree) {
1089
      if (!_blossom_set->trivial(blossom)) {
1090
        _delta4->erase(blossom);
1091
        (*_blossom_data)[blossom].pot -=
1092
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
1093
      }
1094

	
1095
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1096
           n != INVALID; ++n) {
1097
        int ni = (*_node_index)[n];
1098

	
1099
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1100

	
1101
        (*_node_data)[ni].heap.clear();
1102
        (*_node_data)[ni].heap_index.clear();
1103
        (*_node_data)[ni].pot +=
1104
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
1105

	
1106
        _delta1->push(n, (*_node_data)[ni].pot);
1107

	
1108
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1109
          Node v = _graph.source(e);
1110
          int vb = _blossom_set->find(v);
1111
          int vi = (*_node_index)[v];
1112

	
1113
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1114
            dualScale * _weight[e];
1115

	
1116
          if ((*_blossom_data)[vb].status == EVEN) {
1117
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
1118
              _delta3->push(e, rw / 2);
1119
            }
1120
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1121
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1122
              _delta3->push(e, rw);
1123
            }
1124
          } else {
1125

	
1126
            typename std::map<int, Arc>::iterator it =
1127
              (*_node_data)[vi].heap_index.find(tree);
1128

	
1129
            if (it != (*_node_data)[vi].heap_index.end()) {
1130
              if ((*_node_data)[vi].heap[it->second] > rw) {
1131
                (*_node_data)[vi].heap.replace(it->second, e);
1132
                (*_node_data)[vi].heap.decrease(e, rw);
1133
                it->second = e;
1134
              }
1135
            } else {
1136
              (*_node_data)[vi].heap.push(e, rw);
1137
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
1138
            }
1139

	
1140
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
1141
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
1142

	
1143
              if ((*_blossom_data)[vb].status == MATCHED) {
1144
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
1145
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
1146
                               (*_blossom_data)[vb].offset);
1147
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
1148 945
                           (*_blossom_data)[vb].offset) {
1149 946
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
1150 947
                                   (*_blossom_data)[vb].offset);
1151 948
                }
1152 949
              }
1153 950
            }
1154 951
          }
1155 952
        }
1156 953
      }
1157 954
      (*_blossom_data)[blossom].offset = 0;
1158 955
    }
1159 956

	
1160

	
1161
    void matchedToUnmatched(int blossom) {
957
    void matchedToOdd(int blossom) {
1162 958
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1163 959
        _delta2->erase(blossom);
1164 960
      }
961
      (*_blossom_data)[blossom].offset += _delta_sum;
962
      if (!_blossom_set->trivial(blossom)) {
963
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
964
                      (*_blossom_data)[blossom].offset);
965
      }
966
    }
967

	
968
    void evenToMatched(int blossom, int tree) {
969
      if (!_blossom_set->trivial(blossom)) {
970
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
971
      }
1165 972

	
1166 973
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1167 974
           n != INVALID; ++n) {
1168 975
        int ni = (*_node_index)[n];
1169

	
1170
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1171

	
1172
        (*_node_data)[ni].heap.clear();
1173
        (*_node_data)[ni].heap_index.clear();
1174

	
1175
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1176
          Node v = _graph.target(e);
976
        (*_node_data)[ni].pot -= _delta_sum;
977

	
978
        _delta1->erase(n);
979

	
980
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
981
          Node v = _graph.source(e);
1177 982
          int vb = _blossom_set->find(v);
1178 983
          int vi = (*_node_index)[v];
1179 984

	
1180 985
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1181 986
            dualScale * _weight[e];
1182 987

	
1183
          if ((*_blossom_data)[vb].status == EVEN) {
1184
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1185
              _delta3->push(e, rw);
988
          if (vb == blossom) {
989
            if (_delta3->state(e) == _delta3->IN_HEAP) {
990
              _delta3->erase(e);
991
            }
992
          } else if ((*_blossom_data)[vb].status == EVEN) {
993

	
994
            if (_delta3->state(e) == _delta3->IN_HEAP) {
995
              _delta3->erase(e);
996
            }
997

	
998
            int vt = _tree_set->find(vb);
999

	
1000
            if (vt != tree) {
1001

	
1002
              Arc r = _graph.oppositeArc(e);
1003

	
1004
              typename std::map<int, Arc>::iterator it =
1005
                (*_node_data)[ni].heap_index.find(vt);
1006

	
1007
              if (it != (*_node_data)[ni].heap_index.end()) {
1008
                if ((*_node_data)[ni].heap[it->second] > rw) {
1009
                  (*_node_data)[ni].heap.replace(it->second, r);
1010
                  (*_node_data)[ni].heap.decrease(r, rw);
1011
                  it->second = r;
1012
                }
1013
              } else {
1014
                (*_node_data)[ni].heap.push(r, rw);
1015
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1016
              }
1017

	
1018
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1019
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1020

	
1021
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1022
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1023
                               (*_blossom_data)[blossom].offset);
1024
                } else if ((*_delta2)[blossom] >
1025
                           _blossom_set->classPrio(blossom) -
1026
                           (*_blossom_data)[blossom].offset){
1027
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1028
                                   (*_blossom_data)[blossom].offset);
1029
                }
1030
              }
1031
            }
1032
          } else {
1033

	
1034
            typename std::map<int, Arc>::iterator it =
1035
              (*_node_data)[vi].heap_index.find(tree);
1036

	
1037
            if (it != (*_node_data)[vi].heap_index.end()) {
1038
              (*_node_data)[vi].heap.erase(it->second);
1039
              (*_node_data)[vi].heap_index.erase(it);
1040
              if ((*_node_data)[vi].heap.empty()) {
1041
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1042
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1043
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
1044
              }
1045

	
1046
              if ((*_blossom_data)[vb].status == MATCHED) {
1047
                if (_blossom_set->classPrio(vb) ==
1048
                    std::numeric_limits<Value>::max()) {
1049
                  _delta2->erase(vb);
1050
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
1051
                           (*_blossom_data)[vb].offset) {
1052
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
1053
                                   (*_blossom_data)[vb].offset);
1054
                }
1055
              }
1186 1056
            }
1187 1057
          }
1188 1058
        }
1189 1059
      }
1190 1060
    }
1191 1061

	
1192
    void unmatchedToMatched(int blossom) {
1062
    void oddToMatched(int blossom) {
1063
      (*_blossom_data)[blossom].offset -= _delta_sum;
1064

	
1065
      if (_blossom_set->classPrio(blossom) !=
1066
          std::numeric_limits<Value>::max()) {
1067
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1068
                      (*_blossom_data)[blossom].offset);
1069
      }
1070

	
1071
      if (!_blossom_set->trivial(blossom)) {
1072
        _delta4->erase(blossom);
1073
      }
1074
    }
1075

	
1076
    void oddToEven(int blossom, int tree) {
1077
      if (!_blossom_set->trivial(blossom)) {
1078
        _delta4->erase(blossom);
1079
        (*_blossom_data)[blossom].pot -=
1080
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
1081
      }
1082

	
1193 1083
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1194 1084
           n != INVALID; ++n) {
1195 1085
        int ni = (*_node_index)[n];
1196 1086

	
1087
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1088

	
1089
        (*_node_data)[ni].heap.clear();
1090
        (*_node_data)[ni].heap_index.clear();
1091
        (*_node_data)[ni].pot +=
1092
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
1093

	
1094
        _delta1->push(n, (*_node_data)[ni].pot);
1095

	
1197 1096
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1198 1097
          Node v = _graph.source(e);
1199 1098
          int vb = _blossom_set->find(v);
1200 1099
          int vi = (*_node_index)[v];
1201 1100

	
1202 1101
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1203 1102
            dualScale * _weight[e];
1204 1103

	
1205
          if (vb == blossom) {
1206
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1207
              _delta3->erase(e);
1104
          if ((*_blossom_data)[vb].status == EVEN) {
1105
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
1106
              _delta3->push(e, rw / 2);
1208 1107
            }
1209
          } else if ((*_blossom_data)[vb].status == EVEN) {
1210

	
1211
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1212
              _delta3->erase(e);
1213
            }
1214

	
1215
            int vt = _tree_set->find(vb);
1216

	
1217
            Arc r = _graph.oppositeArc(e);
1108
          } else {
1218 1109

	
1219 1110
            typename std::map<int, Arc>::iterator it =
1220
              (*_node_data)[ni].heap_index.find(vt);
1221

	
1222
            if (it != (*_node_data)[ni].heap_index.end()) {
1223
              if ((*_node_data)[ni].heap[it->second] > rw) {
1224
                (*_node_data)[ni].heap.replace(it->second, r);
1225
                (*_node_data)[ni].heap.decrease(r, rw);
1226
                it->second = r;
1111
              (*_node_data)[vi].heap_index.find(tree);
1112

	
1113
            if (it != (*_node_data)[vi].heap_index.end()) {
1114
              if ((*_node_data)[vi].heap[it->second] > rw) {
1115
                (*_node_data)[vi].heap.replace(it->second, e);
1116
                (*_node_data)[vi].heap.decrease(e, rw);
1117
                it->second = e;
1227 1118
              }
1228 1119
            } else {
1229
              (*_node_data)[ni].heap.push(r, rw);
1230
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1120
              (*_node_data)[vi].heap.push(e, rw);
1121
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
1231 1122
            }
1232 1123

	
1233
            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1234
              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1235

	
1236
              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1237
                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1238
                             (*_blossom_data)[blossom].offset);
1239
              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
1240
                         (*_blossom_data)[blossom].offset){
1241
                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1242
                                 (*_blossom_data)[blossom].offset);
1124
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
1125
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
1126

	
1127
              if ((*_blossom_data)[vb].status == MATCHED) {
1128
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
1129
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
1130
                               (*_blossom_data)[vb].offset);
1131
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
1132
                           (*_blossom_data)[vb].offset) {
1133
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
1134
                                   (*_blossom_data)[vb].offset);
1135
                }
1243 1136
              }
1244 1137
            }
1245

	
1246
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1247
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1248
              _delta3->erase(e);
1249
            }
1250 1138
          }
1251 1139
        }
1252 1140
      }
1141
      (*_blossom_data)[blossom].offset = 0;
1253 1142
    }
1254 1143

	
1255 1144
    void alternatePath(int even, int tree) {
1256 1145
      int odd;
1257 1146

	
1258 1147
      evenToMatched(even, tree);
1259 1148
      (*_blossom_data)[even].status = MATCHED;
1260 1149

	
1261 1150
      while ((*_blossom_data)[even].pred != INVALID) {
1262 1151
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
1263 1152
        (*_blossom_data)[odd].status = MATCHED;
1264 1153
        oddToMatched(odd);
1265 1154
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
1266 1155

	
1267 1156
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
1268 1157
        (*_blossom_data)[even].status = MATCHED;
1269 1158
        evenToMatched(even, tree);
1270 1159
        (*_blossom_data)[even].next =
1271 1160
          _graph.oppositeArc((*_blossom_data)[odd].pred);
1272 1161
      }
1273 1162

	
1274 1163
    }
1275 1164

	
1276 1165
    void destroyTree(int tree) {
1277 1166
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
1278 1167
        if ((*_blossom_data)[b].status == EVEN) {
1279 1168
          (*_blossom_data)[b].status = MATCHED;
1280 1169
          evenToMatched(b, tree);
1281 1170
        } else if ((*_blossom_data)[b].status == ODD) {
1282 1171
          (*_blossom_data)[b].status = MATCHED;
1283 1172
          oddToMatched(b);
1284 1173
        }
1285 1174
      }
1286 1175
      _tree_set->eraseClass(tree);
1287 1176
    }
1288 1177

	
1289 1178

	
1290 1179
    void unmatchNode(const Node& node) {
1291 1180
      int blossom = _blossom_set->find(node);
1292 1181
      int tree = _tree_set->find(blossom);
1293 1182

	
1294 1183
      alternatePath(blossom, tree);
1295 1184
      destroyTree(tree);
1296 1185

	
1297
      (*_blossom_data)[blossom].status = UNMATCHED;
1298 1186
      (*_blossom_data)[blossom].base = node;
1299
      matchedToUnmatched(blossom);
1187
      (*_blossom_data)[blossom].next = INVALID;
1300 1188
    }
1301 1189

	
1302

	
1303 1190
    void augmentOnEdge(const Edge& edge) {
1304 1191

	
1305 1192
      int left = _blossom_set->find(_graph.u(edge));
1306 1193
      int right = _blossom_set->find(_graph.v(edge));
1307 1194

	
1308
      if ((*_blossom_data)[left].status == EVEN) {
1309
        int left_tree = _tree_set->find(left);
1310
        alternatePath(left, left_tree);
1311
        destroyTree(left_tree);
1312
      } else {
1313
        (*_blossom_data)[left].status = MATCHED;
1314
        unmatchedToMatched(left);
1315
      }
1316

	
1317
      if ((*_blossom_data)[right].status == EVEN) {
1318
        int right_tree = _tree_set->find(right);
1319
        alternatePath(right, right_tree);
1320
        destroyTree(right_tree);
1321
      } else {
1322
        (*_blossom_data)[right].status = MATCHED;
1323
        unmatchedToMatched(right);
1324
      }
1195
      int left_tree = _tree_set->find(left);
1196
      alternatePath(left, left_tree);
1197
      destroyTree(left_tree);
1198

	
1199
      int right_tree = _tree_set->find(right);
1200
      alternatePath(right, right_tree);
1201
      destroyTree(right_tree);
1325 1202

	
1326 1203
      (*_blossom_data)[left].next = _graph.direct(edge, true);
1327 1204
      (*_blossom_data)[right].next = _graph.direct(edge, false);
1328 1205
    }
1329 1206

	
1207
    void augmentOnArc(const Arc& arc) {
1208

	
1209
      int left = _blossom_set->find(_graph.source(arc));
1210
      int right = _blossom_set->find(_graph.target(arc));
1211

	
1212
      (*_blossom_data)[left].status = MATCHED;
1213

	
1214
      int right_tree = _tree_set->find(right);
1215
      alternatePath(right, right_tree);
1216
      destroyTree(right_tree);
1217

	
1218
      (*_blossom_data)[left].next = arc;
1219
      (*_blossom_data)[right].next = _graph.oppositeArc(arc);
1220
    }
1221

	
1330 1222
    void extendOnArc(const Arc& arc) {
1331 1223
      int base = _blossom_set->find(_graph.target(arc));
1332 1224
      int tree = _tree_set->find(base);
1333 1225

	
1334 1226
      int odd = _blossom_set->find(_graph.source(arc));
1335 1227
      _tree_set->insert(odd, tree);
1336 1228
      (*_blossom_data)[odd].status = ODD;
1337 1229
      matchedToOdd(odd);
1338 1230
      (*_blossom_data)[odd].pred = arc;
1339 1231

	
1340 1232
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
1341 1233
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
1342 1234
      _tree_set->insert(even, tree);
1343 1235
      (*_blossom_data)[even].status = EVEN;
1344 1236
      matchedToEven(even, tree);
1345 1237
    }
1346 1238

	
1347 1239
    void shrinkOnEdge(const Edge& edge, int tree) {
1348 1240
      int nca = -1;
1349 1241
      std::vector<int> left_path, right_path;
1350 1242

	
1351 1243
      {
1352 1244
        std::set<int> left_set, right_set;
1353 1245
        int left = _blossom_set->find(_graph.u(edge));
... ...
@@ -1508,49 +1400,49 @@
1508 1400
                        _blossom_set->classPrio(subblossoms[i]) -
1509 1401
                        (*_blossom_data)[subblossoms[i]].offset);
1510 1402
        }
1511 1403
      }
1512 1404

	
1513 1405
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
1514 1406
        for (int i = (id + 1) % subblossoms.size();
1515 1407
             i != ib; i = (i + 2) % subblossoms.size()) {
1516 1408
          int sb = subblossoms[i];
1517 1409
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1518 1410
          (*_blossom_data)[sb].next =
1519 1411
            _graph.oppositeArc((*_blossom_data)[tb].next);
1520 1412
        }
1521 1413

	
1522 1414
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
1523 1415
          int sb = subblossoms[i];
1524 1416
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1525 1417
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1526 1418

	
1527 1419
          (*_blossom_data)[sb].status = ODD;
1528 1420
          matchedToOdd(sb);
1529 1421
          _tree_set->insert(sb, tree);
1530 1422
          (*_blossom_data)[sb].pred = pred;
1531 1423
          (*_blossom_data)[sb].next =
1532
                           _graph.oppositeArc((*_blossom_data)[tb].next);
1424
            _graph.oppositeArc((*_blossom_data)[tb].next);
1533 1425

	
1534 1426
          pred = (*_blossom_data)[ub].next;
1535 1427

	
1536 1428
          (*_blossom_data)[tb].status = EVEN;
1537 1429
          matchedToEven(tb, tree);
1538 1430
          _tree_set->insert(tb, tree);
1539 1431
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
1540 1432
        }
1541 1433

	
1542 1434
        (*_blossom_data)[subblossoms[id]].status = ODD;
1543 1435
        matchedToOdd(subblossoms[id]);
1544 1436
        _tree_set->insert(subblossoms[id], tree);
1545 1437
        (*_blossom_data)[subblossoms[id]].next = next;
1546 1438
        (*_blossom_data)[subblossoms[id]].pred = pred;
1547 1439

	
1548 1440
      } else {
1549 1441

	
1550 1442
        for (int i = (ib + 1) % subblossoms.size();
1551 1443
             i != id; i = (i + 2) % subblossoms.size()) {
1552 1444
          int sb = subblossoms[i];
1553 1445
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1554 1446
          (*_blossom_data)[sb].next =
1555 1447
            _graph.oppositeArc((*_blossom_data)[tb].next);
1556 1448
        }
... ...
@@ -1608,49 +1500,49 @@
1608 1500

	
1609 1501
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
1610 1502
          int sb = subblossoms[(ib + i) % subblossoms.size()];
1611 1503
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
1612 1504

	
1613 1505
          Arc m = (*_blossom_data)[tb].next;
1614 1506
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
1615 1507
          extractBlossom(tb, _graph.source(m), m);
1616 1508
        }
1617 1509
        extractBlossom(subblossoms[ib], base, matching);
1618 1510

	
1619 1511
        int en = _blossom_node_list.size();
1620 1512

	
1621 1513
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1622 1514
      }
1623 1515
    }
1624 1516

	
1625 1517
    void extractMatching() {
1626 1518
      std::vector<int> blossoms;
1627 1519
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1628 1520
        blossoms.push_back(c);
1629 1521
      }
1630 1522

	
1631 1523
      for (int i = 0; i < int(blossoms.size()); ++i) {
1632
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
1524
        if ((*_blossom_data)[blossoms[i]].next != INVALID) {
1633 1525

	
1634 1526
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1635 1527
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1636 1528
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1637 1529
               n != INVALID; ++n) {
1638 1530
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1639 1531
          }
1640 1532

	
1641 1533
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1642 1534
          Node base = _graph.source(matching);
1643 1535
          extractBlossom(blossoms[i], base, matching);
1644 1536
        } else {
1645 1537
          Node base = (*_blossom_data)[blossoms[i]].base;
1646 1538
          extractBlossom(blossoms[i], base, INVALID);
1647 1539
        }
1648 1540
      }
1649 1541
    }
1650 1542

	
1651 1543
  public:
1652 1544

	
1653 1545
    /// \brief Constructor
1654 1546
    ///
1655 1547
    /// Constructor.
1656 1548
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
... ...
@@ -1736,218 +1628,210 @@
1736 1628
    /// \brief Start the algorithm
1737 1629
    ///
1738 1630
    /// This function starts the algorithm.
1739 1631
    ///
1740 1632
    /// \pre \ref init() must be called before using this function.
1741 1633
    void start() {
1742 1634
      enum OpType {
1743 1635
        D1, D2, D3, D4
1744 1636
      };
1745 1637

	
1746 1638
      int unmatched = _node_num;
1747 1639
      while (unmatched > 0) {
1748 1640
        Value d1 = !_delta1->empty() ?
1749 1641
          _delta1->prio() : std::numeric_limits<Value>::max();
1750 1642

	
1751 1643
        Value d2 = !_delta2->empty() ?
1752 1644
          _delta2->prio() : std::numeric_limits<Value>::max();
1753 1645

	
1754 1646
        Value d3 = !_delta3->empty() ?
1755 1647
          _delta3->prio() : std::numeric_limits<Value>::max();
1756 1648

	
1757 1649
        Value d4 = !_delta4->empty() ?
1758 1650
          _delta4->prio() : std::numeric_limits<Value>::max();
1759 1651

	
1760
        _delta_sum = d1; OpType ot = D1;
1652
        _delta_sum = d3; OpType ot = D3;
1653
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
1761 1654
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1762
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
1763 1655
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1764 1656

	
1765

	
1766 1657
        switch (ot) {
1767 1658
        case D1:
1768 1659
          {
1769 1660
            Node n = _delta1->top();
1770 1661
            unmatchNode(n);
1771 1662
            --unmatched;
1772 1663
          }
1773 1664
          break;
1774 1665
        case D2:
1775 1666
          {
1776 1667
            int blossom = _delta2->top();
1777 1668
            Node n = _blossom_set->classTop(blossom);
1778
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
1779
            extendOnArc(e);
1669
            Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
1670
            if ((*_blossom_data)[blossom].next == INVALID) {
1671
              augmentOnArc(a);
1672
              --unmatched;
1673
            } else {
1674
              extendOnArc(a);
1675
            }
1780 1676
          }
1781 1677
          break;
1782 1678
        case D3:
1783 1679
          {
1784 1680
            Edge e = _delta3->top();
1785 1681

	
1786 1682
            int left_blossom = _blossom_set->find(_graph.u(e));
1787 1683
            int right_blossom = _blossom_set->find(_graph.v(e));
1788 1684

	
1789 1685
            if (left_blossom == right_blossom) {
1790 1686
              _delta3->pop();
1791 1687
            } else {
1792
              int left_tree;
1793
              if ((*_blossom_data)[left_blossom].status == EVEN) {
1794
                left_tree = _tree_set->find(left_blossom);
1795
              } else {
1796
                left_tree = -1;
1797
                ++unmatched;
1798
              }
1799
              int right_tree;
1800
              if ((*_blossom_data)[right_blossom].status == EVEN) {
1801
                right_tree = _tree_set->find(right_blossom);
1802
              } else {
1803
                right_tree = -1;
1804
                ++unmatched;
1805
              }
1688
              int left_tree = _tree_set->find(left_blossom);
1689
              int right_tree = _tree_set->find(right_blossom);
1806 1690

	
1807 1691
              if (left_tree == right_tree) {
1808 1692
                shrinkOnEdge(e, left_tree);
1809 1693
              } else {
1810 1694
                augmentOnEdge(e);
1811 1695
                unmatched -= 2;
1812 1696
              }
1813 1697
            }
1814 1698
          } break;
1815 1699
        case D4:
1816 1700
          splitBlossom(_delta4->top());
1817 1701
          break;
1818 1702
        }
1819 1703
      }
1820 1704
      extractMatching();
1821 1705
    }
1822 1706

	
1823 1707
    /// \brief Run the algorithm.
1824 1708
    ///
1825 1709
    /// This method runs the \c %MaxWeightedMatching algorithm.
1826 1710
    ///
1827 1711
    /// \note mwm.run() is just a shortcut of the following code.
1828 1712
    /// \code
1829 1713
    ///   mwm.init();
1830 1714
    ///   mwm.start();
1831 1715
    /// \endcode
1832 1716
    void run() {
1833 1717
      init();
1834 1718
      start();
1835 1719
    }
1836 1720

	
1837 1721
    /// @}
1838 1722

	
1839 1723
    /// \name Primal Solution
1840
    /// Functions to get the primal solution, i.e. the maximum weighted 
1724
    /// Functions to get the primal solution, i.e. the maximum weighted
1841 1725
    /// matching.\n
1842 1726
    /// Either \ref run() or \ref start() function should be called before
1843 1727
    /// using them.
1844 1728

	
1845 1729
    /// @{
1846 1730

	
1847 1731
    /// \brief Return the weight of the matching.
1848 1732
    ///
1849 1733
    /// This function returns the weight of the found matching.
1850 1734
    ///
1851 1735
    /// \pre Either run() or start() must be called before using this function.
1852 1736
    Value matchingWeight() const {
1853 1737
      Value sum = 0;
1854 1738
      for (NodeIt n(_graph); n != INVALID; ++n) {
1855 1739
        if ((*_matching)[n] != INVALID) {
1856 1740
          sum += _weight[(*_matching)[n]];
1857 1741
        }
1858 1742
      }
1859
      return sum /= 2;
1743
      return sum / 2;
1860 1744
    }
1861 1745

	
1862 1746
    /// \brief Return the size (cardinality) of the matching.
1863 1747
    ///
1864 1748
    /// This function returns the size (cardinality) of the found matching.
1865 1749
    ///
1866 1750
    /// \pre Either run() or start() must be called before using this function.
1867 1751
    int matchingSize() const {
1868 1752
      int num = 0;
1869 1753
      for (NodeIt n(_graph); n != INVALID; ++n) {
1870 1754
        if ((*_matching)[n] != INVALID) {
1871 1755
          ++num;
1872 1756
        }
1873 1757
      }
1874 1758
      return num /= 2;
1875 1759
    }
1876 1760

	
1877 1761
    /// \brief Return \c true if the given edge is in the matching.
1878 1762
    ///
1879
    /// This function returns \c true if the given edge is in the found 
1763
    /// This function returns \c true if the given edge is in the found
1880 1764
    /// matching.
1881 1765
    ///
1882 1766
    /// \pre Either run() or start() must be called before using this function.
1883 1767
    bool matching(const Edge& edge) const {
1884 1768
      return edge == (*_matching)[_graph.u(edge)];
1885 1769
    }
1886 1770

	
1887 1771
    /// \brief Return the matching arc (or edge) incident to the given node.
1888 1772
    ///
1889 1773
    /// This function returns the matching arc (or edge) incident to the
1890
    /// given node in the found matching or \c INVALID if the node is 
1774
    /// given node in the found matching or \c INVALID if the node is
1891 1775
    /// not covered by the matching.
1892 1776
    ///
1893 1777
    /// \pre Either run() or start() must be called before using this function.
1894 1778
    Arc matching(const Node& node) const {
1895 1779
      return (*_matching)[node];
1896 1780
    }
1897 1781

	
1898 1782
    /// \brief Return a const reference to the matching map.
1899 1783
    ///
1900 1784
    /// This function returns a const reference to a node map that stores
1901 1785
    /// the matching arc (or edge) incident to each node.
1902 1786
    const MatchingMap& matchingMap() const {
1903 1787
      return *_matching;
1904 1788
    }
1905 1789

	
1906 1790
    /// \brief Return the mate of the given node.
1907 1791
    ///
1908
    /// This function returns the mate of the given node in the found 
1792
    /// This function returns the mate of the given node in the found
1909 1793
    /// matching or \c INVALID if the node is not covered by the matching.
1910 1794
    ///
1911 1795
    /// \pre Either run() or start() must be called before using this function.
1912 1796
    Node mate(const Node& node) const {
1913 1797
      return (*_matching)[node] != INVALID ?
1914 1798
        _graph.target((*_matching)[node]) : INVALID;
1915 1799
    }
1916 1800

	
1917 1801
    /// @}
1918 1802

	
1919 1803
    /// \name Dual Solution
1920 1804
    /// Functions to get the dual solution.\n
1921 1805
    /// Either \ref run() or \ref start() function should be called before
1922 1806
    /// using them.
1923 1807

	
1924 1808
    /// @{
1925 1809

	
1926 1810
    /// \brief Return the value of the dual solution.
1927 1811
    ///
1928
    /// This function returns the value of the dual solution. 
1929
    /// It should be equal to the primal value scaled by \ref dualScale 
1812
    /// This function returns the value of the dual solution.
1813
    /// It should be equal to the primal value scaled by \ref dualScale
1930 1814
    /// "dual scale".
1931 1815
    ///
1932 1816
    /// \pre Either run() or start() must be called before using this function.
1933 1817
    Value dualValue() const {
1934 1818
      Value sum = 0;
1935 1819
      for (NodeIt n(_graph); n != INVALID; ++n) {
1936 1820
        sum += nodeValue(n);
1937 1821
      }
1938 1822
      for (int i = 0; i < blossomNum(); ++i) {
1939 1823
        sum += blossomValue(i) * (blossomSize(i) / 2);
1940 1824
      }
1941 1825
      return sum;
1942 1826
    }
1943 1827

	
1944 1828
    /// \brief Return the dual value (potential) of the given node.
1945 1829
    ///
1946 1830
    /// This function returns the dual value (potential) of the given node.
1947 1831
    ///
1948 1832
    /// \pre Either run() or start() must be called before using this function.
1949 1833
    Value nodeValue(const Node& n) const {
1950 1834
      return (*_node_potential)[n];
1951 1835
    }
1952 1836

	
1953 1837
    /// \brief Return the number of the blossoms in the basis.
... ...
@@ -1960,61 +1844,61 @@
1960 1844
      return _blossom_potential.size();
1961 1845
    }
1962 1846

	
1963 1847
    /// \brief Return the number of the nodes in the given blossom.
1964 1848
    ///
1965 1849
    /// This function returns the number of the nodes in the given blossom.
1966 1850
    ///
1967 1851
    /// \pre Either run() or start() must be called before using this function.
1968 1852
    /// \see BlossomIt
1969 1853
    int blossomSize(int k) const {
1970 1854
      return _blossom_potential[k].end - _blossom_potential[k].begin;
1971 1855
    }
1972 1856

	
1973 1857
    /// \brief Return the dual value (ptential) of the given blossom.
1974 1858
    ///
1975 1859
    /// This function returns the dual value (ptential) of the given blossom.
1976 1860
    ///
1977 1861
    /// \pre Either run() or start() must be called before using this function.
1978 1862
    Value blossomValue(int k) const {
1979 1863
      return _blossom_potential[k].value;
1980 1864
    }
1981 1865

	
1982 1866
    /// \brief Iterator for obtaining the nodes of a blossom.
1983 1867
    ///
1984
    /// This class provides an iterator for obtaining the nodes of the 
1868
    /// This class provides an iterator for obtaining the nodes of the
1985 1869
    /// given blossom. It lists a subset of the nodes.
1986
    /// Before using this iterator, you must allocate a 
1870
    /// Before using this iterator, you must allocate a
1987 1871
    /// MaxWeightedMatching class and execute it.
1988 1872
    class BlossomIt {
1989 1873
    public:
1990 1874

	
1991 1875
      /// \brief Constructor.
1992 1876
      ///
1993 1877
      /// Constructor to get the nodes of the given variable.
1994 1878
      ///
1995
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
1996
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
1879
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
1880
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
1997 1881
      /// called before initializing this iterator.
1998 1882
      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
1999 1883
        : _algorithm(&algorithm)
2000 1884
      {
2001 1885
        _index = _algorithm->_blossom_potential[variable].begin;
2002 1886
        _last = _algorithm->_blossom_potential[variable].end;
2003 1887
      }
2004 1888

	
2005 1889
      /// \brief Conversion to \c Node.
2006 1890
      ///
2007 1891
      /// Conversion to \c Node.
2008 1892
      operator Node() const {
2009 1893
        return _algorithm->_blossom_node_list[_index];
2010 1894
      }
2011 1895

	
2012 1896
      /// \brief Increment operator.
2013 1897
      ///
2014 1898
      /// Increment operator.
2015 1899
      BlossomIt& operator++() {
2016 1900
        ++_index;
2017 1901
        return *this;
2018 1902
      }
2019 1903

	
2020 1904
      /// \brief Validity checking
... ...
@@ -2025,82 +1909,82 @@
2025 1909
      /// \brief Validity checking
2026 1910
      ///
2027 1911
      /// Checks whether the iterator is valid.
2028 1912
      bool operator!=(Invalid) const { return _index != _last; }
2029 1913

	
2030 1914
    private:
2031 1915
      const MaxWeightedMatching* _algorithm;
2032 1916
      int _last;
2033 1917
      int _index;
2034 1918
    };
2035 1919

	
2036 1920
    /// @}
2037 1921

	
2038 1922
  };
2039 1923

	
2040 1924
  /// \ingroup matching
2041 1925
  ///
2042 1926
  /// \brief Weighted perfect matching in general graphs
2043 1927
  ///
2044 1928
  /// This class provides an efficient implementation of Edmond's
2045 1929
  /// maximum weighted perfect matching algorithm. The implementation
2046 1930
  /// is based on extensive use of priority queues and provides
2047 1931
  /// \f$O(nm\log n)\f$ time complexity.
2048 1932
  ///
2049
  /// The maximum weighted perfect matching problem is to find a subset of 
2050
  /// the edges in an undirected graph with maximum overall weight for which 
1933
  /// The maximum weighted perfect matching problem is to find a subset of
1934
  /// the edges in an undirected graph with maximum overall weight for which
2051 1935
  /// each node has exactly one incident edge.
2052 1936
  /// It can be formulated with the following linear program.
2053 1937
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
2054 1938
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
2055 1939
      \quad \forall B\in\mathcal{O}\f] */
2056 1940
  /// \f[x_e \ge 0\quad \forall e\in E\f]
2057 1941
  /// \f[\max \sum_{e\in E}x_ew_e\f]
2058 1942
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
2059 1943
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
2060 1944
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
2061 1945
  /// subsets of the nodes.
2062 1946
  ///
2063 1947
  /// The algorithm calculates an optimal matching and a proof of the
2064 1948
  /// optimality. The solution of the dual problem can be used to check
2065 1949
  /// the result of the algorithm. The dual linear problem is the
2066 1950
  /// following.
2067 1951
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
2068 1952
      w_{uv} \quad \forall uv\in E\f] */
2069 1953
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
2070 1954
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
2071 1955
      \frac{\vert B \vert - 1}{2}z_B\f] */
2072 1956
  ///
2073
  /// The algorithm can be executed with the run() function. 
1957
  /// The algorithm can be executed with the run() function.
2074 1958
  /// After it the matching (the primal solution) and the dual solution
2075
  /// can be obtained using the query functions and the 
2076
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
2077
  /// which is able to iterate on the nodes of a blossom. 
1959
  /// can be obtained using the query functions and the
1960
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
1961
  /// which is able to iterate on the nodes of a blossom.
2078 1962
  /// If the value type is integer, then the dual solution is multiplied
2079 1963
  /// by \ref MaxWeightedMatching::dualScale "4".
2080 1964
  ///
2081 1965
  /// \tparam GR The undirected graph type the algorithm runs on.
2082
  /// \tparam WM The type edge weight map. The default type is 
1966
  /// \tparam WM The type edge weight map. The default type is
2083 1967
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
2084 1968
#ifdef DOXYGEN
2085 1969
  template <typename GR, typename WM>
2086 1970
#else
2087 1971
  template <typename GR,
2088 1972
            typename WM = typename GR::template EdgeMap<int> >
2089 1973
#endif
2090 1974
  class MaxWeightedPerfectMatching {
2091 1975
  public:
2092 1976

	
2093 1977
    /// The graph type of the algorithm
2094 1978
    typedef GR Graph;
2095 1979
    /// The type of the edge weight map
2096 1980
    typedef WM WeightMap;
2097 1981
    /// The value type of the edge weights
2098 1982
    typedef typename WeightMap::Value Value;
2099 1983

	
2100 1984
    /// \brief Scaling factor for dual solution
2101 1985
    ///
2102 1986
    /// Scaling factor for dual solution, it is equal to 4 or 1
2103 1987
    /// according to the value type.
2104 1988
    static const int dualScale =
2105 1989
      std::numeric_limits<Value>::is_integer ? 4 : 1;
2106 1990

	
... ...
@@ -2212,51 +2096,48 @@
2212 2096
        _node_heap_index = new IntArcMap(_graph);
2213 2097
        _node_data = new RangeMap<NodeData>(_node_num,
2214 2098
                                            NodeData(*_node_heap_index));
2215 2099
      }
2216 2100

	
2217 2101
      if (!_tree_set) {
2218 2102
        _tree_set_index = new IntIntMap(_blossom_num);
2219 2103
        _tree_set = new TreeSet(*_tree_set_index);
2220 2104
      }
2221 2105
      if (!_delta2) {
2222 2106
        _delta2_index = new IntIntMap(_blossom_num);
2223 2107
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
2224 2108
      }
2225 2109
      if (!_delta3) {
2226 2110
        _delta3_index = new IntEdgeMap(_graph);
2227 2111
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
2228 2112
      }
2229 2113
      if (!_delta4) {
2230 2114
        _delta4_index = new IntIntMap(_blossom_num);
2231 2115
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
2232 2116
      }
2233 2117
    }
2234 2118

	
2235 2119
    void destroyStructures() {
2236
      _node_num = countNodes(_graph);
2237
      _blossom_num = _node_num * 3 / 2;
2238

	
2239 2120
      if (_matching) {
2240 2121
        delete _matching;
2241 2122
      }
2242 2123
      if (_node_potential) {
2243 2124
        delete _node_potential;
2244 2125
      }
2245 2126
      if (_blossom_set) {
2246 2127
        delete _blossom_index;
2247 2128
        delete _blossom_set;
2248 2129
        delete _blossom_data;
2249 2130
      }
2250 2131

	
2251 2132
      if (_node_index) {
2252 2133
        delete _node_index;
2253 2134
        delete _node_heap_index;
2254 2135
        delete _node_data;
2255 2136
      }
2256 2137

	
2257 2138
      if (_tree_set) {
2258 2139
        delete _tree_set_index;
2259 2140
        delete _tree_set;
2260 2141
      }
2261 2142
      if (_delta2) {
2262 2143
        delete _delta2_index;
... ...
@@ -2970,50 +2851,50 @@
2970 2851
      }
2971 2852
    }
2972 2853

	
2973 2854
    /// \brief Start the algorithm
2974 2855
    ///
2975 2856
    /// This function starts the algorithm.
2976 2857
    ///
2977 2858
    /// \pre \ref init() must be called before using this function.
2978 2859
    bool start() {
2979 2860
      enum OpType {
2980 2861
        D2, D3, D4
2981 2862
      };
2982 2863

	
2983 2864
      int unmatched = _node_num;
2984 2865
      while (unmatched > 0) {
2985 2866
        Value d2 = !_delta2->empty() ?
2986 2867
          _delta2->prio() : std::numeric_limits<Value>::max();
2987 2868

	
2988 2869
        Value d3 = !_delta3->empty() ?
2989 2870
          _delta3->prio() : std::numeric_limits<Value>::max();
2990 2871

	
2991 2872
        Value d4 = !_delta4->empty() ?
2992 2873
          _delta4->prio() : std::numeric_limits<Value>::max();
2993 2874

	
2994
        _delta_sum = d2; OpType ot = D2;
2995
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
2875
        _delta_sum = d3; OpType ot = D3;
2876
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
2996 2877
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
2997 2878

	
2998 2879
        if (_delta_sum == std::numeric_limits<Value>::max()) {
2999 2880
          return false;
3000 2881
        }
3001 2882

	
3002 2883
        switch (ot) {
3003 2884
        case D2:
3004 2885
          {
3005 2886
            int blossom = _delta2->top();
3006 2887
            Node n = _blossom_set->classTop(blossom);
3007 2888
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
3008 2889
            extendOnArc(e);
3009 2890
          }
3010 2891
          break;
3011 2892
        case D3:
3012 2893
          {
3013 2894
            Edge e = _delta3->top();
3014 2895

	
3015 2896
            int left_blossom = _blossom_set->find(_graph.u(e));
3016 2897
            int right_blossom = _blossom_set->find(_graph.v(e));
3017 2898

	
3018 2899
            if (left_blossom == right_blossom) {
3019 2900
              _delta3->pop();
... ...
@@ -3034,122 +2915,122 @@
3034 2915
          break;
3035 2916
        }
3036 2917
      }
3037 2918
      extractMatching();
3038 2919
      return true;
3039 2920
    }
3040 2921

	
3041 2922
    /// \brief Run the algorithm.
3042 2923
    ///
3043 2924
    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
3044 2925
    ///
3045 2926
    /// \note mwpm.run() is just a shortcut of the following code.
3046 2927
    /// \code
3047 2928
    ///   mwpm.init();
3048 2929
    ///   mwpm.start();
3049 2930
    /// \endcode
3050 2931
    bool run() {
3051 2932
      init();
3052 2933
      return start();
3053 2934
    }
3054 2935

	
3055 2936
    /// @}
3056 2937

	
3057 2938
    /// \name Primal Solution
3058
    /// Functions to get the primal solution, i.e. the maximum weighted 
2939
    /// Functions to get the primal solution, i.e. the maximum weighted
3059 2940
    /// perfect matching.\n
3060 2941
    /// Either \ref run() or \ref start() function should be called before
3061 2942
    /// using them.
3062 2943

	
3063 2944
    /// @{
3064 2945

	
3065 2946
    /// \brief Return the weight of the matching.
3066 2947
    ///
3067 2948
    /// This function returns the weight of the found matching.
3068 2949
    ///
3069 2950
    /// \pre Either run() or start() must be called before using this function.
3070 2951
    Value matchingWeight() const {
3071 2952
      Value sum = 0;
3072 2953
      for (NodeIt n(_graph); n != INVALID; ++n) {
3073 2954
        if ((*_matching)[n] != INVALID) {
3074 2955
          sum += _weight[(*_matching)[n]];
3075 2956
        }
3076 2957
      }
3077
      return sum /= 2;
2958
      return sum / 2;
3078 2959
    }
3079 2960

	
3080 2961
    /// \brief Return \c true if the given edge is in the matching.
3081 2962
    ///
3082
    /// This function returns \c true if the given edge is in the found 
2963
    /// This function returns \c true if the given edge is in the found
3083 2964
    /// matching.
3084 2965
    ///
3085 2966
    /// \pre Either run() or start() must be called before using this function.
3086 2967
    bool matching(const Edge& edge) const {
3087 2968
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
3088 2969
    }
3089 2970

	
3090 2971
    /// \brief Return the matching arc (or edge) incident to the given node.
3091 2972
    ///
3092 2973
    /// This function returns the matching arc (or edge) incident to the
3093
    /// given node in the found matching or \c INVALID if the node is 
2974
    /// given node in the found matching or \c INVALID if the node is
3094 2975
    /// not covered by the matching.
3095 2976
    ///
3096 2977
    /// \pre Either run() or start() must be called before using this function.
3097 2978
    Arc matching(const Node& node) const {
3098 2979
      return (*_matching)[node];
3099 2980
    }
3100 2981

	
3101 2982
    /// \brief Return a const reference to the matching map.
3102 2983
    ///
3103 2984
    /// This function returns a const reference to a node map that stores
3104 2985
    /// the matching arc (or edge) incident to each node.
3105 2986
    const MatchingMap& matchingMap() const {
3106 2987
      return *_matching;
3107 2988
    }
3108 2989

	
3109 2990
    /// \brief Return the mate of the given node.
3110 2991
    ///
3111
    /// This function returns the mate of the given node in the found 
2992
    /// This function returns the mate of the given node in the found
3112 2993
    /// matching or \c INVALID if the node is not covered by the matching.
3113 2994
    ///
3114 2995
    /// \pre Either run() or start() must be called before using this function.
3115 2996
    Node mate(const Node& node) const {
3116 2997
      return _graph.target((*_matching)[node]);
3117 2998
    }
3118 2999

	
3119 3000
    /// @}
3120 3001

	
3121 3002
    /// \name Dual Solution
3122 3003
    /// Functions to get the dual solution.\n
3123 3004
    /// Either \ref run() or \ref start() function should be called before
3124 3005
    /// using them.
3125 3006

	
3126 3007
    /// @{
3127 3008

	
3128 3009
    /// \brief Return the value of the dual solution.
3129 3010
    ///
3130
    /// This function returns the value of the dual solution. 
3131
    /// It should be equal to the primal value scaled by \ref dualScale 
3011
    /// This function returns the value of the dual solution.
3012
    /// It should be equal to the primal value scaled by \ref dualScale
3132 3013
    /// "dual scale".
3133 3014
    ///
3134 3015
    /// \pre Either run() or start() must be called before using this function.
3135 3016
    Value dualValue() const {
3136 3017
      Value sum = 0;
3137 3018
      for (NodeIt n(_graph); n != INVALID; ++n) {
3138 3019
        sum += nodeValue(n);
3139 3020
      }
3140 3021
      for (int i = 0; i < blossomNum(); ++i) {
3141 3022
        sum += blossomValue(i) * (blossomSize(i) / 2);
3142 3023
      }
3143 3024
      return sum;
3144 3025
    }
3145 3026

	
3146 3027
    /// \brief Return the dual value (potential) of the given node.
3147 3028
    ///
3148 3029
    /// This function returns the dual value (potential) of the given node.
3149 3030
    ///
3150 3031
    /// \pre Either run() or start() must be called before using this function.
3151 3032
    Value nodeValue(const Node& n) const {
3152 3033
      return (*_node_potential)[n];
3153 3034
    }
3154 3035

	
3155 3036
    /// \brief Return the number of the blossoms in the basis.
... ...
@@ -3162,83 +3043,83 @@
3162 3043
      return _blossom_potential.size();
3163 3044
    }
3164 3045

	
3165 3046
    /// \brief Return the number of the nodes in the given blossom.
3166 3047
    ///
3167 3048
    /// This function returns the number of the nodes in the given blossom.
3168 3049
    ///
3169 3050
    /// \pre Either run() or start() must be called before using this function.
3170 3051
    /// \see BlossomIt
3171 3052
    int blossomSize(int k) const {
3172 3053
      return _blossom_potential[k].end - _blossom_potential[k].begin;
3173 3054
    }
3174 3055

	
3175 3056
    /// \brief Return the dual value (ptential) of the given blossom.
3176 3057
    ///
3177 3058
    /// This function returns the dual value (ptential) of the given blossom.
3178 3059
    ///
3179 3060
    /// \pre Either run() or start() must be called before using this function.
3180 3061
    Value blossomValue(int k) const {
3181 3062
      return _blossom_potential[k].value;
3182 3063
    }
3183 3064

	
3184 3065
    /// \brief Iterator for obtaining the nodes of a blossom.
3185 3066
    ///
3186
    /// This class provides an iterator for obtaining the nodes of the 
3067
    /// This class provides an iterator for obtaining the nodes of the
3187 3068
    /// given blossom. It lists a subset of the nodes.
3188
    /// Before using this iterator, you must allocate a 
3069
    /// Before using this iterator, you must allocate a
3189 3070
    /// MaxWeightedPerfectMatching class and execute it.
3190 3071
    class BlossomIt {
3191 3072
    public:
3192 3073

	
3193 3074
      /// \brief Constructor.
3194 3075
      ///
3195 3076
      /// Constructor to get the nodes of the given variable.
3196 3077
      ///
3197
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
3198
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
3078
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
3079
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
3199 3080
      /// must be called before initializing this iterator.
3200 3081
      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
3201 3082
        : _algorithm(&algorithm)
3202 3083
      {
3203 3084
        _index = _algorithm->_blossom_potential[variable].begin;
3204 3085
        _last = _algorithm->_blossom_potential[variable].end;
3205 3086
      }
3206 3087

	
3207 3088
      /// \brief Conversion to \c Node.
3208 3089
      ///
3209 3090
      /// Conversion to \c Node.
3210 3091
      operator Node() const {
3211 3092
        return _algorithm->_blossom_node_list[_index];
3212 3093
      }
3213 3094

	
3214 3095
      /// \brief Increment operator.
3215 3096
      ///
3216 3097
      /// Increment operator.
3217 3098
      BlossomIt& operator++() {
3218 3099
        ++_index;
3219 3100
        return *this;
3220 3101
      }
3221 3102

	
3222 3103
      /// \brief Validity checking
3223 3104
      ///
3224 3105
      /// This function checks whether the iterator is invalid.
3225 3106
      bool operator==(Invalid) const { return _index == _last; }
3226 3107

	
3227 3108
      /// \brief Validity checking
3228 3109
      ///
3229 3110
      /// This function checks whether the iterator is valid.
3230 3111
      bool operator!=(Invalid) const { return _index != _last; }
3231 3112

	
3232 3113
    private:
3233 3114
      const MaxWeightedPerfectMatching* _algorithm;
3234 3115
      int _last;
3235 3116
      int _index;
3236 3117
    };
3237 3118

	
3238 3119
    /// @}
3239 3120

	
3240 3121
  };
3241 3122

	
3242 3123
} //END OF NAMESPACE LEMON
3243 3124

	
3244
#endif //LEMON_MAX_MATCHING_H
3125
#endif //LEMON_MATCHING_H
0 comments (0 inline)