// Copyright (C) 2005, International Business Machines // Corporation and others. All Rights Reserved. #if defined(_MSC_VER) // Turn off compiler warning about long names # pragma warning(disable:4786) #endif #include #include #include #include #include #include //#define CGL_DEBUG 2 #include "CoinHelperFunctions.hpp" #include "CoinPackedVector.hpp" #include "OsiRowCutDebugger.hpp" #include "CoinWarmStartBasis.hpp" #include "CglStored.hpp" #include "CglTreeInfo.hpp" #include "CoinFinite.hpp" //------------------------------------------------------------------- // Generate Stored cuts //------------------------------------------------------------------- void CglStored::generateCuts(const OsiSolverInterface & si, OsiCuts & cs, const CglTreeInfo /*info*/) const { // Get basic problem information const double * solution = si.getColSolution(); int numberRowCuts = cuts_.sizeRowCuts(); for (int i=0;iviolated(solution); if (violation>=requiredViolation_) cs.insert(*rowCutPointer); } if (probingInfo_) { int number01 = probingInfo_->numberIntegers(); const cliqueEntry * entry = probingInfo_->fixEntries(); const int * toZero = probingInfo_->toZero(); const int * toOne = probingInfo_->toOne(); const int * integerVariable = probingInfo_->integerVariable(); const double * lower = si.getColLower(); const double * upper = si.getColUpper(); OsiRowCut cut; int column[2]; double element[2]; for (int i=0;i=0); double value2 = solution[jColumn]; if (oneFixesInCliqueEntry(entry[j])) { double violation = 1.0-value1-value2; if (violation>requiredViolation_) { //printf("XXX can do %d + %d >=1\n",iColumn,jColumn); cut.setLb(1.0); cut.setUb(COIN_DBL_MAX); column[0]=iColumn; element[0]=1.0; column[1]=jColumn; element[1]= 1.0; cut.setEffectiveness(violation); cut.setRow(2,column,element,false); cs.insert(cut); } } else { double violation = value2-value1; if (violation>requiredViolation_) { //printf("XXX can do %d >= %d\n",iColumn,jColumn); cut.setLb(0.0); cut.setUb(COIN_DBL_MAX); column[0]=iColumn; element[0]=1.0; column[1]=jColumn; element[1]= -1.0; cut.setEffectiveness(violation); cut.setRow(2,column,element,false); cs.insert(cut); } } } else { jColumn -= number01; // not 0-1 double value2 = solution[jColumn]; double lowerValue = lower[jColumn]; double upperValue = upper[jColumn]; if (oneFixesInCliqueEntry(entry[j])) { double violation = upperValue-value1*(upperValue-lowerValue)-value2; if (violation>requiredViolation_) { //printf("XXX can do %g*%d + %d >=%g\n",(upperValue-lowerValue),iColumn,jColumn,upperValue); cut.setLb(upperValue); cut.setUb(COIN_DBL_MAX); column[0]=iColumn; element[0]=upperValue-lowerValue; column[1]=jColumn; element[1]= 1.0; cut.setEffectiveness(violation); cut.setRow(2,column,element,false); cs.insert(cut); } } else { double violation = value2-value1*(upperValue-lowerValue)-lowerValue; if (violation>requiredViolation_) { //printf("XXX can do %g*%d >= %d -%g\n",(upperValue-lowerValue),iColumn,jColumn,lowerValue); cut.setLb(-lowerValue); cut.setUb(COIN_DBL_MAX); column[0]=iColumn; element[0]=upperValue-lowerValue; column[1]=jColumn; element[1]= -1.0; cut.setEffectiveness(violation); cut.setRow(2,column,element,false); cs.insert(cut); } } } } for (int j=toOne[i];j=0); double value2 = solution[jColumn]; if (oneFixesInCliqueEntry(entry[j])) { double violation = value1-value2; if (violation>requiredViolation_) { //printf("XXX can do %d <= %d\n",iColumn,jColumn); cut.setLb(-COIN_DBL_MAX); cut.setUb(0.0); column[0]=iColumn; element[0]=1.0; column[1]=jColumn; element[1]= -1.0; cut.setEffectiveness(violation); cut.setRow(2,column,element,false); cs.insert(cut); } } else { double violation = value1+value2-1.0; if (violation>requiredViolation_) { //printf("XXX can do %d + %d <=1\n",iColumn,jColumn); cut.setLb(-COIN_DBL_MAX); cut.setUb(1.0); column[0]=iColumn; element[0]=1.0; column[1]=jColumn; element[1]= 1.0; cut.setEffectiveness(violation); cut.setRow(2,column,element,false); cs.insert(cut); } } } else { jColumn -= number01; // not 0-1 double value2 = solution[jColumn]; double lowerValue = lower[jColumn]; double upperValue = upper[jColumn]; if (oneFixesInCliqueEntry(entry[j])) { double violation = lowerValue +(upperValue-lowerValue)*value1-value2; if (violation>requiredViolation_) { //printf("XXX can do %g*%d <= %d -%g\n",(upperValue-lowerValue),iColumn,jColumn,lowerValue); cut.setLb(-COIN_DBL_MAX); cut.setUb(-lowerValue); column[0]=iColumn; element[0]=upperValue-lowerValue; column[1]=jColumn; element[1]= -1.0; cut.setEffectiveness(violation); cut.setRow(2,column,element,false); cs.insert(cut); } } else { double violation = (upperValue-lowerValue)*value1+value2-upperValue; if (violation>requiredViolation_) { //printf("XXX can do %g*%d + %d <=%g\n",(upperValue-lowerValue),iColumn,jColumn,upperValue); cut.setLb(-COIN_DBL_MAX); cut.setUb(upperValue); column[0]=iColumn; element[0]=upperValue-lowerValue; column[1]=jColumn; element[1]= 1.0; cut.setEffectiveness(violation); cut.setRow(2,column,element,false); cs.insert(cut); } } } } } } } // Add cuts void CglStored::addCut(const OsiCuts & cs) { int numberRowCuts = cs.sizeRowCuts(); for (int i=0;i=0) { numberRead = fread(&n,sizeof(int),1,fp); assert (numberRead==1); if (n<0) break; if (n>maxInCut) { maxInCut=n; delete [] index; delete [] coefficient; index = new int [maxInCut]; coefficient = new double [maxInCut]; } numberRead = fread(rhs,sizeof(double),2,fp); assert (numberRead==2); numberRead = fread(index,sizeof(int),n,fp); //assert (numberRead==n); numberRead = fread(coefficient,sizeof(double),n,fp); //assert (numberRead==n); OsiRowCut rc; rc.setRow(n,index,coefficient,false); rc.setLb(rhs[0]); rc.setUb(rhs[1]); cuts_.insert(rc); } delete [] index; delete [] coefficient; fclose(fp); } } //------------------------------------------------------------------- // Clone //------------------------------------------------------------------- CglCutGenerator * CglStored::clone() const { return new CglStored(*this); } //------------------------------------------------------------------- // Destructor //------------------------------------------------------------------- CglStored::~CglStored () { delete probingInfo_; delete [] bestSolution_; delete [] bounds_; } //---------------------------------------------------------------- // Assignment operator //------------------------------------------------------------------- CglStored & CglStored::operator=(const CglStored& rhs) { if (this != &rhs) { CglCutGenerator::operator=(rhs); requiredViolation_=rhs.requiredViolation_; cuts_=rhs.cuts_; delete probingInfo_; if (rhs.probingInfo_) probingInfo_ = new CglTreeProbingInfo(*rhs.probingInfo_); else probingInfo_ = NULL; delete [] bestSolution_; delete [] bounds_; bestSolution_ = NULL; bounds_ = NULL; numberColumns_ = rhs.numberColumns_; if (numberColumns_) { bestSolution_ = CoinCopyOfArray(rhs.bestSolution_,numberColumns_+1); bounds_ = CoinCopyOfArray(rhs.bounds_,2*numberColumns_); } } return *this; } // Save stuff void CglStored::saveStuff(double bestObjective, const double * bestSolution, const double * lower, const double * upper) { assert (numberColumns_); delete [] bestSolution_; delete [] bounds_; if (bestSolution) { bestSolution_ = new double[numberColumns_+1]; memcpy(bestSolution_,bestSolution,numberColumns_*sizeof(double)); bestSolution_[numberColumns_]=bestObjective; } else { bestSolution_=NULL; } bounds_ = new double [2*numberColumns_]; memcpy(bounds_,lower,numberColumns_*sizeof(double)); memcpy(bounds_+numberColumns_,upper,numberColumns_*sizeof(double)); } // Best objective double CglStored::bestObjective() const { if (bestSolution_) return bestSolution_[numberColumns_]; else return COIN_DBL_MAX; }