[Lemon-commits] deba: r3427 - in lemon/trunk: lemon test

Lemon SVN svn at lemon.cs.elte.hu
Sat Dec 29 16:11:42 CET 2007


Author: deba
Date: Sat Dec 29 16:11:41 2007
New Revision: 3427

Added:
   lemon/trunk/test/max_weighted_matching_test.cc
Modified:
   lemon/trunk/lemon/max_matching.h
   lemon/trunk/test/Makefile.am

Log:
Test program for max weighted matchings



Modified: lemon/trunk/lemon/max_matching.h
==============================================================================
--- lemon/trunk/lemon/max_matching.h	(original)
+++ lemon/trunk/lemon/max_matching.h	Sat Dec 29 16:11:41 2007
@@ -30,7 +30,7 @@
 
 ///\ingroup matching
 ///\file
-///\brief Maximum matching algorithm in undirected graph.
+///\brief Maximum matching algorithms in undirected graph.
 
 namespace lemon {
 
@@ -1467,7 +1467,7 @@
       int b = _blossom_set->find(_ugraph.source(pred));
       int d = _blossom_set->find(_ugraph.source(next));
       
-      int ib, id;
+      int ib = -1, id = -1;
       for (int i = 0; i < int(subblossoms.size()); ++i) {
 	if (subblossoms[i] == b) ib = i;
 	if (subblossoms[i] == d) id = i;
@@ -2654,7 +2654,7 @@
       int b = _blossom_set->find(_ugraph.source(pred));
       int d = _blossom_set->find(_ugraph.source(next));
       
-      int ib, id;
+      int ib = -1, id = -1;
       for (int i = 0; i < int(subblossoms.size()); ++i) {
 	if (subblossoms[i] == b) ib = i;
 	if (subblossoms[i] == d) id = i;

Modified: lemon/trunk/test/Makefile.am
==============================================================================
--- lemon/trunk/test/Makefile.am	(original)
+++ lemon/trunk/test/Makefile.am	Sat Dec 29 16:11:41 2007
@@ -30,6 +30,7 @@
 	test/maps_test \
 	test/matrix_maps_test \
 	test/max_matching_test \
+	test/max_weighted_matching_test \
 	test/min_cost_flow_test \
 	test/path_test \
 	test/polynomial_test \
@@ -79,6 +80,7 @@
 test_maps_test_SOURCES = test/maps_test.cc
 test_matrix_maps_test_SOURCES = test/matrix_maps_test.cc
 test_max_matching_test_SOURCES = test/max_matching_test.cc
+test_max_weighted_matching_test_SOURCES = test/max_weighted_matching_test.cc
 test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
 test_path_test_SOURCES = test/path_test.cc
 test_polynomial_test_SOURCES = test/polynomial_test.cc

Added: lemon/trunk/test/max_weighted_matching_test.cc
==============================================================================
--- (empty file)
+++ lemon/trunk/test/max_weighted_matching_test.cc	Sat Dec 29 16:11:41 2007
@@ -0,0 +1,253 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2007
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <queue>
+#include <cmath>
+#include <cstdlib>
+
+#include "test_tools.h"
+#include <lemon/smart_graph.h>
+#include <lemon/max_matching.h>
+#include <lemon/graph_reader.h>
+
+UGRAPH_TYPEDEFS(SmartUGraph);
+
+using namespace std;
+using namespace lemon;
+
+const int lgfn = 3;
+const std::string lgf[lgfn] = {   
+  "@nodeset\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@uedgeset\n"
+  "label        weight\n"
+  "7    4       0       984\n"
+  "0    7       1       73\n"
+  "7    1       2       204\n"
+  "2    3       3       583\n"
+  "2    7       4       565\n"
+  "2    1       5       582\n"
+  "0    4       6       551\n"
+  "2    5       7       385\n"
+  "1    5       8       561\n"
+  "5    3       9       484\n"
+  "7    5       10      904\n"
+  "3    6       11      47\n"
+  "7    6       12      888\n"
+  "3    0       13      747\n"
+  "6    1       14      310\n"
+  "@end\n",
+
+  "@nodeset\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@uedgeset\n"
+  "label        weight\n"
+  "2    5       0       710\n"
+  "0    5       1       241\n"
+  "2    4       2       856\n"
+  "2    6       3       762\n"
+  "4    1       4       747\n"
+  "6    1       5       962\n"
+  "4    7       6       723\n"
+  "1    7       7       661\n"
+  "2    3       8       376\n"
+  "1    0       9       416\n"
+  "6    7       10      391\n"
+  "@end\n",
+
+  "@nodeset\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@uedgeset\n"
+  "label        weight\n"
+  "6    2       0       553\n"
+  "0    7       1       653\n"
+  "6    3       2       22\n"
+  "4    7       3       846\n"
+  "7    2       4       981\n"
+  "7    6       5       250\n"
+  "5    2       6       539\n"
+  "@end\n"
+};
+
+void checkMatching(const SmartUGraph& ugraph,
+		   const SmartUGraph::UEdgeMap<int>& weight,
+		   const MaxWeightedMatching<SmartUGraph>& mwm) {
+  for (SmartUGraph::UEdgeIt e(ugraph); e != INVALID; ++e) {
+    if (ugraph.source(e) == ugraph.target(e)) continue;
+    int rw = 
+      mwm.nodeValue(ugraph.source(e)) + mwm.nodeValue(ugraph.target(e));
+
+    for (int i = 0; i < mwm.blossomNum(); ++i) {
+      bool s = false, t = false;
+      for (MaxWeightedMatching<SmartUGraph>::BlossomIt n(mwm, i); 
+	   n != INVALID; ++n) {
+	if (ugraph.source(e) == n) s = true;
+	if (ugraph.target(e) == n) t = true;
+      }
+      if (s == true && t == true) {
+	rw += mwm.blossomValue(i);
+      }
+    }
+    rw -= weight[e] * mwm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwm.matching(e), 
+	  "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartUGraph::NodeIt n(ugraph); n != INVALID; ++n) {
+    if (mwm.matching(n) != INVALID) {
+      check(mwm.nodeValue(n) >= 0, "Invalid node value");
+      pv += weight[mwm.matching(n)];
+      SmartUGraph::Node o = ugraph.target(mwm.matching(n));
+      check(mwm.mate(n) == o, "Invalid matching");
+      check(mwm.matching(n) == ugraph.oppositeEdge(mwm.matching(o)), 
+	    "Invalid matching");
+    } else {
+      check(mwm.mate(n) == INVALID, "Invalid matching");
+      check(mwm.nodeValue(n) == 0, "Invalid matching");
+    }
+  }
+
+  int dv = 0;
+  for (SmartUGraph::NodeIt n(ugraph); n != INVALID; ++n) {
+    dv += mwm.nodeValue(n);
+  }
+
+  for (int i = 0; i < mwm.blossomNum(); ++i) {
+    check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
+    check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
+    dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
+  }
+
+  check(pv * mwm.dualScale == dv * 2, "Wrong duality");
+
+  return;
+}
+
+void checkPerfectMatching(const SmartUGraph& ugraph,
+			  const SmartUGraph::UEdgeMap<int>& weight,
+			  const MaxWeightedPerfectMatching<SmartUGraph>& mwpm) {
+  for (SmartUGraph::UEdgeIt e(ugraph); e != INVALID; ++e) {
+    if (ugraph.source(e) == ugraph.target(e)) continue;
+    int rw = 
+      mwpm.nodeValue(ugraph.source(e)) + mwpm.nodeValue(ugraph.target(e));
+
+    for (int i = 0; i < mwpm.blossomNum(); ++i) {
+      bool s = false, t = false;
+      for (MaxWeightedPerfectMatching<SmartUGraph>::BlossomIt n(mwpm, i); 
+	   n != INVALID; ++n) {
+	if (ugraph.source(e) == n) s = true;
+	if (ugraph.target(e) == n) t = true;
+      }
+      if (s == true && t == true) {
+	rw += mwpm.blossomValue(i);
+      }
+    }
+    rw -= weight[e] * mwpm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwpm.matching(e), 
+	  "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartUGraph::NodeIt n(ugraph); n != INVALID; ++n) {
+    check(mwpm.matching(n) != INVALID, "Non perfect");
+    pv += weight[mwpm.matching(n)];
+    SmartUGraph::Node o = ugraph.target(mwpm.matching(n));
+    check(mwpm.mate(n) == o, "Invalid matching");
+    check(mwpm.matching(n) == ugraph.oppositeEdge(mwpm.matching(o)), 
+	  "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartUGraph::NodeIt n(ugraph); n != INVALID; ++n) {
+    dv += mwpm.nodeValue(n);
+  }
+
+  for (int i = 0; i < mwpm.blossomNum(); ++i) {
+    check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
+    check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
+    dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
+  }
+
+  check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
+
+  return;
+}
+
+
+int main() {
+
+  for (int i = 0; i < lgfn; ++i) {
+    SmartUGraph ugraph;
+    SmartUGraph::UEdgeMap<int> weight(ugraph);
+    
+    istringstream lgfs(lgf[i]);
+    UGraphReader<SmartUGraph>(lgfs, ugraph).
+      readUEdgeMap("weight", weight).run();
+
+    MaxWeightedMatching<SmartUGraph> mwm(ugraph, weight);
+    mwm.run();
+    checkMatching(ugraph, weight, mwm);
+
+    MaxMatching<SmartUGraph> mm(ugraph);
+    mm.run();
+
+    MaxWeightedPerfectMatching<SmartUGraph> mwpm(ugraph, weight);
+    bool perfect = mwpm.run();
+
+    check(perfect == (mm.size() * 2 == countNodes(ugraph)), 
+	  "Perfect matching found");
+
+    if (perfect) {
+      checkPerfectMatching(ugraph, weight, mwpm);
+    }
+  }
+  
+  return 0;
+}



More information about the Lemon-commits mailing list