1 /* -*- mode: C++; indent-tabs-mode: nil; -*- |
1 /* -*- mode: C++; indent-tabs-mode: nil; -*- |
2 * |
2 * |
3 * This file is a part of LEMON, a generic C++ optimization library. |
3 * This file is a part of LEMON, a generic C++ optimization library. |
4 * |
4 * |
5 * Copyright (C) 2003-2009 |
5 * Copyright (C) 2003-2011 |
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 * |
8 * |
9 * Permission to use, modify and distribute this software is granted |
9 * Permission to use, modify and distribute this software is granted |
10 * provided that this copyright notice appears in all copies. For |
10 * provided that this copyright notice appears in all copies. For |
39 /// |
39 /// |
40 /// \brief Maximum cardinality matching in general graphs |
40 /// \brief Maximum cardinality matching in general graphs |
41 /// |
41 /// |
42 /// This class implements Edmonds' alternating forest matching algorithm |
42 /// This class implements Edmonds' alternating forest matching algorithm |
43 /// for finding a maximum cardinality matching in a general undirected graph. |
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 /// (the default is the empty one). |
45 /// (the default is the empty one). |
46 /// |
46 /// |
47 /// The dual solution of the problem is a map of the nodes to |
47 /// The dual solution of the problem is a map of the nodes to |
48 /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D), |
48 /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D), |
49 /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds |
49 /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds |
67 typedef typename Graph::template NodeMap<typename Graph::Arc> |
67 typedef typename Graph::template NodeMap<typename Graph::Arc> |
68 MatchingMap; |
68 MatchingMap; |
69 |
69 |
70 ///\brief Status constants for Gallai-Edmonds decomposition. |
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 ///decomposition of a graph. The nodes with status \c EVEN (or \c D) |
73 ///decomposition of a graph. The nodes with status \c EVEN (or \c D) |
74 ///induce a subgraph with factor-critical components, the nodes with |
74 ///induce a subgraph with factor-critical components, the nodes with |
75 ///status \c ODD (or \c A) form the canonical barrier, and the nodes |
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 ///perfect matching. |
77 ///perfect matching. |
78 enum Status { |
78 enum Status { |
79 EVEN = 1, ///< = 1. (\c D is an alias for \c EVEN.) |
79 EVEN = 1, ///< = 1. (\c D is an alias for \c EVEN.) |
80 D = 1, |
80 D = 1, |
81 MATCHED = 0, ///< = 0. (\c C is an alias for \c MATCHED.) |
81 MATCHED = 0, ///< = 0. (\c C is an alias for \c MATCHED.) |
532 } |
532 } |
533 |
533 |
534 |
534 |
535 /// \brief Run Edmonds' algorithm |
535 /// \brief Run Edmonds' algorithm |
536 /// |
536 /// |
537 /// This function runs Edmonds' algorithm. An additional heuristic of |
537 /// This function runs Edmonds' algorithm. An additional heuristic of |
538 /// postponing shrinks is used for relatively dense graphs |
538 /// postponing shrinks is used for relatively dense graphs |
539 /// (for which <tt>m>=2*n</tt> holds). |
539 /// (for which <tt>m>=2*n</tt> holds). |
540 void run() { |
540 void run() { |
541 if (countEdges(_graph) < 2 * countNodes(_graph)) { |
541 if (countEdges(_graph) < 2 * countNodes(_graph)) { |
542 greedyInit(); |
542 greedyInit(); |
543 startSparse(); |
543 startSparse(); |
554 |
554 |
555 /// @{ |
555 /// @{ |
556 |
556 |
557 /// \brief Return the size (cardinality) of the matching. |
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 /// After run() it returns the size of the maximum matching in the graph. |
560 /// After run() it returns the size of the maximum matching in the graph. |
561 int matchingSize() const { |
561 int matchingSize() const { |
562 int size = 0; |
562 int size = 0; |
563 for (NodeIt n(_graph); n != INVALID; ++n) { |
563 for (NodeIt n(_graph); n != INVALID; ++n) { |
564 if ((*_matching)[n] != INVALID) { |
564 if ((*_matching)[n] != INVALID) { |
568 return size / 2; |
568 return size / 2; |
569 } |
569 } |
570 |
570 |
571 /// \brief Return \c true if the given edge is in the matching. |
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 /// matching. |
574 /// matching. |
575 bool matching(const Edge& edge) const { |
575 bool matching(const Edge& edge) const { |
576 return edge == (*_matching)[_graph.u(edge)]; |
576 return edge == (*_matching)[_graph.u(edge)]; |
577 } |
577 } |
578 |
578 |
579 /// \brief Return the matching arc (or edge) incident to the given node. |
579 /// \brief Return the matching arc (or edge) incident to the given node. |
580 /// |
580 /// |
581 /// This function returns the matching arc (or edge) incident to the |
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 /// not covered by the matching. |
583 /// not covered by the matching. |
584 Arc matching(const Node& n) const { |
584 Arc matching(const Node& n) const { |
585 return (*_matching)[n]; |
585 return (*_matching)[n]; |
586 } |
586 } |
587 |
587 |
593 return *_matching; |
593 return *_matching; |
594 } |
594 } |
595 |
595 |
596 /// \brief Return the mate of the given node. |
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 /// matching or \c INVALID if the node is not covered by the matching. |
599 /// matching or \c INVALID if the node is not covered by the matching. |
600 Node mate(const Node& n) const { |
600 Node mate(const Node& n) const { |
601 return (*_matching)[n] != INVALID ? |
601 return (*_matching)[n] != INVALID ? |
602 _graph.target((*_matching)[n]) : INVALID; |
602 _graph.target((*_matching)[n]) : INVALID; |
603 } |
603 } |
604 |
604 |
605 /// @} |
605 /// @} |
606 |
606 |
607 /// \name Dual Solution |
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 /// decomposition. |
609 /// decomposition. |
610 |
610 |
611 /// @{ |
611 /// @{ |
612 |
612 |
613 /// \brief Return the status of the given node in the Edmonds-Gallai |
613 /// \brief Return the status of the given node in the Edmonds-Gallai |
646 /// This class provides an efficient implementation of Edmond's |
646 /// This class provides an efficient implementation of Edmond's |
647 /// maximum weighted matching algorithm. The implementation is based |
647 /// maximum weighted matching algorithm. The implementation is based |
648 /// on extensive use of priority queues and provides |
648 /// on extensive use of priority queues and provides |
649 /// \f$O(nm\log n)\f$ time complexity. |
649 /// \f$O(nm\log n)\f$ time complexity. |
650 /// |
650 /// |
651 /// The maximum weighted matching problem is to find a subset of the |
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 |
652 /// edges in an undirected graph with maximum overall weight for which |
653 /// each node has at most one incident edge. |
653 /// each node has at most one incident edge. |
654 /// It can be formulated with the following linear program. |
654 /// It can be formulated with the following linear program. |
655 /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f] |
655 /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f] |
656 /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2} |
656 /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2} |
657 \quad \forall B\in\mathcal{O}\f] */ |
657 \quad \forall B\in\mathcal{O}\f] */ |
671 /// \f[y_u \ge 0 \quad \forall u \in V\f] |
671 /// \f[y_u \ge 0 \quad \forall u \in V\f] |
672 /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f] |
672 /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f] |
673 /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}} |
673 /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}} |
674 \frac{\vert B \vert - 1}{2}z_B\f] */ |
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 /// After it the matching (the primal solution) and the dual solution |
677 /// After it the matching (the primal solution) and the dual solution |
678 /// can be obtained using the query functions and the |
678 /// can be obtained using the query functions and the |
679 /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, |
679 /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, |
680 /// which is able to iterate on the nodes of a blossom. |
680 /// which is able to iterate on the nodes of a blossom. |
681 /// If the value type is integer, then the dual solution is multiplied |
681 /// If the value type is integer, then the dual solution is multiplied |
682 /// by \ref MaxWeightedMatching::dualScale "4". |
682 /// by \ref MaxWeightedMatching::dualScale "4". |
683 /// |
683 /// |
684 /// \tparam GR The undirected graph type the algorithm runs on. |
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 /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>". |
686 /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>". |
687 #ifdef DOXYGEN |
687 #ifdef DOXYGEN |
688 template <typename GR, typename WM> |
688 template <typename GR, typename WM> |
689 #else |
689 #else |
690 template <typename GR, |
690 template <typename GR, |
1905 return num /= 2; |
1905 return num /= 2; |
1906 } |
1906 } |
1907 |
1907 |
1908 /// \brief Return \c true if the given edge is in the matching. |
1908 /// \brief Return \c true if the given edge is in the matching. |
1909 /// |
1909 /// |
1910 /// This function returns \c true if the given edge is in the found |
1910 /// This function returns \c true if the given edge is in the found |
1911 /// matching. |
1911 /// matching. |
1912 /// |
1912 /// |
1913 /// \pre Either run() or start() must be called before using this function. |
1913 /// \pre Either run() or start() must be called before using this function. |
1914 bool matching(const Edge& edge) const { |
1914 bool matching(const Edge& edge) const { |
1915 return edge == (*_matching)[_graph.u(edge)]; |
1915 return edge == (*_matching)[_graph.u(edge)]; |
1916 } |
1916 } |
1917 |
1917 |
1918 /// \brief Return the matching arc (or edge) incident to the given node. |
1918 /// \brief Return the matching arc (or edge) incident to the given node. |
1919 /// |
1919 /// |
1920 /// This function returns the matching arc (or edge) incident to the |
1920 /// This function returns the matching arc (or edge) incident to the |
1921 /// given node in the found matching or \c INVALID if the node is |
1921 /// given node in the found matching or \c INVALID if the node is |
1922 /// not covered by the matching. |
1922 /// not covered by the matching. |
1923 /// |
1923 /// |
1924 /// \pre Either run() or start() must be called before using this function. |
1924 /// \pre Either run() or start() must be called before using this function. |
1925 Arc matching(const Node& node) const { |
1925 Arc matching(const Node& node) const { |
1926 return (*_matching)[node]; |
1926 return (*_matching)[node]; |
1934 return *_matching; |
1934 return *_matching; |
1935 } |
1935 } |
1936 |
1936 |
1937 /// \brief Return the mate of the given node. |
1937 /// \brief Return the mate of the given node. |
1938 /// |
1938 /// |
1939 /// This function returns the mate of the given node in the found |
1939 /// This function returns the mate of the given node in the found |
1940 /// matching or \c INVALID if the node is not covered by the matching. |
1940 /// matching or \c INVALID if the node is not covered by the matching. |
1941 /// |
1941 /// |
1942 /// \pre Either run() or start() must be called before using this function. |
1942 /// \pre Either run() or start() must be called before using this function. |
1943 Node mate(const Node& node) const { |
1943 Node mate(const Node& node) const { |
1944 return (*_matching)[node] != INVALID ? |
1944 return (*_matching)[node] != INVALID ? |
1954 |
1954 |
1955 /// @{ |
1955 /// @{ |
1956 |
1956 |
1957 /// \brief Return the value of the dual solution. |
1957 /// \brief Return the value of the dual solution. |
1958 /// |
1958 /// |
1959 /// This function returns the value of the dual solution. |
1959 /// This function returns the value of the dual solution. |
1960 /// It should be equal to the primal value scaled by \ref dualScale |
1960 /// It should be equal to the primal value scaled by \ref dualScale |
1961 /// "dual scale". |
1961 /// "dual scale". |
1962 /// |
1962 /// |
1963 /// \pre Either run() or start() must be called before using this function. |
1963 /// \pre Either run() or start() must be called before using this function. |
1964 Value dualValue() const { |
1964 Value dualValue() const { |
1965 Value sum = 0; |
1965 Value sum = 0; |
2010 return _blossom_potential[k].value; |
2010 return _blossom_potential[k].value; |
2011 } |
2011 } |
2012 |
2012 |
2013 /// \brief Iterator for obtaining the nodes of a blossom. |
2013 /// \brief Iterator for obtaining the nodes of a blossom. |
2014 /// |
2014 /// |
2015 /// This class provides an iterator for obtaining the nodes of the |
2015 /// This class provides an iterator for obtaining the nodes of the |
2016 /// given blossom. It lists a subset of the nodes. |
2016 /// given blossom. It lists a subset of the nodes. |
2017 /// Before using this iterator, you must allocate a |
2017 /// Before using this iterator, you must allocate a |
2018 /// MaxWeightedMatching class and execute it. |
2018 /// MaxWeightedMatching class and execute it. |
2019 class BlossomIt { |
2019 class BlossomIt { |
2020 public: |
2020 public: |
2021 |
2021 |
2022 /// \brief Constructor. |
2022 /// \brief Constructor. |
2023 /// |
2023 /// |
2024 /// Constructor to get the nodes of the given variable. |
2024 /// Constructor to get the nodes of the given variable. |
2025 /// |
2025 /// |
2026 /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or |
2026 /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or |
2027 /// \ref MaxWeightedMatching::start() "algorithm.start()" must be |
2027 /// \ref MaxWeightedMatching::start() "algorithm.start()" must be |
2028 /// called before initializing this iterator. |
2028 /// called before initializing this iterator. |
2029 BlossomIt(const MaxWeightedMatching& algorithm, int variable) |
2029 BlossomIt(const MaxWeightedMatching& algorithm, int variable) |
2030 : _algorithm(&algorithm) |
2030 : _algorithm(&algorithm) |
2031 { |
2031 { |
2032 _index = _algorithm->_blossom_potential[variable].begin; |
2032 _index = _algorithm->_blossom_potential[variable].begin; |
2075 /// This class provides an efficient implementation of Edmond's |
2075 /// This class provides an efficient implementation of Edmond's |
2076 /// maximum weighted perfect matching algorithm. The implementation |
2076 /// maximum weighted perfect matching algorithm. The implementation |
2077 /// is based on extensive use of priority queues and provides |
2077 /// is based on extensive use of priority queues and provides |
2078 /// \f$O(nm\log n)\f$ time complexity. |
2078 /// \f$O(nm\log n)\f$ time complexity. |
2079 /// |
2079 /// |
2080 /// The maximum weighted perfect matching problem is to find a subset of |
2080 /// The maximum weighted perfect matching problem is to find a subset of |
2081 /// the edges in an undirected graph with maximum overall weight for which |
2081 /// the edges in an undirected graph with maximum overall weight for which |
2082 /// each node has exactly one incident edge. |
2082 /// each node has exactly one incident edge. |
2083 /// It can be formulated with the following linear program. |
2083 /// It can be formulated with the following linear program. |
2084 /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f] |
2084 /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f] |
2085 /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2} |
2085 /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2} |
2086 \quad \forall B\in\mathcal{O}\f] */ |
2086 \quad \forall B\in\mathcal{O}\f] */ |
2099 w_{uv} \quad \forall uv\in E\f] */ |
2099 w_{uv} \quad \forall uv\in E\f] */ |
2100 /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f] |
2100 /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f] |
2101 /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}} |
2101 /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}} |
2102 \frac{\vert B \vert - 1}{2}z_B\f] */ |
2102 \frac{\vert B \vert - 1}{2}z_B\f] */ |
2103 /// |
2103 /// |
2104 /// The algorithm can be executed with the run() function. |
2104 /// The algorithm can be executed with the run() function. |
2105 /// After it the matching (the primal solution) and the dual solution |
2105 /// After it the matching (the primal solution) and the dual solution |
2106 /// can be obtained using the query functions and the |
2106 /// can be obtained using the query functions and the |
2107 /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, |
2107 /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, |
2108 /// which is able to iterate on the nodes of a blossom. |
2108 /// which is able to iterate on the nodes of a blossom. |
2109 /// If the value type is integer, then the dual solution is multiplied |
2109 /// If the value type is integer, then the dual solution is multiplied |
2110 /// by \ref MaxWeightedMatching::dualScale "4". |
2110 /// by \ref MaxWeightedMatching::dualScale "4". |
2111 /// |
2111 /// |
2112 /// \tparam GR The undirected graph type the algorithm runs on. |
2112 /// \tparam GR The undirected graph type the algorithm runs on. |
2113 /// \tparam WM The type edge weight map. The default type is |
2113 /// \tparam WM The type edge weight map. The default type is |
2114 /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>". |
2114 /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>". |
2115 #ifdef DOXYGEN |
2115 #ifdef DOXYGEN |
2116 template <typename GR, typename WM> |
2116 template <typename GR, typename WM> |
2117 #else |
2117 #else |
2118 template <typename GR, |
2118 template <typename GR, |
3137 return sum /= 2; |
3137 return sum /= 2; |
3138 } |
3138 } |
3139 |
3139 |
3140 /// \brief Return \c true if the given edge is in the matching. |
3140 /// \brief Return \c true if the given edge is in the matching. |
3141 /// |
3141 /// |
3142 /// This function returns \c true if the given edge is in the found |
3142 /// This function returns \c true if the given edge is in the found |
3143 /// matching. |
3143 /// matching. |
3144 /// |
3144 /// |
3145 /// \pre Either run() or start() must be called before using this function. |
3145 /// \pre Either run() or start() must be called before using this function. |
3146 bool matching(const Edge& edge) const { |
3146 bool matching(const Edge& edge) const { |
3147 return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge; |
3147 return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge; |
3148 } |
3148 } |
3149 |
3149 |
3150 /// \brief Return the matching arc (or edge) incident to the given node. |
3150 /// \brief Return the matching arc (or edge) incident to the given node. |
3151 /// |
3151 /// |
3152 /// This function returns the matching arc (or edge) incident to the |
3152 /// This function returns the matching arc (or edge) incident to the |
3153 /// given node in the found matching or \c INVALID if the node is |
3153 /// given node in the found matching or \c INVALID if the node is |
3154 /// not covered by the matching. |
3154 /// not covered by the matching. |
3155 /// |
3155 /// |
3156 /// \pre Either run() or start() must be called before using this function. |
3156 /// \pre Either run() or start() must be called before using this function. |
3157 Arc matching(const Node& node) const { |
3157 Arc matching(const Node& node) const { |
3158 return (*_matching)[node]; |
3158 return (*_matching)[node]; |
3166 return *_matching; |
3166 return *_matching; |
3167 } |
3167 } |
3168 |
3168 |
3169 /// \brief Return the mate of the given node. |
3169 /// \brief Return the mate of the given node. |
3170 /// |
3170 /// |
3171 /// This function returns the mate of the given node in the found |
3171 /// This function returns the mate of the given node in the found |
3172 /// matching or \c INVALID if the node is not covered by the matching. |
3172 /// matching or \c INVALID if the node is not covered by the matching. |
3173 /// |
3173 /// |
3174 /// \pre Either run() or start() must be called before using this function. |
3174 /// \pre Either run() or start() must be called before using this function. |
3175 Node mate(const Node& node) const { |
3175 Node mate(const Node& node) const { |
3176 return _graph.target((*_matching)[node]); |
3176 return _graph.target((*_matching)[node]); |
3185 |
3185 |
3186 /// @{ |
3186 /// @{ |
3187 |
3187 |
3188 /// \brief Return the value of the dual solution. |
3188 /// \brief Return the value of the dual solution. |
3189 /// |
3189 /// |
3190 /// This function returns the value of the dual solution. |
3190 /// This function returns the value of the dual solution. |
3191 /// It should be equal to the primal value scaled by \ref dualScale |
3191 /// It should be equal to the primal value scaled by \ref dualScale |
3192 /// "dual scale". |
3192 /// "dual scale". |
3193 /// |
3193 /// |
3194 /// \pre Either run() or start() must be called before using this function. |
3194 /// \pre Either run() or start() must be called before using this function. |
3195 Value dualValue() const { |
3195 Value dualValue() const { |
3196 Value sum = 0; |
3196 Value sum = 0; |
3241 return _blossom_potential[k].value; |
3241 return _blossom_potential[k].value; |
3242 } |
3242 } |
3243 |
3243 |
3244 /// \brief Iterator for obtaining the nodes of a blossom. |
3244 /// \brief Iterator for obtaining the nodes of a blossom. |
3245 /// |
3245 /// |
3246 /// This class provides an iterator for obtaining the nodes of the |
3246 /// This class provides an iterator for obtaining the nodes of the |
3247 /// given blossom. It lists a subset of the nodes. |
3247 /// given blossom. It lists a subset of the nodes. |
3248 /// Before using this iterator, you must allocate a |
3248 /// Before using this iterator, you must allocate a |
3249 /// MaxWeightedPerfectMatching class and execute it. |
3249 /// MaxWeightedPerfectMatching class and execute it. |
3250 class BlossomIt { |
3250 class BlossomIt { |
3251 public: |
3251 public: |
3252 |
3252 |
3253 /// \brief Constructor. |
3253 /// \brief Constructor. |
3254 /// |
3254 /// |
3255 /// Constructor to get the nodes of the given variable. |
3255 /// Constructor to get the nodes of the given variable. |
3256 /// |
3256 /// |
3257 /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" |
3257 /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" |
3258 /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" |
3258 /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" |
3259 /// must be called before initializing this iterator. |
3259 /// must be called before initializing this iterator. |
3260 BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable) |
3260 BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable) |
3261 : _algorithm(&algorithm) |
3261 : _algorithm(&algorithm) |
3262 { |
3262 { |
3263 _index = _algorithm->_blossom_potential[variable].begin; |
3263 _index = _algorithm->_blossom_potential[variable].begin; |