// copyright (C) 2000, International Business Machines // Corporation and others. All Rights Reserved. /* OPEN: have a look at the OPEN tags */ /* OPEN: read/set more controls ... */ #if defined(_MSC_VER) // Turn off compiler warning about long names # pragma warning(disable:4786) #endif #include #include #include #ifdef _WIN32 #define DLL #endif #define __ANSIC_ #include #undef __ANSIC_ #include "OsiXprSolverInterface.hpp" #include "CoinHelperFunctions.hpp" #include "OsiCuts.hpp" #include "OsiColCut.hpp" #include "CoinPackedMatrix.hpp" #include "OsiRowCut.hpp" #include "CoinWarmStartBasis.hpp" #define DEBUG void reporterror(const char *fname, int iline, int ierr) { fprintf( stdout, "ERROR: %s in line %d error %d occured\n", fname, iline, ierr ); } #define XPRS_CHECKED(function, args) do { \ int _nReturn; \ if( (_nReturn = function args ) !=0 ) { \ reporterror (#function,__LINE__,_nReturn); \ } \ } while (0) //############################################################################# // Solve methods //############################################################################# void OsiXprSolverInterface::initialSolve(){ freeSolution(); if ( objsense_ == 1.0 ) { XPRS_CHECKED( XPRSminim, (prob_,"l") ); } else if ( objsense_ == -1.0 ) { XPRS_CHECKED( XPRSmaxim, (prob_,"l")); } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::resolve(){ freeSolution(); if ( objsense_ == 1.0 ) { XPRS_CHECKED( XPRSminim, (prob_,"dl") ); } else if ( objsense_ == -1.0 ) { XPRS_CHECKED( XPRSmaxim, (prob_,"dl") ) ; } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::branchAndBound(){ freeSolution(); XPRS_CHECKED( XPRSglobal, (prob_) ); } //############################################################################# // Parameter related methods //############################################################################# bool OsiXprSolverInterface::setIntParam(OsiIntParam key, int value) { bool retval = false; switch (key) { case OsiMaxNumIteration: retval = XPRSsetintcontrol(prob_,XPRS_LPITERLIMIT, value) == 0; break; case OsiMaxNumIterationHotStart: retval = false; break; case OsiLastIntParam: retval = false; break; } return retval; } //----------------------------------------------------------------------------- /* OPEN: more dbl parameters ... */ bool OsiXprSolverInterface::setDblParam(OsiDblParam key, double value) { bool retval = false; switch (key) { case OsiDualObjectiveLimit: retval = XPRSsetdblcontrol(prob_,XPRS_MIPABSCUTOFF, value) == 0; break; case OsiPrimalObjectiveLimit: retval = false; break; case OsiDualTolerance: retval = XPRSsetdblcontrol(prob_, XPRS_FEASTOL, value) == 0; break; case OsiPrimalTolerance: retval = XPRSsetdblcontrol(prob_, XPRS_FEASTOL, value) == 0; break; case OsiObjOffset: return OsiSolverInterface::setDblParam(key, value); case OsiLastDblParam: retval = false; break; } return retval; } //----------------------------------------------------------------------------- bool OsiXprSolverInterface::setStrParam(OsiStrParam key, const std::string & value) { bool retval=false; switch (key) { case OsiProbName: /* OPEN: what does this mean */ OsiSolverInterface::setStrParam(key,value); return retval = true; case OsiLastStrParam: return false; case OsiSolverName: return false; } return false; } //----------------------------------------------------------------------------- bool OsiXprSolverInterface::getIntParam(OsiIntParam key, int& value) const { bool retval = false; switch (key) { case OsiMaxNumIteration: /* OPEN: the return value was logically wrong */ retval = XPRSgetintcontrol(prob_,XPRS_LPITERLIMIT, &value) == 0; break; case OsiMaxNumIterationHotStart: retval = false; break; case OsiLastIntParam: retval = false; break; } return retval; } //----------------------------------------------------------------------------- bool OsiXprSolverInterface::getDblParam(OsiDblParam key, double& value) const { bool retval = false; switch (key) { case OsiDualObjectiveLimit: retval = XPRSgetdblcontrol(prob_,XPRS_MIPABSCUTOFF, &value) == 0; break; case OsiPrimalObjectiveLimit: retval = false; break; case OsiDualTolerance: retval = XPRSgetdblcontrol(prob_, XPRS_FEASTOL, &value) == 0; break; case OsiPrimalTolerance: retval = XPRSgetdblcontrol(prob_, XPRS_FEASTOL, &value) == 0; break; case OsiObjOffset: retval = OsiSolverInterface::getDblParam(key, value); break; case OsiLastDblParam: retval = false; break; } return retval; } //----------------------------------------------------------------------------- bool OsiXprSolverInterface::getStrParam(OsiStrParam key, std::string & value) const { bool retval = false; switch (key) { case OsiProbName: OsiSolverInterface::getStrParam(key, value); retval = true; break; case OsiSolverName: value = "xpress"; retval = true; break; case OsiLastStrParam: retval = false; } return retval; } //############################################################################# // Methods returning info on how the solution process terminated //############################################################################# bool OsiXprSolverInterface::isAbandoned() const { int status, glstat; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_LPSTATUS, &status) ); XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_MIPSTATUS, &glstat) ); return status == XPRS_LP_UNFINISHED // LP unfinished || glstat == XPRS_MIP_NO_SOL_FOUND // global search incomplete -- no int sol || glstat == XPRS_MIP_SOLUTION; // global search incomplete -- int sol found } bool OsiXprSolverInterface::isProvenOptimal() const { int status, glstat; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_LPSTATUS, &status) ); XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_MIPSTATUS, &glstat) ); return status == XPRS_LP_OPTIMAL // LP optimal || status == XPRS_LP_CUTOFF // LP obj worse than cutoff || glstat == XPRS_MIP_OPTIMAL; // global search complete -- int found } bool OsiXprSolverInterface::isProvenPrimalInfeasible() const { int status; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_LPSTATUS, &status) ); return status == XPRS_LP_INFEAS; // LP infeasible } bool OsiXprSolverInterface::isProvenDualInfeasible() const { int status; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_LPSTATUS, &status) ); return status == XPRS_LP_UNBOUNDED; // LP Unbounded } bool OsiXprSolverInterface::isPrimalObjectiveLimitReached() const { /* OPEN: what does that mean */ return false; // N/A in XOSL } bool OsiXprSolverInterface::isDualObjectiveLimitReached() const { int status; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_LPSTATUS, &status) ); return status == XPRS_LP_CUTOFF_IN_DUAL; // LP cut off in dual } bool OsiXprSolverInterface::isIterationLimitReached() const { int itrlim, itcnt; XPRS_CHECKED( XPRSgetintcontrol, (prob_,XPRS_LPITERLIMIT, &itrlim) ); XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_SIMPLEXITER, &itcnt) ); return itcnt >= itrlim; } //############################################################################# // WarmStart related methods //############################################################################# CoinWarmStart* OsiXprSolverInterface::getWarmStart() const { int pstat, retstat; /* OPEN: what does this mean */ XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_PRESOLVESTATE, &pstat) ); if ( pstat != 7 ) return NULL; CoinWarmStartBasis *ws = NULL; int numcols = getNumCols(); int numrows = getNumRows(); const double *lb = getColLower(); double infty = getInfinity(); int *rstatus = new int[numrows]; int *cstatus = new int[numcols]; retstat = XPRSgetbasis(prob_,rstatus, cstatus); if ( retstat == 0 ) { int i; ws = new CoinWarmStartBasis; ws->setSize( numcols, numrows ); for( i = 0; i < numrows; i++ ) { switch( rstatus[i] ) { case 0: ws->setArtifStatus(i, CoinWarmStartBasis::atLowerBound); break; case 1: ws->setArtifStatus(i, CoinWarmStartBasis::basic); break; case 2: ws->setArtifStatus(i, CoinWarmStartBasis::atUpperBound); break; default: // unknown row status delete ws; ws = NULL; goto TERMINATE; } } for( i = 0; i < numcols; i++ ) { switch( cstatus[i] ) { case 0: if ( lb[i] <= -infty ) ws->setStructStatus(i, CoinWarmStartBasis::isFree); else ws->setStructStatus(i, CoinWarmStartBasis::atLowerBound); break; case 1: ws->setStructStatus( i, CoinWarmStartBasis::basic ); break; case 2: ws->setStructStatus( i, CoinWarmStartBasis::atUpperBound ); break; default: // unknown column status delete ws; ws = NULL; goto TERMINATE; } } } TERMINATE: delete[] cstatus; delete[] rstatus; return ws; } //----------------------------------------------------------------------------- bool OsiXprSolverInterface::setWarmStart(const CoinWarmStart* warmstart) { const CoinWarmStartBasis* ws = dynamic_cast(warmstart); if ( !ws ) return false; int numcols = ws->getNumStructural(); int numrows = ws->getNumArtificial(); if ( numcols != getNumCols() || numrows != getNumRows() ) return false; bool retval; int retstat; int *cstatus = new int[numcols]; int *rstatus = new int[numrows]; int i; for ( i = 0; i < numrows; i++ ) { switch( ws->getArtifStatus(i) ) { case CoinWarmStartBasis::atLowerBound: rstatus[i] = 0; break; case CoinWarmStartBasis::basic: rstatus[i] = 1; break; case CoinWarmStartBasis::atUpperBound: rstatus[i] = 2; break; default: // unknown row status retval = false; goto TERMINATE; } } for( i = 0; i < numcols; i++ ) { switch( ws->getStructStatus(i) ) { case CoinWarmStartBasis::atLowerBound: case CoinWarmStartBasis::isFree: cstatus[i] = 0; break; case CoinWarmStartBasis::basic: cstatus[i] = 1; break; case CoinWarmStartBasis::atUpperBound: cstatus[i] = 2; break; default: // unknown row status retval = false; goto TERMINATE; } } retstat = XPRSloadbasis(prob_,rstatus, cstatus); retval = (retstat == 0); TERMINATE: delete[] cstatus; delete[] rstatus; return retval; } //############################################################################# // Hotstart related methods (primarily used in strong branching) //############################################################################# void OsiXprSolverInterface::markHotStart() { // *FIXME* : do better... -LL OsiSolverInterface::markHotStart(); } void OsiXprSolverInterface::solveFromHotStart() { // *FIXME* : do better... -LL OsiSolverInterface::solveFromHotStart(); } void OsiXprSolverInterface::unmarkHotStart() { // *FIXME* : do better... -LL OsiSolverInterface::unmarkHotStart(); } //############################################################################# // Problem information methods (original data) //############################################################################# //------------------------------------------------------------------ // Get number of rows and columns //------------------------------------------------------------------ int OsiXprSolverInterface::getNumCols() const { if ( !isDataLoaded() ) return 0; int ncols; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_COLS, &ncols) ); return ncols; } //----------------------------------------------------------------------------- int OsiXprSolverInterface::getNumRows() const { if ( !isDataLoaded() ) return 0; int nrows; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_ROWS, &nrows) ); return nrows; } //----------------------------------------------------------------------------- int OsiXprSolverInterface::getNumElements() const { if ( !isDataLoaded() ) return 0; int retVal; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_ELEMS, &retVal) ); return retVal; } //------------------------------------------------------------------ // Get pointer to rim vectors //------------------------------------------------------------------ const double * OsiXprSolverInterface::getColLower() const { if ( collower_ == NULL ) { if ( isDataLoaded() ) { int ncols = getNumCols(); if ( ncols > 0 ) { collower_ = new double[ncols]; XPRS_CHECKED( XPRSgetlb, (prob_,collower_, 0, ncols - 1) ); } } } return collower_; } //----------------------------------------------------------------------------- const double * OsiXprSolverInterface::getColUpper() const { if ( colupper_ == NULL ) { if ( isDataLoaded() ) { int ncols = getNumCols(); if ( ncols > 0 ) { colupper_ = new double[ncols]; XPRS_CHECKED( XPRSgetub, (prob_,colupper_, 0, ncols - 1) ); } } } return colupper_; } //----------------------------------------------------------------------------- const char * OsiXprSolverInterface::getRowSense() const { if ( rowsense_ == NULL ) { if ( isDataLoaded() ) { int nrows = getNumRows(); if ( nrows > 0 ) { rowsense_ = new char[nrows]; XPRS_CHECKED( XPRSgetrowtype, (prob_,rowsense_, 0, nrows - 1) ); } } } return rowsense_; } //----------------------------------------------------------------------------- const double * OsiXprSolverInterface::getRightHandSide() const { if ( rhs_ == NULL ) { if ( isDataLoaded() ) { int nrows = getNumRows(); if ( nrows > 0 ) { rhs_ = new double[nrows]; XPRS_CHECKED( XPRSgetrhs, (prob_,rhs_, 0, nrows - 1) ); // Make sure free rows have rhs of zero const char * rs = getRowSense(); int nr = getNumRows(); int i; for ( i = 0; i < nr; i++ ) { if ( rs[i] == 'N' ) rhs_[i]=0.0; } } } } return rhs_; } //----------------------------------------------------------------------------- const double * OsiXprSolverInterface::getRowRange() const { if ( rowrange_ == NULL ) { if ( isDataLoaded() ) { int nrows = getNumRows(); if ( nrows > 0 ) { rowrange_ = new double[nrows]; XPRS_CHECKED( XPRSgetrhsrange, (prob_,rowrange_, 0, nrows - 1) ); // Make sure non-R rows have range of 0.0 // XPRESS seems to set N and L rows to a range of Infinity const char * rs = getRowSense(); int nr = getNumRows(); int i; for ( i = 0; i < nr; i++ ) { if ( rs[i] != 'R' ) rowrange_[i] = 0.0; } } } } return rowrange_; } //----------------------------------------------------------------------------- const double * OsiXprSolverInterface::getRowLower() const { if ( rowlower_ == NULL ) { int nrows = getNumRows(); const char *rowsense = getRowSense(); const double *rhs = getRightHandSide(); const double *rowrange = getRowRange(); if ( nrows > 0 ) { rowlower_ = new double[nrows]; double dum1; for ( int i = 0; i < nrows; i++ ) { convertSenseToBound(rowsense[i], rhs[i], rowrange[i], rowlower_[i], dum1); } } } return rowlower_; } //----------------------------------------------------------------------------- const double * OsiXprSolverInterface::getRowUpper() const { if ( rowupper_ == NULL ) { int nrows = getNumRows(); const char *rowsense = getRowSense(); const double *rhs = getRightHandSide(); const double *rowrange = getRowRange(); if ( nrows > 0 ) { rowupper_ = new double[nrows]; double dum1; for ( int i = 0; i < nrows; i++ ) { convertSenseToBound(rowsense[i], rhs[i], rowrange[i], dum1, rowupper_[i]); } } } return rowupper_; } //----------------------------------------------------------------------------- const double * OsiXprSolverInterface::getObjCoefficients() const { if ( objcoeffs_ == NULL ) { if ( isDataLoaded() ) { int ncols = getNumCols(); if ( ncols > 0 ) { objcoeffs_ = new double[ncols]; XPRS_CHECKED( XPRSgetobj, (prob_,objcoeffs_, 0, ncols - 1) ); } } } return objcoeffs_; } //----------------------------------------------------------------------------- double OsiXprSolverInterface::getObjSense() const { return objsense_; } //----------------------------------------------------------------------------- // Return information on integrality //----------------------------------------------------------------------------- bool OsiXprSolverInterface::isContinuous(int colNumber) const { getVarTypes(); //std::cerr <<"OsiXprSolverInterface::isContinuous " <colupper(); const double *collower = this->collower(); getVarTypes(); return isBinary(colNumber) && colupper[colNumber] != collower[colNumber]; } #endif //------------------------------------------------------------------ // Row and column copies of the matrix ... //------------------------------------------------------------------ const CoinPackedMatrix * OsiXprSolverInterface::getMatrixByRow() const { if ( matrixByRow_ == NULL ) { if ( isDataLoaded() ) { int nrows = getNumRows(); int ncols = getNumCols(); int nelems; XPRS_CHECKED( XPRSgetrows, (prob_,NULL, NULL, NULL, 0, &nelems, 0, nrows - 1) ); int *start = new int [nrows + 1]; int *length = new int [nrows]; int *index = new int [nelems]; double *element = new double[nelems]; XPRS_CHECKED( XPRSgetrows, (prob_,start, index, element, nelems, &nelems, 0, nrows - 1) ); std::adjacent_difference(start + 1, start + (nrows+1), length); matrixByRow_ = new CoinPackedMatrix(true,0,0); // (mjs) No gaps! // Gaps =><= presolve. matrixByRow_->assignMatrix(false /* not column ordered */, ncols, nrows, nelems, element, index, start, length); } else { matrixByRow_ = new CoinPackedMatrix(true,0,0); // (mjs) No gaps! matrixByRow_->reverseOrdering(); } } return matrixByRow_; } //----------------------------------------------------------------------------- const CoinPackedMatrix * OsiXprSolverInterface::getMatrixByCol() const { if ( matrixByCol_ == NULL ) { matrixByCol_ = new CoinPackedMatrix(*getMatrixByRow()); matrixByCol_->reverseOrdering(); } return matrixByCol_; } //------------------------------------------------------------------ // Get solver's value for infinity //------------------------------------------------------------------ double OsiXprSolverInterface::getInfinity() const { return XPRS_PLUSINFINITY; } //############################################################################# // Problem information methods (results) //############################################################################# const double * OsiXprSolverInterface::getColSolution() const { if ( colsol_ == NULL ) { if ( isDataLoaded() ) { int nc = getNumCols(); if ( nc > 0 ) { colsol_ = new double[nc]; XPRS_CHECKED( XPRSgetsol, (prob_,colsol_, NULL, NULL, NULL) ); } } } return colsol_; } //----------------------------------------------------------------------------- const double * OsiXprSolverInterface::getRowPrice() const { if ( rowprice_ == NULL ) { if ( isDataLoaded() ) { int nr = getNumRows(); if ( nr > 0 ) { rowprice_ = new double[nr]; XPRS_CHECKED( XPRSgetsol, (prob_,NULL, NULL, rowprice_, NULL) ); } } } return rowprice_; } //----------------------------------------------------------------------------- const double * OsiXprSolverInterface::getReducedCost() const { if ( colprice_ == NULL ) { int nc = getNumCols(); if ( isDataLoaded() ) { colprice_ = new double[nc]; XPRS_CHECKED( XPRSgetsol, (prob_,NULL, NULL, NULL, colprice_) ); } } return colprice_; } //----------------------------------------------------------------------------- const double * OsiXprSolverInterface::getRowActivity() const { if( rowact_ == NULL ) { if ( isDataLoaded() ) { int nrows = getNumRows(); const double *rhs = getRightHandSide(); if( nrows > 0 ) { int status; rowact_ = new double[nrows]; /* OPEN: why do we need the presolve state here ??? */ XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_PRESOLVESTATE, &status) ); if ( status == 7 ) { int i; XPRS_CHECKED( XPRSgetsol, (prob_,NULL, rowact_, NULL, NULL) ); for ( i = 0; i < nrows; i++ ) rowact_[i] = rhs[i] - rowact_[i]; } else { CoinFillN(rowact_, nrows, 0.0); } } } } return rowact_; } //----------------------------------------------------------------------------- double OsiXprSolverInterface::getObjValue() const { double objvalue = 0; double objconstant = 0; if ( isDataLoaded() ) { XPRS_CHECKED( XPRSgetdblattrib, (prob_,XPRS_LPOBJVAL, &objvalue) ); OsiSolverInterface::getDblParam(OsiObjOffset, objconstant); // Constant offset is not saved with the xpress representation, // but it has to be returned from here anyway. } return objvalue - objconstant; } //----------------------------------------------------------------------------- int OsiXprSolverInterface::getIterationCount() const { int itcnt; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_SIMPLEXITER, &itcnt) ); return itcnt; } //----------------------------------------------------------------------------- std::vector OsiXprSolverInterface::getDualRays(int maxNumRays) const { // *FIXME* : must write the method -LL throw CoinError("method is not yet written", "getDualRays", "OsiXprSolverInterface"); return std::vector(); } //----------------------------------------------------------------------------- std::vector OsiXprSolverInterface::getPrimalRays(int maxNumRays) const { #if 0 // *FIXME* : Still need to expand column into full ncols-length vector const int nrows = getNumRows(); int nrspar; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_SPAREROWS, &nrspar) ); int junb; int retcode; retcode = XPRSgetunbvec(prob_,&junb); if ( retcode != 0 ) return std::vector(0, (double *) NULL);; double *ray = new double[nrows]; if ( junb < nrows ) { // it's a slack int i; for ( i = 0; i < nrows; i++ ) ray[i] = 0.0; ray[junb] = 1.0; XPRS_CHECKED( XPRSftran, (prob_,ray) ); } else if ( junb >= nrows + nrspar && junb < nrows + nrspar + getNumCols() ){ // it's a structural variable int *mstart = new int[nrows]; int *mrowind = new int[nrows]; double *dmatval = new double[nrows]; int nelt; int jcol = junb - nrows - nrspar; XPRS_CHECKED( XPRSgetcols, (prob_,mstart, mrowind, dmatval, nrows, &nelt, jcol, jcol) ); /* Unpack into the zeroed array y */ int i, ielt; for ( i = 0; i < nrows; i++ ) ray[i] = 0.0; for ( ielt = 0; ielt < nelt; ielt++ ) ray[mrowind[ielt]] = dmatval[ielt]; XPRS_CHECKED( XPRSftran, (prob_,ray) ); delete [] mstart; delete [] mrowind; delete [] dmatval; } else { // it's an error retcode = 1; } if ( retcode == 0 ) return std::vector(1, ray); else { delete ray; return std::vector(0, (double *) NULL); } #endif // *FIXME* : must write the method -LL throw CoinError("method is not yet written", "getPrimalRays", "OsiXprSolverInterface"); return std::vector(); } //----------------------------------------------------------------------------- #if 0 OsiVectorInt OsiXprSolverInterface::getFractionalIndices(const double etol) const { OsiVectorInt retVal; int numInts = numintvars(); const double *sol = colsol(); getVarTypes(); OsiRelFltEq eq(etol); for ( int i = 0; i < numInts; i++ ) { double colSolElem = sol[ivarind_[i]]; double distanceFromInteger = colSolElem - floor(colSolElem + 0.5); if ( !eq( distanceFromInteger, 0.0 ) ) retVal.push_back(ivarind_[i]); } return retVal; } #endif //############################################################################# // Problem modifying methods (rim vectors) //############################################################################# void OsiXprSolverInterface::setObjCoeff( int elementIndex, double elementValue ) { if ( isDataLoaded() ) { XPRS_CHECKED( XPRSchgobj, (prob_,1, &elementIndex, &elementValue) ); freeCachedResults(); } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setColLower( int elementIndex, double elementValue ) { if ( isDataLoaded() ) { char boundType = 'L'; getVarTypes(); if ( vartype_ && vartype_[elementIndex] == 'B' && (elementValue != 0.0 && elementValue != 1.0) ) { char elementType = 'I'; XPRS_CHECKED( XPRSchgcoltype, (prob_,1, &elementIndex, &elementType) ); } XPRS_CHECKED( XPRSchgbounds, (prob_,1, &elementIndex, &boundType, &elementValue) ); freeCachedResults(); // delete [] collower_; // collower_ = NULL; } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setColUpper( int elementIndex, double elementValue ) { if ( isDataLoaded() ) { char boundType = 'U'; getVarTypes(); XPRS_CHECKED( XPRSchgbounds, (prob_,1, &elementIndex, &boundType, &elementValue) ); if ( vartype_ && vartype_[elementIndex] == 'B' && (elementValue != 0.0 && elementValue != 1.0) ) { char elementType = 'I'; XPRS_CHECKED( XPRSchgcoltype, (prob_,1, &elementIndex, &elementType) ); } freeCachedResults(); // delete [] colupper_; // colupper_ = NULL; } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setColBounds(const int elementIndex, double lower, double upper ) { if ( isDataLoaded() ) { char qbtype[2] = { 'L', 'U' }; int mindex[2]; double bnd[2]; getVarTypes(); mindex[0] = elementIndex; mindex[1] = elementIndex; bnd[0] = lower; bnd[1] = upper; XPRS_CHECKED( XPRSchgbounds, (prob_,2, mindex, qbtype, bnd) ); if ( vartype_ && vartype_[mindex[0]] == 'B' && !((lower == 0.0 && upper == 0.0) || (lower == 1.0 && upper == 1.0) || (lower == 0.0 && upper == 1.0)) ) { char elementType = 'I'; XPRS_CHECKED( XPRSchgcoltype, (prob_,1, &mindex[0], &elementType) ); } freeCachedResults(); // delete [] colupper_; // colupper_ = NULL; } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setColSetBounds(const int* indexFirst, const int* indexLast, const double* boundList) { OsiSolverInterface::setColSetBounds(indexFirst, indexLast, boundList); } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setRowLower( int elementIndex, double elementValue ) { double rhs = getRightHandSide()[elementIndex]; double range = getRowRange()[elementIndex]; char sense = getRowSense()[elementIndex]; double lower = 0, upper = 0; convertSenseToBound(sense, rhs, range, lower, upper); if( lower != elementValue ) { convertBoundToSense(elementValue, upper, sense, rhs, range); setRowType(elementIndex, sense, rhs, range); // freeCachedResults(); --- invoked in setRowType() } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setRowUpper( int elementIndex, double elementValue ) { double rhs = getRightHandSide()[elementIndex]; double range = getRowRange()[elementIndex]; char sense = getRowSense()[elementIndex]; double lower = 0, upper = 0; convertSenseToBound( sense, rhs, range, lower, upper ); if( upper != elementValue ) { convertBoundToSense(lower, elementValue, sense, rhs, range); setRowType(elementIndex, sense, rhs, range); // freeCachedResults(); --- invoked in setRowType() } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setRowBounds( int elementIndex, double lower, double upper ) { double rhs, range; char sense; convertBoundToSense( lower, upper, sense, rhs, range ); setRowType( elementIndex, sense, rhs, range ); // freeCachedRowRim(); --- invoked in setRowType() } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setRowType(int index, char sense, double rightHandSide, double range) { if ( isDataLoaded() ) { int mindex[1] = {index}; char qrtype[1] = {sense}; double rhs[1] = {rightHandSide}; double rng[1] = {range}; XPRS_CHECKED( XPRSchgrowtype, (prob_,1, mindex, qrtype) ); XPRS_CHECKED( XPRSchgrhs, (prob_,1, mindex, rhs) ); XPRS_CHECKED( XPRSchgrhsrange, (prob_,1, mindex, rng) ); freeCachedResults(); } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setRowSetBounds(const int* indexFirst, const int* indexLast, const double* boundList) { OsiSolverInterface::setRowSetBounds(indexFirst, indexLast, boundList); } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setRowSetTypes(const int* indexFirst, const int* indexLast, const char* senseList, const double* rhsList, const double* rangeList) { OsiSolverInterface::setRowSetTypes(indexFirst, indexLast, senseList, rhsList, rangeList); } //############################################################################# void OsiXprSolverInterface::setContinuous(int index) { if ( isDataLoaded() ) { int pstat; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_PRESOLVESTATE, &pstat) ); if ( (pstat & 6) == 0 ) { // not presolved char qctype = 'C'; XPRS_CHECKED( XPRSchgcoltype, (prob_,1, &index, &qctype) ); freeCachedResults(); } } } void OsiXprSolverInterface::setInteger(int index) { if ( isDataLoaded() ) { int pstat; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_PRESOLVESTATE, &pstat) ); if ( (pstat & 6) == 0 ) { // not presolved char qctype; if ( getColLower()[index] == 0.0 && getColUpper()[index] == 1.0 ) qctype = 'B'; else qctype = 'I'; XPRS_CHECKED( XPRSchgcoltype, (prob_,1, &index, &qctype) ); freeCachedResults(); } } } void OsiXprSolverInterface::setContinuous(const int* indices, int len) { if ( isDataLoaded() ) { int pstat; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_PRESOLVESTATE, &pstat) ); if ( (pstat & 6) == 0 ) { // not presolved char *qctype = new char[len]; CoinFillN(qctype, len, 'C'); XPRS_CHECKED( XPRSchgcoltype, (prob_,len, const_cast(indices), qctype) ); freeCachedResults(); } } } void OsiXprSolverInterface::setInteger(const int* indices, int len) { if ( isDataLoaded() ) { int pstat; XPRS_CHECKED( XPRSgetintattrib, (prob_,XPRS_PRESOLVESTATE, &pstat) ); if ( (pstat & 6) == 0 ) { // not presolved char *qctype = new char[len]; const double* clb = getColLower(); const double* cub = getColUpper(); for ( int i = 0; i < len; i++ ) { if ( clb[indices[i]] == 0.0 && cub[indices[i]] == 1.0 ) qctype[i] = 'B'; else qctype[i] = 'I'; } XPRS_CHECKED( XPRSchgcoltype, (prob_,len, const_cast(indices), qctype) ); freeCachedResults(); } } } //############################################################################# void OsiXprSolverInterface::setObjSense(double s) { objsense_ = s; } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setColSolution(const double *colsol) { freeSolution(); colsol_ = new double[getNumCols()]; for ( int i = 0; i < getNumCols(); i++ ) colsol_[i] = colsol[i]; } //----------------------------------------------------------------------------- void OsiXprSolverInterface::setRowPrice(const double *rowprice) { freeSolution(); rowprice_ = new double[getNumRows()]; for ( int i = 0; i < getNumRows(); i++ ) rowprice_[i] = rowprice[i]; } //############################################################################# // Problem modifying methods (matrix) //############################################################################# void OsiXprSolverInterface::addCol(const CoinPackedVectorBase& vec, const double collb, const double colub, const double obj) { if ( isDataLoaded() ) { freeCachedResults(); int mstart = 0; XPRS_CHECKED( XPRSaddcols, (prob_,1, vec.getNumElements(), const_cast(&obj), &mstart, const_cast(vec.getIndices()), const_cast(vec.getElements()), const_cast(&collb), const_cast(&colub)) ); } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::addCols(const int numcols, const CoinPackedVectorBase * const * cols, const double* collb, const double* colub, const double* obj) { // freeCachedResults(); for( int i = 0; i < numcols; i++ ) addCol( *(cols[i]), collb[i], colub[i], obj[i] ); } //----------------------------------------------------------------------------- void OsiXprSolverInterface::deleteCols(const int num, const int *columnIndices) { freeCachedResults(); XPRS_CHECKED( XPRSdelcols, (prob_,num, const_cast(columnIndices)) ); } //----------------------------------------------------------------------------- void OsiXprSolverInterface::addRow(const CoinPackedVectorBase& vec, const double rowlb, const double rowub) { // freeCachedResults(); -- will be invoked char sense; double rhs, range; convertBoundToSense(rowlb, rowub, sense, rhs, range); addRow(vec, sense, rhs, range); } //----------------------------------------------------------------------------- void OsiXprSolverInterface::addRow(const CoinPackedVectorBase& vec, const char rowsen, const double rowrhs, const double rowrng) { freeCachedResults(); int mstart[2] = {0, vec.getNumElements()}; XPRS_CHECKED( XPRSaddrows, (prob_,1, vec.getNumElements(), const_cast(&rowsen), const_cast(&rowrhs), const_cast(&rowrng), mstart, const_cast(vec.getIndices()), const_cast(vec.getElements())) ); } //----------------------------------------------------------------------------- void OsiXprSolverInterface::addRows(const int numrows, const CoinPackedVectorBase * const * rows, const double* rowlb, const double* rowub) { // *FIXME* : must write the method -LL throw CoinError("method is not yet written", "addRows", "OsiXprSolverInterface"); } //----------------------------------------------------------------------------- void OsiXprSolverInterface::addRows(const int numrows, const CoinPackedVectorBase * const * rows, const char* rowsen, const double* rowrhs, const double* rowrng) { // *FIXME* : must write the method -LL throw CoinError("method is not yet written", "addRows", "OsiXprSolverInterface"); } //----------------------------------------------------------------------------- void OsiXprSolverInterface::deleteRows(const int num, const int * rowIndices) { freeCachedResults(); XPRS_CHECKED( XPRSdelrows, (prob_,num, const_cast(rowIndices)) ); } //############################################################################# // Methods to input a problem //############################################################################# void OsiXprSolverInterface::loadProblem(const CoinPackedMatrix& matrix, const double* collb, const double* colub, const double* obj, const double* rowlb, const double* rowub) { const double inf = getInfinity(); char * rowSense = new char [matrix.getNumRows()]; double * rowRhs = new double[matrix.getNumRows()]; double * rowRange = new double[matrix.getNumRows()]; int i; for ( i = matrix.getNumRows() - 1; i >= 0; --i) { double rlb; if ( rowlb!=NULL ) rlb = rowlb[i]; else rlb = -inf; double rub; if ( rowub!=NULL ) rub = rowub[i]; else rub = inf; convertBoundToSense(rlb,rub,rowSense[i],rowRhs[i],rowRange[i]); #if 0 if ( rlb==rub ) { rowSense[i]='E'; rowRhs[i] =rlb; rowRange[i]=0.0; continue; } if ( rlb<=-inf && rub>=inf ) { rowSense[i]='N'; rowRhs[i] =inf; rowRange[i]=0.0; continue; } if ( rlb<=-inf && !(rub>=inf) ) { rowSense[i]='L'; rowRhs[i] =rub; rowRange[i]=0.0; continue; } if ( !(rlb<=-inf) && rub>=inf ) { rowSense[i]='G'; rowRhs[i] =rlb; rowRange[i]=0.0; continue; } if ( !(rlb<=-inf) && !(rub>=inf) ) { rowSense[i]='R'; rowRhs[i] =rub; rowRange[i]=rub-rlb; continue; } #endif } loadProblem(matrix, collb, colub, obj, rowSense, rowRhs, rowRange ); delete [] rowSense; delete [] rowRhs; delete [] rowRange; } //----------------------------------------------------------------------------- void OsiXprSolverInterface::assignProblem(CoinPackedMatrix*& matrix, double*& collb, double*& colub, double*& obj, double*& rowlb, double*& rowub) { loadProblem(*matrix, collb, colub, obj, rowlb, rowub); delete matrix; matrix = 0; delete[] collb; collb = 0; delete[] colub; colub = 0; delete[] obj; obj = 0; delete[] rowlb; rowlb = 0; delete[] rowub; rowub = 0; } //----------------------------------------------------------------------------- // #define OSIXPR_ADD_OBJ_ROW void OsiXprSolverInterface::loadProblem(const CoinPackedMatrix& matrix, const double* collb, const double* colub, const double* obj, const char* rowsen, const double* rowrhs, const double* rowrng) { assert( rowsen != NULL ); assert( rowrhs != NULL ); freeCachedResults(); int i; // Set column values to defaults if NULL pointer passed int nc=matrix.getNumCols(); double * clb; double * cub; double * ob; if ( collb!=NULL ) { clb=const_cast(collb); } else { clb = new double[nc]; for( i=0; i(colub); else { cub = new double[nc]; for( i=0; i(obj); else { ob = new double[nc]; for( i=0; ireverseOrderedCopyOf(matrix); freeMatrixRequired = true; } else { m = const_cast(&matrix); } // Generate a problem name char probName[256]; sprintf(probName, "Prob%i", osiSerial_); nc = m->getNumCols(); int nr = m->getNumRows(); if ( getLogFilePtr()!=NULL ) { fprintf(getLogFilePtr(),"{\n"); fprintf(getLogFilePtr()," char rowsen[%d];\n",nr); for ( i=0; igetVectorStarts()[i]); fprintf(getLogFilePtr()," int vectorLengths[%d];\n",nc); for ( i=0; igetVectorLengths()[i]); fprintf(getLogFilePtr()," int indices[%d];\n",m->getVectorStarts()[nc]); for ( i=0; igetVectorStarts()[nc]; i++ ) fprintf(getLogFilePtr()," indices[%d]=%d;\n",i,m->getIndices()[i]); fprintf(getLogFilePtr()," double elements[%d];\n",m->getVectorStarts()[nc]); for ( i=0; igetVectorStarts()[nc]; i++ ) fprintf(getLogFilePtr()," elements[%d]=%f;\n",i,m->getElements()[i]); fprintf(getLogFilePtr(),"}\n"); } int iret = XPRSloadlp( prob_, probName, nc, nr, const_cast(rowsen), const_cast(rowrhs), const_cast(rowrng), ob, const_cast(m->getVectorStarts()), const_cast(m->getVectorLengths()), const_cast(m->getIndices()), const_cast(m->getElements()), clb, cub ); setStrParam(OsiProbName,probName); if ( iret != 0 ) XPRSgetintattrib(prob_,XPRS_ERRORCODE, &iret); assert( iret == 0 ); char pname[256]; // Problem names can be 200 chars in XPRESS 12 XPRS_CHECKED( XPRSgetprobname,(prob_,pname) ); xprProbname_ = pname; if ( collb==NULL ) delete[] clb; if ( colub==NULL ) delete[] cub; if ( obj ==NULL ) delete[] ob; if (freeMatrixRequired) { delete m; } } //----------------------------------------------------------------------------- void OsiXprSolverInterface::assignProblem(CoinPackedMatrix*& matrix, double*& collb, double*& colub, double*& obj, char*& rowsen, double*& rowrhs, double*& rowrng) { loadProblem(*matrix, collb, colub, obj, rowsen, rowrhs, rowrng); delete matrix; matrix = 0; delete[] collb; collb = 0; delete[] colub; colub = 0; delete[] obj; obj = 0; delete[] rowsen; rowsen = 0; delete[] rowrhs; rowrhs = 0; delete[] rowrng; rowrng = 0; } //----------------------------------------------------------------------------- void OsiXprSolverInterface::loadProblem(const int numcols, const int numrows, const int* start, const int* index, const double* value, const double* collb, const double* colub, const double* obj, const double* rowlb, const double* rowub ) { const double inf = getInfinity(); char * rowSense = new char [numrows]; double * rowRhs = new double[numrows]; double * rowRange = new double[numrows]; for ( int i = numrows - 1; i >= 0; --i ) { const double lower = rowlb ? rowlb[i] : -inf; const double upper = rowub ? rowub[i] : inf; convertBoundToSense( lower, upper, rowSense[i], rowRhs[i], rowRange[i] ); } loadProblem(numcols, numrows, start, index, value, collb, colub, obj, rowSense, rowRhs, rowRange); delete [] rowSense; delete [] rowRhs; delete [] rowRange; } //----------------------------------------------------------------------------- void OsiXprSolverInterface::loadProblem(const int numcols, const int numrows, const int* start, const int* index, const double* value, const double* collb, const double* colub, const double* obj, const char* rowsen, const double* rowrhs, const double* rowrng ) { assert( rowsen != NULL ); assert( rowrhs != NULL ); freeCachedResults(); int i; // Set column values to defaults if NULL pointer passed int nc = numcols; int nr = numrows; int * len = new int[nc]; double * clb; double * cub; double * ob; std::adjacent_difference(start, start + (nc+1), len); if ( collb!=NULL ) { clb=const_cast(collb); } else { clb = new double[nc]; for( i=0; i(colub); else { cub = new double[nc]; for( i=0; i(obj); else { ob = new double[nc]; for( i=0; i(rowsen), const_cast(rowrhs), const_cast(rowrng), ob, const_cast(start), const_cast(len), const_cast(index), const_cast(value), clb, cub ); setStrParam(OsiProbName,probName); if ( iret != 0 ) XPRSgetintattrib(prob_,XPRS_ERRORCODE, &iret); assert( iret == 0 ); char pname[256]; // Problem names can be 200 chars in XPRESS 12 XPRS_CHECKED( XPRSgetprobname, (prob_,pname) ); xprProbname_ = pname; if ( collb == NULL ) delete[] clb; if ( colub == NULL ) delete[] cub; if ( obj == NULL ) delete[] ob; delete[] len; } //----------------------------------------------------------------------------- // Read mps files //----------------------------------------------------------------------------- int OsiXprSolverInterface::readMps(const char *filename, const char *extension) { #if 0 if (getLogFilePtr()!=NULL) { fprintf(getLogFilePtr(),"{\n"); fprintf(getLogFilePtr()," XPRSreadprob(prob_,\"%s\");\n",filename); fprintf(getLogFilePtr()," int namlen;\n"); fprintf(getLogFilePtr()," XPRSgetintcontrol(prob_,XPRS_NAMELENGTH,&namlen);\n"); fprintf(getLogFilePtr()," namlen *= 8;\n"); } // Read Mps file. // XPRESS generates its own file extensions, so we ignore any supplied. int iret = XPRSreadprob(prob_,filename); if ( iret != 0 ) XPRSgetintattrib(prob_,XPRS_ERRORCODE, &iret); assert( iret == 0 ); // Get length of Mps names int namlen; XPRSgetintattrib(prob_,XPRS_NAMELENGTH, &namlen); namlen *= 8; if (getLogFilePtr()!=NULL) { fprintf(getLogFilePtr()," char objRowName[%d],rowName[%d];\n",namlen,namlen); fprintf(getLogFilePtr()," XPRSgetstrcontrol(prob_,XPRS_MPSOBJNAME, objRowName);\n"); fprintf(getLogFilePtr()," int nr;\n"); fprintf(getLogFilePtr()," XPRSsetintcontrol(prob_,XPRS_ROWS, &nr);"); } // Allocate space to hold row names. char * objRowName = new char[namlen+1]; char * rowName = new char[namlen+1]; // Get name of objective row. // If "" returned, then first N row is objective row XPRSgetstrcontrol(prob_,XPRS_MPSOBJNAME,objRowName); // Get number of rows int nr; XPRSgetintattrib(prob_,XPRS_ROWS, &nr); if (getLogFilePtr()!=NULL) { fprintf(getLogFilePtr()," char rs[%d];\n",nr); fprintf(getLogFilePtr()," XPRSgetrowtype(prob_,rs, 0, %d);\n",nr-1); } // Get row sense. char * rs = new char[nr]; XPRSgetrowtype(prob_,rs, 0, nr - 1); // Loop once for each row looking for objective row int i; for ( i=0; i 0 && newnz > 0 ) { XPRS_CHECKED( XPRSsetintcontrol,(prob_,XPRS_EXTRAROWS, newrows) ); XPRS_CHECKED( XPRSsetintcontrol, (prob_,XPRS_EXTRAELEMS, newnz) ); } } //---------------------------------------------------------------- // Clone //---------------------------------------------------------------- OsiSolverInterface * OsiXprSolverInterface::clone(bool copyData) const { return (new OsiXprSolverInterface(*this)); } //------------------------------------------------------------------- // Copy constructor //------------------------------------------------------------------- OsiXprSolverInterface:: OsiXprSolverInterface (const OsiXprSolverInterface & source) : OsiSolverInterface(source), prob_(NULL), matrixByRow_(NULL), matrixByCol_(NULL), colupper_(NULL), collower_(NULL), rowupper_(NULL), rowlower_(NULL), rowsense_(NULL), rhs_(NULL), rowrange_(NULL), objcoeffs_(NULL), objsense_(1), colsol_(NULL), rowsol_(NULL), rowact_(NULL), rowprice_(NULL), colprice_(NULL), ivarind_(NULL), ivartype_(NULL), vartype_(NULL) { incrementInstanceCounter(); xprProbname_ = ""; gutsOfConstructor(); gutsOfCopy(source); // Other values remain NULL until requested } //------------------------------------------------------------------- // Destructor //------------------------------------------------------------------- OsiXprSolverInterface::~OsiXprSolverInterface () { gutsOfDestructor(); XPRSdestroyprob(prob_); decrementInstanceCounter(); } //------------------------------------------------------------------- // Assignment operator //------------------------------------------------------------------- OsiXprSolverInterface & OsiXprSolverInterface::operator=(const OsiXprSolverInterface& rhs) { if ( this != &rhs ) { OsiSolverInterface::operator=(rhs); osiSerial_++; // even though numInstances_ doesn't change gutsOfDestructor(); gutsOfCopy(rhs); } return *this; } //############################################################################# // Applying cuts //############################################################################# void OsiXprSolverInterface::applyColCut( const OsiColCut & cc ) { const double *collower = getColLower(); const double *colupper = getColUpper(); const CoinPackedVector & lbs = cc.lbs(); const CoinPackedVector & ubs = cc.ubs(); int *index = new int [lbs.getNumElements() + ubs.getNumElements()]; char *btype = new char [lbs.getNumElements() + ubs.getNumElements()]; double *value = new double[lbs.getNumElements() + ubs.getNumElements()]; int i, nbds; for ( i = nbds = 0; i < lbs.getNumElements(); i++, nbds++ ) { index[nbds] = lbs.getIndices()[i]; btype[nbds] = 'L'; value[nbds] = (collower[index[nbds]] > lbs.getElements()[i]) ? collower[index[nbds]] : lbs.getElements()[i]; } for ( i = 0; i < ubs.getNumElements(); i++, nbds++ ) { index[nbds] = ubs.getIndices()[i]; btype[nbds] = 'U'; value[nbds] = (colupper[index[nbds]] < ubs.getElements()[i]) ? colupper[index[nbds]] : ubs.getElements()[i]; } if (getLogFilePtr()!=NULL) { fprintf(getLogFilePtr(),"{\n"); fprintf(getLogFilePtr()," int index[%d];\n",nbds); fprintf(getLogFilePtr()," char btype[%d];\n",nbds); fprintf(getLogFilePtr()," double value[%d];\n",nbds); for ( i=0; i(row.getIndices()), const_cast(row.getElements())); assert( rc == 0 ); freeCachedResults(); } //############################################################################# // Private methods //############################################################################# void OsiXprSolverInterface::gutsOfCopy( const OsiXprSolverInterface & source ) { if ( source.xprProbname_ != "" ) { // source has data std::ostringstream pname; pname << xprProbname_ << "#" << osiSerial_ <<'\0'; xprProbname_ = pname.str(); // sprintf(xprProbname_, "%s#%d", source.xprProbname_, osiSerial_); // std::cout << "Problem " << xprProbname_ << " copied to matrix "; XPRS_CHECKED( XPRScopyprob, ( prob_, source.prob_, xprProbname_.c_str() ) ); XPRS_CHECKED( XPRScopycontrols, ( prob_, source.prob_ ) ); /* if the callbacks are used, a XPRScopycallbacks needs to be added */ } } //------------------------------------------------------------------- void OsiXprSolverInterface::gutsOfConstructor() { XPRS_CHECKED( XPRScreateprob, (&prob_) ); /* always create an empty problem to initialize all data structures */ int istart = 0; XPRS_CHECKED( XPRSloadlp, ( prob_, "_xprs_", 0, 0, NULL, NULL, NULL, NULL, &istart, NULL, NULL, NULL, NULL, NULL) ); //OPEN: only switched off for debugging //XPRS_CHECKED( XPRSsetlogfile, (prob_,"xpress.log") ); // **FIXME** (mjs) Integer problems require solution file or callback to save // optimal solution. The quick fix is to leave the default solutionfile setting, // but implementing a callback would be better. // XPRS_CHECKED( XPRSsetintcontrol, (prob_, XPRS_SOLUTIONFILE,0) ); // XPRS_CHECKED( XPRSsetintcontrol, ( prob_, XPRS_PRESOLVE, 0) ); } //------------------------------------------------------------------- void OsiXprSolverInterface::gutsOfDestructor() { freeCachedResults(); assert(matrixByRow_ == NULL); assert(matrixByCol_ == NULL); assert(colupper_ == NULL); assert(collower_ == NULL); assert(rowupper_ == NULL); assert(rowlower_ == NULL); assert(rowsense_ == NULL); assert(rhs_ == NULL); assert(rowrange_ == NULL); assert(objcoeffs_ == NULL); assert(colsol_ == NULL); assert(rowsol_ == NULL); assert(rowprice_ == NULL); assert(colprice_ == NULL); assert(rowact_ == NULL); assert(vartype_ == NULL); } //------------------------------------------------------------------- void OsiXprSolverInterface::freeSolution() { delete [] colsol_; colsol_ = NULL; delete [] rowsol_; rowsol_ = NULL; delete [] rowact_; rowact_ = NULL; delete [] rowprice_; rowprice_ = NULL; delete [] colprice_; colprice_ = NULL; } //------------------------------------------------------------------- void OsiXprSolverInterface::freeCachedResults() { delete matrixByRow_; matrixByRow_ = NULL; delete matrixByCol_; matrixByCol_ = NULL; delete [] colupper_; colupper_ = NULL; delete [] collower_; collower_ = NULL; delete [] rowupper_; rowupper_ = NULL; delete [] rowlower_; rowlower_ = NULL; delete [] rowsense_; rowsense_ = NULL; delete [] rhs_; rhs_ = NULL; delete [] rowrange_; rowrange_ = NULL; delete [] objcoeffs_; objcoeffs_ = NULL; freeSolution(); delete [] ivarind_; ivarind_ = NULL; delete [] ivartype_; ivartype_ = NULL; delete [] vartype_; vartype_ = NULL; } //------------------------------------------------------------------- // Set up lists of integer variables //------------------------------------------------------------------- int OsiXprSolverInterface::getNumIntVars() const { int nintvars = 0, nsets = 0; if ( isDataLoaded() ) { XPRS_CHECKED( XPRSgetglobal, (prob_,&nintvars, &nsets, NULL, NULL, NULL, NULL, NULL, NULL, NULL) ); } return nintvars; } void OsiXprSolverInterface::getVarTypes() const { int nintvars = getNumIntVars(); int nsets; int ncols = getNumCols(); if ( vartype_ == NULL && nintvars > 0 ) { if (getLogFilePtr()!=NULL) { fprintf(getLogFilePtr(),"{\n"); fprintf(getLogFilePtr()," int nintvars = %d;\n",nintvars); fprintf(getLogFilePtr()," int nsets;\n"); fprintf(getLogFilePtr()," char ivartype[%d];\n",nintvars); fprintf(getLogFilePtr()," char ivarind[%d];\n",nintvars); fprintf(getLogFilePtr(),"}\n"); } ivartype_ = new char[nintvars]; ivarind_ = new int[nintvars]; XPRS_CHECKED( XPRSgetglobal, (prob_,&nintvars, &nsets, ivartype_, ivarind_, NULL, NULL, NULL, NULL, NULL) ); // Currently, only binary and integer vars are supported. vartype_ = new char[ncols]; int i, j; for ( i = j = 0; j < ncols; j++ ) { if ( i < nintvars && j == ivarind_[i] ) { vartype_[j] = ivartype_[i]; i++; } else vartype_[j] = 'C'; } } } bool OsiXprSolverInterface::isDataLoaded() const { int istatus; XPRS_CHECKED( XPRSgetintattrib, ( prob_, XPRS_MIPSTATUS, &istatus ) ); istatus &= XPRS_MIP_NOT_LOADED; return istatus == 0; } //#############################################################################