/* $Id$ */ // Copyright (C) 2005, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). #include "CoinUtilsConfig.h" #include "CoinHelperFunctions.hpp" #include "CoinSnapshot.hpp" #include "CoinPackedMatrix.hpp" #include "CoinFinite.hpp" //############################################################################# // Constructors / Destructor / Assignment //############################################################################# //------------------------------------------------------------------- // Default Constructor //------------------------------------------------------------------- CoinSnapshot::CoinSnapshot () { gutsOfDestructor(13); } //------------------------------------------------------------------- // Copy constructor //------------------------------------------------------------------- CoinSnapshot::CoinSnapshot (const CoinSnapshot & rhs) { gutsOfDestructor(13); gutsOfCopy(rhs); } //------------------------------------------------------------------- // Destructor //------------------------------------------------------------------- CoinSnapshot::~CoinSnapshot () { gutsOfDestructor(15); } //---------------------------------------------------------------- // Assignment operator //------------------------------------------------------------------- CoinSnapshot & CoinSnapshot::operator=(const CoinSnapshot& rhs) { if (this != &rhs) { gutsOfDestructor(15); gutsOfCopy(rhs); } return *this; } // Does main work of destructor void CoinSnapshot::gutsOfDestructor(int type) { if ((type&2)!=0) { if (owned_.colLower) delete [] colLower_; if (owned_.colUpper) delete [] colUpper_; if (owned_.rowLower) delete [] rowLower_; if (owned_.rowUpper) delete [] rowUpper_; if (owned_.rightHandSide) delete [] rightHandSide_; if (owned_.objCoefficients) delete [] objCoefficients_; if (owned_.colType) delete [] colType_; if (owned_.matrixByRow) delete matrixByRow_; if (owned_.matrixByCol) delete matrixByCol_; if (owned_.originalMatrixByRow) delete originalMatrixByRow_; if (owned_.originalMatrixByCol) delete originalMatrixByCol_; if (owned_.colSolution) delete [] colSolution_; if (owned_.rowPrice) delete [] rowPrice_; if (owned_.reducedCost) delete [] reducedCost_; if (owned_.rowActivity) delete [] rowActivity_; if (owned_.doNotSeparateThis) delete [] doNotSeparateThis_; } if ((type&4)!=0) { objSense_ = 1.0; infinity_ = COIN_DBL_MAX; dualTolerance_ = 1.0e-7; primalTolerance_ = 1.0e-7; integerTolerance_ = 1.0e-7; } if ((type&8)!=0) { objValue_ = COIN_DBL_MAX; objOffset_ = 0.0; integerUpperBound_ = COIN_DBL_MAX; integerLowerBound_ = -COIN_DBL_MAX; } if ((type&1)!=0) { colLower_ = NULL; colUpper_ = NULL; rowLower_ = NULL; rowUpper_ = NULL; rightHandSide_ = NULL; objCoefficients_ = NULL; colType_ = NULL; matrixByRow_ = NULL; matrixByCol_ = NULL; originalMatrixByRow_ = NULL; originalMatrixByCol_ = NULL; colSolution_ = NULL; rowPrice_ = NULL; reducedCost_ = NULL; rowActivity_ = NULL; doNotSeparateThis_ = NULL; numCols_ = 0; numRows_ = 0; numElements_ = 0; numIntegers_ = 0; // say nothing owned memset(&owned_,0,sizeof(owned_)); } } // Does main work of copy void CoinSnapshot::gutsOfCopy(const CoinSnapshot & rhs) { objSense_ = rhs.objSense_; infinity_ = rhs.infinity_; objValue_ = rhs.objValue_; objOffset_ = rhs.objOffset_; dualTolerance_ = rhs.dualTolerance_; primalTolerance_ = rhs.primalTolerance_; integerTolerance_ = rhs.integerTolerance_; integerUpperBound_ = rhs.integerUpperBound_; integerLowerBound_ = rhs.integerLowerBound_; numCols_ = rhs.numCols_; numRows_ = rhs.numRows_; numElements_ = rhs.numElements_; numIntegers_ = rhs.numIntegers_; owned_ = rhs.owned_; if (owned_.colLower) colLower_ = CoinCopyOfArray(rhs.colLower_,numCols_); else colLower_ = rhs.colLower_; if (owned_.colUpper) colUpper_ = CoinCopyOfArray(rhs.colUpper_,numCols_); else colUpper_ = rhs.colUpper_; if (owned_.rowLower) rowLower_ = CoinCopyOfArray(rhs.rowLower_,numRows_); else rowLower_ = rhs.rowLower_; if (owned_.rowUpper) rowUpper_ = CoinCopyOfArray(rhs.rowUpper_,numRows_); else rowUpper_ = rhs.rowUpper_; if (owned_.rightHandSide) rightHandSide_ = CoinCopyOfArray(rhs.rightHandSide_,numRows_); else rightHandSide_ = rhs.rightHandSide_; if (owned_.objCoefficients) objCoefficients_ = CoinCopyOfArray(rhs.objCoefficients_,numCols_); else objCoefficients_ = rhs.objCoefficients_; if (owned_.colType) colType_ = CoinCopyOfArray(rhs.colType_,numCols_); else colType_ = rhs.colType_; if (owned_.colSolution) colSolution_ = CoinCopyOfArray(rhs.colSolution_,numCols_); else colSolution_ = rhs.colSolution_; if (owned_.rowPrice) rowPrice_ = CoinCopyOfArray(rhs.rowPrice_,numRows_); else rowPrice_ = rhs.rowPrice_; if (owned_.reducedCost) reducedCost_ = CoinCopyOfArray(rhs.reducedCost_,numCols_); else reducedCost_ = rhs.reducedCost_; if (owned_.rowActivity) rowActivity_ = CoinCopyOfArray(rhs.rowActivity_,numRows_); else rowActivity_ = rhs.rowActivity_; if (owned_.doNotSeparateThis) doNotSeparateThis_ = CoinCopyOfArray(rhs.doNotSeparateThis_,numCols_); else doNotSeparateThis_ = rhs.doNotSeparateThis_; if (owned_.matrixByRow) matrixByRow_ = new CoinPackedMatrix(*rhs.matrixByRow_); else matrixByRow_ = rhs.matrixByRow_; if (owned_.matrixByCol) matrixByCol_ = new CoinPackedMatrix(*rhs.matrixByCol_); else matrixByCol_ = rhs.matrixByCol_; if (owned_.originalMatrixByRow) originalMatrixByRow_ = new CoinPackedMatrix(*rhs.originalMatrixByRow_); else originalMatrixByRow_ = rhs.originalMatrixByRow_; if (owned_.originalMatrixByCol) originalMatrixByCol_ = new CoinPackedMatrix(*rhs.originalMatrixByCol_); else originalMatrixByCol_ = rhs.originalMatrixByCol_; } /* Load in an problem by copying the arguments (the constraints on the rows are given by lower and upper bounds). If a pointer is NULL then the following values are the default: */ void CoinSnapshot::loadProblem(const CoinPackedMatrix& matrix, const double* collb, const double* colub, const double* obj, const double* rowlb, const double* rowub, bool makeRowCopy) { // Keep scalars (apart from objective value etc) gutsOfDestructor(3+8); numRows_ = matrix.getNumRows(); numCols_ = matrix.getNumCols(); numElements_ = matrix.getNumElements(); owned_.matrixByCol = 1; matrixByCol_ = new CoinPackedMatrix(matrix); if (makeRowCopy) { owned_.matrixByRow = 1; CoinPackedMatrix * matrixByRow = new CoinPackedMatrix(matrix); matrixByRow->reverseOrdering(); matrixByRow_ = matrixByRow; } colLower_ = CoinCopyOfArray(collb,numCols_,0.0); colUpper_ = CoinCopyOfArray(colub,numCols_,infinity_); objCoefficients_ = CoinCopyOfArray(obj,numCols_,0.0); rowLower_ = CoinCopyOfArray(rowlb,numRows_,-infinity_); rowUpper_ = CoinCopyOfArray(rowub,numRows_,infinity_); // do rhs as well createRightHandSide(); } // Set pointer to array[getNumCols()] of column lower bounds void CoinSnapshot::setColLower(const double * array, bool copyIn) { if (owned_.colLower) delete [] colLower_; if (copyIn) { owned_.colLower=1; colLower_ = CoinCopyOfArray(array,numCols_); } else { owned_.colLower=0; colLower_ = array; } } // Set pointer to array[getNumCols()] of column upper bounds void CoinSnapshot::setColUpper(const double * array, bool copyIn) { if (owned_.colUpper) delete [] colUpper_; if (copyIn) { owned_.colUpper=1; colUpper_ = CoinCopyOfArray(array,numCols_); } else { owned_.colUpper=0; colUpper_ = array; } } // Set pointer to array[getNumRows()] of row lower bounds void CoinSnapshot::setRowLower(const double * array, bool copyIn) { if (owned_.rowLower) delete [] rowLower_; if (copyIn) { owned_.rowLower=1; rowLower_ = CoinCopyOfArray(array,numRows_); } else { owned_.rowLower=0; rowLower_ = array; } } // Set pointer to array[getNumRows()] of row upper bounds void CoinSnapshot::setRowUpper(const double * array, bool copyIn) { if (owned_.rowUpper) delete [] rowUpper_; if (copyIn) { owned_.rowUpper=1; rowUpper_ = CoinCopyOfArray(array,numRows_); } else { owned_.rowUpper=0; rowUpper_ = array; } } /* Set pointer to array[getNumRows()] of rhs side values This gives same results as OsiSolverInterface for useful cases If getRowUpper()[i] != infinity then getRightHandSide()[i] == getRowUpper()[i] else getRightHandSide()[i] == getRowLower()[i] */ void CoinSnapshot::setRightHandSide(const double * array, bool copyIn) { if (owned_.rightHandSide) delete [] rightHandSide_; if (copyIn) { owned_.rightHandSide=1; rightHandSide_ = CoinCopyOfArray(array,numRows_); } else { owned_.rightHandSide=0; rightHandSide_ = array; } } /* Create array[getNumRows()] of rhs side values This gives same results as OsiSolverInterface for useful cases If getRowUpper()[i] != infinity then getRightHandSide()[i] == getRowUpper()[i] else getRightHandSide()[i] == getRowLower()[i] */ void CoinSnapshot::createRightHandSide() { if (owned_.rightHandSide) delete [] rightHandSide_; owned_.rightHandSide=1; assert (rowUpper_); assert (rowLower_); double * rightHandSide = CoinCopyOfArray(rowUpper_,numRows_); for (int i=0;igetNumCols()==numCols_); assert (matrixByRow_->getNumRows()==numRows_); } // Create row-wise copy from MatrixByCol void CoinSnapshot::createMatrixByRow() { if (owned_.matrixByRow) delete matrixByRow_; assert (matrixByCol_); owned_.matrixByRow = 1; CoinPackedMatrix * matrixByRow = new CoinPackedMatrix(*matrixByCol_); matrixByRow->reverseOrdering(); matrixByRow_ = matrixByRow; } // Set pointer to column-wise copy of current matrix void CoinSnapshot::setMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn) { if (owned_.matrixByCol) delete matrixByCol_; if (copyIn) { owned_.matrixByCol=1; matrixByCol_ = new CoinPackedMatrix(*matrix); } else { owned_.matrixByCol=0; matrixByCol_ = matrix; } assert (matrixByCol_->getNumCols()==numCols_); assert (matrixByCol_->getNumRows()==numRows_); } // Set pointer to row-wise copy of "original" matrix void CoinSnapshot::setOriginalMatrixByRow(const CoinPackedMatrix * matrix, bool copyIn) { if (owned_.originalMatrixByRow) delete originalMatrixByRow_; if (copyIn) { owned_.originalMatrixByRow=1; originalMatrixByRow_ = new CoinPackedMatrix(*matrix); } else { owned_.originalMatrixByRow=0; originalMatrixByRow_ = matrix; } assert (matrixByRow_->getNumCols()==numCols_); } // Set pointer to column-wise copy of "original" matrix void CoinSnapshot::setOriginalMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn) { if (owned_.originalMatrixByCol) delete originalMatrixByCol_; if (copyIn) { owned_.originalMatrixByCol=1; originalMatrixByCol_ = new CoinPackedMatrix(*matrix); } else { owned_.originalMatrixByCol=0; originalMatrixByCol_ = matrix; } assert (matrixByCol_->getNumCols()==numCols_); } // Set pointer to array[getNumCols()] of primal variable values void CoinSnapshot::setColSolution(const double * array, bool copyIn) { if (owned_.colSolution) delete [] colSolution_; if (copyIn) { owned_.colSolution=1; colSolution_ = CoinCopyOfArray(array,numCols_); } else { owned_.colSolution=0; colSolution_ = array; } } // Set pointer to array[getNumRows()] of dual variable values void CoinSnapshot::setRowPrice(const double * array, bool copyIn) { if (owned_.rowPrice) delete [] rowPrice_; if (copyIn) { owned_.rowPrice=1; rowPrice_ = CoinCopyOfArray(array,numRows_); } else { owned_.rowPrice=0; rowPrice_ = array; } } // Set a pointer to array[getNumCols()] of reduced costs void CoinSnapshot::setReducedCost(const double * array, bool copyIn) { if (owned_.reducedCost) delete [] reducedCost_; if (copyIn) { owned_.reducedCost=1; reducedCost_ = CoinCopyOfArray(array,numCols_); } else { owned_.reducedCost=0; reducedCost_ = array; } } // Set pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). void CoinSnapshot::setRowActivity(const double * array, bool copyIn) { if (owned_.rowActivity) delete [] rowActivity_; if (copyIn) { owned_.rowActivity=1; rowActivity_ = CoinCopyOfArray(array,numRows_); } else { owned_.rowActivity=0; rowActivity_ = array; } } // Set pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) void CoinSnapshot::setDoNotSeparateThis(const double * array, bool copyIn) { if (owned_.doNotSeparateThis) delete [] doNotSeparateThis_; if (copyIn) { owned_.doNotSeparateThis=1; doNotSeparateThis_ = CoinCopyOfArray(array,numCols_); } else { owned_.doNotSeparateThis=0; doNotSeparateThis_ = array; } }