test/max_matching_test.cc
author deba
Wed, 01 Mar 2006 10:25:30 +0000
changeset 1991 d7442141d9ef
parent 1909 2d806130e700
child 1993 2115143eceea
permissions -rw-r--r--
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

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