gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Extend and modify the interface of matching algorithms (#265) - Rename decomposition() to status() in MaxMatching. - Add a new query function statusMap() to MaxMatching. - Add a new query function matchingMap() to all the three classes. - Rename matchingValue() to matchingWeight() in the weighted matching classes.
0 2 0
default
2 files changed with 70 insertions and 23 deletions:
↑ Collapse diff ↑
Show white space 48 line context
... ...
@@ -19,92 +19,94 @@
19 19
#ifndef LEMON_MAX_MATCHING_H
20 20
#define LEMON_MAX_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
  /// for finding a maximum cardinality matching in a general graph. 
43
  /// for finding a maximum cardinality matching in a general undirected graph.
44 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
  /// tight. This decomposition can be obtained by calling \c
57
  /// decomposition() after running the algorithm.
56
  /// tight. This decomposition can be obtained using \ref status() or
57
  /// \ref statusMap() after running the algorithm.
58 58
  ///
59
  /// \tparam GR The graph type the algorithm runs on.
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
    /// The type of the matching map
66 67
    typedef typename Graph::template NodeMap<typename Graph::Arc>
67 68
    MatchingMap;
68 69

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

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

	
89 91
  private:
90 92

	
91 93
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
92 94

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

	
99 101
    const Graph& _graph;
100 102
    MatchingMap* _matching;
101 103
    StatusMap* _status;
102 104

	
103 105
    EarMap* _ear;
104 106

	
105 107
    IntNodeMap* _blossom_set_index;
106 108
    BlossomSet* _blossom_set;
107 109
    NodeIntMap* _blossom_rep;
108 110

	
109 111
    IntNodeMap* _tree_set_index;
110 112
    TreeSet* _tree_set;
... ...
@@ -562,74 +564,91 @@
562 564
        if ((*_matching)[n] != INVALID) {
563 565
          ++size;
564 566
        }
565 567
      }
566 568
      return size / 2;
567 569
    }
568 570

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

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

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

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

	
595 605
    /// @}
596 606

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

	
601 611
    /// @{
602 612

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

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

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

	
619 638
    /// @}
620 639

	
621 640
  };
622 641

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

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

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

	
687 707
    /// \brief Scaling factor for dual solution
688 708
    ///
689 709
    /// Scaling factor for dual solution. It is equal to 4 or 1
690 710
    /// according to the value type.
691 711
    static const int dualScale =
692 712
      std::numeric_limits<Value>::is_integer ? 4 : 1;
693 713

	
694 714
  private:
695 715

	
696 716
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
697 717

	
698 718
    typedef typename Graph::template NodeMap<Value> NodePotential;
699 719
    typedef std::vector<Node> BlossomNodeList;
700 720

	
701 721
    struct BlossomVariable {
702 722
      int begin, end;
703 723
      Value value;
704 724

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

	
... ...
@@ -1808,94 +1828,102 @@
1808 1828
    /// \code
1809 1829
    ///   mwm.init();
1810 1830
    ///   mwm.start();
1811 1831
    /// \endcode
1812 1832
    void run() {
1813 1833
      init();
1814 1834
      start();
1815 1835
    }
1816 1836

	
1817 1837
    /// @}
1818 1838

	
1819 1839
    /// \name Primal Solution
1820 1840
    /// Functions to get the primal solution, i.e. the maximum weighted 
1821 1841
    /// matching.\n
1822 1842
    /// Either \ref run() or \ref start() function should be called before
1823 1843
    /// using them.
1824 1844

	
1825 1845
    /// @{
1826 1846

	
1827 1847
    /// \brief Return the weight of the matching.
1828 1848
    ///
1829 1849
    /// This function returns the weight of the found matching.
1830 1850
    ///
1831 1851
    /// \pre Either run() or start() must be called before using this function.
1832
    Value matchingValue() const {
1852
    Value matchingWeight() const {
1833 1853
      Value sum = 0;
1834 1854
      for (NodeIt n(_graph); n != INVALID; ++n) {
1835 1855
        if ((*_matching)[n] != INVALID) {
1836 1856
          sum += _weight[(*_matching)[n]];
1837 1857
        }
1838 1858
      }
1839 1859
      return sum /= 2;
1840 1860
    }
1841 1861

	
1842 1862
    /// \brief Return the size (cardinality) of the matching.
1843 1863
    ///
1844 1864
    /// This function returns the size (cardinality) of the found matching.
1845 1865
    ///
1846 1866
    /// \pre Either run() or start() must be called before using this function.
1847 1867
    int matchingSize() const {
1848 1868
      int num = 0;
1849 1869
      for (NodeIt n(_graph); n != INVALID; ++n) {
1850 1870
        if ((*_matching)[n] != INVALID) {
1851 1871
          ++num;
1852 1872
        }
1853 1873
      }
1854 1874
      return num /= 2;
1855 1875
    }
1856 1876

	
1857 1877
    /// \brief Return \c true if the given edge is in the matching.
1858 1878
    ///
1859 1879
    /// This function returns \c true if the given edge is in the found 
1860 1880
    /// matching.
1861 1881
    ///
1862 1882
    /// \pre Either run() or start() must be called before using this function.
1863 1883
    bool matching(const Edge& edge) const {
1864 1884
      return edge == (*_matching)[_graph.u(edge)];
1865 1885
    }
1866 1886

	
1867 1887
    /// \brief Return the matching arc (or edge) incident to the given node.
1868 1888
    ///
1869 1889
    /// This function returns the matching arc (or edge) incident to the
1870 1890
    /// given node in the found matching or \c INVALID if the node is 
1871 1891
    /// not covered by the matching.
1872 1892
    ///
1873 1893
    /// \pre Either run() or start() must be called before using this function.
1874 1894
    Arc matching(const Node& node) const {
1875 1895
      return (*_matching)[node];
1876 1896
    }
1877 1897

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

	
1878 1906
    /// \brief Return the mate of the given node.
1879 1907
    ///
1880 1908
    /// This function returns the mate of the given node in the found 
1881 1909
    /// matching or \c INVALID if the node is not covered by the matching.
1882 1910
    ///
1883 1911
    /// \pre Either run() or start() must be called before using this function.
1884 1912
    Node mate(const Node& node) const {
1885 1913
      return (*_matching)[node] != INVALID ?
1886 1914
        _graph.target((*_matching)[node]) : INVALID;
1887 1915
    }
1888 1916

	
1889 1917
    /// @}
1890 1918

	
1891 1919
    /// \name Dual Solution
1892 1920
    /// Functions to get the dual solution.\n
1893 1921
    /// Either \ref run() or \ref start() function should be called before
1894 1922
    /// using them.
1895 1923

	
1896 1924
    /// @{
1897 1925

	
1898 1926
    /// \brief Return the value of the dual solution.
1899 1927
    ///
1900 1928
    /// This function returns the value of the dual solution. 
1901 1929
    /// It should be equal to the primal value scaled by \ref dualScale 
... ...
@@ -2029,74 +2057,75 @@
2029 2057
  /// \f[\max \sum_{e\in E}x_ew_e\f]
2030 2058
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
2031 2059
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
2032 2060
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
2033 2061
  /// subsets of the nodes.
2034 2062
  ///
2035 2063
  /// The algorithm calculates an optimal matching and a proof of the
2036 2064
  /// optimality. The solution of the dual problem can be used to check
2037 2065
  /// the result of the algorithm. The dual linear problem is the
2038 2066
  /// following.
2039 2067
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
2040 2068
      w_{uv} \quad \forall uv\in E\f] */
2041 2069
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
2042 2070
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
2043 2071
      \frac{\vert B \vert - 1}{2}z_B\f] */
2044 2072
  ///
2045 2073
  /// The algorithm can be executed with the run() function. 
2046 2074
  /// After it the matching (the primal solution) and the dual solution
2047 2075
  /// can be obtained using the query functions and the 
2048 2076
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
2049 2077
  /// which is able to iterate on the nodes of a blossom. 
2050 2078
  /// If the value type is integer, then the dual solution is multiplied
2051 2079
  /// by \ref MaxWeightedMatching::dualScale "4".
2052 2080
  ///
2053
  /// \tparam GR The graph type the algorithm runs on.
2081
  /// \tparam GR The undirected graph type the algorithm runs on.
2054 2082
  /// \tparam WM The type edge weight map. The default type is 
2055 2083
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
2056 2084
#ifdef DOXYGEN
2057 2085
  template <typename GR, typename WM>
2058 2086
#else
2059 2087
  template <typename GR,
2060 2088
            typename WM = typename GR::template EdgeMap<int> >
2061 2089
#endif
2062 2090
  class MaxWeightedPerfectMatching {
2063 2091
  public:
2064 2092

	
2065 2093
    /// The graph type of the algorithm
2066 2094
    typedef GR Graph;
2067 2095
    /// The type of the edge weight map
2068 2096
    typedef WM WeightMap;
2069 2097
    /// The value type of the edge weights
2070 2098
    typedef typename WeightMap::Value Value;
2071 2099

	
2072 2100
    /// \brief Scaling factor for dual solution
2073 2101
    ///
2074 2102
    /// Scaling factor for dual solution, it is equal to 4 or 1
2075 2103
    /// according to the value type.
2076 2104
    static const int dualScale =
2077 2105
      std::numeric_limits<Value>::is_integer ? 4 : 1;
2078 2106

	
2107
    /// The type of the matching map
2079 2108
    typedef typename Graph::template NodeMap<typename Graph::Arc>
2080 2109
    MatchingMap;
2081 2110

	
2082 2111
  private:
2083 2112

	
2084 2113
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2085 2114

	
2086 2115
    typedef typename Graph::template NodeMap<Value> NodePotential;
2087 2116
    typedef std::vector<Node> BlossomNodeList;
2088 2117

	
2089 2118
    struct BlossomVariable {
2090 2119
      int begin, end;
2091 2120
      Value value;
2092 2121

	
2093 2122
      BlossomVariable(int _begin, int _end, Value _value)
2094 2123
        : begin(_begin), end(_end), value(_value) {}
2095 2124

	
2096 2125
    };
2097 2126

	
2098 2127
    typedef std::vector<BlossomVariable> BlossomPotential;
2099 2128

	
2100 2129
    const Graph& _graph;
2101 2130
    const WeightMap& _weight;
2102 2131

	
... ...
@@ -3017,79 +3046,87 @@
3017 3046
    /// \code
3018 3047
    ///   mwpm.init();
3019 3048
    ///   mwpm.start();
3020 3049
    /// \endcode
3021 3050
    bool run() {
3022 3051
      init();
3023 3052
      return start();
3024 3053
    }
3025 3054

	
3026 3055
    /// @}
3027 3056

	
3028 3057
    /// \name Primal Solution
3029 3058
    /// Functions to get the primal solution, i.e. the maximum weighted 
3030 3059
    /// perfect matching.\n
3031 3060
    /// Either \ref run() or \ref start() function should be called before
3032 3061
    /// using them.
3033 3062

	
3034 3063
    /// @{
3035 3064

	
3036 3065
    /// \brief Return the weight of the matching.
3037 3066
    ///
3038 3067
    /// This function returns the weight of the found matching.
3039 3068
    ///
3040 3069
    /// \pre Either run() or start() must be called before using this function.
3041
    Value matchingValue() const {
3070
    Value matchingWeight() const {
3042 3071
      Value sum = 0;
3043 3072
      for (NodeIt n(_graph); n != INVALID; ++n) {
3044 3073
        if ((*_matching)[n] != INVALID) {
3045 3074
          sum += _weight[(*_matching)[n]];
3046 3075
        }
3047 3076
      }
3048 3077
      return sum /= 2;
3049 3078
    }
3050 3079

	
3051 3080
    /// \brief Return \c true if the given edge is in the matching.
3052 3081
    ///
3053 3082
    /// This function returns \c true if the given edge is in the found 
3054 3083
    /// matching.
3055 3084
    ///
3056 3085
    /// \pre Either run() or start() must be called before using this function.
3057 3086
    bool matching(const Edge& edge) const {
3058 3087
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
3059 3088
    }
3060 3089

	
3061 3090
    /// \brief Return the matching arc (or edge) incident to the given node.
3062 3091
    ///
3063 3092
    /// This function returns the matching arc (or edge) incident to the
3064 3093
    /// given node in the found matching or \c INVALID if the node is 
3065 3094
    /// not covered by the matching.
3066 3095
    ///
3067 3096
    /// \pre Either run() or start() must be called before using this function.
3068 3097
    Arc matching(const Node& node) const {
3069 3098
      return (*_matching)[node];
3070 3099
    }
3071 3100

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

	
3072 3109
    /// \brief Return the mate of the given node.
3073 3110
    ///
3074 3111
    /// This function returns the mate of the given node in the found 
3075 3112
    /// matching or \c INVALID if the node is not covered by the matching.
3076 3113
    ///
3077 3114
    /// \pre Either run() or start() must be called before using this function.
3078 3115
    Node mate(const Node& node) const {
3079 3116
      return _graph.target((*_matching)[node]);
3080 3117
    }
3081 3118

	
3082 3119
    /// @}
3083 3120

	
3084 3121
    /// \name Dual Solution
3085 3122
    /// Functions to get the dual solution.\n
3086 3123
    /// Either \ref run() or \ref start() function should be called before
3087 3124
    /// using them.
3088 3125

	
3089 3126
    /// @{
3090 3127

	
3091 3128
    /// \brief Return the value of the dual solution.
3092 3129
    ///
3093 3130
    /// This function returns the value of the dual solution. 
3094 3131
    /// It should be equal to the primal value scaled by \ref dualScale 
3095 3132
    /// "dual scale".
Show white space 48 line context
... ...
@@ -117,167 +117,177 @@
117 117
  typedef concepts::Graph Graph;
118 118
  typedef Graph::Node Node;
119 119
  typedef Graph::Edge Edge;
120 120
  typedef Graph::EdgeMap<bool> MatMap;
121 121

	
122 122
  Graph g;
123 123
  Node n;
124 124
  Edge e;
125 125
  MatMap mat(g);
126 126

	
127 127
  MaxMatching<Graph> mat_test(g);
128 128
  const MaxMatching<Graph>&
129 129
    const_mat_test = mat_test;
130 130

	
131 131
  mat_test.init();
132 132
  mat_test.greedyInit();
133 133
  mat_test.matchingInit(mat);
134 134
  mat_test.startSparse();
135 135
  mat_test.startDense();
136 136
  mat_test.run();
137 137
  
138 138
  const_mat_test.matchingSize();
139 139
  const_mat_test.matching(e);
140 140
  const_mat_test.matching(n);
141
  const MaxMatching<Graph>::MatchingMap& mmap =
142
    const_mat_test.matchingMap();
143
  e = mmap[n];
141 144
  const_mat_test.mate(n);
142 145

	
143 146
  MaxMatching<Graph>::Status stat = 
144
    const_mat_test.decomposition(n);
147
    const_mat_test.status(n);
148
  const MaxMatching<Graph>::StatusMap& smap =
149
    const_mat_test.statusMap();
150
  stat = smap[n];
145 151
  const_mat_test.barrier(n);
146
  
147
  ignore_unused_variable_warning(stat);
148 152
}
149 153

	
150 154
void checkMaxWeightedMatchingCompile()
151 155
{
152 156
  typedef concepts::Graph Graph;
153 157
  typedef Graph::Node Node;
154 158
  typedef Graph::Edge Edge;
155 159
  typedef Graph::EdgeMap<int> WeightMap;
156 160

	
157 161
  Graph g;
158 162
  Node n;
159 163
  Edge e;
160 164
  WeightMap w(g);
161 165

	
162 166
  MaxWeightedMatching<Graph> mat_test(g, w);
163 167
  const MaxWeightedMatching<Graph>&
164 168
    const_mat_test = mat_test;
165 169

	
166 170
  mat_test.init();
167 171
  mat_test.start();
168 172
  mat_test.run();
169 173
  
170
  const_mat_test.matchingValue();
174
  const_mat_test.matchingWeight();
171 175
  const_mat_test.matchingSize();
172 176
  const_mat_test.matching(e);
173 177
  const_mat_test.matching(n);
178
  const MaxWeightedMatching<Graph>::MatchingMap& mmap =
179
    const_mat_test.matchingMap();
180
  e = mmap[n];
174 181
  const_mat_test.mate(n);
175 182
  
176 183
  int k = 0;
177 184
  const_mat_test.dualValue();
178 185
  const_mat_test.nodeValue(n);
179 186
  const_mat_test.blossomNum();
180 187
  const_mat_test.blossomSize(k);
181 188
  const_mat_test.blossomValue(k);
182 189
}
183 190

	
184 191
void checkMaxWeightedPerfectMatchingCompile()
185 192
{
186 193
  typedef concepts::Graph Graph;
187 194
  typedef Graph::Node Node;
188 195
  typedef Graph::Edge Edge;
189 196
  typedef Graph::EdgeMap<int> WeightMap;
190 197

	
191 198
  Graph g;
192 199
  Node n;
193 200
  Edge e;
194 201
  WeightMap w(g);
195 202

	
196 203
  MaxWeightedPerfectMatching<Graph> mat_test(g, w);
197 204
  const MaxWeightedPerfectMatching<Graph>&
198 205
    const_mat_test = mat_test;
199 206

	
200 207
  mat_test.init();
201 208
  mat_test.start();
202 209
  mat_test.run();
203 210
  
204
  const_mat_test.matchingValue();
211
  const_mat_test.matchingWeight();
205 212
  const_mat_test.matching(e);
206 213
  const_mat_test.matching(n);
214
  const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
215
    const_mat_test.matchingMap();
216
  e = mmap[n];
207 217
  const_mat_test.mate(n);
208 218
  
209 219
  int k = 0;
210 220
  const_mat_test.dualValue();
211 221
  const_mat_test.nodeValue(n);
212 222
  const_mat_test.blossomNum();
213 223
  const_mat_test.blossomSize(k);
214 224
  const_mat_test.blossomValue(k);
215 225
}
216 226

	
217 227
void checkMatching(const SmartGraph& graph,
218 228
                   const MaxMatching<SmartGraph>& mm) {
219 229
  int num = 0;
220 230

	
221 231
  IntNodeMap comp_index(graph);
222 232
  UnionFind<IntNodeMap> comp(comp_index);
223 233

	
224 234
  int barrier_num = 0;
225 235

	
226 236
  for (NodeIt n(graph); n != INVALID; ++n) {
227
    check(mm.decomposition(n) == MaxMatching<SmartGraph>::EVEN ||
237
    check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
228 238
          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
229
    if (mm.decomposition(n) == MaxMatching<SmartGraph>::ODD) {
239
    if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
230 240
      ++barrier_num;
231 241
    } else {
232 242
      comp.insert(n);
233 243
    }
234 244
  }
235 245

	
236 246
  for (EdgeIt e(graph); e != INVALID; ++e) {
237 247
    if (mm.matching(e)) {
238 248
      check(e == mm.matching(graph.u(e)), "Wrong matching");
239 249
      check(e == mm.matching(graph.v(e)), "Wrong matching");
240 250
      ++num;
241 251
    }
242
    check(mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
243
          mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
252
    check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
253
          mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
244 254
          "Wrong Gallai-Edmonds decomposition");
245 255

	
246
    check(mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
247
          mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
256
    check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
257
          mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
248 258
          "Wrong Gallai-Edmonds decomposition");
249 259

	
250
    if (mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
251
        mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
260
    if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
261
        mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
252 262
      comp.join(graph.u(e), graph.v(e));
253 263
    }
254 264
  }
255 265

	
256 266
  std::set<int> comp_root;
257 267
  int odd_comp_num = 0;
258 268
  for (NodeIt n(graph); n != INVALID; ++n) {
259
    if (mm.decomposition(n) != MaxMatching<SmartGraph>::ODD) {
269
    if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
260 270
      int root = comp.find(n);
261 271
      if (comp_root.find(root) == comp_root.end()) {
262 272
        comp_root.insert(root);
263 273
        if (comp.size(n) % 2 == 1) {
264 274
          ++odd_comp_num;
265 275
        }
266 276
      }
267 277
    }
268 278
  }
269 279

	
270 280
  check(mm.matchingSize() == num, "Wrong matching");
271 281
  check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
272 282
         "Wrong matching");
273 283
  return;
274 284
}
275 285

	
276 286
void checkWeightedMatching(const SmartGraph& graph,
277 287
                   const SmartGraph::EdgeMap<int>& weight,
278 288
                   const MaxWeightedMatching<SmartGraph>& mwm) {
279 289
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
280 290
    if (graph.u(e) == graph.v(e)) continue;
281 291
    int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
282 292

	
283 293
    for (int i = 0; i < mwm.blossomNum(); ++i) {
0 comments (0 inline)