src/work/marci/lp/max_flow_by_lp.cc
author marci
Sat, 20 Nov 2004 16:12:47 +0000
changeset 1015 e3bb0e118bb4
parent 1014 aae850a2394d
child 1017 f588efc6d607
permissions -rw-r--r--
RoadMap to more general flow algs.
marci@764
     1
// -*- c++ -*-
marci@764
     2
#include <iostream>
marci@764
     3
#include <fstream>
marci@764
     4
alpar@921
     5
#include <lemon/smart_graph.h>
marci@1014
     6
#include <lemon/list_graph.h>
alpar@921
     7
#include <lemon/dimacs.h>
alpar@921
     8
#include <lemon/time_measure.h>
marci@764
     9
//#include <graph_wrapper.h>
marci@1014
    10
#include <lemon/preflow.h>
marci@764
    11
#include <augmenting_flow.h>
marci@764
    12
//#include <preflow_res.h>
marci@764
    13
#include <lp_solver_wrapper.h>
marci@764
    14
marci@764
    15
// Use a DIMACS max flow file as stdin.
marci@764
    16
// max_flow_demo < dimacs_max_flow_file
marci@764
    17
marci@1015
    18
using namespace lemon;
marci@1015
    19
marci@1015
    20
namespace lemon {
marci@1015
    21
marci@1015
    22
  template<typename Edge, typename EdgeIndexMap> 
marci@1015
    23
  class PrimalMap {
marci@1015
    24
  protected:
marci@1015
    25
    LPSolverWrapper* lp;
marci@1015
    26
    EdgeIndexMap* edge_index_map;
marci@1015
    27
  public:
marci@1015
    28
    PrimalMap(LPSolverWrapper& _lp, EdgeIndexMap& _edge_index_map) : 
marci@1015
    29
      lp(&_lp), edge_index_map(&_edge_index_map) { }
marci@1015
    30
    double operator[](Edge e) const { 
marci@1015
    31
      return lp->getPrimal((*edge_index_map)[e]);
marci@1015
    32
    }
marci@1015
    33
  };
marci@1015
    34
marci@1015
    35
  // excess: rho-delta
marci@1015
    36
  template <typename Graph, typename Num,
marci@1015
    37
	    typename Excess=typename Graph::template NodeMap<Num>, 
marci@1015
    38
	    typename LCapMap=typename Graph::template EdgeMap<Num>,
marci@1015
    39
	    typename CapMap=typename Graph::template EdgeMap<Num>,
marci@1015
    40
            typename FlowMap=typename Graph::template EdgeMap<Num>,
marci@1015
    41
	    typename CostMap=typename Graph::template EdgeMap<Num> >
marci@1015
    42
  class MinCostGenFlow {
marci@1015
    43
  protected:
marci@1015
    44
    const Graph& g;
marci@1015
    45
    const Excess& excess;
marci@1015
    46
    const LCapMap& lcapacity;
marci@1015
    47
    const CapMap& capacity;
marci@1015
    48
    FlowMap& flow;
marci@1015
    49
    const CostMap& cost;
marci@1015
    50
  public:
marci@1015
    51
    MinCostGenFlow(const Graph& _g, const Excess& _excess, 
marci@1015
    52
		   const LCapMap& _lcapacity, const CapMap& _capacity, 
marci@1015
    53
		   FlowMap& _flow, 
marci@1015
    54
		   const CostMap& _cost) :
marci@1015
    55
      g(_g), excess(_excess), lcapacity(_lcapacity),
marci@1015
    56
      capacity(_capacity), flow(_flow), cost(_cost) { }
marci@1015
    57
    void run() {
marci@1015
    58
      LPSolverWrapper lp;
marci@1015
    59
      lp.setMinimize();
marci@1015
    60
      typedef LPSolverWrapper::ColIt ColIt;
marci@1015
    61
      typedef LPSolverWrapper::RowIt RowIt;
marci@1015
    62
      typedef typename Graph::template EdgeMap<ColIt> EdgeIndexMap;
marci@1015
    63
      EdgeIndexMap edge_index_map(g);
marci@1015
    64
      PrimalMap<typename Graph::Edge, EdgeIndexMap> lp_flow(lp, edge_index_map);
marci@1015
    65
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1015
    66
	ColIt col_it=lp.addCol();
marci@1015
    67
	edge_index_map.set(e, col_it);
marci@1015
    68
	if (lcapacity[e]==capacity[e])
marci@1015
    69
	  lp.setColBounds(col_it, LPX_FX, lcapacity[e], capacity[e]);
marci@1015
    70
	else 
marci@1015
    71
	  lp.setColBounds(col_it, LPX_DB, lcapacity[e], capacity[e]);
marci@1015
    72
	lp.setObjCoef(col_it, cost[e]);
marci@1015
    73
      }
marci@1015
    74
      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
marci@1015
    75
	typename Graph::template EdgeMap<Num> coeffs(g, 0);
marci@1015
    76
	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
marci@1015
    77
	coeffs.set(e, coeffs[e]+1);
marci@1015
    78
	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) 
marci@1015
    79
	coeffs.set(e, coeffs[e]-1);
marci@1015
    80
	RowIt row_it=lp.addRow();
marci@1015
    81
	typename std::vector< std::pair<ColIt, double> > row;
marci@1015
    82
	//std::cout << "node:" <<g.id(n)<<std::endl;
marci@1015
    83
	for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1015
    84
	  if (coeffs[e]!=0) {
marci@1015
    85
	    //std::cout << " edge:" <<g.id(e)<<" "<<coeffs[e];
marci@1015
    86
	    row.push_back(std::make_pair(edge_index_map[e], coeffs[e]));
marci@1015
    87
	  }
marci@1015
    88
	}
marci@1015
    89
	//std::cout << std::endl;
marci@1015
    90
	lp.setRowCoeffs(row_it, row.begin(), row.end());
marci@1015
    91
	lp.setRowBounds(row_it, LPX_FX, 0.0, 0.0);
marci@1015
    92
      }
marci@1015
    93
      lp.solveSimplex();
marci@1015
    94
      //std::cout << lp.colNum() << std::endl;
marci@1015
    95
      //std::cout << lp.rowNum() << std::endl;
marci@1015
    96
      //std::cout << "flow value: "<< lp.getObjVal() << std::endl;
marci@1015
    97
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) 
marci@1015
    98
      flow.set(e, lp_flow[e]);
marci@1015
    99
    }
marci@1015
   100
  };
marci@1015
   101
marci@1015
   102
}
marci@764
   103
marci@764
   104
int main(int, char **) {
marci@764
   105
marci@1014
   106
  typedef ListGraph MutableGraph;
marci@1014
   107
  typedef SmartGraph Graph;
marci@764
   108
  typedef Graph::Node Node;
marci@1015
   109
  typedef Graph::Edge Edge;
marci@764
   110
  typedef Graph::EdgeIt EdgeIt;
marci@764
   111
marci@764
   112
  Graph g;
marci@764
   113
marci@764
   114
  Node s, t;
marci@764
   115
  Graph::EdgeMap<int> cap(g);
marci@764
   116
  //readDimacsMaxFlow(std::cin, g, s, t, cap);
marci@764
   117
  readDimacs(std::cin, g, cap, s, t);
marci@764
   118
  Timer ts;
marci@764
   119
  Graph::EdgeMap<int> flow(g); //0 flow
marci@1014
   120
  Preflow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > 
marci@764
   121
    max_flow_test(g, s, t, cap, flow);
marci@764
   122
  AugmentingFlow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > 
marci@764
   123
    augmenting_flow_test(g, s, t, cap, flow);
marci@764
   124
  
marci@764
   125
  Graph::NodeMap<bool> cut(g);
marci@764
   126
marci@764
   127
  {
marci@764
   128
    std::cout << "preflow ..." << std::endl;
marci@764
   129
    ts.reset();
marci@764
   130
    max_flow_test.run();
marci@764
   131
    std::cout << "elapsed time: " << ts << std::endl;
marci@764
   132
    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
marci@1014
   133
    max_flow_test.minCut(cut);
marci@764
   134
marci@1015
   135
    for (EdgeIt e(g); e!=INVALID; ++e) {
alpar@986
   136
      if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
marci@764
   137
	std::cout << "Slackness does not hold!" << std::endl;
alpar@986
   138
      if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
marci@764
   139
	std::cout << "Slackness does not hold!" << std::endl;
marci@764
   140
    }
marci@764
   141
  }
marci@764
   142
marci@764
   143
//   {
marci@764
   144
//     std::cout << "preflow ..." << std::endl;
marci@764
   145
//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
marci@764
   146
//     ts.reset();
marci@1014
   147
//     max_flow_test.preflow(Preflow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >::GEN_FLOW);
marci@764
   148
//     std::cout << "elapsed time: " << ts << std::endl;
marci@764
   149
//     std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
marci@764
   150
marci@764
   151
//     FOR_EACH_LOC(Graph::EdgeIt, e, g) {
alpar@986
   152
//       if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
marci@764
   153
// 	std::cout << "Slackness does not hold!" << std::endl;
alpar@986
   154
//       if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
marci@764
   155
// 	std::cout << "Slackness does not hold!" << std::endl;
marci@764
   156
//     }
marci@764
   157
//   }
marci@764
   158
marci@764
   159
//   {
marci@764
   160
//     std::cout << "wrapped preflow ..." << std::endl;
marci@764
   161
//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
marci@764
   162
//     ts.reset();
marci@764
   163
//     pre_flow_res.run();
marci@764
   164
//     std::cout << "elapsed time: " << ts << std::endl;
marci@764
   165
//     std::cout << "flow value: "<< pre_flow_test.flowValue() << std::endl;
marci@764
   166
//   }
marci@764
   167
marci@764
   168
  {
marci@764
   169
    std::cout << "physical blocking flow augmentation ..." << std::endl;
marci@1015
   170
    for (EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0);
marci@764
   171
    ts.reset();
marci@764
   172
    int i=0;
marci@764
   173
    while (augmenting_flow_test.augmentOnBlockingFlow<MutableGraph>()) { ++i; }
marci@764
   174
    std::cout << "elapsed time: " << ts << std::endl;
marci@764
   175
    std::cout << "number of augmentation phases: " << i << std::endl; 
marci@764
   176
    std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl;
marci@764
   177
marci@1015
   178
    for (EdgeIt e(g); e!=INVALID; ++e) {
alpar@986
   179
      if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
marci@764
   180
	std::cout << "Slackness does not hold!" << std::endl;
alpar@986
   181
      if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
marci@764
   182
	std::cout << "Slackness does not hold!" << std::endl;
marci@764
   183
    }
marci@764
   184
  }
marci@764
   185
marci@764
   186
//   {
marci@764
   187
//     std::cout << "faster physical blocking flow augmentation ..." << std::endl;
marci@764
   188
//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
marci@764
   189
//     ts.reset();
marci@764
   190
//     int i=0;
marci@764
   191
//     while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) { ++i; }
marci@764
   192
//     std::cout << "elapsed time: " << ts << std::endl;
marci@764
   193
//     std::cout << "number of augmentation phases: " << i << std::endl; 
marci@764
   194
//     std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
marci@764
   195
//   }
marci@764
   196
marci@764
   197
  {
marci@764
   198
    std::cout << "on-the-fly blocking flow augmentation ..." << std::endl;
marci@1015
   199
    for (EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0);
marci@764
   200
    ts.reset();
marci@764
   201
    int i=0;
marci@764
   202
    while (augmenting_flow_test.augmentOnBlockingFlow2()) { ++i; }
marci@764
   203
    std::cout << "elapsed time: " << ts << std::endl;
marci@764
   204
    std::cout << "number of augmentation phases: " << i << std::endl; 
marci@764
   205
    std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl;
marci@764
   206
marci@1015
   207
    for (EdgeIt e(g); e!=INVALID; ++e) {
alpar@986
   208
      if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
marci@764
   209
	std::cout << "Slackness does not hold!" << std::endl;
alpar@986
   210
      if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
marci@764
   211
	std::cout << "Slackness does not hold!" << std::endl;
marci@764
   212
    }
marci@764
   213
  }
marci@764
   214
marci@764
   215
//   {
marci@764
   216
//     std::cout << "on-the-fly shortest path augmentation ..." << std::endl;
marci@764
   217
//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
marci@764
   218
//     ts.reset();
marci@764
   219
//     int i=0;
marci@764
   220
//     while (augmenting_flow_test.augmentOnShortestPath()) { ++i; }
marci@764
   221
//     std::cout << "elapsed time: " << ts << std::endl;
marci@764
   222
//     std::cout << "number of augmentation phases: " << i << std::endl; 
marci@764
   223
//     std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl;
marci@764
   224
marci@764
   225
//     FOR_EACH_LOC(Graph::EdgeIt, e, g) {
alpar@986
   226
//       if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
marci@764
   227
// 	std::cout << "Slackness does not hold!" << std::endl;
alpar@986
   228
//       if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
marci@764
   229
// 	std::cout << "Slackness does not hold!" << std::endl;
marci@764
   230
//     }
marci@764
   231
//   }
marci@764
   232
marci@764
   233
//   {
marci@764
   234
//     std::cout << "on-the-fly shortest path augmentation ..." << std::endl;
marci@764
   235
//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
marci@764
   236
//     ts.reset();
marci@764
   237
//     int i=0;
marci@764
   238
//     while (augmenting_flow_test.augmentOnShortestPath2()) { ++i; }
marci@764
   239
//     std::cout << "elapsed time: " << ts << std::endl;
marci@764
   240
//     std::cout << "number of augmentation phases: " << i << std::endl; 
marci@764
   241
//     std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl;
marci@764
   242
marci@764
   243
//     FOR_EACH_LOC(Graph::EdgeIt, e, g) {
alpar@986
   244
//       if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
marci@764
   245
// 	std::cout << "Slackness does not hold!" << std::endl;
alpar@986
   246
//       if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
marci@764
   247
// 	std::cout << "Slackness does not hold!" << std::endl;
marci@764
   248
//     }
marci@764
   249
//   }
marci@764
   250
marci@764
   251
  ts.reset();
marci@1015
   252
marci@1015
   253
  Edge e=g.addEdge(t, s);
marci@1015
   254
  Graph::EdgeMap<int> cost(g, 0);
marci@1015
   255
  cost.set(e, -1);
marci@1015
   256
  cap.set(e, 10000);
marci@1015
   257
  typedef ConstMap<Node, int> Excess;
marci@1015
   258
  Excess excess(0);
marci@1015
   259
  typedef ConstMap<Edge, int> LCap;
marci@1015
   260
  LCap lcap(0);
marci@1015
   261
marci@1015
   262
  MinCostGenFlow<Graph, int, Excess, LCap> 
marci@1015
   263
    min_cost(g, excess, lcap, cap, flow, cost); 
marci@1015
   264
  min_cost.run();
marci@1015
   265
marci@764
   266
  std::cout << "elapsed time: " << ts << std::endl;
marci@1015
   267
  std::cout << "flow value: "<< flow[e] << std::endl;
marci@764
   268
}