src/work/marci/bipartite_matching_try_3.cc
author athos
Tue, 04 May 2004 16:52:15 +0000
changeset 530 d9c06ac0b3a3
parent 510 72143568cadc
child 555 995bc1f1a3ce
permissions -rw-r--r--
Minimum cost flows of small values: algorithm from Andras Frank's lecture notes (approximately)
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
protected:
marci@510
    47
//   EdgeCap* edge_cap;
marci@510
    48
//   NodeCap* node_cap;
marci@510
    49
//   EdgeFlow* edge_flow;
marci@510
    50
//   NodeFlow* node_flow;
marci@510
    51
  typedef  stGraphWrapper<Graph> stGW;
marci@510
    52
  stGW stgw;
marci@510
    53
  typedef typename stGW::template EdgeMapWrapper<EdgeCap, NodeCap> CapMap; 
marci@510
    54
  CapMap cap;
marci@512
    55
  NodeFlow* node_flow;
marci@510
    56
  typedef typename stGW::template EdgeMapWrapper<EdgeFlow, NodeFlow> FlowMap;
marci@510
    57
  FlowMap flow;
marci@510
    58
  MaxFlow<stGW, int, CapMap, FlowMap> mf;
marci@510
    59
  //graph* g;
marci@510
    60
  //EdgeCap* edge_cap;
marci@510
    61
  //EdgeFlow* edge_flow;
marci@510
    62
public:
marci@510
    63
  MaxMatching(Graph& _g, EdgeCap& _edge_cap, NodeCap& _node_cap, 
marci@510
    64
	      EdgeFlow& _edge_flow, NodeFlow& _node_flow) : 
marci@510
    65
    stgw(_g), 
marci@512
    66
    cap(_edge_cap, _node_cap), 
marci@512
    67
    node_flow(0), 
marci@512
    68
    flow(_edge_flow, _node_flow), 
marci@510
    69
    mf(stgw, stgw.S_NODE, stgw.T_NODE, cap, flow) { }
marci@512
    70
  MaxMatching(Graph& _g, EdgeCap& _edge_cap, NodeCap& _node_cap, 
marci@512
    71
	      EdgeFlow& _edge_flow/*, NodeFlow& _node_flow*/) : 
marci@512
    72
    stgw(_g), 
marci@512
    73
    cap(_edge_cap, _node_cap), 
marci@512
    74
    node_flow(new NodeFlow(_g)), 
marci@512
    75
    flow(_edge_flow, *node_flow), 
marci@512
    76
    mf(stgw, stgw.S_NODE, stgw.T_NODE, cap, flow) { }
marci@512
    77
  ~MaxMatching() { if (node_flow) delete node_flow; }
marci@510
    78
  void run() { mf.run(); } 
marci@510
    79
  int matchingValue() { return mf.flowValue(); }
marci@510
    80
};
marci@510
    81
marci@510
    82
/**
marci@510
    83
 * Inicializalja a veletlenszamgeneratort.
marci@510
    84
 * Figyelem, ez nem jo igazi random szamokhoz,
marci@510
    85
 * erre ne bizzad a titkaidat!
marci@510
    86
 */
marci@510
    87
void random_init()
marci@510
    88
{
marci@510
    89
	unsigned int seed = getpid();
marci@510
    90
	seed |= seed << 15;
marci@510
    91
	seed ^= time(0);
marci@510
    92
marci@510
    93
	srand(seed);
marci@510
    94
}
marci@510
    95
marci@510
    96
/**
marci@510
    97
 * Egy veletlen int-et ad vissza 0 es m-1 kozott.
marci@510
    98
 */
marci@510
    99
int random(int m)
marci@510
   100
{
marci@510
   101
  return int( double(m) * rand() / (RAND_MAX + 1.0) );
marci@510
   102
}
marci@510
   103
marci@510
   104
int main() {
marci@510
   105
  //typedef UndirListGraph Graph; 
marci@510
   106
  typedef BipartiteGraph<ListGraph> Graph;
marci@510
   107
  
marci@510
   108
  typedef Graph::Node Node;
marci@510
   109
  typedef Graph::NodeIt NodeIt;
marci@510
   110
  typedef Graph::Edge Edge;
marci@510
   111
  typedef Graph::EdgeIt EdgeIt;
marci@510
   112
  typedef Graph::OutEdgeIt OutEdgeIt;
marci@510
   113
marci@510
   114
  Graph g;
marci@510
   115
marci@510
   116
  std::vector<Graph::Node> s_nodes;
marci@510
   117
  std::vector<Graph::Node> t_nodes;
marci@510
   118
marci@510
   119
  int a;
marci@510
   120
  std::cout << "number of nodes in the first color class=";
marci@510
   121
  std::cin >> a; 
marci@510
   122
  int b;
marci@510
   123
  std::cout << "number of nodes in the second color class=";
marci@510
   124
  std::cin >> b; 
marci@510
   125
  int m;
marci@510
   126
  std::cout << "number of edges=";
marci@510
   127
  std::cin >> m; 
marci@510
   128
  
marci@510
   129
  std::cout << "Generatig a random bipartite graph..." << std::endl;
marci@510
   130
  for (int i=0; i<a; ++i) s_nodes.push_back(g.addNode(false));
marci@510
   131
  for (int i=0; i<b; ++i) t_nodes.push_back(g.addNode(true));
marci@510
   132
marci@510
   133
  random_init();
marci@510
   134
  for(int i=0; i<m; ++i) {
marci@510
   135
    g.addEdge(s_nodes[random(a)], t_nodes[random(b)]);
marci@510
   136
  }
marci@510
   137
marci@512
   138
//   std::cout << "Edges of the bipartite graph:" << std::endl;
marci@512
   139
//   FOR_EACH_LOC(EdgeIt, e, g) std::cout << e << " ";
marci@512
   140
//   std::cout << std::endl;
marci@510
   141
marci@512
   142
//   std::cout << "Nodes:" << std::endl;
marci@512
   143
//   FOR_EACH_LOC(Graph::NodeIt, v, g) std::cout << v << " ";
marci@512
   144
//   std::cout << std::endl;
marci@512
   145
//   std::cout << "Nodes in T:" << std::endl;
marci@512
   146
//   FOR_EACH_INC_LOC(Graph::ClassNodeIt, v, g, Graph::T_CLASS) std::cout << v << " ";
marci@512
   147
//   std::cout << std::endl;
marci@512
   148
//   std::cout << "Nodes in S:" << std::endl;
marci@512
   149
//   FOR_EACH_INC_LOC(Graph::ClassNodeIt, v, g, Graph::S_CLASS) std::cout << v << " ";
marci@512
   150
//   std::cout << std::endl;
marci@510
   151
marci@512
   152
//   std::cout << "Erasing the first node..." << std::endl;
marci@512
   153
//   NodeIt n;
marci@512
   154
//   g.first(n);
marci@512
   155
//   g.erase(n);
marci@512
   156
//   std::cout << "Nodes of the bipartite graph:" << std::endl;
marci@512
   157
//   FOR_EACH_GLOB(n, g) std::cout << n << " ";
marci@512
   158
//   std::cout << std::endl;
marci@510
   159
marci@512
   160
//   std::cout << "Nodes in T:" << std::endl;
marci@512
   161
//   FOR_EACH_INC_LOC(Graph::ClassNodeIt, v, g, Graph::T_CLASS) std::cout << v << " ";
marci@512
   162
//   std::cout << std::endl;
marci@512
   163
//   std::cout << "Nodes in S:" << std::endl;
marci@512
   164
//   FOR_EACH_INC_LOC(Graph::ClassNodeIt, v, g, Graph::S_CLASS) std::cout << v << " ";
marci@512
   165
//   std::cout << std::endl;
marci@510
   166
marci@510
   167
  typedef stGraphWrapper<Graph> stGW;
marci@510
   168
  stGW stgw(g);
marci@510
   169
  ConstMap<stGW::Edge, int> const1map(1);
marci@510
   170
marci@510
   171
  Timer ts;
marci@510
   172
  ts.reset();
marci@510
   173
  stGW::EdgeMap<int> flow(stgw);
marci@510
   174
  MaxFlow<stGW, int, ConstMap<stGW::Edge, int>, stGW::EdgeMap<int> > 
marci@510
   175
    max_flow_test(stgw, stgw.S_NODE, stgw.T_NODE, const1map, flow);
marci@510
   176
  max_flow_test.run();
marci@510
   177
//  while (max_flow_test.augmentOnShortestPath()) { }
marci@510
   178
//  typedef ListGraph MutableGraph;
marci@510
   179
//  while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) {
marci@510
   180
//  while (max_flow_test.augmentOnBlockingFlow2()) {
marci@510
   181
//   std::cout << max_flow_test.flowValue() << std::endl;
marci@510
   182
//  }
marci@510
   183
  std::cout << "max flow value: " << max_flow_test.flowValue() << std::endl;
marci@510
   184
  std::cout << "elapsed time: " << ts << std::endl;
marci@512
   185
//   FOR_EACH_LOC(stGW::EdgeIt, e, stgw) { 
marci@512
   186
//     if (flow[e]) std::cout << e << std::endl; 
marci@512
   187
//   }
marci@510
   188
  std::cout << std::endl;
marci@510
   189
marci@510
   190
  typedef ConstMap<Graph::Edge, int> EdgeCap; 
marci@510
   191
  EdgeCap ge1(1);
marci@510
   192
  typedef ConstMap<Graph::Node, int> NodeCap;
marci@510
   193
  NodeCap gn1(1);
marci@510
   194
  typedef Graph::EdgeMap<int> EdgeFlow;
marci@510
   195
  EdgeFlow gef(g); //0
marci@510
   196
  typedef Graph::NodeMap<int> NodeFlow; 
marci@510
   197
  NodeFlow gnf(g); //0 
marci@510
   198
marci@510
   199
  typedef stGraphWrapper<Graph>::EdgeMapWrapper<EdgeCap, NodeCap> CapMap; 
marci@510
   200
  typedef stGraphWrapper<Graph>::EdgeMapWrapper<EdgeFlow, NodeFlow> FlowMap; 
marci@510
   201
  CapMap cm(ge1, gn1);
marci@510
   202
  FlowMap fm(gef, gnf);
marci@510
   203
marci@510
   204
  //Timer ts;
marci@510
   205
  ts.reset();
marci@510
   206
  //stGW::EdgeMap<int> flow(stgw);
marci@510
   207
  MaxFlow<stGW, int, CapMap, FlowMap> 
marci@510
   208
    max_flow_test1(stgw, stgw.S_NODE, stgw.T_NODE, cm, fm);
marci@510
   209
  max_flow_test1.run();
marci@510
   210
//  while (max_flow_test.augmentOnShortestPath()) { }
marci@510
   211
//  typedef ListGraph MutableGraph;
marci@510
   212
//  while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) {
marci@510
   213
//  while (max_flow_test.augmentOnBlockingFlow2()) {
marci@510
   214
//   std::cout << max_flow_test.flowValue() << std::endl;
marci@510
   215
//  }
marci@510
   216
  std::cout << "max flow value: " << max_flow_test1.flowValue() << std::endl;
marci@510
   217
  std::cout << "elapsed time: " << ts << std::endl;
marci@510
   218
//   FOR_EACH_LOC(Graph::EdgeIt, e, g) { 
marci@510
   219
//     if (gef[e]) std::cout << e << std::endl; 
marci@510
   220
//   }
marci@510
   221
  std::cout << std::endl;
marci@510
   222
marci@510
   223
  ts.reset();
marci@510
   224
  FOR_EACH_LOC(Graph::EdgeIt, e, g) gef.set(e, 0); 
marci@510
   225
  FOR_EACH_LOC(Graph::NodeIt, n, g) gnf.set(n, 0); 
marci@510
   226
  MaxMatching<Graph, ConstMap<Graph::Edge, int>, ConstMap<Graph::Node, int>, 
marci@510
   227
    Graph::EdgeMap<int>, Graph::NodeMap<int> > 
marci@510
   228
    matching_test(g, ge1, gn1, gef, gnf);
marci@510
   229
  matching_test.run();
marci@510
   230
marci@510
   231
  std::cout << "max flow value: " << matching_test.matchingValue() << std::endl;
marci@510
   232
  std::cout << "elapsed time: " << ts << std::endl;
marci@510
   233
//   FOR_EACH_LOC(Graph::EdgeIt, e, g) { 
marci@510
   234
//     if (gef[e]) std::cout << e << std::endl; 
marci@510
   235
//   }
marci@510
   236
  std::cout << std::endl;
marci@512
   237
marci@512
   238
  ts.reset();
marci@512
   239
  FOR_EACH_LOC(Graph::EdgeIt, e, g) gef.set(e, 0); 
marci@512
   240
  //FOR_EACH_LOC(Graph::NodeIt, n, g) gnf.set(n, 0); 
marci@512
   241
  MaxMatching<Graph, ConstMap<Graph::Edge, int>, ConstMap<Graph::Node, int>, 
marci@512
   242
    Graph::EdgeMap<int>, Graph::NodeMap<int> > 
marci@512
   243
    matching_test_1(g, ge1, gn1, gef/*, gnf*/);
marci@512
   244
  matching_test_1.run();
marci@512
   245
marci@512
   246
  std::cout << "max flow value: " << matching_test_1.matchingValue() << std::endl;
marci@512
   247
  std::cout << "elapsed time: " << ts << std::endl;
marci@512
   248
//   FOR_EACH_LOC(Graph::EdgeIt, e, g) { 
marci@512
   249
//     if (gef[e]) std::cout << e << std::endl; 
marci@512
   250
//   }
marci@512
   251
  std::cout << std::endl;
marci@512
   252
marci@510
   253
  return 0;
marci@510
   254
}