deba@458: /* -*- mode: C++; indent-tabs-mode: nil; -*- deba@458: * deba@458: * This file is a part of LEMON, a generic C++ optimization library. deba@458: * deba@458: * Copyright (C) 2003-2008 deba@458: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@458: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@458: * deba@458: * Permission to use, modify and distribute this software is granted deba@458: * provided that this copyright notice appears in all copies. For deba@458: * precise terms see the accompanying LICENSE file. deba@458: * deba@458: * This software is provided "AS IS" with no warranty of any kind, deba@458: * express or implied, and with no claim as to its suitability for any deba@458: * purpose. deba@458: * deba@458: */ deba@458: deba@458: ///\file deba@458: ///\brief Implementation of the LEMON-CPLEX mip solver interface. deba@458: deba@458: #include deba@458: deba@458: extern "C" { deba@458: #include deba@458: } deba@458: deba@458: namespace lemon { deba@458: deba@458: MipCplex::MipCplex() { deba@458: //This is unnecessary: setting integrality constraints on deba@458: //variables will set this, too deba@458: deba@458: ///\todo The constant CPXPROB_MIP is deba@458: ///called CPXPROB_MILP in later versions deba@458: #if CPX_VERSION < 800 deba@458: CPXchgprobtype( env, lp, CPXPROB_MIP); deba@458: #else deba@458: CPXchgprobtype( env, lp, CPXPROB_MILP); deba@458: #endif deba@458: deba@458: } deba@458: deba@458: void MipCplex::_colType(int i, MipCplex::ColTypes col_type){ deba@458: deba@458: // Note If a variable is to be changed to binary, a call to CPXchgbds deba@458: // should also be made to change the bounds to 0 and 1. deba@458: deba@458: int indices[1]; deba@458: indices[0]=i; deba@458: char ctype[1]; deba@458: switch (col_type){ deba@458: case INT: deba@458: ctype[0]=CPX_INTEGER;//'I' deba@458: break; deba@458: case REAL: deba@458: ctype[0]=CPX_CONTINUOUS ;//'C' deba@458: break; deba@458: default:; deba@458: //FIXME problem deba@458: } deba@458: CPXchgctype (env, lp, 1, indices, ctype); deba@458: } deba@458: deba@458: MipCplex::ColTypes MipCplex::_colType(int i) const { deba@458: deba@458: char ctype[1]; deba@458: CPXgetctype (env, lp, ctype, i, i); deba@458: switch (ctype[0]){ deba@458: deba@458: case CPX_INTEGER: deba@458: return INT; deba@458: case CPX_CONTINUOUS: deba@458: return REAL; deba@458: default: deba@458: return REAL;//Error! deba@458: } deba@458: deba@458: } deba@458: deba@458: LpCplex::SolveExitStatus MipCplex::_solve(){ deba@458: deba@458: status = CPXmipopt (env, lp); deba@458: if (status==0) deba@458: return SOLVED; deba@458: else deba@458: return UNSOLVED; deba@458: deba@458: } deba@458: deba@458: deba@458: LpCplex::SolutionStatus MipCplex::_getMipStatus() const { deba@458: deba@458: int stat = CPXgetstat(env, lp); deba@458: deba@458: //Fortunately, MIP statuses did not change for cplex 8.0 deba@458: switch (stat) deba@458: { deba@458: case CPXMIP_OPTIMAL: deba@458: // Optimal integer solution has been found. deba@458: case CPXMIP_OPTIMAL_TOL: deba@458: // Optimal soluton with the tolerance defined by epgap or epagap has deba@458: // been found. deba@458: return OPTIMAL; deba@458: //This also exists in later issues deba@458: // case CPXMIP_UNBOUNDED: deba@458: //return INFINITE; deba@458: case CPXMIP_INFEASIBLE: deba@458: return INFEASIBLE; deba@458: default: deba@458: return UNDEFINED; deba@458: } deba@458: //Unboundedness not treated well: the following is from cplex 9.0 doc deba@458: // About Unboundedness deba@458: deba@458: // The treatment of models that are unbounded involves a few deba@458: // subtleties. Specifically, a declaration of unboundedness means that deba@458: // ILOG CPLEX has determined that the model has an unbounded deba@458: // ray. Given any feasible solution x with objective z, a multiple of deba@458: // the unbounded ray can be added to x to give a feasible solution deba@458: // with objective z-1 (or z+1 for maximization models). Thus, if a deba@458: // feasible solution exists, then the optimal objective is deba@458: // unbounded. Note that ILOG CPLEX has not necessarily concluded that deba@458: // a feasible solution exists. Users can call the routine CPXsolninfo deba@458: // to determine whether ILOG CPLEX has also concluded that the model deba@458: // has a feasible solution. deba@458: deba@458: } deba@458: deba@458: MipCplex::Value MipCplex::_getPrimal(int i) const { deba@458: Value x; deba@458: CPXgetmipx(env, lp, &x, i, i); deba@458: return x; deba@458: } deba@458: deba@458: MipCplex::Value MipCplex::_getPrimalValue() const { deba@458: Value objval; deba@458: CPXgetmipobjval(env, lp, &objval); deba@458: return objval; deba@458: } deba@458: } //END OF NAMESPACE LEMON