src/work/marci/lp/min_cost_gen_flow.h
author klao
Thu, 25 Nov 2004 14:48:24 +0000
changeset 1021 fd1d073b6557
child 1025 3b1ad8bc21da
permissions -rw-r--r--
Advances in UndirGraph.
* IterableExtender is complete
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@1017
     4
//#include <iostream>
marci@1017
     5
//#include <fstream>
marci@1017
     6
marci@1017
     7
//#include <lemon/smart_graph.h>
marci@1017
     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@1017
    12
//#include <lemon/preflow.h>
marci@1017
    13
//#include <augmenting_flow.h>
marci@1017
    14
//#include <preflow_res.h>
marci@1017
    15
#include <lemon/../work/marci/lp/lp_solver_wrapper.h>
marci@1017
    16
marci@1017
    17
namespace lemon {
marci@1017
    18
marci@1017
    19
  template<typename Edge, typename EdgeIndexMap> 
marci@1017
    20
  class PrimalMap {
marci@1017
    21
  protected:
marci@1017
    22
    LPSolverWrapper* lp;
marci@1017
    23
    EdgeIndexMap* edge_index_map;
marci@1017
    24
  public:
marci@1017
    25
    PrimalMap(LPSolverWrapper& _lp, EdgeIndexMap& _edge_index_map) : 
marci@1017
    26
      lp(&_lp), edge_index_map(&_edge_index_map) { }
marci@1017
    27
    double operator[](Edge e) const { 
marci@1017
    28
      return lp->getPrimal((*edge_index_map)[e]);
marci@1017
    29
    }
marci@1017
    30
  };
marci@1017
    31
marci@1017
    32
  // excess: rho-delta
marci@1017
    33
  template <typename Graph, typename Num,
marci@1017
    34
	    typename Excess=typename Graph::template NodeMap<Num>, 
marci@1017
    35
	    typename LCapMap=typename Graph::template EdgeMap<Num>,
marci@1017
    36
	    typename CapMap=typename Graph::template EdgeMap<Num>,
marci@1017
    37
            typename FlowMap=typename Graph::template EdgeMap<Num>,
marci@1017
    38
	    typename CostMap=typename Graph::template EdgeMap<Num> >
marci@1017
    39
  class MinCostGenFlow {
marci@1017
    40
  protected:
marci@1017
    41
    const Graph& g;
marci@1017
    42
    const Excess& excess;
marci@1017
    43
    const LCapMap& lcapacity;
marci@1017
    44
    const CapMap& capacity;
marci@1017
    45
    FlowMap& flow;
marci@1017
    46
    const CostMap& cost;
marci@1017
    47
  public:
marci@1017
    48
    MinCostGenFlow(const Graph& _g, const Excess& _excess, 
marci@1017
    49
		   const LCapMap& _lcapacity, const CapMap& _capacity, 
marci@1017
    50
		   FlowMap& _flow, 
marci@1017
    51
		   const CostMap& _cost) :
marci@1017
    52
      g(_g), excess(_excess), lcapacity(_lcapacity),
marci@1017
    53
      capacity(_capacity), flow(_flow), cost(_cost) { }
marci@1017
    54
    void run() {
marci@1017
    55
      LPSolverWrapper lp;
marci@1017
    56
      lp.setMinimize();
marci@1017
    57
      typedef LPSolverWrapper::ColIt ColIt;
marci@1017
    58
      typedef LPSolverWrapper::RowIt RowIt;
marci@1017
    59
      typedef typename Graph::template EdgeMap<ColIt> EdgeIndexMap;
marci@1017
    60
      EdgeIndexMap edge_index_map(g);
marci@1017
    61
      PrimalMap<typename Graph::Edge, EdgeIndexMap> lp_flow(lp, edge_index_map);
marci@1017
    62
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1017
    63
	ColIt col_it=lp.addCol();
marci@1017
    64
	edge_index_map.set(e, col_it);
marci@1017
    65
	if (lcapacity[e]==capacity[e])
marci@1017
    66
	  lp.setColBounds(col_it, LPX_FX, lcapacity[e], capacity[e]);
marci@1017
    67
	else 
marci@1017
    68
	  lp.setColBounds(col_it, LPX_DB, lcapacity[e], capacity[e]);
marci@1017
    69
	lp.setObjCoef(col_it, cost[e]);
marci@1017
    70
      }
marci@1017
    71
      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
marci@1017
    72
	typename Graph::template EdgeMap<Num> coeffs(g, 0);
marci@1017
    73
	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
marci@1017
    74
	coeffs.set(e, coeffs[e]+1);
marci@1017
    75
	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) 
marci@1017
    76
	coeffs.set(e, coeffs[e]-1);
marci@1017
    77
	RowIt row_it=lp.addRow();
marci@1017
    78
	typename std::vector< std::pair<ColIt, double> > row;
marci@1017
    79
	//std::cout << "node:" <<g.id(n)<<std::endl;
marci@1017
    80
	for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1017
    81
	  if (coeffs[e]!=0) {
marci@1017
    82
	    //std::cout << " edge:" <<g.id(e)<<" "<<coeffs[e];
marci@1017
    83
	    row.push_back(std::make_pair(edge_index_map[e], coeffs[e]));
marci@1017
    84
	  }
marci@1017
    85
	}
marci@1017
    86
	//std::cout << std::endl;
marci@1017
    87
	lp.setRowCoeffs(row_it, row.begin(), row.end());
marci@1017
    88
	lp.setRowBounds(row_it, LPX_FX, 0.0, 0.0);
marci@1017
    89
      }
marci@1017
    90
      lp.solveSimplex();
marci@1017
    91
      //std::cout << lp.colNum() << std::endl;
marci@1017
    92
      //std::cout << lp.rowNum() << std::endl;
marci@1017
    93
      //std::cout << "flow value: "<< lp.getObjVal() << std::endl;
marci@1017
    94
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) 
marci@1017
    95
      flow.set(e, lp_flow[e]);
marci@1017
    96
    }
marci@1017
    97
  };
marci@1017
    98
marci@1017
    99
} // namespace lemon
marci@1017
   100
marci@1017
   101
#endif //LEMON_MIN_COST_GEN_FLOW_H