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