athos@1560: /* -*- C++ -*- athos@1560: * demo/lp_maxflow_demo.cc - Part of LEMON, a generic C++ optimization library athos@1560: * athos@1560: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport athos@1560: * (Egervary Research Group on Combinatorial Optimization, EGRES). athos@1560: * athos@1560: * Permission to use, modify and distribute this software is granted athos@1560: * provided that this copyright notice appears in all copies. For athos@1560: * precise terms see the accompanying LICENSE file. athos@1560: * athos@1560: * This software is provided "AS IS" with no warranty of any kind, athos@1560: * express or implied, and with no claim as to its suitability for any athos@1560: * purpose. athos@1560: * athos@1560: */ athos@1560: athos@1560: ///\ingroup demos athos@1560: ///\file athos@1560: ///\brief Max flow problem solved with an LP solver (demo). athos@1560: /// athos@1560: ///This demo program shows how to solve a maximum (or maximal) flow athos@1560: ///problem using the LEMON LP solver interface. We would like to lay athos@1560: ///the emphasis on the simplicity of the way one can formulate the LP athos@1560: ///constraints with LEMON that arise in graph theory. athos@1560: ladanyi@1387: #ifdef HAVE_CONFIG_H ladanyi@1387: #include ladanyi@1387: #endif ladanyi@1387: alpar@1361: #include alpar@1361: #include alpar@1361: athos@1560: #include athos@1560: #include athos@1560: alpar@1381: alpar@1381: #ifdef HAVE_GLPK alpar@1381: #include alpar@1381: #elif HAVE_CPLEX alpar@1381: #include alpar@1381: #endif alpar@1381: alpar@1361: using namespace lemon; alpar@1361: alpar@1381: #ifdef HAVE_GLPK alpar@1381: typedef LpGlpk LpDefault; alpar@1381: #elif HAVE_CPLEX alpar@1381: typedef LpCplex LpDefault; alpar@1381: #endif alpar@1381: alpar@1381: alpar@1361: template alpar@1361: double maxFlow(const G &g,const C &cap,typename G::Node s,typename G::Node t) alpar@1361: { alpar@1381: LpDefault lp; alpar@1361: alpar@1361: typedef G Graph; alpar@1361: typedef typename G::Node Node; alpar@1361: typedef typename G::NodeIt NodeIt; alpar@1361: typedef typename G::Edge Edge; alpar@1361: typedef typename G::EdgeIt EdgeIt; alpar@1361: typedef typename G::OutEdgeIt OutEdgeIt; alpar@1361: typedef typename G::InEdgeIt InEdgeIt; alpar@1361: athos@1518: //Define a map on the edges for the variables of the LP problem alpar@1381: typename G::template EdgeMap x(g); alpar@1361: lp.addColSet(x); alpar@1361: athos@1518: //Nonnegativity and capacity constraints alpar@1361: for(EdgeIt e(g);e!=INVALID;++e) { alpar@1361: lp.colUpperBound(x[e],cap[e]); alpar@1361: lp.colLowerBound(x[e],0); alpar@1361: } alpar@1361: athos@1518: athos@1518: //Flow conservation constraints for the nodes (except for 's' and 't') alpar@1361: for(NodeIt n(g);n!=INVALID;++n) if(n!=s&&n!=t) { alpar@1381: LpDefault::Expr ex; alpar@1361: for(InEdgeIt e(g,n);e!=INVALID;++e) ex+=x[e]; alpar@1361: for(OutEdgeIt e(g,n);e!=INVALID;++e) ex-=x[e]; alpar@1361: lp.addRow(ex==0); alpar@1361: } athos@1518: athos@1518: //Objective function: the flow value entering 't' alpar@1361: { alpar@1381: LpDefault::Expr ex; alpar@1361: for(InEdgeIt e(g,t);e!=INVALID;++e) ex+=x[e]; alpar@1361: for(OutEdgeIt e(g,t);e!=INVALID;++e) ex-=x[e]; alpar@1361: lp.setObj(ex); alpar@1361: } athos@1518: athos@1518: //Maximization alpar@1361: lp.max(); alpar@1361: alpar@1381: #ifdef HAVE_GLPK alpar@1361: lp.presolver(true); alpar@1361: lp.messageLevel(3); alpar@1381: #endif alpar@1361: athos@1518: //Solve with the underlying solver alpar@1361: lp.solve(); alpar@1361: alpar@1361: return lp.primalValue(); alpar@1361: } alpar@1361: athos@1560: int main(int argc, char *argv[]) alpar@1361: { athos@1560: if(argc<2) athos@1560: { alpar@1561: std::cerr << " USAGE: lp_maxflow_demo " << std::endl; alpar@1561: std::cerr << " The file 'input_file.lgf' has to contain a max " alpar@1561: << "flow instance in\n" alpar@1561: << " LEMON format (e.g. sample.lgf is such a file)." alpar@1561: << std::endl; athos@1560: return 0; athos@1560: } athos@1560: athos@1560: athos@1560: //input stream to read the graph from athos@1560: std::ifstream is(argv[1]); athos@1560: athos@1560: alpar@1361: ListGraph g; alpar@1361: ListGraph::Node s; alpar@1361: ListGraph::Node t; alpar@1361: alpar@1361: ListGraph::EdgeMap cap(g); alpar@1361: athos@1560: GraphReader reader(is,g); deba@1394: reader.readNode("source",s).readNode("target",t) deba@1394: .readEdgeMap("capacity",cap).run(); alpar@1361: alpar@1361: std::cout << "Max flow value = " << maxFlow(g,cap,s,t) << std::endl; alpar@1361: alpar@1361: }