test/mip_test.cc
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 982 bb70ad62c95f
parent 678 d21b38647e53
child 1300 62dba6c90f35
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
     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 }