[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