# HG changeset patch
# User Balazs Dezso <deba@inf.elte.hu>
# Date 1267712459 -3600
# Node ID 41d7ac528c3a59d8b7cad357b6cacaa493a1c89f
# Parent  86613aa28a0ce5afcae34ad41acd910079f97394
Uniforming primal scale to 2 (#314)

diff -r 86613aa28a0c -r 41d7ac528c3a lemon/fractional_matching.h
--- a/lemon/fractional_matching.h	Thu Mar 04 10:17:02 2010 +0100
+++ b/lemon/fractional_matching.h	Thu Mar 04 15:20:59 2010 +0100
@@ -658,10 +658,11 @@
   /// After it the matching (the primal solution) and the dual solution
   /// can be obtained using the query functions.
   ///
-  /// If the value type is integer, then the primal and the dual
-  /// solutions are multiplied by
-  /// \ref MaxWeightedFractionalMatching::primalScale "2" and
-  /// \ref MaxWeightedFractionalMatching::dualScale "4" respectively.
+  /// The primal solution is multiplied by
+  /// \ref MaxWeightedFractionalMatching::primalScale "2".
+  /// If the value type is integer, then the dual
+  /// solution is scaled by
+  /// \ref MaxWeightedFractionalMatching::dualScale "4".
   ///
   /// \tparam GR The undirected graph type the algorithm runs on.
   /// \tparam WM The type edge weight map. The default type is
@@ -688,10 +689,8 @@
 
     /// \brief Scaling factor for primal solution
     ///
-    /// Scaling factor for primal solution. It is equal to 2 or 1
-    /// according to the value type.
-    static const int primalScale =
-      std::numeric_limits<Value>::is_integer ? 2 : 1;
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
 
     /// \brief Scaling factor for dual solution
     ///
@@ -1329,10 +1328,9 @@
     /// "primal scale".
     ///
     /// \pre Either run() or start() must be called before using this function.
-    Value matching(const Edge& edge) const {
-      return Value(edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
-        * primalScale / 2 + Value(edge == (*_matching)[_graph.v(edge)] ? 1 : 0)
-        * primalScale / 2;
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
+        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
     }
 
     /// \brief Return the fractional matching arc (or edge) incident
@@ -1423,11 +1421,12 @@
   /// The algorithm can be executed with the run() function.
   /// After it the matching (the primal solution) and the dual solution
   /// can be obtained using the query functions.
-
-  /// If the value type is integer, then the primal and the dual
-  /// solutions are multiplied by
-  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2" and
-  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4" respectively.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
+  /// If the value type is integer, then the dual
+  /// solution is scaled by
+  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
   ///
   /// \tparam GR The undirected graph type the algorithm runs on.
   /// \tparam WM The type edge weight map. The default type is
@@ -1454,10 +1453,8 @@
 
     /// \brief Scaling factor for primal solution
     ///
-    /// Scaling factor for primal solution. It is equal to 2 or 1
-    /// according to the value type.
-    static const int primalScale =
-      std::numeric_limits<Value>::is_integer ? 2 : 1;
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
 
     /// \brief Scaling factor for dual solution
     ///
@@ -2064,10 +2061,9 @@
     /// "primal scale".
     ///
     /// \pre Either run() or start() must be called before using this function.
-    Value matching(const Edge& edge) const {
-      return Value(edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
-        * primalScale / 2 + Value(edge == (*_matching)[_graph.v(edge)] ? 1 : 0)
-        * primalScale / 2;
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
+        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
     }
 
     /// \brief Return the fractional matching arc (or edge) incident
diff -r 86613aa28a0c -r 41d7ac528c3a test/fractional_matching_test.cc
--- a/test/fractional_matching_test.cc	Thu Mar 04 10:17:02 2010 +0100
+++ b/test/fractional_matching_test.cc	Thu Mar 04 15:20:59 2010 +0100
@@ -236,6 +236,12 @@
   }
   check(pv == mfm.matchingSize(), "Wrong matching size");
 
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mfm.matching(graph.v(e)) ? 1 : 0) == 
+          mfm.matching(e), "Invalid matching");
+  }
+
   SmartGraph::NodeMap<bool> processed(graph, false);
   for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
     if (processed[n]) continue;
@@ -284,6 +290,11 @@
       check(mfm.matching(n) != INVALID, "Invalid matching");
       check(indeg == 1, "Invalid matching");
     }
+    for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+      check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
+            (e == mfm.matching(graph.v(e)) ? 1 : 0) == 
+            mfm.matching(e), "Invalid matching");
+    }
   } else {
     int anum = 0, bnum = 0;
     SmartGraph::NodeMap<bool> neighbours(graph, false);
@@ -337,6 +348,12 @@
     }
   }
 
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mwfm.matching(graph.v(e)) ? 1 : 0) == 
+          mwfm.matching(e), "Invalid matching");
+  }
+
   int dv = 0;
   for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
     dv += mwfm.nodeValue(n);
@@ -391,6 +408,12 @@
     SmartGraph::Node o = graph.target(mwpfm.matching(n));
   }
 
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mwpfm.matching(graph.v(e)) ? 1 : 0) == 
+          mwpfm.matching(e), "Invalid matching");
+  }
+
   int dv = 0;
   for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
     dv += mwpfm.nodeValue(n);