# HG changeset patch # User Peter Kovacs # Date 1267406784 -3600 # Node ID e99a7fb6bff536620b05d23509457ced4ec88ba5 # Parent 0f695eac7e0769c94cfb1ce6ce83d8cc8d57e1ff Port and rework LP demo files from SVN -r3524 diff -r 0f695eac7e07 -r e99a7fb6bff5 demo/hello_lemon.cc --- a/demo/hello_lemon.cc Sun Feb 28 19:38:57 2010 +0100 +++ b/demo/hello_lemon.cc Mon Mar 01 02:26:24 2010 +0100 @@ -20,6 +20,7 @@ ///\brief Simple "Hello World!" program for LEMON. /// /// Simple "Hello World!" program for LEMON. +/// /// \include hello_lemon.cc #include diff -r 0f695eac7e07 -r e99a7fb6bff5 demo/lp_demo.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo/lp_demo.cc Mon Mar 01 02:26:24 2010 +0100 @@ -0,0 +1,68 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief Demo program for the LP solver interface. +/// +/// This demo program shows how the LEMON LP solver interface can be used. +/// A simple linear programming (LP) problem is formulated and solved using +/// the default LP solver (e.g. GLPK). +/// +/// \include lp_demo.cc + +#include +#include + +using namespace lemon; + +int main() +{ + // Create an instance of the default LP solver class + // (it will represent an "empty" problem at first) + Lp lp; + + // Add two columns (variables) to the problem + Lp::Col x1 = lp.addCol(); + Lp::Col x2 = lp.addCol(); + + // Add rows (constraints) to the problem + lp.addRow(x1 - 5 <= x2); + lp.addRow(0 <= 2 * x1 + x2 <= 25); + + // Set lower and upper bounds for the columns (variables) + lp.colLowerBound(x1, 0); + lp.colUpperBound(x2, 10); + + // Specify the objective function + lp.max(); + lp.obj(5 * x1 + 3 * x2); + + // Solve the problem using the underlying LP solver + lp.solve(); + + // Print the results + if (lp.primalType() == Lp::OPTIMAL) { + std::cout << "Objective function value: " << lp.primal() << std::endl; + std::cout << "x1 = " << lp.primal(x1) << std::endl; + std::cout << "x2 = " << lp.primal(x2) << std::endl; + } else { + std::cout << "Optimal solution not found." << std::endl; + } + + return 0; +} diff -r 0f695eac7e07 -r e99a7fb6bff5 demo/lp_maxflow_demo.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo/lp_maxflow_demo.cc Mon Mar 01 02:26:24 2010 +0100 @@ -0,0 +1,105 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief Demo program that solves maximum flow problems using the LP interface +/// +/// This demo program shows how to solve the maximum flow problem using +/// the LEMON LP solver interface. We would like to lay the emphasis on the +/// simplicity of the way one can formulate LP constraints that arise in graph +/// theory using LEMON. +/// +/// \include lp_maxflow_demo.cc + +#include +#include +#include +#include + +using namespace lemon; + +template +double maxFlow(const GR &g, const CAP &capacity, + typename GR::Node source, typename GR::Node target) +{ + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + // Create an instance of the default LP solver + Lp lp; + + // Add a column to the problem for each arc + typename GR::template ArcMap f(g); + lp.addColSet(f); + + // Capacity constraints + for (ArcIt a(g); a != INVALID; ++a) { + lp.colLowerBound(f[a], 0); + lp.colUpperBound(f[a], capacity[a]); + } + + // Flow conservation constraints + for (NodeIt n(g); n != INVALID; ++n) { + if (n == source || n == target) continue; + Lp::Expr e; + for (OutArcIt a(g, n); a != INVALID; ++a) e += f[a]; + for (InArcIt a(g, n); a != INVALID; ++a) e -= f[a]; + lp.addRow(e == 0); + } + + // Objective function + Lp::Expr o; + for (OutArcIt a(g, source); a != INVALID; ++a) o += f[a]; + for (InArcIt a(g, source); a != INVALID; ++a) o -= f[a]; + lp.max(); + lp.obj(o); + + // Solve the LP problem + lp.solve(); + + return lp.primal(); +} + + +int main(int argc, char *argv[]) +{ + // Check the arguments + if (argc < 2) { + std::cerr << "Usage:" << std::endl; + std::cerr << " lp_maxflow_demo " << std::endl; + std::cerr << "The given input file has to contain a maximum flow\n" + << "problem in LGF format (like 'maxflow.lgf')." + << std::endl; + return 0; + } + + // Read the input file + SmartDigraph g; + SmartDigraph::ArcMap cap(g); + SmartDigraph::Node s, t; + + digraphReader(g, argv[1]) + .arcMap("capacity", cap) + .node("source", s) + .node("target", t) + .run(); + + // Solve the problem and print the result + std::cout << "Max flow value: " << maxFlow(g, cap, s, t) << std::endl; + + return 0; +} diff -r 0f695eac7e07 -r e99a7fb6bff5 demo/maxflow.lgf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo/maxflow.lgf Mon Mar 01 02:26:24 2010 +0100 @@ -0,0 +1,34 @@ +@nodes +label +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +@arcs + capacity +0 1 20 +0 2 0 +1 1 3 +1 2 8 +1 3 8 +2 5 5 +3 2 5 +3 5 5 +3 6 5 +4 3 3 +5 7 3 +5 6 10 +5 8 10 +6 8 8 +8 9 20 +8 1 5 +9 5 5 +@attributes +source 1 +target 8 diff -r 0f695eac7e07 -r e99a7fb6bff5 demo/mip_demo.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo/mip_demo.cc Mon Mar 01 02:26:24 2010 +0100 @@ -0,0 +1,72 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief Demo program for the MIP solver interface. +/// +/// This demo program shows how the LEMON MIP solver interface can be used. +/// A simple mixed integer programming (MIP) problem is formulated and solved +/// using the default MIP solver (e.g. GLPK). +/// +/// \include mip_demo.cc + +#include +#include + +using namespace lemon; + +int main() +{ + // Create an instance of the default MIP solver class + // (it will represent an "empty" problem at first) + Mip mip; + + // Add two columns (variables) to the problem + Mip::Col x1 = mip.addCol(); + Mip::Col x2 = mip.addCol(); + + // Add rows (constraints) to the problem + mip.addRow(x1 - 5 <= x2); + mip.addRow(0 <= 2 * x1 + x2 <= 25); + + // Set lower and upper bounds for the columns (variables) + mip.colLowerBound(x1, 0); + mip.colUpperBound(x2, 10); + + // Set the type of the columns + mip.colType(x1, Mip::INTEGER); + mip.colType(x2, Mip::REAL); + + // Specify the objective function + mip.max(); + mip.obj(5 * x1 + 3 * x2); + + // Solve the problem using the underlying MIP solver + mip.solve(); + + // Print the results + if (mip.type() == Mip::OPTIMAL) { + std::cout << "Objective function value: " << mip.solValue() << std::endl; + std::cout << "x1 = " << mip.sol(x1) << std::endl; + std::cout << "x2 = " << mip.sol(x2) << std::endl; + } else { + std::cout << "Optimal solution not found." << std::endl; + } + + return 0; +}