src/work/marci/bipartite_matching_try_3.cc
author marci
Mon, 03 May 2004 10:04:27 +0000
changeset 510 72143568cadc
child 512 d5fe2f3f95fc
permissions -rw-r--r--
matching, flows
marci@510
     1
// -*- c++ -*-
marci@510
     2
#include <iostream>
marci@510
     3
#include <fstream>
marci@510
     4
#include <vector>
marci@510
     5
#include <cstdlib>
marci@510
     6
marci@510
     7
#include <list_graph.h>
marci@510
     8
//#include <smart_graph.h>
marci@510
     9
//#include <dimacs.h>
marci@510
    10
#include <time_measure.h>
marci@510
    11
#include <for_each_macros.h>
marci@510
    12
#include <bfs_iterator.h>
marci@510
    13
#include <bipartite_graph_wrapper.h>
marci@510
    14
#include <maps.h>
marci@510
    15
#include <max_flow.h>
marci@510
    16
marci@510
    17
using namespace hugo;
marci@510
    18
marci@510
    19
// template <typename Graph, typename EdgeCap, typename NodeCap, 
marci@510
    20
// 	  typename EdgeFlow, typename NodeFlow>
marci@510
    21
// class MaxMatching : public MaxFlow<stGraphWrapper<Graph>, 
marci@510
    22
// 				   stGraphWrapper<Graph>:: EdgeMapWrapper<EdgeCan, NodeCap>, stGraphWrapper<Graph>::EdgeMapWrapper<EdgeFlow, NodeFlow> > {
marci@510
    23
//   typedef MaxFlow<stGraphWrapper<Graph>, 
marci@510
    24
// 		  stGraphWrapper<Graph>::EdgeMapWrapper<EdgeCan, NodeCap>, 
marci@510
    25
// 		  stGraphWrapper<Graph>::EdgeMapWrapper<EdgeFlow, NodeFlow> >
marci@510
    26
//   Parent;
marci@510
    27
// protected:
marci@510
    28
//   stGraphWrapper<Graph> gw;
marci@510
    29
//   stGraphWrapper<Graph>::EdgeMapWrapper<EdgeCap, NodeCap> cap;
marci@510
    30
//   stGraphWrapper<Graph>::EdgeMapWrapper<EdgeFlow, NodeFlow> flow;
marci@510
    31
//   //graph* g;
marci@510
    32
//   //EdgeCap* edge_cap;
marci@510
    33
//   //EdgeFlow* edge_flow;
marci@510
    34
// public:
marci@510
    35
//   MaxMatching(Graph& _g, EdgeCap& _edge_cap, NodeCap& _node_cap, 
marci@510
    36
// 	      EdgeFlow& _edge_flow, NodeFlow& _node_flow) : 
marci@510
    37
//     MaxFlow(), gw(_g), 
marci@510
    38
//     cap(_edge_cap, _node_cap), flow(_edge_flow, _node_flow) {
marci@510
    39
//     Parent::set(gw, cap, flow);
marci@510
    40
//   }
marci@510
    41
// };
marci@510
    42
marci@510
    43
template <typename Graph, typename EdgeCap, typename NodeCap, 
marci@510
    44
	  typename EdgeFlow, typename NodeFlow>
marci@510
    45
class MaxMatching {
marci@510
    46
// : public MaxFlow<stGraphWrapper<Graph>, 
marci@510
    47
// 				   stGraphWrapper<Graph>:: EdgeMapWrapper<EdgeCan, NodeCap>, stGraphWrapper<Graph>::EdgeMapWrapper<EdgeFlow, NodeFlow> > {
marci@510
    48
//   typedef MaxFlow<stGraphWrapper<Graph>, 
marci@510
    49
// 		  stGraphWrapper<Graph>::EdgeMapWrapper<EdgeCan, NodeCap>, 
marci@510
    50
// 		  stGraphWrapper<Graph>::EdgeMapWrapper<EdgeFlow, NodeFlow> >
marci@510
    51
//   Parent;
marci@510
    52
protected:
marci@510
    53
//   EdgeCap* edge_cap;
marci@510
    54
//   NodeCap* node_cap;
marci@510
    55
//   EdgeFlow* edge_flow;
marci@510
    56
//   NodeFlow* node_flow;
marci@510
    57
  typedef  stGraphWrapper<Graph> stGW;
marci@510
    58
  stGW stgw;
marci@510
    59
  typedef typename stGW::template EdgeMapWrapper<EdgeCap, NodeCap> CapMap; 
marci@510
    60
  CapMap cap;
marci@510
    61
  typedef typename stGW::template EdgeMapWrapper<EdgeFlow, NodeFlow> FlowMap;
marci@510
    62
  FlowMap flow;
marci@510
    63
  MaxFlow<stGW, int, CapMap, FlowMap> mf;
marci@510
    64
  //graph* g;
marci@510
    65
  //EdgeCap* edge_cap;
marci@510
    66
  //EdgeFlow* edge_flow;
marci@510
    67
public:
marci@510
    68
  MaxMatching(Graph& _g, EdgeCap& _edge_cap, NodeCap& _node_cap, 
marci@510
    69
	      EdgeFlow& _edge_flow, NodeFlow& _node_flow) : 
marci@510
    70
    stgw(_g), 
marci@510
    71
    cap(_edge_cap, _node_cap), flow(_edge_flow, _node_flow), 
marci@510
    72
    mf(stgw, stgw.S_NODE, stgw.T_NODE, cap, flow) { }
marci@510
    73
  void run() { mf.run(); } 
marci@510
    74
  int matchingValue() { return mf.flowValue(); }
marci@510
    75
};
marci@510
    76
marci@510
    77
/**
marci@510
    78
 * Inicializalja a veletlenszamgeneratort.
marci@510
    79
 * Figyelem, ez nem jo igazi random szamokhoz,
marci@510
    80
 * erre ne bizzad a titkaidat!
marci@510
    81
 */
marci@510
    82
void random_init()
marci@510
    83
{
marci@510
    84
	unsigned int seed = getpid();
marci@510
    85
	seed |= seed << 15;
marci@510
    86
	seed ^= time(0);
marci@510
    87
marci@510
    88
	srand(seed);
marci@510
    89
}
marci@510
    90
marci@510
    91
/**
marci@510
    92
 * Egy veletlen int-et ad vissza 0 es m-1 kozott.
marci@510
    93
 */
marci@510
    94
int random(int m)
marci@510
    95
{
marci@510
    96
  return int( double(m) * rand() / (RAND_MAX + 1.0) );
marci@510
    97
}
marci@510
    98
marci@510
    99
int main() {
marci@510
   100
  //typedef UndirListGraph Graph; 
marci@510
   101
  typedef BipartiteGraph<ListGraph> Graph;
marci@510
   102
  
marci@510
   103
  typedef Graph::Node Node;
marci@510
   104
  typedef Graph::NodeIt NodeIt;
marci@510
   105
  typedef Graph::Edge Edge;
marci@510
   106
  typedef Graph::EdgeIt EdgeIt;
marci@510
   107
  typedef Graph::OutEdgeIt OutEdgeIt;
marci@510
   108
marci@510
   109
  Graph g;
marci@510
   110
marci@510
   111
  std::vector<Graph::Node> s_nodes;
marci@510
   112
  std::vector<Graph::Node> t_nodes;
marci@510
   113
marci@510
   114
  int a;
marci@510
   115
  std::cout << "number of nodes in the first color class=";
marci@510
   116
  std::cin >> a; 
marci@510
   117
  int b;
marci@510
   118
  std::cout << "number of nodes in the second color class=";
marci@510
   119
  std::cin >> b; 
marci@510
   120
  int m;
marci@510
   121
  std::cout << "number of edges=";
marci@510
   122
  std::cin >> m; 
marci@510
   123
  
marci@510
   124
  std::cout << "Generatig a random bipartite graph..." << std::endl;
marci@510
   125
  for (int i=0; i<a; ++i) s_nodes.push_back(g.addNode(false));
marci@510
   126
  for (int i=0; i<b; ++i) t_nodes.push_back(g.addNode(true));
marci@510
   127
marci@510
   128
  random_init();
marci@510
   129
  for(int i=0; i<m; ++i) {
marci@510
   130
    g.addEdge(s_nodes[random(a)], t_nodes[random(b)]);
marci@510
   131
  }
marci@510
   132
marci@510
   133
  std::cout << "Edges of the bipartite graph:" << std::endl;
marci@510
   134
  FOR_EACH_LOC(EdgeIt, e, g) std::cout << e << " ";
marci@510
   135
  std::cout << std::endl;
marci@510
   136
marci@510
   137
  std::cout << "Nodes:" << std::endl;
marci@510
   138
  FOR_EACH_LOC(Graph::NodeIt, v, g) std::cout << v << " ";
marci@510
   139
  std::cout << std::endl;
marci@510
   140
  std::cout << "Nodes in T:" << std::endl;
marci@510
   141
  FOR_EACH_INC_LOC(Graph::ClassNodeIt, v, g, Graph::T_CLASS) std::cout << v << " ";
marci@510
   142
  std::cout << std::endl;
marci@510
   143
  std::cout << "Nodes in S:" << std::endl;
marci@510
   144
  FOR_EACH_INC_LOC(Graph::ClassNodeIt, v, g, Graph::S_CLASS) std::cout << v << " ";
marci@510
   145
  std::cout << std::endl;
marci@510
   146
marci@510
   147
  std::cout << "Erasing the first node..." << std::endl;
marci@510
   148
  NodeIt n;
marci@510
   149
  g.first(n);
marci@510
   150
  g.erase(n);
marci@510
   151
  std::cout << "Nodes of the bipartite graph:" << std::endl;
marci@510
   152
  FOR_EACH_GLOB(n, g) std::cout << n << " ";
marci@510
   153
  std::cout << std::endl;
marci@510
   154
marci@510
   155
  std::cout << "Nodes in T:" << std::endl;
marci@510
   156
  FOR_EACH_INC_LOC(Graph::ClassNodeIt, v, g, Graph::T_CLASS) std::cout << v << " ";
marci@510
   157
  std::cout << std::endl;
marci@510
   158
  std::cout << "Nodes in S:" << std::endl;
marci@510
   159
  FOR_EACH_INC_LOC(Graph::ClassNodeIt, v, g, Graph::S_CLASS) std::cout << v << " ";
marci@510
   160
  std::cout << std::endl;
marci@510
   161
marci@510
   162
  typedef stGraphWrapper<Graph> stGW;
marci@510
   163
  stGW stgw(g);
marci@510
   164
  ConstMap<stGW::Edge, int> const1map(1);
marci@510
   165
marci@510
   166
  Timer ts;
marci@510
   167
  ts.reset();
marci@510
   168
  stGW::EdgeMap<int> flow(stgw);
marci@510
   169
  MaxFlow<stGW, int, ConstMap<stGW::Edge, int>, stGW::EdgeMap<int> > 
marci@510
   170
    max_flow_test(stgw, stgw.S_NODE, stgw.T_NODE, const1map, flow);
marci@510
   171
  max_flow_test.run();
marci@510
   172
//  while (max_flow_test.augmentOnShortestPath()) { }
marci@510
   173
//  typedef ListGraph MutableGraph;
marci@510
   174
//  while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) {
marci@510
   175
//  while (max_flow_test.augmentOnBlockingFlow2()) {
marci@510
   176
//   std::cout << max_flow_test.flowValue() << std::endl;
marci@510
   177
//  }
marci@510
   178
  std::cout << "max flow value: " << max_flow_test.flowValue() << std::endl;
marci@510
   179
  std::cout << "elapsed time: " << ts << std::endl;
marci@510
   180
  FOR_EACH_LOC(stGW::EdgeIt, e, stgw) { 
marci@510
   181
    if (flow[e]) std::cout << e << std::endl; 
marci@510
   182
  }
marci@510
   183
  std::cout << std::endl;
marci@510
   184
marci@510
   185
  typedef ConstMap<Graph::Edge, int> EdgeCap; 
marci@510
   186
  EdgeCap ge1(1);
marci@510
   187
  typedef ConstMap<Graph::Node, int> NodeCap;
marci@510
   188
  NodeCap gn1(1);
marci@510
   189
  typedef Graph::EdgeMap<int> EdgeFlow;
marci@510
   190
  EdgeFlow gef(g); //0
marci@510
   191
  typedef Graph::NodeMap<int> NodeFlow; 
marci@510
   192
  NodeFlow gnf(g); //0 
marci@510
   193
marci@510
   194
  typedef stGraphWrapper<Graph>::EdgeMapWrapper<EdgeCap, NodeCap> CapMap; 
marci@510
   195
  typedef stGraphWrapper<Graph>::EdgeMapWrapper<EdgeFlow, NodeFlow> FlowMap; 
marci@510
   196
  CapMap cm(ge1, gn1);
marci@510
   197
  FlowMap fm(gef, gnf);
marci@510
   198
marci@510
   199
  //Timer ts;
marci@510
   200
  ts.reset();
marci@510
   201
  //stGW::EdgeMap<int> flow(stgw);
marci@510
   202
  MaxFlow<stGW, int, CapMap, FlowMap> 
marci@510
   203
    max_flow_test1(stgw, stgw.S_NODE, stgw.T_NODE, cm, fm);
marci@510
   204
  max_flow_test1.run();
marci@510
   205
//  while (max_flow_test.augmentOnShortestPath()) { }
marci@510
   206
//  typedef ListGraph MutableGraph;
marci@510
   207
//  while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) {
marci@510
   208
//  while (max_flow_test.augmentOnBlockingFlow2()) {
marci@510
   209
//   std::cout << max_flow_test.flowValue() << std::endl;
marci@510
   210
//  }
marci@510
   211
  std::cout << "max flow value: " << max_flow_test1.flowValue() << std::endl;
marci@510
   212
  std::cout << "elapsed time: " << ts << std::endl;
marci@510
   213
//   FOR_EACH_LOC(Graph::EdgeIt, e, g) { 
marci@510
   214
//     if (gef[e]) std::cout << e << std::endl; 
marci@510
   215
//   }
marci@510
   216
  std::cout << std::endl;
marci@510
   217
marci@510
   218
  ts.reset();
marci@510
   219
  FOR_EACH_LOC(Graph::EdgeIt, e, g) gef.set(e, 0); 
marci@510
   220
  FOR_EACH_LOC(Graph::NodeIt, n, g) gnf.set(n, 0); 
marci@510
   221
  MaxMatching<Graph, ConstMap<Graph::Edge, int>, ConstMap<Graph::Node, int>, 
marci@510
   222
    Graph::EdgeMap<int>, Graph::NodeMap<int> > 
marci@510
   223
    matching_test(g, ge1, gn1, gef, gnf);
marci@510
   224
  matching_test.run();
marci@510
   225
marci@510
   226
  std::cout << "max flow value: " << matching_test.matchingValue() << std::endl;
marci@510
   227
  std::cout << "elapsed time: " << ts << std::endl;
marci@510
   228
//   FOR_EACH_LOC(Graph::EdgeIt, e, g) { 
marci@510
   229
//     if (gef[e]) std::cout << e << std::endl; 
marci@510
   230
//   }
marci@510
   231
  std::cout << std::endl;
marci@510
   232
  return 0;
marci@510
   233
}