src/work/marci/lp/min_cost_gen_flow.h
author alpar
Thu, 31 Mar 2005 14:04:13 +0000
changeset 1284 b941d044f87b
parent 1074 4a24a46407db
permissions -rw-r--r--
SmartGraph can also split() a node!
marci@1017
     1
// -*- c++ -*-
marci@1017
     2
#ifndef LEMON_MIN_COST_GEN_FLOW_H
marci@1017
     3
#define LEMON_MIN_COST_GEN_FLOW_H
marci@1025
     4
#include <iostream>
marci@1017
     5
//#include <fstream>
marci@1017
     6
marci@1025
     7
#include <lemon/smart_graph.h>
marci@1025
     8
#include <lemon/list_graph.h>
marci@1017
     9
//#include <lemon/dimacs.h>
marci@1017
    10
//#include <lemon/time_measure.h>
marci@1017
    11
//#include <graph_wrapper.h>
marci@1025
    12
#include <lemon/preflow.h>
marci@1028
    13
#include <lemon/min_cost_flow.h>
marci@1017
    14
//#include <augmenting_flow.h>
marci@1017
    15
//#include <preflow_res.h>
marci@1028
    16
#include <work/marci/merge_node_graph_wrapper.h>
marci@1074
    17
#include <work/marci/lp/lp_solver_wrapper_3.h>
marci@1017
    18
marci@1017
    19
namespace lemon {
marci@1017
    20
marci@1017
    21
  template<typename Edge, typename EdgeIndexMap> 
marci@1017
    22
  class PrimalMap {
marci@1017
    23
  protected:
marci@1081
    24
    LPGLPK* lp;
marci@1017
    25
    EdgeIndexMap* edge_index_map;
marci@1017
    26
  public:
marci@1081
    27
    PrimalMap(LPGLPK& _lp, EdgeIndexMap& _edge_index_map) : 
marci@1017
    28
      lp(&_lp), edge_index_map(&_edge_index_map) { }
marci@1017
    29
    double operator[](Edge e) const { 
marci@1017
    30
      return lp->getPrimal((*edge_index_map)[e]);
marci@1017
    31
    }
marci@1017
    32
  };
marci@1017
    33
marci@1028
    34
  // excess: rho-delta egyelore csak =0-ra.
marci@1017
    35
  template <typename Graph, typename Num,
marci@1017
    36
	    typename Excess=typename Graph::template NodeMap<Num>, 
marci@1017
    37
	    typename LCapMap=typename Graph::template EdgeMap<Num>,
marci@1017
    38
	    typename CapMap=typename Graph::template EdgeMap<Num>,
marci@1017
    39
            typename FlowMap=typename Graph::template EdgeMap<Num>,
marci@1017
    40
	    typename CostMap=typename Graph::template EdgeMap<Num> >
marci@1017
    41
  class MinCostGenFlow {
marci@1017
    42
  protected:
marci@1017
    43
    const Graph& g;
marci@1017
    44
    const Excess& excess;
marci@1017
    45
    const LCapMap& lcapacity;
marci@1017
    46
    const CapMap& capacity;
marci@1017
    47
    FlowMap& flow;
marci@1017
    48
    const CostMap& cost;
marci@1017
    49
  public:
marci@1017
    50
    MinCostGenFlow(const Graph& _g, const Excess& _excess, 
marci@1017
    51
		   const LCapMap& _lcapacity, const CapMap& _capacity, 
marci@1017
    52
		   FlowMap& _flow, 
marci@1017
    53
		   const CostMap& _cost) :
marci@1017
    54
      g(_g), excess(_excess), lcapacity(_lcapacity),
marci@1017
    55
      capacity(_capacity), flow(_flow), cost(_cost) { }
marci@1025
    56
    bool feasible() {
marci@1025
    57
      //      std::cout << "making new vertices..." << std::endl; 
marci@1025
    58
      typedef ListGraph Graph2;
marci@1025
    59
      Graph2 g2;
marci@1025
    60
      typedef MergeEdgeGraphWrapper<const Graph, Graph2> GW;
marci@1025
    61
      //      std::cout << "merging..." << std::endl; 
marci@1025
    62
      GW gw(g, g2);
marci@1025
    63
      typename GW::Node s(INVALID, g2.addNode(), true);
marci@1025
    64
      typename GW::Node t(INVALID, g2.addNode(), true);
marci@1025
    65
      typedef SmartGraph Graph3;
marci@1025
    66
      //      std::cout << "making extender graph..." << std::endl; 
marci@1025
    67
      typedef NewEdgeSetGraphWrapper2<GW, Graph3> GWW;
marci@1025
    68
//       {
marci@1025
    69
// 	checkConcept<StaticGraph, GWW>();   
marci@1025
    70
//       }
marci@1025
    71
      GWW gww(gw);
marci@1025
    72
      typedef AugmentingGraphWrapper<GW, GWW> GWWW;
marci@1025
    73
      GWWW gwww(gw, gww);
marci@1025
    74
marci@1025
    75
      //      std::cout << "making new edges..." << std::endl; 
marci@1025
    76
      typename GWWW::template EdgeMap<Num> translated_cap(gwww);
marci@1025
    77
marci@1028
    78
      for (typename GW::EdgeIt e(gw); e!=INVALID; ++e) {
marci@1028
    79
	translated_cap.set(typename GWWW::Edge(e,INVALID,false), 
marci@1028
    80
			   capacity[e]-lcapacity[e]);
marci@1028
    81
	//	cout << "t_cap " << gw.id(e) << " " 
marci@1028
    82
	//	     << translated_cap[typename GWWW::Edge(e,INVALID,false)] << endl;
marci@1028
    83
      }
marci@1025
    84
marci@1025
    85
      Num expected=0;
marci@1025
    86
marci@1025
    87
      //      std::cout << "making new edges 2..." << std::endl; 
marci@1025
    88
      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
marci@1025
    89
	Num a=0;
marci@1025
    90
	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
marci@1025
    91
	  a+=lcapacity[e];
marci@1025
    92
	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) 
marci@1025
    93
	  a-=lcapacity[e];
marci@1025
    94
	if (excess[n]>a) {
marci@1025
    95
	  typename GWW::Edge e=
marci@1025
    96
	    gww.addEdge(typename GW::Node(n,INVALID,false), t);
marci@1025
    97
	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
marci@1025
    98
			     excess[n]-a);
marci@1028
    99
	  //	  std::cout << g.id(n) << "->t " << excess[n]-a << std::endl;
marci@1025
   100
	}
marci@1025
   101
	if (excess[n]<a) {
marci@1025
   102
	  typename GWW::Edge e=
marci@1025
   103
	    gww.addEdge(s, typename GW::Node(n,INVALID,false));
marci@1025
   104
	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
marci@1025
   105
			     a-excess[n]);
marci@1025
   106
	  expected+=a-excess[n];
marci@1028
   107
	  //	  std::cout << "s->" << g.id(n) << " "<< a-excess[n] <<std:: endl;
marci@1025
   108
	}
marci@1025
   109
      }
marci@1025
   110
marci@1025
   111
      //      std::cout << "preflow..." << std::endl; 
marci@1025
   112
      typename GWWW::template EdgeMap<Num> translated_flow(gwww, 0);
marci@1025
   113
      Preflow<GWWW, Num> preflow(gwww, s, t, 
marci@1025
   114
				 translated_cap, translated_flow);
marci@1025
   115
      preflow.run();
marci@1025
   116
      //      std::cout << "fv: " << preflow.flowValue() << std::endl; 
marci@1025
   117
      //      std::cout << "expected: " << expected << std::endl; 
marci@1025
   118
marci@1025
   119
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1025
   120
	typename GW::Edge ew(e, INVALID, false);
marci@1025
   121
	typename GWWW::Edge ewww(ew, INVALID, false);
marci@1025
   122
	flow.set(e, translated_flow[ewww]+lcapacity[e]);
marci@1025
   123
      }
marci@1033
   124
      return (preflow.flowValue()>=expected);
marci@1025
   125
    }
marci@1028
   126
    // for nonnegative costs
marci@1028
   127
    bool run() {
marci@1028
   128
      //      std::cout << "making new vertices..." << std::endl; 
marci@1028
   129
      typedef ListGraph Graph2;
marci@1028
   130
      Graph2 g2;
marci@1028
   131
      typedef MergeEdgeGraphWrapper<const Graph, Graph2> GW;
marci@1028
   132
      //      std::cout << "merging..." << std::endl; 
marci@1028
   133
      GW gw(g, g2);
marci@1028
   134
      typename GW::Node s(INVALID, g2.addNode(), true);
marci@1028
   135
      typename GW::Node t(INVALID, g2.addNode(), true);
marci@1028
   136
      typedef SmartGraph Graph3;
marci@1028
   137
      //      std::cout << "making extender graph..." << std::endl; 
marci@1028
   138
      typedef NewEdgeSetGraphWrapper2<GW, Graph3> GWW;
marci@1028
   139
//       {
marci@1028
   140
// 	checkConcept<StaticGraph, GWW>();   
marci@1028
   141
//       }
marci@1028
   142
      GWW gww(gw);
marci@1028
   143
      typedef AugmentingGraphWrapper<GW, GWW> GWWW;
marci@1028
   144
      GWWW gwww(gw, gww);
marci@1028
   145
marci@1028
   146
      //      std::cout << "making new edges..." << std::endl; 
marci@1028
   147
      typename GWWW::template EdgeMap<Num> translated_cap(gwww);
marci@1028
   148
marci@1028
   149
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1028
   150
	typename GW::Edge ew(e, INVALID, false);
marci@1028
   151
	typename GWWW::Edge ewww(ew, INVALID, false);
marci@1028
   152
	translated_cap.set(ewww, capacity[e]-lcapacity[e]);
marci@1028
   153
	//	cout << "t_cap " << g.id(e) << " " 
marci@1028
   154
	//	     << translated_cap[ewww] << endl;
marci@1028
   155
      }
marci@1028
   156
marci@1028
   157
      Num expected=0;
marci@1028
   158
marci@1028
   159
      //      std::cout << "making new edges 2..." << std::endl; 
marci@1028
   160
      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
marci@1028
   161
	//	std::cout << "node: " << g.id(n) << std::endl;
marci@1028
   162
	Num a=0;
marci@1028
   163
	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e) {
marci@1028
   164
	  a+=lcapacity[e];
marci@1028
   165
	  //	  std::cout << "bee: " << g.id(e) << " " << lcapacity[e] << std::endl;
marci@1028
   166
	}
marci@1028
   167
	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) {
marci@1028
   168
	  a-=lcapacity[e];
marci@1028
   169
	  //	  std::cout << "kie: " << g.id(e) << " " << lcapacity[e] << std::endl;
marci@1028
   170
	}
marci@1028
   171
	//	std::cout << "excess " << g.id(n) << ": " << a << std::endl;
marci@1028
   172
	if (0>a) {
marci@1028
   173
	  typename GWW::Edge e=
marci@1028
   174
	    gww.addEdge(typename GW::Node(n,INVALID,false), t);
marci@1028
   175
	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
marci@1028
   176
			     -a);
marci@1028
   177
	  //	  std::cout << g.id(n) << "->t " << -a << std::endl;
marci@1028
   178
	}
marci@1028
   179
	if (0<a) {
marci@1028
   180
	  typename GWW::Edge e=
marci@1028
   181
	    gww.addEdge(s, typename GW::Node(n,INVALID,false));
marci@1028
   182
	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
marci@1028
   183
			     a);
marci@1028
   184
	  expected+=a;
marci@1028
   185
	  //	  std::cout << "s->" << g.id(n) << " "<< a <<std:: endl;
marci@1028
   186
	}
marci@1028
   187
      }
marci@1028
   188
marci@1028
   189
      //      std::cout << "preflow..." << std::endl; 
marci@1028
   190
      typename GWWW::template EdgeMap<Num> translated_cost(gwww, 0);
marci@1028
   191
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1028
   192
	translated_cost.set(typename GWWW::Edge(
marci@1028
   193
        typename GW::Edge(e, INVALID, false), INVALID, false), cost[e]);
marci@1028
   194
      }
marci@1028
   195
      //      typename GWWW::template EdgeMap<Num> translated_flow(gwww, 0);
marci@1028
   196
      MinCostFlow<GWWW, typename GWWW::template EdgeMap<Num>, 
marci@1028
   197
      typename GWWW::template EdgeMap<Num> > 
marci@1028
   198
      min_cost_flow(gwww, translated_cost, translated_cap, 
marci@1028
   199
		    s, t);
marci@1028
   200
      while (min_cost_flow.augment()) { }
marci@1028
   201
      std::cout << "fv: " << min_cost_flow.flowValue() << std::endl; 
marci@1028
   202
      std::cout << "expected: " << expected << std::endl; 
marci@1028
   203
marci@1028
   204
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1028
   205
	typename GW::Edge ew(e, INVALID, false);
marci@1028
   206
	typename GWWW::Edge ewww(ew, INVALID, false);
marci@1028
   207
	//	std::cout << g.id(e) << " " << flow[e] << std::endl;
marci@1028
   208
	flow.set(e, lcapacity[e]+
marci@1028
   209
		 min_cost_flow.getFlow()[ewww]);
marci@1028
   210
      }
marci@1033
   211
      return (min_cost_flow.flowValue()>=expected);
marci@1028
   212
    }
marci@1028
   213
    void runByLP() {
marci@1081
   214
      typedef LPGLPK LPSolver;
marci@1031
   215
      LPSolver lp;
marci@1017
   216
      lp.setMinimize();
marci@1031
   217
      typedef LPSolver::ColIt ColIt;
marci@1031
   218
      typedef LPSolver::RowIt RowIt;
marci@1017
   219
      typedef typename Graph::template EdgeMap<ColIt> EdgeIndexMap;
marci@1017
   220
      EdgeIndexMap edge_index_map(g);
marci@1017
   221
      PrimalMap<typename Graph::Edge, EdgeIndexMap> lp_flow(lp, edge_index_map);
marci@1017
   222
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1017
   223
	ColIt col_it=lp.addCol();
marci@1017
   224
	edge_index_map.set(e, col_it);
marci@1017
   225
	if (lcapacity[e]==capacity[e])
marci@1081
   226
	  lp.setColBounds(col_it, LPSolver::FIXED, lcapacity[e], capacity[e]);
marci@1017
   227
	else 
marci@1081
   228
	  lp.setColBounds(col_it, LPSolver::DOUBLE, lcapacity[e], capacity[e]);
marci@1017
   229
	lp.setObjCoef(col_it, cost[e]);
marci@1017
   230
      }
marci@1074
   231
      LPSolver::ColIt col_it;
marci@1074
   232
      for (lp.col_iter_map.first(col_it, lp.VALID_CLASS); 
marci@1074
   233
	   lp.col_iter_map.valid(col_it); 
marci@1074
   234
	   lp.col_iter_map.next(col_it)) {
marci@1081
   235
//	std::cout << "ize " << lp.col_iter_map[col_it] << std::endl;
marci@1074
   236
      }
marci@1017
   237
      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
marci@1017
   238
	typename Graph::template EdgeMap<Num> coeffs(g, 0);
marci@1017
   239
	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
marci@1017
   240
	coeffs.set(e, coeffs[e]+1);
marci@1017
   241
	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) 
marci@1017
   242
	coeffs.set(e, coeffs[e]-1);
marci@1017
   243
	RowIt row_it=lp.addRow();
marci@1017
   244
	typename std::vector< std::pair<ColIt, double> > row;
marci@1017
   245
	//std::cout << "node:" <<g.id(n)<<std::endl;
marci@1017
   246
	for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1017
   247
	  if (coeffs[e]!=0) {
marci@1017
   248
	    //std::cout << " edge:" <<g.id(e)<<" "<<coeffs[e];
marci@1017
   249
	    row.push_back(std::make_pair(edge_index_map[e], coeffs[e]));
marci@1017
   250
	  }
marci@1017
   251
	}
marci@1017
   252
	//std::cout << std::endl;
marci@1081
   253
	//std::cout << " " << g.id(n) << " " << row.size() << std::endl;
marci@1017
   254
	lp.setRowCoeffs(row_it, row.begin(), row.end());
marci@1081
   255
	lp.setRowBounds(row_it, LPSolver::FIXED, 0.0, 0.0);
marci@1017
   256
      }
marci@1017
   257
      lp.solveSimplex();
marci@1017
   258
      //std::cout << lp.colNum() << std::endl;
marci@1017
   259
      //std::cout << lp.rowNum() << std::endl;
marci@1017
   260
      //std::cout << "flow value: "<< lp.getObjVal() << std::endl;
marci@1017
   261
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) 
marci@1017
   262
      flow.set(e, lp_flow[e]);
marci@1017
   263
    }
marci@1017
   264
  };
marci@1017
   265
marci@1017
   266
} // namespace lemon
marci@1017
   267
marci@1017
   268
#endif //LEMON_MIN_COST_GEN_FLOW_H