Changeset 1451 for stable/2.4


Ignore:
Timestamp:
May 20, 2010 10:19:37 AM (9 years ago)
Author:
forrest
Message:

more changes for bonmin

File:
1 edited

Legend:

Unmodified
Added
Removed
  • stable/2.4/Cbc/src/CbcModel.cpp

    r1449 r1451  
    71087108# endif
    71097109      int switchOff = (!doCutsNow(1)&&!fullScan) ? 1 : 0;
    7110       //if (2*solver_->getNumRows()+solver_->getNumCols()>1000)
    7111       //switchOff *= 2;
    7112       for (i = 0;i<numberCutGenerators_;i++) {
    7113         int numberRowCutsBefore = theseCuts.sizeRowCuts() ;
    7114         int numberColumnCutsBefore = theseCuts.sizeColCuts() ;
    7115         int numberRowCutsAfter = numberRowCutsBefore;
    7116         int numberColumnCutsAfter = numberColumnCutsBefore;
    7117         bool generate = generator_[i]->normal();
    7118         // skip if not optimal and should be (maybe a cut generator has fixed variables)
    7119         if (generator_[i]->howOften()==-100||
    7120             (generator_[i]->needsOptimalBasis()&&!solver_->basisIsAvailable())
    7121             ||generator_[i]->switchedOff())
    7122           generate=false;
    7123         if (switchOff&&!generator_[i]->mustCallAgain()) {
    7124           // switch off if default
    7125           if (generator_[i]->howOften()==1&&generator_[i]->whatDepth()<0) {
    7126             /*if (generate)
    7127               printf("Gg %d %d %d\n",i,
    7128               generator_[i]->howOften(),generator_[i]->whatDepth());*/
     7110      // Skip cuts if bonmin type code and global cuts did something
     7111      if (solverCharacteristics_->solutionAddsCuts()&&numberViolated) {
     7112        for (i = 0;i<numberCutGenerators_;i++) {
     7113          if (generator_[i]->mustCallAgain()) {
     7114            keepGoing=true; // say must go round
     7115            break;
     7116          }
     7117        }
     7118      }
     7119      if (!keepGoing) {
     7120        // do cuts
     7121        for (i = 0;i<numberCutGenerators_;i++) {
     7122          int numberRowCutsBefore = theseCuts.sizeRowCuts() ;
     7123          int numberColumnCutsBefore = theseCuts.sizeColCuts() ;
     7124          int numberRowCutsAfter = numberRowCutsBefore;
     7125          int numberColumnCutsAfter = numberColumnCutsBefore;
     7126          bool generate = generator_[i]->normal();
     7127          // skip if not optimal and should be (maybe a cut generator has fixed variables)
     7128          if (generator_[i]->howOften()==-100||
     7129              (generator_[i]->needsOptimalBasis()&&!solver_->basisIsAvailable())
     7130              ||generator_[i]->switchedOff())
    71297131            generate=false;
    7130           } else if (currentDepth_>-10&&switchOff==2) {
    7131             generate=false;
    7132           }
    7133         }
    7134         if (generate) {
    7135           if (!node&&cut_obj[CUT_HISTORY-1]!=-COIN_DBL_MAX&&
    7136               fabs(cut_obj[CUT_HISTORY-1]-cut_obj[CUT_HISTORY-2])<1.0e-7)
    7137             generator_[i]->setIneffectualCuts(true);
    7138           bool mustResolve =
    7139             generator_[i]->generateCuts(theseCuts,fullScan,solver_,node) ;
    7140           generator_[i]->setIneffectualCuts(false);
    7141           numberRowCutsAfter = theseCuts.sizeRowCuts() ;
    7142           if (fullScan&&generator_[i]->howOften()==1000000+SCANCUTS_PROBING) {
    7143             CglProbing * probing =
    7144               dynamic_cast<CglProbing*>(generator_[i]->generator());
    7145             if (probing&&(numberRowCutsBefore < numberRowCutsAfter||
    7146                           numberColumnCutsBefore<theseCuts.sizeColCuts())) {
    7147               // switch on
    7148 #ifdef COIN_DEVELOP
    7149               printf("Switching on probing\n");
    7150 #endif
    7151               generator_[i]->setHowOften(1);
     7132          if (switchOff&&!generator_[i]->mustCallAgain()) {
     7133            // switch off if default
     7134            if (generator_[i]->howOften()==1&&generator_[i]->whatDepth()<0) {
     7135              /*if (generate)
     7136                printf("Gg %d %d %d\n",i,
     7137                generator_[i]->howOften(),generator_[i]->whatDepth());*/
     7138              generate=false;
     7139            } else if (currentDepth_>-10&&switchOff==2) {
     7140              generate=false;
    71527141            }
    71537142          }
    7154           if(numberRowCutsBefore < numberRowCutsAfter &&
    7155              generator_[i]->mustCallAgain())
    7156             keepGoing=true; // say must go round
    7157           // Check last cut to see if infeasible
    7158           if(numberRowCutsBefore < numberRowCutsAfter) {
    7159             const OsiRowCut * thisCut = theseCuts.rowCutPtr(numberRowCutsAfter-1) ;
    7160             if (thisCut->lb()>thisCut->ub()) {
    7161               feasible = false; // sub-problem is infeasible
    7162               break;
     7143          if (generate) {
     7144            if (!node&&cut_obj[CUT_HISTORY-1]!=-COIN_DBL_MAX&&
     7145                fabs(cut_obj[CUT_HISTORY-1]-cut_obj[CUT_HISTORY-2])<1.0e-7)
     7146              generator_[i]->setIneffectualCuts(true);
     7147            bool mustResolve =
     7148              generator_[i]->generateCuts(theseCuts,fullScan,solver_,node) ;
     7149            generator_[i]->setIneffectualCuts(false);
     7150            numberRowCutsAfter = theseCuts.sizeRowCuts() ;
     7151            if (fullScan&&generator_[i]->howOften()==1000000+SCANCUTS_PROBING) {
     7152              CglProbing * probing =
     7153                dynamic_cast<CglProbing*>(generator_[i]->generator());
     7154              if (probing&&(numberRowCutsBefore < numberRowCutsAfter||
     7155                            numberColumnCutsBefore<theseCuts.sizeColCuts())) {
     7156                // switch on
     7157#ifdef COIN_DEVELOP
     7158                printf("Switching on probing\n");
     7159#endif
     7160                generator_[i]->setHowOften(1);
     7161              }
     7162            }
     7163            if(numberRowCutsBefore < numberRowCutsAfter &&
     7164               generator_[i]->mustCallAgain())
     7165              keepGoing=true; // say must go round
     7166            // Check last cut to see if infeasible
     7167            if(numberRowCutsBefore < numberRowCutsAfter) {
     7168              const OsiRowCut * thisCut = theseCuts.rowCutPtr(numberRowCutsAfter-1) ;
     7169              if (thisCut->lb()>thisCut->ub()) {
     7170                feasible = false; // sub-problem is infeasible
     7171                break;
     7172              }
     7173            }
     7174#ifdef CBC_DEBUG
     7175            {
     7176              int k ;
     7177              for (k = numberRowCutsBefore;k<numberRowCutsAfter;k++) {
     7178                OsiRowCut thisCut = theseCuts.rowCut(k) ;
     7179                /* check size of elements.
     7180                   We can allow smaller but this helps debug generators as it
     7181                   is unsafe to have small elements */
     7182                int n=thisCut.row().getNumElements();
     7183                const int * column = thisCut.row().getIndices();
     7184                const double * element = thisCut.row().getElements();
     7185                //assert (n);
     7186                for (int i=0;i<n;i++) {
     7187                  double value = element[i];
     7188                  assert(fabs(value)>1.0e-12&&fabs(value)<1.0e20);
     7189                }
     7190              }
     7191            }
     7192#endif
     7193            if (mustResolve) {
     7194              int returnCode = resolve(node ? node->nodeInfo() : NULL,2);
     7195              feasible = (returnCode  != 0) ;
     7196              if (returnCode<0)
     7197                numberTries=0;
     7198              if ((specialOptions_&1)!=0) {
     7199                debugger = solver_->getRowCutDebugger() ;
     7200                if (debugger)
     7201                  onOptimalPath = (debugger->onOptimalPath(*solver_)) ;
     7202                else
     7203                  onOptimalPath=false;
     7204                if (onOptimalPath && !solver_->isDualObjectiveLimitReached())
     7205                  assert(feasible) ;
     7206              }
     7207              if (!feasible)
     7208                break ;
    71637209            }
    71647210          }
    7165 #ifdef CBC_DEBUG
    7166           {
    7167             int k ;
    7168             for (k = numberRowCutsBefore;k<numberRowCutsAfter;k++) {
    7169               OsiRowCut thisCut = theseCuts.rowCut(k) ;
    7170               /* check size of elements.
    7171                  We can allow smaller but this helps debug generators as it
    7172                  is unsafe to have small elements */
    7173               int n=thisCut.row().getNumElements();
    7174               const int * column = thisCut.row().getIndices();
    7175               const double * element = thisCut.row().getElements();
    7176               //assert (n);
    7177               for (int i=0;i<n;i++) {
    7178                 double value = element[i];
    7179                 assert(fabs(value)>1.0e-12&&fabs(value)<1.0e20);
     7211          numberRowCutsAfter = theseCuts.sizeRowCuts() ;
     7212          numberColumnCutsAfter = theseCuts.sizeColCuts() ;
     7213          if ((specialOptions_&1)!=0) {
     7214            if (onOptimalPath) {
     7215              int k ;
     7216              for (k = numberRowCutsBefore;k<numberRowCutsAfter;k++) {
     7217                OsiRowCut thisCut = theseCuts.rowCut(k) ;
     7218                if(debugger->invalidCut(thisCut)) {     
     7219                  solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     7220                  solver_->writeMpsNative("badCut.mps",NULL,NULL,2);
     7221                  printf("Cut generator %d (%s) produced invalid cut (%dth in this go)\n",
     7222                         i,generator_[i]->cutGeneratorName(),k-numberRowCutsBefore);
     7223                  const double *lower = getColLower() ;
     7224                  const double *upper = getColUpper() ;
     7225                  int numberColumns = solver_->getNumCols();
     7226                  if (numberColumns<200) {
     7227                    for (int i=0;i<numberColumns;i++)
     7228                      printf("%d bounds %g,%g\n",i,lower[i],upper[i]);
     7229                  }
     7230#ifdef CGL_DEBUG_GOMORY
     7231                  printf("Value of gomory_try is %d, recompile with -%d\n",
     7232                         gomory_try,gomory_try);
     7233#endif
     7234                  abort();
     7235                }
     7236                assert(!debugger->invalidCut(thisCut)) ;
    71807237              }
    71817238            }
    71827239          }
    7183 #endif
    7184           if (mustResolve) {
    7185             int returnCode = resolve(node ? node->nodeInfo() : NULL,2);
    7186             feasible = (returnCode  != 0) ;
    7187             if (returnCode<0)
    7188               numberTries=0;
    7189             if ((specialOptions_&1)!=0) {
    7190               debugger = solver_->getRowCutDebugger() ;
    7191               if (debugger)
    7192                 onOptimalPath = (debugger->onOptimalPath(*solver_)) ;
    7193               else
    7194                 onOptimalPath=false;
    7195               if (onOptimalPath && !solver_->isDualObjectiveLimitReached())
    7196                 assert(feasible) ;
     7240          /*
     7241            The cut generator has done its thing, and maybe it generated some
     7242            cuts.  Do a bit of bookkeeping: load
     7243            whichGenerator[i] with the index of the generator responsible for a cut,
     7244            and place cuts flagged as global in the global cut pool for the model.
     7245           
     7246            lastNumberCuts is the sum of cuts added in previous iterations; it's the
     7247            offset to the proper starting position in whichGenerator.
     7248          */
     7249          int numberBefore =
     7250            numberRowCutsBefore+lastNumberCuts ;
     7251          int numberAfter =
     7252            numberRowCutsAfter+lastNumberCuts ;
     7253          // possibly extend whichGenerator
     7254          resizeWhichGenerator(numberBefore, numberAfter);
     7255          int j ;
     7256         
     7257          bool dodgyCuts=false;
     7258          for (j = numberRowCutsBefore;j<numberRowCutsAfter;j++) {
     7259            const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ;
     7260            if (thisCut->lb()>1.0e10||thisCut->ub()<-1.0e10) {
     7261              dodgyCuts=true;
     7262              break;
    71977263            }
    7198             if (!feasible)
    7199               break ;
    7200           }
    7201         }
    7202         numberRowCutsAfter = theseCuts.sizeRowCuts() ;
    7203         numberColumnCutsAfter = theseCuts.sizeColCuts() ;
    7204         if ((specialOptions_&1)!=0) {
    7205           if (onOptimalPath) {
    7206             int k ;
    7207             for (k = numberRowCutsBefore;k<numberRowCutsAfter;k++) {
    7208               OsiRowCut thisCut = theseCuts.rowCut(k) ;
    7209               if(debugger->invalidCut(thisCut)) {       
    7210                 solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
    7211                 solver_->writeMpsNative("badCut.mps",NULL,NULL,2);
    7212                 printf("Cut generator %d (%s) produced invalid cut (%dth in this go)\n",
    7213                        i,generator_[i]->cutGeneratorName(),k-numberRowCutsBefore);
    7214                 const double *lower = getColLower() ;
    7215                 const double *upper = getColUpper() ;
    7216                 int numberColumns = solver_->getNumCols();
    7217                 if (numberColumns<200) {
    7218                   for (int i=0;i<numberColumns;i++)
    7219                     printf("%d bounds %g,%g\n",i,lower[i],upper[i]);
    7220                 }
    7221 #ifdef CGL_DEBUG_GOMORY
    7222                 printf("Value of gomory_try is %d, recompile with -%d\n",
    7223                        gomory_try,gomory_try);
    7224 #endif
    7225                 abort();
    7226               }
    7227               assert(!debugger->invalidCut(thisCut)) ;
    7228             }
    7229           }
    7230         }
    7231 /*
    7232   The cut generator has done its thing, and maybe it generated some
    7233   cuts.  Do a bit of bookkeeping: load
    7234   whichGenerator[i] with the index of the generator responsible for a cut,
    7235   and place cuts flagged as global in the global cut pool for the model.
    7236 
    7237   lastNumberCuts is the sum of cuts added in previous iterations; it's the
    7238   offset to the proper starting position in whichGenerator.
    7239 */
    7240         int numberBefore =
    7241           numberRowCutsBefore+lastNumberCuts ;
    7242         int numberAfter =
    7243           numberRowCutsAfter+lastNumberCuts ;
    7244         // possibly extend whichGenerator
    7245         resizeWhichGenerator(numberBefore, numberAfter);
    7246         int j ;
    7247        
    7248         bool dodgyCuts=false;
    7249         for (j = numberRowCutsBefore;j<numberRowCutsAfter;j++) {
    7250           const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ;
    7251           if (thisCut->lb()>1.0e10||thisCut->ub()<-1.0e10) {
    7252             dodgyCuts=true;
    7253             break;
    7254           }
    7255           whichGenerator_[numberBefore++] = i ;
    7256           if (thisCut->lb()>thisCut->ub())
    7257             violated=-2; // sub-problem is infeasible
    7258           if (thisCut->globallyValid()) {
    7259             // add to global list
    7260             OsiRowCut newCut(*thisCut);
    7261             newCut.setGloballyValid(true);
    7262             newCut.mutableRow().setTestForDuplicateIndex(false);
    7263             globalCuts_.insert(newCut) ;
    7264           }
    7265         }
    7266         if (dodgyCuts) {
    7267           for (int k=numberRowCutsAfter-1;k>=j;k--) {
    7268             const OsiRowCut * thisCut = theseCuts.rowCutPtr(k) ;
     7264            whichGenerator_[numberBefore++] = i ;
    72697265            if (thisCut->lb()>thisCut->ub())
    72707266              violated=-2; // sub-problem is infeasible
    7271             if (thisCut->lb()>1.0e10||thisCut->ub()<-1.0e10)
    7272               theseCuts.eraseRowCut(k);
    7273           }
    7274           numberRowCutsAfter = theseCuts.sizeRowCuts() ;
    7275           for (;j<numberRowCutsAfter;j++) {
    7276             const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ;
    7277             whichGenerator_[numberBefore++] = i ;
    72787267            if (thisCut->globallyValid()) {
    72797268              // add to global list
     
    72847273            }
    72857274          }
    7286         }
    7287         for (j = numberColumnCutsBefore;j<numberColumnCutsAfter;j++) {
    7288           //whichGenerator_[numberBefore++] = i ;
    7289           const OsiColCut * thisCut = theseCuts.colCutPtr(j) ;
    7290           if (thisCut->globallyValid()) {
    7291             // add to global list
    7292             OsiColCut newCut(*thisCut);
    7293             newCut.setGloballyValid(true);
    7294             globalCuts_.insert(newCut) ;
     7275          if (dodgyCuts) {
     7276            for (int k=numberRowCutsAfter-1;k>=j;k--) {
     7277              const OsiRowCut * thisCut = theseCuts.rowCutPtr(k) ;
     7278              if (thisCut->lb()>thisCut->ub())
     7279                violated=-2; // sub-problem is infeasible
     7280              if (thisCut->lb()>1.0e10||thisCut->ub()<-1.0e10)
     7281                theseCuts.eraseRowCut(k);
     7282            }
     7283            numberRowCutsAfter = theseCuts.sizeRowCuts() ;
     7284            for (;j<numberRowCutsAfter;j++) {
     7285              const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ;
     7286              whichGenerator_[numberBefore++] = i ;
     7287              if (thisCut->globallyValid()) {
     7288                // add to global list
     7289                OsiRowCut newCut(*thisCut);
     7290                newCut.setGloballyValid(true);
     7291                newCut.mutableRow().setTestForDuplicateIndex(false);
     7292                globalCuts_.insert(newCut) ;
     7293              }
     7294            }
     7295          }
     7296          for (j = numberColumnCutsBefore;j<numberColumnCutsAfter;j++) {
     7297            //whichGenerator_[numberBefore++] = i ;
     7298            const OsiColCut * thisCut = theseCuts.colCutPtr(j) ;
     7299            if (thisCut->globallyValid()) {
     7300              // add to global list
     7301              OsiColCut newCut(*thisCut);
     7302              newCut.setGloballyValid(true);
     7303              globalCuts_.insert(newCut) ;
     7304            }
    72957305          }
    72967306        }
     
    1098110991        delete [] saveLower;
    1098210992        delete [] saveUpper;
     10993        resolve(solver_);
    1098310994      }
    1098410995    //If the variables were fixed the cutting plane procedure may have believed that the node could be fathomed
Note: See TracChangeset for help on using the changeset viewer.