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