test/mip_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 631 d21b38647e53
child 1105 62dba6c90f35
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
     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-2009
     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 #include "test_tools.h"
    20 
    21 #include <lemon/config.h>
    22 
    23 #ifdef LEMON_HAVE_CPLEX
    24 #include <lemon/cplex.h>
    25 #endif
    26 
    27 #ifdef LEMON_HAVE_GLPK
    28 #include <lemon/glpk.h>
    29 #endif
    30 
    31 #ifdef LEMON_HAVE_CBC
    32 #include <lemon/cbc.h>
    33 #endif
    34 
    35 
    36 using namespace lemon;
    37 
    38 void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
    39                    double exp_opt) {
    40   using std::string;
    41 
    42   mip.solve();
    43   //int decimal,sign;
    44   std::ostringstream buf;
    45   buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
    46 
    47 
    48   //  itoa(stat,buf1, 10);
    49   check(mip.type()==stat, buf.str());
    50 
    51   if (stat ==  MipSolver::OPTIMAL) {
    52     std::ostringstream sbuf;
    53     sbuf << "Wrong optimal value ("<< mip.solValue()
    54          <<" instead of " << exp_opt << ")";
    55     check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
    56     //+ecvt(exp_opt,2)
    57   }
    58 }
    59 
    60 void aTest(MipSolver& mip)
    61 {
    62   //The following example is very simple
    63 
    64 
    65   typedef MipSolver::Row Row;
    66   typedef MipSolver::Col Col;
    67 
    68 
    69   Col x1 = mip.addCol();
    70   Col x2 = mip.addCol();
    71 
    72 
    73   //Objective function
    74   mip.obj(x1);
    75 
    76   mip.max();
    77 
    78   //Unconstrained optimization
    79   mip.solve();
    80   //Check it out!
    81 
    82   //Constraints
    83   mip.addRow(2 * x1 + x2 <= 2);
    84   Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
    85 
    86   //Nonnegativity of the variable x1
    87   mip.colLowerBound(x1, 0);
    88 
    89 
    90   //Maximization of x1
    91   //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
    92   double expected_opt=4.0/5.0;
    93   solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
    94 
    95 
    96   //Restrict x2 to integer
    97   mip.colType(x2,MipSolver::INTEGER);
    98   expected_opt=1.0/2.0;
    99   solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
   100 
   101 
   102   //Restrict both to integer
   103   mip.colType(x1,MipSolver::INTEGER);
   104   expected_opt=0;
   105   solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
   106 
   107   //Erase a variable
   108   mip.erase(x2);
   109   mip.rowUpperBound(y2, 8);
   110   expected_opt=1;
   111   solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
   112 
   113 }
   114 
   115 
   116 template<class MIP>
   117 void cloneTest()
   118 {
   119 
   120   MIP* mip = new MIP();
   121   MIP* mipnew = mip->newSolver();
   122   MIP* mipclone = mip->cloneSolver();
   123   delete mip;
   124   delete mipnew;
   125   delete mipclone;
   126 }
   127 
   128 int main()
   129 {
   130 
   131 #ifdef LEMON_HAVE_GLPK
   132   {
   133     GlpkMip mip1;
   134     aTest(mip1);
   135     cloneTest<GlpkMip>();
   136   }
   137 #endif
   138 
   139 #ifdef LEMON_HAVE_CPLEX
   140   try {
   141     CplexMip mip2;
   142     aTest(mip2);
   143     cloneTest<CplexMip>();
   144   } catch (CplexEnv::LicenseError& error) {
   145     check(false, error.what());
   146   }
   147 #endif
   148 
   149 #ifdef LEMON_HAVE_CBC
   150   {
   151     CbcMip mip1;
   152     aTest(mip1);
   153     cloneTest<CbcMip>();
   154   }
   155 #endif
   156 
   157   return 0;
   158 
   159 }