src/work/marci/lp/max_flow_expression.cc
changeset 1104 23a54f889272
child 1110 ba28dfbea5f2
equal deleted inserted replaced
-1:000000000000 0:88ee5f956e04
       
     1 // -*- c++ -*-
       
     2 #include <iostream>
       
     3 #include <fstream>
       
     4 
       
     5 #include <lemon/smart_graph.h>
       
     6 #include <lemon/list_graph.h>
       
     7 #include <lemon/dimacs.h>
       
     8 #include <lemon/time_measure.h>
       
     9 #include <lp_solver_wrapper_3.h>
       
    10 
       
    11 using std::cout;
       
    12 using std::endl;
       
    13 using namespace lemon;
       
    14 
       
    15 template<typename Edge, typename EdgeIndexMap> 
       
    16 class PrimalMap {
       
    17 protected:
       
    18   LPGLPK* lp;
       
    19   EdgeIndexMap* edge_index_map;
       
    20 public:
       
    21   PrimalMap(LPGLPK& _lp, EdgeIndexMap& _edge_index_map) : 
       
    22     lp(&_lp), edge_index_map(&_edge_index_map) { }
       
    23   double operator[](Edge e) const { 
       
    24     return lp->getPrimal((*edge_index_map)[e]);
       
    25   }
       
    26 };
       
    27 
       
    28 // Use a DIMACS max flow file as stdin.
       
    29 // max_flow_expresion < dimacs_max_flow_file
       
    30 
       
    31 int main(int, char **) {
       
    32 
       
    33   typedef ListGraph Graph;
       
    34   typedef Graph::Node Node;
       
    35   typedef Graph::Edge Edge;
       
    36   typedef Graph::EdgeIt EdgeIt;
       
    37 
       
    38   Graph g;
       
    39   
       
    40   Node s, t;
       
    41   Graph::EdgeMap<int> cap(g);
       
    42   readDimacs(std::cin, g, cap, s, t);
       
    43   Timer ts;
       
    44   
       
    45   typedef LPGLPK LPSolver;
       
    46   LPSolver lp;
       
    47   lp.setMaximize();
       
    48   typedef LPSolver::ColIt ColIt;
       
    49   typedef LPSolver::RowIt RowIt;
       
    50   typedef Graph::EdgeMap<ColIt> EdgeIndexMap;
       
    51   EdgeIndexMap edge_index_map(g);
       
    52   PrimalMap<Edge, EdgeIndexMap> lp_flow(lp, edge_index_map);
       
    53 
       
    54   // capacity function
       
    55   for (Graph::EdgeIt e(g); e!=INVALID; ++e) {
       
    56     ColIt col_it=lp.addCol();
       
    57     edge_index_map.set(e, col_it);
       
    58     if (cap[e]==0)
       
    59       lp.setColBounds(col_it, LPSolver::FIXED, 0, cap[e]);
       
    60     else 
       
    61       lp.setColBounds(col_it, LPSolver::DOUBLE, 0, cap[e]);
       
    62   }
       
    63   
       
    64   for (Graph::NodeIt n(g); n!=INVALID; ++n) {
       
    65     LPSolver::Expression expr;
       
    66     for (Graph::OutEdgeIt e(g, n); e!=INVALID; ++e)
       
    67       expr+=edge_index_map[e];
       
    68     for (Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
       
    69       expr-=edge_index_map[e];
       
    70     // cost function
       
    71     if (n==s) {
       
    72       lp.setObjCoeffs(expr);      
       
    73     }
       
    74     // flow conservation
       
    75     if ((n!=s) && (n!=t)) {
       
    76       RowIt row_it=lp.addRow();
       
    77       lp.setRowCoeffs(row_it, expr);
       
    78       lp.setRowBounds(row_it, LPSolver::FIXED, 0.0, 0.0);
       
    79     }
       
    80   }
       
    81   lp.solveSimplex();
       
    82   //std::cout << lp.colNum() << std::endl;
       
    83   //std::cout << lp.rowNum() << std::endl;
       
    84   //std::cout << "flow value: "<< lp.getObjVal() << std::endl;
       
    85   for (Graph::EdgeIt e(g); e!=INVALID; ++e) 
       
    86     flow.set(e, lp_flow[e]);
       
    87 }