| 
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@1025
 | 
     4  | 
#include <iostream>
  | 
| 
marci@1017
 | 
     5  | 
//#include <fstream>
  | 
| 
marci@1017
 | 
     6  | 
  | 
| 
marci@1025
 | 
     7  | 
#include <lemon/smart_graph.h>
  | 
| 
marci@1025
 | 
     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@1025
 | 
    12  | 
#include <lemon/preflow.h>
  | 
| 
marci@1028
 | 
    13  | 
#include <lemon/min_cost_flow.h>
  | 
| 
marci@1017
 | 
    14  | 
//#include <augmenting_flow.h>
  | 
| 
marci@1017
 | 
    15  | 
//#include <preflow_res.h>
  | 
| 
marci@1028
 | 
    16  | 
#include <work/marci/merge_node_graph_wrapper.h>
  | 
| 
marci@1074
 | 
    17  | 
#include <work/marci/lp/lp_solver_wrapper_3.h>
  | 
| 
marci@1017
 | 
    18  | 
  | 
| 
marci@1017
 | 
    19  | 
namespace lemon {
 | 
| 
marci@1017
 | 
    20  | 
  | 
| 
marci@1017
 | 
    21  | 
  template<typename Edge, typename EdgeIndexMap> 
  | 
| 
marci@1017
 | 
    22  | 
  class PrimalMap {
 | 
| 
marci@1017
 | 
    23  | 
  protected:
  | 
| 
marci@1081
 | 
    24  | 
    LPGLPK* lp;
  | 
| 
marci@1017
 | 
    25  | 
    EdgeIndexMap* edge_index_map;
  | 
| 
marci@1017
 | 
    26  | 
  public:
  | 
| 
marci@1081
 | 
    27  | 
    PrimalMap(LPGLPK& _lp, EdgeIndexMap& _edge_index_map) : 
  | 
| 
marci@1017
 | 
    28  | 
      lp(&_lp), edge_index_map(&_edge_index_map) { }
 | 
| 
marci@1017
 | 
    29  | 
    double operator[](Edge e) const { 
 | 
| 
marci@1017
 | 
    30  | 
      return lp->getPrimal((*edge_index_map)[e]);
  | 
| 
marci@1017
 | 
    31  | 
    }
  | 
| 
marci@1017
 | 
    32  | 
  };
  | 
| 
marci@1017
 | 
    33  | 
  | 
| 
marci@1028
 | 
    34  | 
  // excess: rho-delta egyelore csak =0-ra.
  | 
| 
marci@1017
 | 
    35  | 
  template <typename Graph, typename Num,
  | 
| 
marci@1017
 | 
    36  | 
	    typename Excess=typename Graph::template NodeMap<Num>, 
  | 
| 
marci@1017
 | 
    37  | 
	    typename LCapMap=typename Graph::template EdgeMap<Num>,
  | 
| 
marci@1017
 | 
    38  | 
	    typename CapMap=typename Graph::template EdgeMap<Num>,
  | 
| 
marci@1017
 | 
    39  | 
            typename FlowMap=typename Graph::template EdgeMap<Num>,
  | 
| 
marci@1017
 | 
    40  | 
	    typename CostMap=typename Graph::template EdgeMap<Num> >
  | 
| 
marci@1017
 | 
    41  | 
  class MinCostGenFlow {
 | 
| 
marci@1017
 | 
    42  | 
  protected:
  | 
| 
marci@1017
 | 
    43  | 
    const Graph& g;
  | 
| 
marci@1017
 | 
    44  | 
    const Excess& excess;
  | 
| 
marci@1017
 | 
    45  | 
    const LCapMap& lcapacity;
  | 
| 
marci@1017
 | 
    46  | 
    const CapMap& capacity;
  | 
| 
marci@1017
 | 
    47  | 
    FlowMap& flow;
  | 
| 
marci@1017
 | 
    48  | 
    const CostMap& cost;
  | 
| 
marci@1017
 | 
    49  | 
  public:
  | 
| 
marci@1017
 | 
    50  | 
    MinCostGenFlow(const Graph& _g, const Excess& _excess, 
  | 
| 
marci@1017
 | 
    51  | 
		   const LCapMap& _lcapacity, const CapMap& _capacity, 
  | 
| 
marci@1017
 | 
    52  | 
		   FlowMap& _flow, 
  | 
| 
marci@1017
 | 
    53  | 
		   const CostMap& _cost) :
  | 
| 
marci@1017
 | 
    54  | 
      g(_g), excess(_excess), lcapacity(_lcapacity),
  | 
| 
marci@1017
 | 
    55  | 
      capacity(_capacity), flow(_flow), cost(_cost) { }
 | 
| 
marci@1025
 | 
    56  | 
    bool feasible() {
 | 
| 
marci@1025
 | 
    57  | 
      //      std::cout << "making new vertices..." << std::endl; 
  | 
| 
marci@1025
 | 
    58  | 
      typedef ListGraph Graph2;
  | 
| 
marci@1025
 | 
    59  | 
      Graph2 g2;
  | 
| 
marci@1025
 | 
    60  | 
      typedef MergeEdgeGraphWrapper<const Graph, Graph2> GW;
  | 
| 
marci@1025
 | 
    61  | 
      //      std::cout << "merging..." << std::endl; 
  | 
| 
marci@1025
 | 
    62  | 
      GW gw(g, g2);
  | 
| 
marci@1025
 | 
    63  | 
      typename GW::Node s(INVALID, g2.addNode(), true);
  | 
| 
marci@1025
 | 
    64  | 
      typename GW::Node t(INVALID, g2.addNode(), true);
  | 
| 
marci@1025
 | 
    65  | 
      typedef SmartGraph Graph3;
  | 
| 
marci@1025
 | 
    66  | 
      //      std::cout << "making extender graph..." << std::endl; 
  | 
| 
marci@1025
 | 
    67  | 
      typedef NewEdgeSetGraphWrapper2<GW, Graph3> GWW;
  | 
| 
marci@1025
 | 
    68  | 
//       {
 | 
| 
marci@1025
 | 
    69  | 
// 	checkConcept<StaticGraph, GWW>();   
  | 
| 
marci@1025
 | 
    70  | 
//       }
  | 
| 
marci@1025
 | 
    71  | 
      GWW gww(gw);
  | 
| 
marci@1025
 | 
    72  | 
      typedef AugmentingGraphWrapper<GW, GWW> GWWW;
  | 
| 
marci@1025
 | 
    73  | 
      GWWW gwww(gw, gww);
  | 
| 
marci@1025
 | 
    74  | 
  | 
| 
marci@1025
 | 
    75  | 
      //      std::cout << "making new edges..." << std::endl; 
  | 
| 
marci@1025
 | 
    76  | 
      typename GWWW::template EdgeMap<Num> translated_cap(gwww);
  | 
| 
marci@1025
 | 
    77  | 
  | 
| 
marci@1028
 | 
    78  | 
      for (typename GW::EdgeIt e(gw); e!=INVALID; ++e) {
 | 
| 
marci@1028
 | 
    79  | 
	translated_cap.set(typename GWWW::Edge(e,INVALID,false), 
  | 
| 
marci@1028
 | 
    80  | 
			   capacity[e]-lcapacity[e]);
  | 
| 
marci@1028
 | 
    81  | 
	//	cout << "t_cap " << gw.id(e) << " " 
  | 
| 
marci@1028
 | 
    82  | 
	//	     << translated_cap[typename GWWW::Edge(e,INVALID,false)] << endl;
  | 
| 
marci@1028
 | 
    83  | 
      }
  | 
| 
marci@1025
 | 
    84  | 
  | 
| 
marci@1025
 | 
    85  | 
      Num expected=0;
  | 
| 
marci@1025
 | 
    86  | 
  | 
| 
marci@1025
 | 
    87  | 
      //      std::cout << "making new edges 2..." << std::endl; 
  | 
| 
marci@1025
 | 
    88  | 
      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
 | 
| 
marci@1025
 | 
    89  | 
	Num a=0;
  | 
| 
marci@1025
 | 
    90  | 
	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
  | 
| 
marci@1025
 | 
    91  | 
	  a+=lcapacity[e];
  | 
| 
marci@1025
 | 
    92  | 
	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) 
  | 
| 
marci@1025
 | 
    93  | 
	  a-=lcapacity[e];
  | 
| 
marci@1025
 | 
    94  | 
	if (excess[n]>a) {
 | 
| 
marci@1025
 | 
    95  | 
	  typename GWW::Edge e=
  | 
| 
marci@1025
 | 
    96  | 
	    gww.addEdge(typename GW::Node(n,INVALID,false), t);
  | 
| 
marci@1025
 | 
    97  | 
	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
  | 
| 
marci@1025
 | 
    98  | 
			     excess[n]-a);
  | 
| 
marci@1028
 | 
    99  | 
	  //	  std::cout << g.id(n) << "->t " << excess[n]-a << std::endl;
  | 
| 
marci@1025
 | 
   100  | 
	}
  | 
| 
marci@1025
 | 
   101  | 
	if (excess[n]<a) {
 | 
| 
marci@1025
 | 
   102  | 
	  typename GWW::Edge e=
  | 
| 
marci@1025
 | 
   103  | 
	    gww.addEdge(s, typename GW::Node(n,INVALID,false));
  | 
| 
marci@1025
 | 
   104  | 
	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
  | 
| 
marci@1025
 | 
   105  | 
			     a-excess[n]);
  | 
| 
marci@1025
 | 
   106  | 
	  expected+=a-excess[n];
  | 
| 
marci@1028
 | 
   107  | 
	  //	  std::cout << "s->" << g.id(n) << " "<< a-excess[n] <<std:: endl;
  | 
| 
marci@1025
 | 
   108  | 
	}
  | 
| 
marci@1025
 | 
   109  | 
      }
  | 
| 
marci@1025
 | 
   110  | 
  | 
| 
marci@1025
 | 
   111  | 
      //      std::cout << "preflow..." << std::endl; 
  | 
| 
marci@1025
 | 
   112  | 
      typename GWWW::template EdgeMap<Num> translated_flow(gwww, 0);
  | 
| 
marci@1025
 | 
   113  | 
      Preflow<GWWW, Num> preflow(gwww, s, t, 
  | 
| 
marci@1025
 | 
   114  | 
				 translated_cap, translated_flow);
  | 
| 
marci@1025
 | 
   115  | 
      preflow.run();
  | 
| 
marci@1025
 | 
   116  | 
      //      std::cout << "fv: " << preflow.flowValue() << std::endl; 
  | 
| 
marci@1025
 | 
   117  | 
      //      std::cout << "expected: " << expected << std::endl; 
  | 
| 
marci@1025
 | 
   118  | 
  | 
| 
marci@1025
 | 
   119  | 
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
 | 
| 
marci@1025
 | 
   120  | 
	typename GW::Edge ew(e, INVALID, false);
  | 
| 
marci@1025
 | 
   121  | 
	typename GWWW::Edge ewww(ew, INVALID, false);
  | 
| 
marci@1025
 | 
   122  | 
	flow.set(e, translated_flow[ewww]+lcapacity[e]);
  | 
| 
marci@1025
 | 
   123  | 
      }
  | 
| 
marci@1033
 | 
   124  | 
      return (preflow.flowValue()>=expected);
  | 
| 
marci@1025
 | 
   125  | 
    }
  | 
| 
marci@1028
 | 
   126  | 
    // for nonnegative costs
  | 
| 
marci@1028
 | 
   127  | 
    bool run() {
 | 
| 
marci@1028
 | 
   128  | 
      //      std::cout << "making new vertices..." << std::endl; 
  | 
| 
marci@1028
 | 
   129  | 
      typedef ListGraph Graph2;
  | 
| 
marci@1028
 | 
   130  | 
      Graph2 g2;
  | 
| 
marci@1028
 | 
   131  | 
      typedef MergeEdgeGraphWrapper<const Graph, Graph2> GW;
  | 
| 
marci@1028
 | 
   132  | 
      //      std::cout << "merging..." << std::endl; 
  | 
| 
marci@1028
 | 
   133  | 
      GW gw(g, g2);
  | 
| 
marci@1028
 | 
   134  | 
      typename GW::Node s(INVALID, g2.addNode(), true);
  | 
| 
marci@1028
 | 
   135  | 
      typename GW::Node t(INVALID, g2.addNode(), true);
  | 
| 
marci@1028
 | 
   136  | 
      typedef SmartGraph Graph3;
  | 
| 
marci@1028
 | 
   137  | 
      //      std::cout << "making extender graph..." << std::endl; 
  | 
| 
marci@1028
 | 
   138  | 
      typedef NewEdgeSetGraphWrapper2<GW, Graph3> GWW;
  | 
| 
marci@1028
 | 
   139  | 
//       {
 | 
| 
marci@1028
 | 
   140  | 
// 	checkConcept<StaticGraph, GWW>();   
  | 
| 
marci@1028
 | 
   141  | 
//       }
  | 
| 
marci@1028
 | 
   142  | 
      GWW gww(gw);
  | 
| 
marci@1028
 | 
   143  | 
      typedef AugmentingGraphWrapper<GW, GWW> GWWW;
  | 
| 
marci@1028
 | 
   144  | 
      GWWW gwww(gw, gww);
  | 
| 
marci@1028
 | 
   145  | 
  | 
| 
marci@1028
 | 
   146  | 
      //      std::cout << "making new edges..." << std::endl; 
  | 
| 
marci@1028
 | 
   147  | 
      typename GWWW::template EdgeMap<Num> translated_cap(gwww);
  | 
| 
marci@1028
 | 
   148  | 
  | 
| 
marci@1028
 | 
   149  | 
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
 | 
| 
marci@1028
 | 
   150  | 
	typename GW::Edge ew(e, INVALID, false);
  | 
| 
marci@1028
 | 
   151  | 
	typename GWWW::Edge ewww(ew, INVALID, false);
  | 
| 
marci@1028
 | 
   152  | 
	translated_cap.set(ewww, capacity[e]-lcapacity[e]);
  | 
| 
marci@1028
 | 
   153  | 
	//	cout << "t_cap " << g.id(e) << " " 
  | 
| 
marci@1028
 | 
   154  | 
	//	     << translated_cap[ewww] << endl;
  | 
| 
marci@1028
 | 
   155  | 
      }
  | 
| 
marci@1028
 | 
   156  | 
  | 
| 
marci@1028
 | 
   157  | 
      Num expected=0;
  | 
| 
marci@1028
 | 
   158  | 
  | 
| 
marci@1028
 | 
   159  | 
      //      std::cout << "making new edges 2..." << std::endl; 
  | 
| 
marci@1028
 | 
   160  | 
      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
 | 
| 
marci@1028
 | 
   161  | 
	//	std::cout << "node: " << g.id(n) << std::endl;
  | 
| 
marci@1028
 | 
   162  | 
	Num a=0;
  | 
| 
marci@1028
 | 
   163  | 
	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e) {
 | 
| 
marci@1028
 | 
   164  | 
	  a+=lcapacity[e];
  | 
| 
marci@1028
 | 
   165  | 
	  //	  std::cout << "bee: " << g.id(e) << " " << lcapacity[e] << std::endl;
  | 
| 
marci@1028
 | 
   166  | 
	}
  | 
| 
marci@1028
 | 
   167  | 
	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) {
 | 
| 
marci@1028
 | 
   168  | 
	  a-=lcapacity[e];
  | 
| 
marci@1028
 | 
   169  | 
	  //	  std::cout << "kie: " << g.id(e) << " " << lcapacity[e] << std::endl;
  | 
| 
marci@1028
 | 
   170  | 
	}
  | 
| 
marci@1028
 | 
   171  | 
	//	std::cout << "excess " << g.id(n) << ": " << a << std::endl;
  | 
| 
marci@1028
 | 
   172  | 
	if (0>a) {
 | 
| 
marci@1028
 | 
   173  | 
	  typename GWW::Edge e=
  | 
| 
marci@1028
 | 
   174  | 
	    gww.addEdge(typename GW::Node(n,INVALID,false), t);
  | 
| 
marci@1028
 | 
   175  | 
	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
  | 
| 
marci@1028
 | 
   176  | 
			     -a);
  | 
| 
marci@1028
 | 
   177  | 
	  //	  std::cout << g.id(n) << "->t " << -a << std::endl;
  | 
| 
marci@1028
 | 
   178  | 
	}
  | 
| 
marci@1028
 | 
   179  | 
	if (0<a) {
 | 
| 
marci@1028
 | 
   180  | 
	  typename GWW::Edge e=
  | 
| 
marci@1028
 | 
   181  | 
	    gww.addEdge(s, typename GW::Node(n,INVALID,false));
  | 
| 
marci@1028
 | 
   182  | 
	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
  | 
| 
marci@1028
 | 
   183  | 
			     a);
  | 
| 
marci@1028
 | 
   184  | 
	  expected+=a;
  | 
| 
marci@1028
 | 
   185  | 
	  //	  std::cout << "s->" << g.id(n) << " "<< a <<std:: endl;
  | 
| 
marci@1028
 | 
   186  | 
	}
  | 
| 
marci@1028
 | 
   187  | 
      }
  | 
| 
marci@1028
 | 
   188  | 
  | 
| 
marci@1028
 | 
   189  | 
      //      std::cout << "preflow..." << std::endl; 
  | 
| 
marci@1028
 | 
   190  | 
      typename GWWW::template EdgeMap<Num> translated_cost(gwww, 0);
  | 
| 
marci@1028
 | 
   191  | 
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
 | 
| 
marci@1028
 | 
   192  | 
	translated_cost.set(typename GWWW::Edge(
  | 
| 
marci@1028
 | 
   193  | 
        typename GW::Edge(e, INVALID, false), INVALID, false), cost[e]);
  | 
| 
marci@1028
 | 
   194  | 
      }
  | 
| 
marci@1028
 | 
   195  | 
      //      typename GWWW::template EdgeMap<Num> translated_flow(gwww, 0);
  | 
| 
marci@1028
 | 
   196  | 
      MinCostFlow<GWWW, typename GWWW::template EdgeMap<Num>, 
  | 
| 
marci@1028
 | 
   197  | 
      typename GWWW::template EdgeMap<Num> > 
  | 
| 
marci@1028
 | 
   198  | 
      min_cost_flow(gwww, translated_cost, translated_cap, 
  | 
| 
marci@1028
 | 
   199  | 
		    s, t);
  | 
| 
marci@1028
 | 
   200  | 
      while (min_cost_flow.augment()) { }
 | 
| 
marci@1028
 | 
   201  | 
      std::cout << "fv: " << min_cost_flow.flowValue() << std::endl; 
  | 
| 
marci@1028
 | 
   202  | 
      std::cout << "expected: " << expected << std::endl; 
  | 
| 
marci@1028
 | 
   203  | 
  | 
| 
marci@1028
 | 
   204  | 
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
 | 
| 
marci@1028
 | 
   205  | 
	typename GW::Edge ew(e, INVALID, false);
  | 
| 
marci@1028
 | 
   206  | 
	typename GWWW::Edge ewww(ew, INVALID, false);
  | 
| 
marci@1028
 | 
   207  | 
	//	std::cout << g.id(e) << " " << flow[e] << std::endl;
  | 
| 
marci@1028
 | 
   208  | 
	flow.set(e, lcapacity[e]+
  | 
| 
marci@1028
 | 
   209  | 
		 min_cost_flow.getFlow()[ewww]);
  | 
| 
marci@1028
 | 
   210  | 
      }
  | 
| 
marci@1033
 | 
   211  | 
      return (min_cost_flow.flowValue()>=expected);
  | 
| 
marci@1028
 | 
   212  | 
    }
  | 
| 
marci@1028
 | 
   213  | 
    void runByLP() {
 | 
| 
marci@1081
 | 
   214  | 
      typedef LPGLPK LPSolver;
  | 
| 
marci@1031
 | 
   215  | 
      LPSolver lp;
  | 
| 
marci@1017
 | 
   216  | 
      lp.setMinimize();
  | 
| 
marci@1031
 | 
   217  | 
      typedef LPSolver::ColIt ColIt;
  | 
| 
marci@1031
 | 
   218  | 
      typedef LPSolver::RowIt RowIt;
  | 
| 
marci@1017
 | 
   219  | 
      typedef typename Graph::template EdgeMap<ColIt> EdgeIndexMap;
  | 
| 
marci@1017
 | 
   220  | 
      EdgeIndexMap edge_index_map(g);
  | 
| 
marci@1017
 | 
   221  | 
      PrimalMap<typename Graph::Edge, EdgeIndexMap> lp_flow(lp, edge_index_map);
  | 
| 
marci@1017
 | 
   222  | 
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
 | 
| 
marci@1017
 | 
   223  | 
	ColIt col_it=lp.addCol();
  | 
| 
marci@1017
 | 
   224  | 
	edge_index_map.set(e, col_it);
  | 
| 
marci@1017
 | 
   225  | 
	if (lcapacity[e]==capacity[e])
  | 
| 
marci@1081
 | 
   226  | 
	  lp.setColBounds(col_it, LPSolver::FIXED, lcapacity[e], capacity[e]);
  | 
| 
marci@1017
 | 
   227  | 
	else 
  | 
| 
marci@1081
 | 
   228  | 
	  lp.setColBounds(col_it, LPSolver::DOUBLE, lcapacity[e], capacity[e]);
  | 
| 
marci@1017
 | 
   229  | 
	lp.setObjCoef(col_it, cost[e]);
  | 
| 
marci@1017
 | 
   230  | 
      }
  | 
| 
marci@1074
 | 
   231  | 
      LPSolver::ColIt col_it;
  | 
| 
marci@1074
 | 
   232  | 
      for (lp.col_iter_map.first(col_it, lp.VALID_CLASS); 
  | 
| 
marci@1074
 | 
   233  | 
	   lp.col_iter_map.valid(col_it); 
  | 
| 
marci@1074
 | 
   234  | 
	   lp.col_iter_map.next(col_it)) {
 | 
| 
marci@1081
 | 
   235  | 
//	std::cout << "ize " << lp.col_iter_map[col_it] << std::endl;
  | 
| 
marci@1074
 | 
   236  | 
      }
  | 
| 
marci@1017
 | 
   237  | 
      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
 | 
| 
marci@1017
 | 
   238  | 
	typename Graph::template EdgeMap<Num> coeffs(g, 0);
  | 
| 
marci@1017
 | 
   239  | 
	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
  | 
| 
marci@1017
 | 
   240  | 
	coeffs.set(e, coeffs[e]+1);
  | 
| 
marci@1017
 | 
   241  | 
	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) 
  | 
| 
marci@1017
 | 
   242  | 
	coeffs.set(e, coeffs[e]-1);
  | 
| 
marci@1017
 | 
   243  | 
	RowIt row_it=lp.addRow();
  | 
| 
marci@1017
 | 
   244  | 
	typename std::vector< std::pair<ColIt, double> > row;
  | 
| 
marci@1017
 | 
   245  | 
	//std::cout << "node:" <<g.id(n)<<std::endl;
  | 
| 
marci@1017
 | 
   246  | 
	for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
 | 
| 
marci@1017
 | 
   247  | 
	  if (coeffs[e]!=0) {
 | 
| 
marci@1017
 | 
   248  | 
	    //std::cout << " edge:" <<g.id(e)<<" "<<coeffs[e];
  | 
| 
marci@1017
 | 
   249  | 
	    row.push_back(std::make_pair(edge_index_map[e], coeffs[e]));
  | 
| 
marci@1017
 | 
   250  | 
	  }
  | 
| 
marci@1017
 | 
   251  | 
	}
  | 
| 
marci@1017
 | 
   252  | 
	//std::cout << std::endl;
  | 
| 
marci@1081
 | 
   253  | 
	//std::cout << " " << g.id(n) << " " << row.size() << std::endl;
  | 
| 
marci@1017
 | 
   254  | 
	lp.setRowCoeffs(row_it, row.begin(), row.end());
  | 
| 
marci@1081
 | 
   255  | 
	lp.setRowBounds(row_it, LPSolver::FIXED, 0.0, 0.0);
  | 
| 
marci@1017
 | 
   256  | 
      }
  | 
| 
marci@1017
 | 
   257  | 
      lp.solveSimplex();
  | 
| 
marci@1017
 | 
   258  | 
      //std::cout << lp.colNum() << std::endl;
  | 
| 
marci@1017
 | 
   259  | 
      //std::cout << lp.rowNum() << std::endl;
  | 
| 
marci@1017
 | 
   260  | 
      //std::cout << "flow value: "<< lp.getObjVal() << std::endl;
  | 
| 
marci@1017
 | 
   261  | 
      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) 
  | 
| 
marci@1017
 | 
   262  | 
      flow.set(e, lp_flow[e]);
  | 
| 
marci@1017
 | 
   263  | 
    }
  | 
| 
marci@1017
 | 
   264  | 
  };
  | 
| 
marci@1017
 | 
   265  | 
  | 
| 
marci@1017
 | 
   266  | 
} // namespace lemon
  | 
| 
marci@1017
 | 
   267  | 
  | 
| 
marci@1017
 | 
   268  | 
#endif //LEMON_MIN_COST_GEN_FLOW_H
  |