src/test/max_matching_test.cc
author ladanyi
Wed, 26 Jan 2005 00:09:06 +0000
changeset 1095 f1eb997f0418
parent 1078 ce8466be7683
child 1098 e3b3667c6857
permissions -rw-r--r--
Removed some unnecessary files.
jacint@1078
     1
/* -*- C++ -*-
jacint@1078
     2
 * src/test/max_matching_test.cc - Part of LEMON, a generic C++ optimization library
jacint@1078
     3
 *
jacint@1078
     4
 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
jacint@1078
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
jacint@1078
     6
 *
jacint@1078
     7
 * Permission to use, modify and distribute this software is granted
jacint@1078
     8
 * provided that this copyright notice appears in all copies. For
jacint@1078
     9
 * precise terms see the accompanying LICENSE file.
jacint@1078
    10
 *
jacint@1078
    11
 * This software is provided "AS IS" with no warranty of any kind,
jacint@1078
    12
 * express or implied, and with no claim as to its suitability for any
jacint@1078
    13
 * purpose.
jacint@1078
    14
 *
jacint@1078
    15
 */
jacint@1078
    16
jacint@1078
    17
#include <iostream>
jacint@1078
    18
#include <queue>
jacint@1078
    19
#include <math.h>
jacint@1078
    20
#include <cstdlib>
jacint@1078
    21
jacint@1078
    22
#include "test_tools.h"
jacint@1078
    23
#include <lemon/invalid.h>
jacint@1078
    24
#include <lemon/list_graph.h>
jacint@1092
    25
#include <lemon/max_matching.h>
jacint@1092
    26
//temporarily
jacint@1092
    27
#include <work/jacint/graph_gen.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@1078
    42
  Graph G;
jacint@1078
    43
jacint@1078
    44
  random_init(); 
jacint@1078
    45
  randomGraph(G, random(5000), random(20000) );  
jacint@1078
    46
jacint@1078
    47
  MaxMatching<Graph> max_matching(G);
jacint@1078
    48
  max_matching.runEdmonds(0);
jacint@1078
    49
  
jacint@1078
    50
  int s=0;
jacint@1078
    51
  Graph::NodeMap<Node> mate(G,INVALID);
jacint@1078
    52
  max_matching.writeNMapNode(mate);
jacint@1078
    53
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
    54
    if ( mate[v]!=INVALID ) ++s;
jacint@1078
    55
  }
jacint@1078
    56
  int size=(int)s/2;  //size will be used as the size of a maxmatching
jacint@1092
    57
jacint@1092
    58
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1092
    59
    max_matching.mate(v);
jacint@1092
    60
  }
jacint@1092
    61
jacint@1078
    62
  check ( size == max_matching.size(), "mate() returns a different size matching than max_matching.size()" );
jacint@1078
    63
jacint@1078
    64
  Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos0(G);
jacint@1078
    65
  max_matching.writePos(pos0);
jacint@1078
    66
  
jacint@1078
    67
  max_matching.resetMatching();
jacint@1078
    68
  max_matching.runEdmonds(1);
jacint@1078
    69
  s=0;
jacint@1078
    70
  max_matching.writeNMapNode(mate);
jacint@1078
    71
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
    72
    if ( mate[v]!=INVALID ) ++s;
jacint@1078
    73
  }
jacint@1078
    74
  check ( (int)s/2 == size, "The size does not equal!" );
jacint@1078
    75
jacint@1078
    76
  Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos1(G);
jacint@1078
    77
  max_matching.writePos(pos1);
jacint@1078
    78
jacint@1078
    79
  max_matching.run();
jacint@1078
    80
  s=0;
jacint@1078
    81
  max_matching.writeNMapNode(mate);
jacint@1078
    82
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
    83
    if ( mate[v]!=INVALID ) ++s;
jacint@1078
    84
  }
jacint@1078
    85
  check ( (int)s/2 == size, "The size does not equal!" ); 
jacint@1078
    86
  
jacint@1078
    87
  Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos2(G);
jacint@1078
    88
  max_matching.writePos(pos2);
jacint@1078
    89
jacint@1078
    90
  max_matching.resetMatching();
jacint@1078
    91
  max_matching.run();
jacint@1078
    92
  s=0;
jacint@1078
    93
  max_matching.writeNMapNode(mate);
jacint@1078
    94
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
    95
    if ( mate[v]!=INVALID ) ++s;
jacint@1078
    96
  }
jacint@1078
    97
  check ( (int)s/2 == size, "The size does not equal!" ); 
jacint@1078
    98
  
jacint@1078
    99
  Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos(G);
jacint@1078
   100
  max_matching.writePos(pos);
jacint@1078
   101
   
jacint@1078
   102
  bool ismatching=true;
jacint@1078
   103
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
   104
    if ( mate[v]!=INVALID ) {
jacint@1078
   105
      Node u=mate[v];
jacint@1078
   106
      if (mate[u]!=v) ismatching=false; 
jacint@1078
   107
    }
jacint@1078
   108
  }  
jacint@1078
   109
  check ( ismatching, "It is not a matching!" );
jacint@1078
   110
jacint@1078
   111
  bool coincide=true;
jacint@1078
   112
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
   113
   if ( pos0[v] != pos1[v] || pos1[v]!=pos2[v] || pos2[v]!=pos[v] ) {
jacint@1078
   114
     coincide=false;
jacint@1078
   115
    }
jacint@1078
   116
  }
jacint@1078
   117
  check ( coincide, "The decompositions do not coincide! " );
jacint@1078
   118
jacint@1078
   119
  bool noedge=true;
jacint@1078
   120
  for(UndirEdgeIt e(G); e!=INVALID; ++e) {
jacint@1078
   121
   if ( (pos[G.target(e)]==max_matching.C && pos[G.source(e)]==max_matching.D) || 
jacint@1078
   122
	 (pos[G.target(e)]==max_matching.D && pos[G.source(e)]==max_matching.C) )
jacint@1078
   123
      noedge=false; 
jacint@1078
   124
  }
jacint@1078
   125
  check ( noedge, "There are edges between D and C!" );
jacint@1078
   126
  
jacint@1078
   127
  bool oddcomp=true;
jacint@1078
   128
  Graph::NodeMap<bool> todo(G,true);
jacint@1078
   129
  int num_comp=0;
jacint@1078
   130
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
   131
   if ( pos[v]==max_matching.D && todo[v] ) {
jacint@1078
   132
      int comp_size=1;
jacint@1078
   133
      ++num_comp;
jacint@1078
   134
      std::queue<Node> Q;
jacint@1078
   135
      Q.push(v);
jacint@1078
   136
      todo.set(v,false);
jacint@1078
   137
      while (!Q.empty()) {
jacint@1078
   138
	Node w=Q.front();	
jacint@1078
   139
	Q.pop();
jacint@1078
   140
	for(IncEdgeIt e(G,w); e!=INVALID; ++e) {
jacint@1078
   141
	  Node u=G.target(e);
jacint@1078
   142
	  if ( pos[u]==max_matching.D && todo[u] ) {
jacint@1078
   143
	    ++comp_size;
jacint@1078
   144
	    Q.push(u);
jacint@1078
   145
	    todo.set(u,false);
jacint@1078
   146
	  }
jacint@1078
   147
	}
jacint@1078
   148
      }
jacint@1078
   149
      if ( !(comp_size % 2) ) oddcomp=false;  
jacint@1078
   150
    }
jacint@1078
   151
  }
jacint@1078
   152
  check ( oddcomp, "A component of G[D] is not odd." );
jacint@1078
   153
jacint@1078
   154
  int barrier=0;
jacint@1078
   155
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
   156
    if ( pos[v]==max_matching.A ) ++barrier;
jacint@1078
   157
  }
jacint@1078
   158
  int expected_size=(int)( countNodes(G)-num_comp+barrier)/2;
jacint@1078
   159
  check ( size==expected_size, "The size of the matching is wrong." );
jacint@1078
   160
  
jacint@1078
   161
  return 0;
jacint@1078
   162
}
jacint@1078
   163
jacint@1078
   164
jacint@1078
   165
void random_init()
jacint@1078
   166
{
jacint@1078
   167
  unsigned int seed = getpid();
jacint@1078
   168
  seed |= seed << 15;
jacint@1078
   169
  seed ^= time(0);
jacint@1078
   170
  
jacint@1078
   171
  srand(seed);
jacint@1078
   172
}
jacint@1078
   173
jacint@1078
   174
jacint@1078
   175
int random(int m)
jacint@1078
   176
{
jacint@1078
   177
  return int( double(m) * rand() / (RAND_MAX + 1.0) );
jacint@1078
   178
}
jacint@1078
   179
jacint@1078
   180
jacint@1078
   181
/// Generates a random graph with n nodes and m edges.
jacint@1078
   182
/// Before generating the random graph, \c g.clear() is called.
jacint@1078
   183
template<typename Graph>
jacint@1078
   184
void randomGraph(Graph& g, int n, int m) {
jacint@1078
   185
  g.clear();
jacint@1078
   186
  std::vector<typename Graph::Node> nodes;
jacint@1078
   187
  for (int i=0; i<n; ++i)
jacint@1078
   188
    nodes.push_back(g.addNode());
jacint@1078
   189
  for (int i=0; i<m; ++i) 
jacint@1078
   190
    g.addEdge(nodes[random(n)], nodes[random(n)]);
jacint@1078
   191
}