// -*- c++ -*- #ifndef LEMON_MIN_COST_GEN_FLOW_H #define LEMON_MIN_COST_GEN_FLOW_H #include //#include #include #include //#include //#include //#include #include #include //#include //#include #include #include 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 egyelore csak =0-ra. 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) { } bool feasible() { // std::cout << "making new vertices..." << std::endl; typedef ListGraph Graph2; Graph2 g2; typedef MergeEdgeGraphWrapper GW; // std::cout << "merging..." << std::endl; GW gw(g, g2); typename GW::Node s(INVALID, g2.addNode(), true); typename GW::Node t(INVALID, g2.addNode(), true); typedef SmartGraph Graph3; // std::cout << "making extender graph..." << std::endl; typedef NewEdgeSetGraphWrapper2 GWW; // { // checkConcept(); // } GWW gww(gw); typedef AugmentingGraphWrapper GWWW; GWWW gwww(gw, gww); // std::cout << "making new edges..." << std::endl; typename GWWW::template EdgeMap translated_cap(gwww); for (typename GW::EdgeIt e(gw); e!=INVALID; ++e) { translated_cap.set(typename GWWW::Edge(e,INVALID,false), capacity[e]-lcapacity[e]); // cout << "t_cap " << gw.id(e) << " " // << translated_cap[typename GWWW::Edge(e,INVALID,false)] << endl; } Num expected=0; // std::cout << "making new edges 2..." << std::endl; for (typename Graph::NodeIt n(g); n!=INVALID; ++n) { Num a=0; for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e) a+=lcapacity[e]; for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) a-=lcapacity[e]; if (excess[n]>a) { typename GWW::Edge e= gww.addEdge(typename GW::Node(n,INVALID,false), t); translated_cap.set(typename GWWW::Edge(INVALID, e, true), excess[n]-a); // std::cout << g.id(n) << "->t " << excess[n]-a << std::endl; } if (excess[n]" << g.id(n) << " "<< a-excess[n] < translated_flow(gwww, 0); Preflow preflow(gwww, s, t, translated_cap, translated_flow); preflow.run(); // std::cout << "fv: " << preflow.flowValue() << std::endl; // std::cout << "expected: " << expected << std::endl; for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) { typename GW::Edge ew(e, INVALID, false); typename GWWW::Edge ewww(ew, INVALID, false); flow.set(e, translated_flow[ewww]+lcapacity[e]); } return (preflow.flowValue()>=expected); } // for nonnegative costs bool run() { // std::cout << "making new vertices..." << std::endl; typedef ListGraph Graph2; Graph2 g2; typedef MergeEdgeGraphWrapper GW; // std::cout << "merging..." << std::endl; GW gw(g, g2); typename GW::Node s(INVALID, g2.addNode(), true); typename GW::Node t(INVALID, g2.addNode(), true); typedef SmartGraph Graph3; // std::cout << "making extender graph..." << std::endl; typedef NewEdgeSetGraphWrapper2 GWW; // { // checkConcept(); // } GWW gww(gw); typedef AugmentingGraphWrapper GWWW; GWWW gwww(gw, gww); // std::cout << "making new edges..." << std::endl; typename GWWW::template EdgeMap translated_cap(gwww); for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) { typename GW::Edge ew(e, INVALID, false); typename GWWW::Edge ewww(ew, INVALID, false); translated_cap.set(ewww, capacity[e]-lcapacity[e]); // cout << "t_cap " << g.id(e) << " " // << translated_cap[ewww] << endl; } Num expected=0; // std::cout << "making new edges 2..." << std::endl; for (typename Graph::NodeIt n(g); n!=INVALID; ++n) { // std::cout << "node: " << g.id(n) << std::endl; Num a=0; for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e) { a+=lcapacity[e]; // std::cout << "bee: " << g.id(e) << " " << lcapacity[e] << std::endl; } for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) { a-=lcapacity[e]; // std::cout << "kie: " << g.id(e) << " " << lcapacity[e] << std::endl; } // std::cout << "excess " << g.id(n) << ": " << a << std::endl; if (0>a) { typename GWW::Edge e= gww.addEdge(typename GW::Node(n,INVALID,false), t); translated_cap.set(typename GWWW::Edge(INVALID, e, true), -a); // std::cout << g.id(n) << "->t " << -a << std::endl; } if (0" << g.id(n) << " "<< a < translated_cost(gwww, 0); for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) { translated_cost.set(typename GWWW::Edge( typename GW::Edge(e, INVALID, false), INVALID, false), cost[e]); } // typename GWWW::template EdgeMap translated_flow(gwww, 0); MinCostFlow, typename GWWW::template EdgeMap > min_cost_flow(gwww, translated_cost, translated_cap, s, t); while (min_cost_flow.augment()) { } std::cout << "fv: " << min_cost_flow.flowValue() << std::endl; std::cout << "expected: " << expected << std::endl; for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) { typename GW::Edge ew(e, INVALID, false); typename GWWW::Edge ewww(ew, INVALID, false); // std::cout << g.id(e) << " " << flow[e] << std::endl; flow.set(e, lcapacity[e]+ min_cost_flow.getFlow()[ewww]); } return (min_cost_flow.flowValue()>=expected); } void runByLP() { typedef LPSolverWrapper LPSolver; LPSolver lp; lp.setMinimize(); typedef LPSolver::ColIt ColIt; typedef LPSolver::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:" <