# HG changeset patch # User marci # Date 1100967167 0 # Node ID e3bb0e118bb401baa5fd8c951b27cb782d247ca0 # Parent aae850a2394d52ea658c41cdb4a6c4144b081f90 RoadMap to more general flow algs. diff -r aae850a2394d -r e3bb0e118bb4 src/work/marci/lp/lp_solver_wrapper.h --- a/src/work/marci/lp/lp_solver_wrapper.h Sat Nov 20 14:23:27 2004 +0000 +++ b/src/work/marci/lp/lp_solver_wrapper.h Sat Nov 20 16:12:47 2004 +0000 @@ -1,6 +1,6 @@ // -*- c++ -*- #ifndef LEMON_LP_SOLVER_WRAPPER_H -#define LEMON_LP_SOLVER_WRAPPER +#define LEMON_LP_SOLVER_WRAPPER_H ///\ingroup misc ///\file diff -r aae850a2394d -r e3bb0e118bb4 src/work/marci/lp/max_flow_by_lp.cc --- a/src/work/marci/lp/max_flow_by_lp.cc Sat Nov 20 14:23:27 2004 +0000 +++ b/src/work/marci/lp/max_flow_by_lp.cc Sat Nov 20 16:12:47 2004 +0000 @@ -12,29 +12,101 @@ //#include #include -using namespace lemon; - // Use a DIMACS max flow file as stdin. // max_flow_demo < dimacs_max_flow_file -template -class PrimalMap { -protected: - LPSolverWrapper* lp; - EdgeIndexMap* edge_index_map; -public: - PrimalMap(LPSolverWrapper& _lp, EdgeIndexMap& _edge_index_map) : - lp(&_lp), edge_index_map(&_edge_index_map) { } - double operator[](Edge e) const { - return lp->getPrimal((*edge_index_map)[e]); - } -}; +using namespace lemon; + +namespace lemon { + + template + class PrimalMap { + protected: + LPSolverWrapper* lp; + EdgeIndexMap* edge_index_map; + public: + PrimalMap(LPSolverWrapper& _lp, EdgeIndexMap& _edge_index_map) : + lp(&_lp), edge_index_map(&_edge_index_map) { } + double operator[](Edge e) const { + return lp->getPrimal((*edge_index_map)[e]); + } + }; + + // excess: rho-delta + template , + typename LCapMap=typename Graph::template EdgeMap, + typename CapMap=typename Graph::template EdgeMap, + typename FlowMap=typename Graph::template EdgeMap, + typename CostMap=typename Graph::template EdgeMap > + class MinCostGenFlow { + protected: + const Graph& g; + const Excess& excess; + const LCapMap& lcapacity; + const CapMap& capacity; + FlowMap& flow; + const CostMap& cost; + public: + MinCostGenFlow(const Graph& _g, const Excess& _excess, + const LCapMap& _lcapacity, const CapMap& _capacity, + FlowMap& _flow, + const CostMap& _cost) : + g(_g), excess(_excess), lcapacity(_lcapacity), + capacity(_capacity), flow(_flow), cost(_cost) { } + void run() { + LPSolverWrapper lp; + lp.setMinimize(); + typedef LPSolverWrapper::ColIt ColIt; + typedef LPSolverWrapper::RowIt RowIt; + typedef typename Graph::template EdgeMap EdgeIndexMap; + EdgeIndexMap edge_index_map(g); + PrimalMap lp_flow(lp, edge_index_map); + for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) { + ColIt col_it=lp.addCol(); + edge_index_map.set(e, col_it); + if (lcapacity[e]==capacity[e]) + lp.setColBounds(col_it, LPX_FX, lcapacity[e], capacity[e]); + else + lp.setColBounds(col_it, LPX_DB, lcapacity[e], capacity[e]); + lp.setObjCoef(col_it, cost[e]); + } + for (typename Graph::NodeIt n(g); n!=INVALID; ++n) { + typename Graph::template EdgeMap coeffs(g, 0); + for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e) + coeffs.set(e, coeffs[e]+1); + for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) + coeffs.set(e, coeffs[e]-1); + RowIt row_it=lp.addRow(); + typename std::vector< std::pair > row; + //std::cout << "node:" <0) @@ -95,7 +167,7 @@ { std::cout << "physical blocking flow augmentation ..." << std::endl; - for (Graph::EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0); + for (EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0); ts.reset(); int i=0; while (augmenting_flow_test.augmentOnBlockingFlow()) { ++i; } @@ -103,7 +175,7 @@ std::cout << "number of augmentation phases: " << i << std::endl; std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl; - for (Graph::EdgeIt e(g); e!=INVALID; ++e) { + for (EdgeIt e(g); e!=INVALID; ++e) { if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) std::cout << "Slackness does not hold!" << std::endl; if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) @@ -124,7 +196,7 @@ { std::cout << "on-the-fly blocking flow augmentation ..." << std::endl; - for (Graph::EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0); + for (EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0); ts.reset(); int i=0; while (augmenting_flow_test.augmentOnBlockingFlow2()) { ++i; } @@ -132,7 +204,7 @@ std::cout << "number of augmentation phases: " << i << std::endl; std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl; - for (Graph::EdgeIt e(g); e!=INVALID; ++e) { + for (EdgeIt e(g); e!=INVALID; ++e) { if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) std::cout << "Slackness does not hold!" << std::endl; if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) @@ -177,46 +249,20 @@ // } ts.reset(); - LPSolverWrapper lp; - lp.setMaximize(); - typedef LPSolverWrapper::ColIt ColIt; - typedef LPSolverWrapper::RowIt RowIt; - typedef Graph::EdgeMap EdgeIndexMap; - EdgeIndexMap edge_index_map(g); - PrimalMap lp_flow(lp, edge_index_map); - for (Graph::EdgeIt e(g); e!=INVALID; ++e) { - ColIt col_it=lp.addCol(); - edge_index_map.set(e, col_it); - lp.setColBounds(col_it, LPX_DB, 0.0, cap[e]); - } - for (Graph::NodeIt n(g); n!=INVALID; ++n) { - if (n!=s) { - //hurokelek miatt - Graph::EdgeMap coeffs(g, 0); - for (Graph::InEdgeIt e(g, n); e!=INVALID; ++e) - coeffs.set(e, coeffs[e]+1); - for (Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) - coeffs.set(e, coeffs[e]-1); - if (n==t) { - for (Graph::EdgeIt e(g); e!=INVALID; ++e) { - if (coeffs[e]!=0) - lp.setObjCoef(edge_index_map[e], coeffs[e]); - } - } else { - RowIt row_it=lp.addRow(); - std::vector< std::pair > row; - for (Graph::EdgeIt e(g); e!=INVALID; ++e) { - if (coeffs[e]!=0) - row.push_back(std::make_pair(edge_index_map[e], coeffs[e])); - } - lp.setRowCoeffs(row_it, row.begin(), row.end()); - lp.setRowBounds(row_it, LPX_FX, 0.0, 0.0); - } - } - } - lp.solveSimplex(); - std::cout << "flow value: "<< lp.getObjVal() << std::endl; + + Edge e=g.addEdge(t, s); + Graph::EdgeMap cost(g, 0); + cost.set(e, -1); + cap.set(e, 10000); + typedef ConstMap Excess; + Excess excess(0); + typedef ConstMap LCap; + LCap lcap(0); + + MinCostGenFlow + min_cost(g, excess, lcap, cap, flow, cost); + min_cost.run(); + std::cout << "elapsed time: " << ts << std::endl; - - return 0; + std::cout << "flow value: "<< flow[e] << std::endl; }