Changeset 2373 for trunk/Cbc/src/CbcModel.cpp
- Timestamp:
- May 18, 2018 5:45:54 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Cbc/src/CbcModel.cpp
r2371 r2373 5361 5361 setBestSolution(CBC_END_SOLUTION, bestObjective_, bestSolution_, 1) ; 5362 5362 continuousSolver_->resolve() ; 5363 // Deal with funny variables 5364 if ((moreSpecialOptions2_&32768)!=0) 5365 cleanBounds(continuousSolver_,NULL); 5363 5366 if (!continuousSolver_->isProvenOptimal()) { 5364 5367 continuousSolver_->messageHandler()->setLogLevel(2) ; … … 12592 12595 } 12593 12596 #endif 12594 return objectiveValue;12597 return 1.0e50; 12595 12598 } 12596 12599 } … … 15275 15278 #endif 15276 15279 #ifdef COIN_HAS_CLP 15280 // Deal with funny variables 15281 if ((moreSpecialOptions2_&32768)!=0) 15282 cleanBounds(solver_,NULL); 15277 15283 int save=0; 15278 15284 OsiClpSolverInterface * clpSolver … … 19693 19699 #endif 19694 19700 } 19695 19701 /* 19702 Clean model i.e. make SOS/integer variables exactly at bound if needed 19703 Only if moreSpecialOptions2_ 32768 19704 Returns number of variables forced out 19705 cleanVariables array will be used if exists 19706 */ 19707 int 19708 CbcModel::cleanBounds(OsiSolverInterface * solver, char * cleanIn) 19709 { 19710 int numberBad=0; 19711 # ifdef COIN_HAS_CLP 19712 #ifndef ZERO_ODD_TOLERANCE 19713 #define ZERO_ODD_TOLERANCE 1.0e-14 19714 #endif 19715 OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); 19716 if (osiclp&&osiclp->isProvenOptimal()) { 19717 int numberColumns = osiclp->getNumCols(); 19718 char * cleanVariables; 19719 if (!cleanIn) { 19720 cleanVariables = setupCleanVariables(); 19721 } else { 19722 cleanVariables = cleanIn; 19723 } 19724 // If any small values re-do 19725 ClpSimplex * clp = osiclp->getModelPtr(); 19726 double * solution = clp->primalColumnSolution(); 19727 const double * columnLower = clp->columnLower(); 19728 const double * columnUpper = clp->columnUpper(); 19729 //#define SHOW_BAD 19730 #ifdef SHOW_BAD 19731 double sumBadLow=0.0; 19732 double sumBadHigh=0.0; 19733 double maxBadLow=0.0; 19734 double maxBadHigh=0.0; 19735 #endif 19736 for (int i=0;i<numberColumns;i++) { 19737 if (cleanVariables[i]) { 19738 if (solution[i]>columnUpper[i]+ZERO_ODD_TOLERANCE) { 19739 numberBad++; 19740 #ifdef SHOW_BAD 19741 sumBadHigh += solution[i]-columnUpper[i]; 19742 maxBadHigh = CoinMax(maxBadHigh,solution[i]-columnUpper[i]); 19743 #endif 19744 } else if (solution[i]<columnLower[i]-ZERO_ODD_TOLERANCE) { 19745 numberBad++; 19746 #ifdef SHOW_BAD 19747 sumBadLow += columnLower[i]-solution[i]; 19748 maxBadLow = CoinMax(maxBadLow,columnLower[i]-solution[i]); 19749 #endif 19750 } 19751 } 19752 } 19753 if (numberBad) { 19754 #ifdef SHOW_BAD 19755 printf("%d small variables low (%g max %g), high (%g max %g)\n",numberBad,sumBadLow,maxBadLow,sumBadHigh,maxBadHigh); 19756 #endif 19757 for (int i=0;i<numberColumns;i++) { 19758 if (cleanVariables[i]) { 19759 if (solution[i]>columnUpper[i]+ZERO_ODD_TOLERANCE) { 19760 solution[i]=columnUpper[i]; 19761 clp->setColumnStatus(i,ClpSimplex::atUpperBound); 19762 } else if (solution[i]<columnLower[i]-ZERO_ODD_TOLERANCE) { 19763 solution[i]=columnLower[i]; 19764 clp->setColumnStatus(i,ClpSimplex::atLowerBound); 19765 } 19766 } 19767 } 19768 int saveLevel=clp->logLevel(); 19769 clp->setLogLevel(0); 19770 clp->dual(); 19771 clp->setLogLevel(saveLevel); 19772 } 19773 if (!cleanIn) 19774 delete [] cleanVariables; 19775 } 19776 #endif 19777 return numberBad; 19778 } 19779 // Sets up cleanVariables array (i.e. ones to be careful about) 19780 char * 19781 CbcModel::setupCleanVariables() 19782 { 19783 OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver_); 19784 int numberColumns = osiclp->getNumCols(); 19785 char * cleanVariables = NULL; 19786 if (osiclp) { 19787 cleanVariables = new char[numberColumns]; 19788 memset(cleanVariables,0,numberColumns); 19789 for (int i = 0; i < numberObjects_; i++) { 19790 const CbcSimpleInteger * intvar = dynamic_cast<const CbcSimpleInteger *>(object_[i]); 19791 const CbcSOS * sos = dynamic_cast<const CbcSOS *>(object_[i]); 19792 if (intvar) { 19793 #ifdef CLEAN_INTEGER_VARIABLES 19794 cleanVariables[intvar->columnNumber()]=1; 19795 #endif 19796 } else if (sos) { 19797 int n = sos->numberMembers(); 19798 const int * members = sos->members(); 19799 for (int j=0;j<n;j++) 19800 cleanVariables[members[j]]=2; 19801 } 19802 } 19803 } 19804 return cleanVariables; 19805 } 19806 19807
Note: See TracChangeset
for help on using the changeset viewer.