test/max_matching_test.cc
author hegyi
Thu, 05 Jan 2006 12:30:09 +0000
changeset 1878 409a31271efd
parent 1494 ae55ba000ebb
child 1909 2d806130e700
permissions -rw-r--r--
Several changes. \n If new map is added to mapstorage it emits signal with the name of the new map. This was important, because from now on not only tha mapwin should be updated. \n Furthermore algobox gets a pointer to mapstorage instead of only the mapnames from it. This is important because without it it would be complicated to pass all of the required maps to algobox.
     1 /* -*- C++ -*-
     2  * test/max_matching_test.cc - 
     3  * Part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2006 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 }