[Lemon-commits] [lemon_svn] marci: r1405 - hugo/trunk/src/work/marci/lp
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:45:10 CET 2006
Author: marci
Date: Sat Nov 20 17:12:47 2004
New Revision: 1405
Modified:
hugo/trunk/src/work/marci/lp/lp_solver_wrapper.h
hugo/trunk/src/work/marci/lp/max_flow_by_lp.cc
Log:
RoadMap to more general flow algs.
Modified: hugo/trunk/src/work/marci/lp/lp_solver_wrapper.h
==============================================================================
--- hugo/trunk/src/work/marci/lp/lp_solver_wrapper.h (original)
+++ hugo/trunk/src/work/marci/lp/lp_solver_wrapper.h Sat Nov 20 17:12:47 2004
@@ -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
Modified: hugo/trunk/src/work/marci/lp/max_flow_by_lp.cc
==============================================================================
--- hugo/trunk/src/work/marci/lp/max_flow_by_lp.cc (original)
+++ hugo/trunk/src/work/marci/lp/max_flow_by_lp.cc Sat Nov 20 17:12:47 2004
@@ -12,29 +12,101 @@
//#include <preflow_res.h>
#include <lp_solver_wrapper.h>
-using namespace lemon;
-
// Use a DIMACS max flow file as stdin.
// max_flow_demo < dimacs_max_flow_file
-template<typename Edge, typename EdgeIndexMap>
-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<typename Edge, typename EdgeIndexMap>
+ 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 Graph, typename Num,
+ typename Excess=typename Graph::template NodeMap<Num>,
+ typename LCapMap=typename Graph::template EdgeMap<Num>,
+ typename CapMap=typename Graph::template EdgeMap<Num>,
+ typename FlowMap=typename Graph::template EdgeMap<Num>,
+ typename CostMap=typename Graph::template EdgeMap<Num> >
+ 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<ColIt> EdgeIndexMap;
+ EdgeIndexMap edge_index_map(g);
+ PrimalMap<typename Graph::Edge, EdgeIndexMap> 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<Num> 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<ColIt, double> > row;
+ //std::cout << "node:" <<g.id(n)<<std::endl;
+ for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
+ if (coeffs[e]!=0) {
+ //std::cout << " edge:" <<g.id(e)<<" "<<coeffs[e];
+ row.push_back(std::make_pair(edge_index_map[e], coeffs[e]));
+ }
+ }
+ //std::cout << std::endl;
+ lp.setRowCoeffs(row_it, row.begin(), row.end());
+ lp.setRowBounds(row_it, LPX_FX, 0.0, 0.0);
+ }
+ lp.solveSimplex();
+ //std::cout << lp.colNum() << std::endl;
+ //std::cout << lp.rowNum() << std::endl;
+ //std::cout << "flow value: "<< lp.getObjVal() << std::endl;
+ for (typename Graph::EdgeIt e(g); e!=INVALID; ++e)
+ flow.set(e, lp_flow[e]);
+ }
+ };
+
+}
int main(int, char **) {
typedef ListGraph MutableGraph;
typedef SmartGraph Graph;
typedef Graph::Node Node;
+ typedef Graph::Edge Edge;
typedef Graph::EdgeIt EdgeIt;
Graph g;
@@ -60,7 +132,7 @@
std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
max_flow_test.minCut(cut);
- 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)
@@ -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<MutableGraph>()) { ++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<ColIt> EdgeIndexMap;
- EdgeIndexMap edge_index_map(g);
- PrimalMap<Graph::Edge, EdgeIndexMap> 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<int> 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<ColIt, double> > 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;
- std::cout << "elapsed time: " << ts << std::endl;
- return 0;
+ Edge e=g.addEdge(t, s);
+ Graph::EdgeMap<int> cost(g, 0);
+ cost.set(e, -1);
+ cap.set(e, 10000);
+ typedef ConstMap<Node, int> Excess;
+ Excess excess(0);
+ typedef ConstMap<Edge, int> LCap;
+ LCap lcap(0);
+
+ MinCostGenFlow<Graph, int, Excess, LCap>
+ min_cost(g, excess, lcap, cap, flow, cost);
+ min_cost.run();
+
+ std::cout << "elapsed time: " << ts << std::endl;
+ std::cout << "flow value: "<< flow[e] << std::endl;
}
More information about the Lemon-commits
mailing list