test/max_matching_test.cc
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1435 8e85e6bbefdf
child 1875 98698b69a902
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
     1 /* -*- C++ -*-
     2  * test/max_matching_test.cc - 
     3  * Part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     6  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     7  *
     8  * Permission to use, modify and distribute this software is granted
     9  * provided that this copyright notice appears in all copies. For
    10  * precise terms see the accompanying LICENSE file.
    11  *
    12  * This software is provided "AS IS" with no warranty of any kind,
    13  * express or implied, and with no claim as to its suitability for any
    14  * purpose.
    15  *
    16  */
    17 
    18 #include <iostream>
    19 #include <vector>
    20 #include <queue>
    21 #include <cmath>
    22 #include <cstdlib>
    23 
    24 #include "test_tools.h"
    25 #include <lemon/invalid.h>
    26 #include <lemon/list_graph.h>
    27 #include <lemon/max_matching.h>
    28 
    29 using namespace std;
    30 using namespace lemon;
    31 
    32 int main() {
    33 
    34   typedef UndirListGraph Graph;
    35 
    36   typedef Graph::Edge Edge;
    37   typedef Graph::UndirEdgeIt UndirEdgeIt;
    38   typedef Graph::IncEdgeIt IncEdgeIt;
    39   typedef Graph::NodeIt NodeIt;
    40   typedef Graph::Node Node;
    41    
    42   Graph g;
    43   g.clear();
    44 
    45   std::vector<Graph::Node> nodes;
    46   for (int i=0; i<13; ++i)
    47       nodes.push_back(g.addNode());
    48 
    49   g.addEdge(nodes[0], nodes[0]);
    50   g.addEdge(nodes[6], nodes[10]);
    51   g.addEdge(nodes[5], nodes[10]);
    52   g.addEdge(nodes[4], nodes[10]);
    53   g.addEdge(nodes[3], nodes[11]);  
    54   g.addEdge(nodes[1], nodes[6]);
    55   g.addEdge(nodes[4], nodes[7]);  
    56   g.addEdge(nodes[1], nodes[8]);
    57   g.addEdge(nodes[0], nodes[8]);
    58   g.addEdge(nodes[3], nodes[12]);
    59   g.addEdge(nodes[6], nodes[9]);
    60   g.addEdge(nodes[9], nodes[11]);
    61   g.addEdge(nodes[2], nodes[10]);
    62   g.addEdge(nodes[10], nodes[8]);
    63   g.addEdge(nodes[5], nodes[8]);
    64   g.addEdge(nodes[6], nodes[3]);
    65   g.addEdge(nodes[0], nodes[5]);
    66   g.addEdge(nodes[6], nodes[12]);
    67   
    68   MaxMatching<Graph> max_matching(g);
    69   max_matching.runEdmonds(0);
    70   
    71   int s=0;
    72   Graph::NodeMap<Node> mate(g,INVALID);
    73   max_matching.writeNMapNode(mate);
    74   for(NodeIt v(g); v!=INVALID; ++v) {
    75     if ( mate[v]!=INVALID ) ++s;
    76   }
    77   int size=(int)s/2;  //size will be used as the size of a maxmatching
    78 
    79   for(NodeIt v(g); v!=INVALID; ++v) {
    80     max_matching.mate(v);
    81   }
    82 
    83   check ( size == max_matching.size(), "mate() returns a different size matching than max_matching.size()" );
    84 
    85   Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos0(g);
    86   max_matching.writePos(pos0);
    87   
    88   max_matching.resetMatching();
    89   max_matching.runEdmonds(1);
    90   s=0;
    91   max_matching.writeNMapNode(mate);
    92   for(NodeIt v(g); v!=INVALID; ++v) {
    93     if ( mate[v]!=INVALID ) ++s;
    94   }
    95   check ( (int)s/2 == size, "The size does not equal!" );
    96 
    97   Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos1(g);
    98   max_matching.writePos(pos1);
    99 
   100   max_matching.run();
   101   s=0;
   102   max_matching.writeNMapNode(mate);
   103   for(NodeIt v(g); v!=INVALID; ++v) {
   104     if ( mate[v]!=INVALID ) ++s;
   105   }
   106   check ( (int)s/2 == size, "The size does not equal!" ); 
   107   
   108   Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos2(g);
   109   max_matching.writePos(pos2);
   110 
   111   max_matching.resetMatching();
   112   max_matching.run();
   113   s=0;
   114   max_matching.writeNMapNode(mate);
   115   for(NodeIt v(g); v!=INVALID; ++v) {
   116     if ( mate[v]!=INVALID ) ++s;
   117   }
   118   check ( (int)s/2 == size, "The size does not equal!" ); 
   119   
   120   Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos(g);
   121   max_matching.writePos(pos);
   122    
   123   bool ismatching=true;
   124   for(NodeIt v(g); v!=INVALID; ++v) {
   125     if ( mate[v]!=INVALID ) {
   126       Node u=mate[v];
   127       if (mate[u]!=v) ismatching=false; 
   128     }
   129   }  
   130   check ( ismatching, "It is not a matching!" );
   131 
   132   bool coincide=true;
   133   for(NodeIt v(g); v!=INVALID; ++v) {
   134    if ( pos0[v] != pos1[v] || pos1[v]!=pos2[v] || pos2[v]!=pos[v] ) {
   135      coincide=false;
   136     }
   137   }
   138   check ( coincide, "The decompositions do not coincide! " );
   139 
   140   bool noedge=true;
   141   for(UndirEdgeIt e(g); e!=INVALID; ++e) {
   142    if ( (pos[g.target(e)]==max_matching.C && pos[g.source(e)]==max_matching.D) || 
   143 	 (pos[g.target(e)]==max_matching.D && pos[g.source(e)]==max_matching.C) )
   144       noedge=false; 
   145   }
   146   check ( noedge, "There are edges between D and C!" );
   147   
   148   bool oddcomp=true;
   149   Graph::NodeMap<bool> todo(g,true);
   150   int num_comp=0;
   151   for(NodeIt v(g); v!=INVALID; ++v) {
   152    if ( pos[v]==max_matching.D && todo[v] ) {
   153       int comp_size=1;
   154       ++num_comp;
   155       std::queue<Node> Q;
   156       Q.push(v);
   157       todo.set(v,false);
   158       while (!Q.empty()) {
   159 	Node w=Q.front();	
   160 	Q.pop();
   161 	for(IncEdgeIt e(g,w); e!=INVALID; ++e) {
   162 	  Node u=g.runningNode(e);
   163 	  if ( pos[u]==max_matching.D && todo[u] ) {
   164 	    ++comp_size;
   165 	    Q.push(u);
   166 	    todo.set(u,false);
   167 	  }
   168 	}
   169       }
   170       if ( !(comp_size % 2) ) oddcomp=false;  
   171     }
   172   }
   173   check ( oddcomp, "A component of g[D] is not odd." );
   174 
   175   int barrier=0;
   176   for(NodeIt v(g); v!=INVALID; ++v) {
   177     if ( pos[v]==max_matching.A ) ++barrier;
   178   }
   179   int expected_size=(int)( countNodes(g)-num_comp+barrier)/2;
   180   check ( size==expected_size, "The size of the matching is wrong." );
   181   
   182   return 0;
   183 }