deba@481: /* -*- mode: C++; indent-tabs-mode: nil; -*- deba@481: * deba@481: * This file is a part of LEMON, a generic C++ optimization library. deba@481: * deba@598: * Copyright (C) 2003-2009 deba@481: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@481: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@481: * deba@481: * Permission to use, modify and distribute this software is granted deba@481: * provided that this copyright notice appears in all copies. For deba@481: * precise terms see the accompanying LICENSE file. deba@481: * deba@481: * This software is provided "AS IS" with no warranty of any kind, deba@481: * express or implied, and with no claim as to its suitability for any deba@481: * purpose. deba@481: * deba@481: */ deba@481: deba@481: #include "test_tools.h" deba@481: deba@481: #include <lemon/config.h> deba@481: ladanyi@674: #ifdef LEMON_HAVE_CPLEX alpar@484: #include <lemon/cplex.h> deba@481: #endif deba@481: ladanyi@674: #ifdef LEMON_HAVE_GLPK alpar@484: #include <lemon/glpk.h> deba@481: #endif deba@481: ladanyi@674: #ifdef LEMON_HAVE_CBC deba@614: #include <lemon/cbc.h> deba@614: #endif deba@614: deba@481: deba@481: using namespace lemon; deba@481: deba@482: void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat, deba@481: double exp_opt) { deba@481: using std::string; deba@481: deba@482: mip.solve(); deba@481: //int decimal,sign; deba@481: std::ostringstream buf; deba@482: buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type()); deba@481: deba@481: deba@481: // itoa(stat,buf1, 10); deba@482: check(mip.type()==stat, buf.str()); deba@481: deba@482: if (stat == MipSolver::OPTIMAL) { deba@481: std::ostringstream sbuf; alpar@795: sbuf << "Wrong optimal value ("<< mip.solValue() alpar@795: <<" instead of " << exp_opt << ")"; deba@482: check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str()); deba@481: //+ecvt(exp_opt,2) deba@481: } deba@481: } deba@481: deba@482: void aTest(MipSolver& mip) deba@481: { deba@614: //The following example is very simple deba@481: deba@481: deba@482: typedef MipSolver::Row Row; deba@482: typedef MipSolver::Col Col; deba@481: deba@481: deba@481: Col x1 = mip.addCol(); deba@481: Col x2 = mip.addCol(); deba@481: deba@481: deba@481: //Objective function deba@481: mip.obj(x1); deba@481: deba@481: mip.max(); deba@481: deba@481: //Unconstrained optimization deba@481: mip.solve(); deba@481: //Check it out! deba@481: deba@481: //Constraints deba@614: mip.addRow(2 * x1 + x2 <= 2); deba@614: Row y2 = mip.addRow(x1 - 2 * x2 <= 0); deba@481: deba@481: //Nonnegativity of the variable x1 deba@481: mip.colLowerBound(x1, 0); deba@481: deba@614: deba@481: //Maximization of x1 deba@481: //over the triangle with vertices (0,0),(4/5,2/5),(0,2) deba@481: double expected_opt=4.0/5.0; deba@482: solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt); deba@481: deba@614: deba@481: //Restrict x2 to integer deba@482: mip.colType(x2,MipSolver::INTEGER); deba@481: expected_opt=1.0/2.0; deba@482: solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt); deba@481: deba@481: deba@481: //Restrict both to integer deba@482: mip.colType(x1,MipSolver::INTEGER); deba@481: expected_opt=0; deba@482: solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt); deba@481: deba@614: //Erase a variable deba@614: mip.erase(x2); deba@614: mip.rowUpperBound(y2, 8); deba@614: expected_opt=1; deba@614: solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt); deba@481: deba@481: } deba@481: deba@614: alpar@587: template<class MIP> alpar@587: void cloneTest() alpar@587: { deba@598: alpar@587: MIP* mip = new MIP(); alpar@587: MIP* mipnew = mip->newSolver(); alpar@587: MIP* mipclone = mip->cloneSolver(); alpar@587: delete mip; alpar@587: delete mipnew; alpar@587: delete mipclone; alpar@587: } deba@481: deba@481: int main() deba@481: { deba@481: ladanyi@674: #ifdef LEMON_HAVE_GLPK deba@482: { alpar@485: GlpkMip mip1; deba@482: aTest(mip1); alpar@587: cloneTest<GlpkMip>(); deba@482: } deba@481: #endif deba@481: ladanyi@674: #ifdef LEMON_HAVE_CPLEX deba@482: try { alpar@485: CplexMip mip2; deba@482: aTest(mip2); deba@598: cloneTest<CplexMip>(); deba@482: } catch (CplexEnv::LicenseError& error) { deba@482: check(false, error.what()); deba@482: } deba@481: #endif deba@481: ladanyi@674: #ifdef LEMON_HAVE_CBC deba@614: { deba@614: CbcMip mip1; deba@614: aTest(mip1); deba@614: cloneTest<CbcMip>(); deba@614: } deba@614: #endif deba@614: deba@481: return 0; deba@481: deba@481: }