lp.dox
author Peter Kovacs <kpeter@inf.elte.hu>
Mon, 01 Mar 2010 02:30:00 +0100
changeset 58 10b6a5b7d4c0
parent 55 edb7d5759e0d
child 60 202688f8024a
permissions -rw-r--r--
Improve Algorithms section (it is still under construction)
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2010
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 namespace lemon {
    20 /**
    21 [PAGE]sec_lp[PAGE] Linear Programming Interface
    22 
    23 Linear programming (LP) is one of the most important general methods of
    24 operations research. Countless optimization problems can be formulated
    25 and solved using LP techniques.
    26 Therefore, developing efficient LP solvers has been of high practical
    27 interest for a long time.
    28 Nowadays various efficient LP solvers are available, including both
    29 open source and commercial software packages.
    30 Therefore, LEMON does not implement its own solver, but it features
    31 wrapper classes for several known LP packages providing a common
    32 high-level interface for all of them.
    33 
    34 The advantage of this approach is twofold. First, our C++ interface is
    35 more comfortable than the typical native interfaces of the solvers.
    36 Second, changing the underlying solver in a certain application using
    37 LEMON's LP interface needs no effort. So, for example, one may try her
    38 idea using an open source solver, demonstrate its usability for a customer
    39 and if it works well, but the performance should be improved, then the
    40 customer may decide to purchase and use a better commercial solver.
    41 
    42 Currently, the following linear and mixed integer programming packages are
    43 supported: GLPK, Clp, Cbc, ILOG CPLEX and SoPlex.
    44 However, additional wrapper classes for new solvers can also be implemented
    45 quite easily.
    46 
    47 [SEC]sec_lp_basics[SEC] Basic LP Features
    48 
    49 The following example demonstrates how simple it is to formalize and solve
    50 an LP problem in LEMON. You can find the whole program in \ref lp_demo.cc.
    51 
    52 \dontinclude lp_demo.cc
    53 \skip Create
    54 \until }
    55 \until }
    56 
    57 \ref LpBase::Col "Lp::Col" type represents the columns, i.e. the (primal)
    58 variables of the LP problem. The numerical operators can be used to form
    59 expressions from columns, which are required for specifying rows
    60 (constraints) and the objective function. Due to the suitable operator
    61 overloads, a problem can be described in C++ conveniently, directly as it is
    62 expressed in mathematics.
    63 After specifying all the parameters of the problem, we can solve it using
    64 the \ref LpSolver::solve() "solve()" function. The status of the solution
    65 (namely OPTIMAL, UNBOUNDED, INFEASIBLE etc.) can be obtained using
    66 \ref LpSolver::primalType() "primalType()" and the results can be
    67 obtained using \ref LpSolver::primal() "primal()".
    68 
    69 The above problem has an optimal solution. If you execute this example,
    70 it will print out the following results.
    71 
    72 \code
    73   Objective function value: 67.5
    74   x1 = 7.5
    75   x2 = 10
    76 \endcode
    77 
    78 However, if you, for example, removed the lines that specify the rows,
    79 you would obtain an LP problem, for which the objective function value
    80 is unbounded over the feasible solutions. Thus the program would print
    81 out this line.
    82 
    83 \code
    84   Optimal solution found.
    85 \endcode
    86 
    87 If you would like to build linear expressions or constraints in more steps,
    88 then you can use the classes \ref LpBase::Expr "Lp::Expr" and
    89 \ref LpBase::Constr "Lp::Constr". For example, this line
    90 \code
    91   lp.addRow(x1 - 5 <= x2);
    92 \endcode
    93 can also be written as
    94 \code
    95   Lp::Expr e1, e2;
    96   e1 = x1;
    97   e1 -= 5;
    98   e2 = x2;
    99   Lp::Constr c = e1 <= e2;
   100   lp.addRow(c);
   101 \endcode
   102 
   103 These classes make it easy to build more complex expressions and constraints,
   104 e.g. using loops. For example, we can sum all the variables (columns) in an
   105 expression using the \ref LpBase::ColIt "Lp::ColIt" iterator, which can be
   106 used the same as node and arc iterators for graphs.
   107 
   108 \code
   109   Lp::Expr sum;
   110   for (Lp::ColIt col(lp); col != INVALID; ++col) {
   111     sum += col;
   112   }
   113 \endcode
   114 
   115 After solving the problem, you can query the value of any primal expression,
   116 not just the individual columns and the objective function.
   117 
   118 \todo Check this example after closing ticket #326.
   119 
   120 \code
   121   std::cout << lp.primal(sum) << std::endl;
   122 \endcode
   123 
   124 Of course, working with the dual problem is also supported by the LP
   125 interface. \ref LpBase::Row "Lp::Row" represents the rows, i.e. the dual
   126 variables of the LP problem.
   127 
   128 \code
   129   Lp::Row r = lp.addRow(x2 >= 3);
   130 \endcode
   131 
   132 The dual solutions of an LP problem can be obtained using the functions
   133 \ref LpSolver::dualType() "dualType()" and \ref LpSolver::dual "dual()"
   134 (after solving the problem).
   135 
   136 \code
   137   std::cout << lp.dual(r) << std::endl;
   138 \endcode
   139 
   140 \ref LpBase::DualExpr "Lp::DualExpr" can be used to build dual expressions
   141 from rows and \ref LpBase::RowIt "Lp::RowIt" can be used to list the rows.
   142 
   143 \code
   144   Lp::DualExpr dual_sum;
   145   for (Lp::RowIt row(lp); row != INVALID; ++row) {
   146     dual_sum += row;
   147   }
   148 \endcode
   149 
   150 The LP solver interface provides several other features, which are
   151 documented in the classes \ref LpBase and \ref LpSolver.
   152 For detailed documentation, see these classes in the reference manual.
   153 
   154 If you would like to use a specific solver instead of the default one,
   155 you can use \ref GlpkLp, \ref ClpLp, \ref CplexLp etc. instead of
   156 the class \ref Lp.
   157 
   158 
   159 [SEC]sec_lp_mip[SEC] Mixed Integer Programming
   160 
   161 LEMON also provides a similar high-level interface for mixed integer
   162 programming (MIP) solvers. The default MIP solver can be used through
   163 the class \ref Mip, while the concrete solvers are implemented in the
   164 classes \ref GlpkMip, \ref CbcMip, \ref CplexMip etc.
   165 
   166 The following example demonstrates the usage of the MIP solver interface.
   167 The whole program can be found in \ref mip_demo.cc.
   168 
   169 \dontinclude mip_demo.cc
   170 \skip Create
   171 \until }
   172 \until }
   173 
   174 \todo Check this demo file after closing ticket #326.
   175 E.g. could we write <tt>mip.sol()</tt> instead of <tt>mip.solValue()</tt>?
   176 Or could we write <tt>primalValue()</tt> for \c Lp in \c lp_demo.cc?
   177 
   178 In this program, the same problem is built as in the above example,
   179 with the exception that the variable \c x1 is specified to be
   180 \c INTEGER valued. \c x2 is set to \c REAL, which is the default option.
   181 
   182 \code
   183   // Set the type of the columns
   184   mip.colType(x1, Mip::INTEGER);
   185   mip.colType(x2, Mip::REAL);
   186 \endcode
   187 
   188 Because of this integrality requirement, the results will be different
   189 from the LP solution.
   190 
   191 \code
   192   Objective function value: 67
   193   x1 = 8
   194   x2 = 9
   195 \endcode
   196 
   197 The documentation of the MIP solver interface can be found in the
   198 reference manual at the class \ref MipSolver. The common parts of the
   199 LP and MIP interfaces are documented in their common ancestor class
   200 \ref LpBase.
   201 
   202 
   203 [SEC]sec_lp_optimization[SEC] Solving Complex Optimization Problems
   204 
   205 The LP and MIP solvers are powerful tools for solving various complex
   206 optimization problems, as well.
   207 The following example solves a maximum flow problem with linear
   208 programming, see the whole program in \re lp_maxflow_demo.cc.
   209 Several other graph optimization problems can also be expressed as
   210 linear programs and the interface provided in LEMON facilitates solving
   211 them easily (though usually not so efficiently as by a direct
   212 combinatorial method, if one exists). 
   213 
   214 \dontinclude lp_maxflow_demo.cc
   215 \skip DIGRAPH_TYPEDEFS
   216 \until solve()
   217 
   218 \note This problem can be solved much more efficiently using common
   219 combinatorial optimization methods, such as the \ref Preflow
   220 "preflow push-relabel algorithm".
   221 
   222 [TRAILER]
   223 */
   224 }