src/test/max_matching_test.cc
author alpar
Fri, 14 Jan 2005 08:01:17 +0000
changeset 1079 81addddaf3d3
child 1092 36284b2500c3
permissions -rw-r--r--
Serious buxfig in findEdge()
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@1078
    25
#include <graph_gen.h>
jacint@1078
    26
#include <max_matching.h>
jacint@1078
    27
jacint@1078
    28
using namespace std;
jacint@1078
    29
using namespace lemon;
jacint@1078
    30
jacint@1078
    31
int main() {
jacint@1078
    32
jacint@1078
    33
  typedef UndirListGraph Graph;
jacint@1078
    34
jacint@1078
    35
  typedef Graph::Edge Edge;
jacint@1078
    36
  typedef Graph::UndirEdgeIt UndirEdgeIt;
jacint@1078
    37
  typedef Graph::IncEdgeIt IncEdgeIt;
jacint@1078
    38
  typedef Graph::NodeIt NodeIt;
jacint@1078
    39
  typedef Graph::Node Node;
jacint@1078
    40
   
jacint@1078
    41
  Graph G;
jacint@1078
    42
jacint@1078
    43
  random_init(); 
jacint@1078
    44
  randomGraph(G, random(5000), random(20000) );  
jacint@1078
    45
jacint@1078
    46
  MaxMatching<Graph> max_matching(G);
jacint@1078
    47
  max_matching.runEdmonds(0);
jacint@1078
    48
  
jacint@1078
    49
  int s=0;
jacint@1078
    50
  Graph::NodeMap<Node> mate(G,INVALID);
jacint@1078
    51
  max_matching.writeNMapNode(mate);
jacint@1078
    52
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
    53
    if ( mate[v]!=INVALID ) ++s;
jacint@1078
    54
  }
jacint@1078
    55
  int size=(int)s/2;  //size will be used as the size of a maxmatching
jacint@1078
    56
  
jacint@1078
    57
  check ( size == max_matching.size(), "mate() returns a different size matching than max_matching.size()" );
jacint@1078
    58
jacint@1078
    59
  Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos0(G);
jacint@1078
    60
  max_matching.writePos(pos0);
jacint@1078
    61
  
jacint@1078
    62
  max_matching.resetPos();
jacint@1078
    63
  max_matching.resetMatching();
jacint@1078
    64
  max_matching.runEdmonds(1);
jacint@1078
    65
  s=0;
jacint@1078
    66
  max_matching.writeNMapNode(mate);
jacint@1078
    67
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
    68
    if ( mate[v]!=INVALID ) ++s;
jacint@1078
    69
  }
jacint@1078
    70
  check ( (int)s/2 == size, "The size does not equal!" );
jacint@1078
    71
jacint@1078
    72
  Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos1(G);
jacint@1078
    73
  max_matching.writePos(pos1);
jacint@1078
    74
jacint@1078
    75
  max_matching.resetPos();
jacint@1078
    76
  max_matching.run();
jacint@1078
    77
  s=0;
jacint@1078
    78
  max_matching.writeNMapNode(mate);
jacint@1078
    79
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
    80
    if ( mate[v]!=INVALID ) ++s;
jacint@1078
    81
  }
jacint@1078
    82
  check ( (int)s/2 == size, "The size does not equal!" ); 
jacint@1078
    83
  
jacint@1078
    84
  Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos2(G);
jacint@1078
    85
  max_matching.writePos(pos2);
jacint@1078
    86
jacint@1078
    87
  max_matching.resetPos();
jacint@1078
    88
  max_matching.resetMatching();
jacint@1078
    89
  max_matching.run();
jacint@1078
    90
  s=0;
jacint@1078
    91
  max_matching.writeNMapNode(mate);
jacint@1078
    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@1078
    97
  Graph::NodeMap<MaxMatching<Graph>::pos_enum> pos(G);
jacint@1078
    98
  max_matching.writePos(pos);
jacint@1078
    99
   
jacint@1078
   100
  bool ismatching=true;
jacint@1078
   101
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
   102
    if ( mate[v]!=INVALID ) {
jacint@1078
   103
      Node u=mate[v];
jacint@1078
   104
      if (mate[u]!=v) ismatching=false; 
jacint@1078
   105
    }
jacint@1078
   106
  }  
jacint@1078
   107
  check ( ismatching, "It is not a matching!" );
jacint@1078
   108
jacint@1078
   109
  bool coincide=true;
jacint@1078
   110
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
   111
   if ( pos0[v] != pos1[v] || pos1[v]!=pos2[v] || pos2[v]!=pos[v] ) {
jacint@1078
   112
     coincide=false;
jacint@1078
   113
    }
jacint@1078
   114
  }
jacint@1078
   115
  check ( coincide, "The decompositions do not coincide! " );
jacint@1078
   116
jacint@1078
   117
  bool noedge=true;
jacint@1078
   118
  for(UndirEdgeIt e(G); e!=INVALID; ++e) {
jacint@1078
   119
   if ( (pos[G.target(e)]==max_matching.C && pos[G.source(e)]==max_matching.D) || 
jacint@1078
   120
	 (pos[G.target(e)]==max_matching.D && pos[G.source(e)]==max_matching.C) )
jacint@1078
   121
      noedge=false; 
jacint@1078
   122
  }
jacint@1078
   123
  check ( noedge, "There are edges between D and C!" );
jacint@1078
   124
  
jacint@1078
   125
  bool oddcomp=true;
jacint@1078
   126
  Graph::NodeMap<bool> todo(G,true);
jacint@1078
   127
  int num_comp=0;
jacint@1078
   128
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
   129
   if ( pos[v]==max_matching.D && todo[v] ) {
jacint@1078
   130
      int comp_size=1;
jacint@1078
   131
      ++num_comp;
jacint@1078
   132
      std::queue<Node> Q;
jacint@1078
   133
      Q.push(v);
jacint@1078
   134
      todo.set(v,false);
jacint@1078
   135
      while (!Q.empty()) {
jacint@1078
   136
	Node w=Q.front();	
jacint@1078
   137
	Q.pop();
jacint@1078
   138
	for(IncEdgeIt e(G,w); e!=INVALID; ++e) {
jacint@1078
   139
	  Node u=G.target(e);
jacint@1078
   140
	  if ( pos[u]==max_matching.D && todo[u] ) {
jacint@1078
   141
	    ++comp_size;
jacint@1078
   142
	    Q.push(u);
jacint@1078
   143
	    todo.set(u,false);
jacint@1078
   144
	  }
jacint@1078
   145
	}
jacint@1078
   146
      }
jacint@1078
   147
      if ( !(comp_size % 2) ) oddcomp=false;  
jacint@1078
   148
    }
jacint@1078
   149
  }
jacint@1078
   150
  check ( oddcomp, "A component of G[D] is not odd." );
jacint@1078
   151
jacint@1078
   152
  int barrier=0;
jacint@1078
   153
  for(NodeIt v(G); v!=INVALID; ++v) {
jacint@1078
   154
    if ( pos[v]==max_matching.A ) ++barrier;
jacint@1078
   155
  }
jacint@1078
   156
  int expected_size=(int)( countNodes(G)-num_comp+barrier)/2;
jacint@1078
   157
  check ( size==expected_size, "The size of the matching is wrong." );
jacint@1078
   158
  
jacint@1078
   159
  return 0;
jacint@1078
   160
}
jacint@1078
   161
jacint@1078
   162
jacint@1078
   163
void random_init()
jacint@1078
   164
{
jacint@1078
   165
  unsigned int seed = getpid();
jacint@1078
   166
  seed |= seed << 15;
jacint@1078
   167
  seed ^= time(0);
jacint@1078
   168
  
jacint@1078
   169
  srand(seed);
jacint@1078
   170
}
jacint@1078
   171
jacint@1078
   172
jacint@1078
   173
int random(int m)
jacint@1078
   174
{
jacint@1078
   175
  return int( double(m) * rand() / (RAND_MAX + 1.0) );
jacint@1078
   176
}
jacint@1078
   177
jacint@1078
   178
jacint@1078
   179
/// Generates a random graph with n nodes and m edges.
jacint@1078
   180
/// Before generating the random graph, \c g.clear() is called.
jacint@1078
   181
template<typename Graph>
jacint@1078
   182
void randomGraph(Graph& g, int n, int m) {
jacint@1078
   183
  g.clear();
jacint@1078
   184
  std::vector<typename Graph::Node> nodes;
jacint@1078
   185
  for (int i=0; i<n; ++i)
jacint@1078
   186
    nodes.push_back(g.addNode());
jacint@1078
   187
  for (int i=0; i<m; ++i) 
jacint@1078
   188
    g.addEdge(nodes[random(n)], nodes[random(n)]);
jacint@1078
   189
}