Changeset 1015


Ignore:
Timestamp:
Jul 19, 2008 7:11:17 PM (11 years ago)
Author:
forrest
Message:

add ifdefs for future exploration

Location:
trunk/Cbc/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Cbc/src/CbcCutGenerator.cpp

    r1013 r1015  
    168168CbcCutGenerator::generateCuts( OsiCuts & cs , int fullScan, OsiSolverInterface * solver, CbcNode * node)
    169169{
     170#define PROBE1 0
     171#define PROBE2 0
     172#define PROBE3 0
     173  int depth;
     174  if (node)
     175    depth=node->depth();
     176  else
     177    depth=0;
    170178  int howOften = whenCutGenerator_;
     179  if (dynamic_cast<CglProbing*>(generator_)&&PROBE1) {
     180    if (howOften==-100&&model_->doCutsNow(3)) {
     181      howOften=1; // do anyway
     182    }
     183  }
    171184  if (howOften==-100)
    172185    return false;
     
    179192  bool returnCode=false;
    180193  //OsiSolverInterface * solver = model_->solver();
    181   int depth;
    182   if (node)
    183     depth=node->depth();
    184   else
    185     depth=0;
    186194  int pass=model_->getCurrentPassNumber()-1;
    187195  bool doThis=(model_->getNodeCount()%howOften)==0;
     
    236244      // Probing - return tight column bounds
    237245      CglTreeProbingInfo * info2 = model_->probingInfo();
     246      bool doCuts=false;
    238247      if (info2&&!depth) {
    239248        info2->level = depth;
     
    243252        info2->randomNumberGenerator=randomNumberGenerator;
    244253        generator->generateCutsAndModify(*solver,cs,info2);
    245       } else {
     254        doCuts=true;
     255      } else if (depth||PROBE2) {
     256#if PROBE3
    246257        if ((numberTimes_==200||(numberTimes_>200&&(numberTimes_%2000)==0))
    247              &&!model_->parentModel()&&false) {
     258             &&!model_->parentModel()) {
    248259          // in tree, maxStack, maxProbe
    249260          int test[]= {
     
    261272          int saveStack = generator->getMaxLook();
    262273          int saveNumber = generator->getMaxProbe();
     274#ifdef CLP_INVESTIGATE
    263275          int kr1=0;
    264276          int kc1=0;
     277#endif
    265278          int bestStackTree=-1;
    266279          int bestNumberTree=-1;
     
    272285            generator->setMaxProbe(number);
    273286            generator_->generateCuts(*solver,cs2,info);
     287#ifdef CLP_INVESTIGATE
    274288            int numberRowCuts = cs2.sizeRowCuts()-numberRowCutsBefore ;
    275289            int numberColumnCuts= cs2.sizeColCuts()-numberColumnCutsBefore ;
     
    285299            printf("maxStack %d number %d gives %d row cuts and %d column cuts\n",
    286300                   stack,number,numberRowCuts,numberColumnCuts);
     301#endif
    287302          }
    288303          generator->setMaxLook(saveStack);
     
    291306            generator->setMaxLook(bestStackTree);
    292307            generator->setMaxProbe(bestNumberTree);
     308#ifdef CLP_INVESTIGATE
    293309            printf("RRNumber %d -> %d, stack %d -> %d\n",
    294310                   saveNumber,bestNumberTree,saveStack,bestStackTree);
     311#endif
    295312          } else {
    296313            // no good
    297             generator->setMaxLook(1);
     314            generator->setMaxLook(0);
     315#ifdef CLP_INVESTIGATE
    298316            printf("RRSwitching off number %d -> %d, stack %d -> %d\n",
    299317                   saveNumber,saveNumber,saveStack,1);
    300           }
    301         }
    302         if (generator->getMaxLook()>0)
     318#endif
     319          }
     320        }
     321#endif
     322        if (generator->getMaxLook()>0) {
    303323          generator->generateCutsAndModify(*solver,cs,&info);
    304       }
    305       const double * tightLower = generator->tightLower();
    306       const double * lower = solver->getColLower();
    307       const double * tightUpper = generator->tightUpper();
    308       const double * upper = solver->getColUpper();
    309       const double * solution = solver->getColSolution();
    310       int j;
    311       int numberColumns = solver->getNumCols();
    312       double primalTolerance = 1.0e-8;
    313       const char * tightenBounds = generator->tightenBounds();
    314       if ((model_->getThreadMode()&2)==0) {
    315         for (j=0;j<numberColumns;j++) {
    316           if (solver->isInteger(j)) {
    317             if (tightUpper[j]<upper[j]) {
    318               double nearest = floor(tightUpper[j]+0.5);
    319               //assert (fabs(tightUpper[j]-nearest)<1.0e-5); may be infeasible
    320               solver->setColUpper(j,nearest);
    321               if (nearest<solution[j]-primalTolerance)
    322                 returnCode=true;
    323             }
    324             if (tightLower[j]>lower[j]) {
    325               double nearest = floor(tightLower[j]+0.5);
    326               //assert (fabs(tightLower[j]-nearest)<1.0e-5); may be infeasible
    327               solver->setColLower(j,nearest);
    328               if (nearest>solution[j]+primalTolerance)
    329                 returnCode=true;
    330             }
    331           } else {
    332             if (upper[j]>lower[j]) {
    333               if (tightUpper[j]==tightLower[j]) {
    334                 // fix
    335                 solver->setColLower(j,tightLower[j]);
    336                 solver->setColUpper(j,tightUpper[j]);
    337                 if (tightLower[j]>solution[j]+primalTolerance||
    338                     tightUpper[j]<solution[j]-primalTolerance)
    339                   returnCode=true;
    340               } else if (tightenBounds&&tightenBounds[j]) {
    341                 solver->setColLower(j,CoinMax(tightLower[j],lower[j]));
    342                 solver->setColUpper(j,CoinMin(tightUpper[j],upper[j]));
    343                 if (tightLower[j]>solution[j]+primalTolerance||
    344                     tightUpper[j]<solution[j]-primalTolerance)
     324          doCuts=true;
     325        }
     326      } else {
     327        // at root - don't always do
     328        if (!PROBE3||pass<15||(pass&1)==0) {
     329          generator->generateCutsAndModify(*solver,cs,&info);
     330          doCuts=true;
     331        }
     332      }
     333      if (doCuts) {
     334        const double * tightLower = generator->tightLower();
     335        const double * lower = solver->getColLower();
     336        const double * tightUpper = generator->tightUpper();
     337        const double * upper = solver->getColUpper();
     338        const double * solution = solver->getColSolution();
     339        int j;
     340        int numberColumns = solver->getNumCols();
     341        double primalTolerance = 1.0e-8;
     342        const char * tightenBounds = generator->tightenBounds();
     343        if ((model_->getThreadMode()&2)==0) {
     344          for (j=0;j<numberColumns;j++) {
     345            if (solver->isInteger(j)) {
     346              if (tightUpper[j]<upper[j]) {
     347                double nearest = floor(tightUpper[j]+0.5);
     348                //assert (fabs(tightUpper[j]-nearest)<1.0e-5); may be infeasible
     349                solver->setColUpper(j,nearest);
     350                if (nearest<solution[j]-primalTolerance)
    345351                  returnCode=true;
    346352              }
     353              if (tightLower[j]>lower[j]) {
     354                double nearest = floor(tightLower[j]+0.5);
     355                //assert (fabs(tightLower[j]-nearest)<1.0e-5); may be infeasible
     356                solver->setColLower(j,nearest);
     357                if (nearest>solution[j]+primalTolerance)
     358                  returnCode=true;
     359              }
     360            } else {
     361              if (upper[j]>lower[j]) {
     362                if (tightUpper[j]==tightLower[j]) {
     363                  // fix
     364                  solver->setColLower(j,tightLower[j]);
     365                  solver->setColUpper(j,tightUpper[j]);
     366                  if (tightLower[j]>solution[j]+primalTolerance||
     367                      tightUpper[j]<solution[j]-primalTolerance)
     368                    returnCode=true;
     369                } else if (tightenBounds&&tightenBounds[j]) {
     370                  solver->setColLower(j,CoinMax(tightLower[j],lower[j]));
     371                  solver->setColUpper(j,CoinMin(tightUpper[j],upper[j]));
     372                  if (tightLower[j]>solution[j]+primalTolerance||
     373                      tightUpper[j]<solution[j]-primalTolerance)
     374                    returnCode=true;
     375                }
     376              }
    347377            }
    348378          }
    349         }
    350       } else {
    351         CoinPackedVector lbs;
    352         CoinPackedVector ubs;
    353         int numberChanged=0;
    354         bool ifCut=false;
    355         for (j=0;j<numberColumns;j++) {
    356           if (solver->isInteger(j)) {
    357             if (tightUpper[j]<upper[j]) {
    358               double nearest = floor(tightUpper[j]+0.5);
    359               //assert (fabs(tightUpper[j]-nearest)<1.0e-5); may be infeasible
    360               ubs.insert(j,nearest);
    361               numberChanged++;
    362               if (nearest<solution[j]-primalTolerance)
    363                 ifCut=true;
    364             }
    365             if (tightLower[j]>lower[j]) {
    366               double nearest = floor(tightLower[j]+0.5);
    367               //assert (fabs(tightLower[j]-nearest)<1.0e-5); may be infeasible
    368               lbs.insert(j,nearest);
    369               numberChanged++;
    370               if (nearest>solution[j]+primalTolerance)
    371                 ifCut=true;
    372             }
    373           } else {
    374             if (upper[j]>lower[j]) {
    375               if (tightUpper[j]==tightLower[j]) {
    376                 // fix
    377                 lbs.insert(j,tightLower[j]);
    378                 ubs.insert(j,tightUpper[j]);
    379                 if (tightLower[j]>solution[j]+primalTolerance||
    380                     tightUpper[j]<solution[j]-primalTolerance)
    381                   ifCut=true;
    382               } else if (tightenBounds&&tightenBounds[j]) {
    383                 lbs.insert(j,CoinMax(tightLower[j],lower[j]));
    384                 ubs.insert(j,CoinMin(tightUpper[j],upper[j]));
    385                 if (tightLower[j]>solution[j]+primalTolerance||
    386                     tightUpper[j]<solution[j]-primalTolerance)
     379        } else {
     380          CoinPackedVector lbs;
     381          CoinPackedVector ubs;
     382          int numberChanged=0;
     383          bool ifCut=false;
     384          for (j=0;j<numberColumns;j++) {
     385            if (solver->isInteger(j)) {
     386              if (tightUpper[j]<upper[j]) {
     387                double nearest = floor(tightUpper[j]+0.5);
     388                //assert (fabs(tightUpper[j]-nearest)<1.0e-5); may be infeasible
     389                ubs.insert(j,nearest);
     390                numberChanged++;
     391                if (nearest<solution[j]-primalTolerance)
    387392                  ifCut=true;
    388393              }
     394              if (tightLower[j]>lower[j]) {
     395                double nearest = floor(tightLower[j]+0.5);
     396                //assert (fabs(tightLower[j]-nearest)<1.0e-5); may be infeasible
     397                lbs.insert(j,nearest);
     398                numberChanged++;
     399                if (nearest>solution[j]+primalTolerance)
     400                  ifCut=true;
     401              }
     402            } else {
     403              if (upper[j]>lower[j]) {
     404                if (tightUpper[j]==tightLower[j]) {
     405                  // fix
     406                  lbs.insert(j,tightLower[j]);
     407                  ubs.insert(j,tightUpper[j]);
     408                  if (tightLower[j]>solution[j]+primalTolerance||
     409                      tightUpper[j]<solution[j]-primalTolerance)
     410                    ifCut=true;
     411                } else if (tightenBounds&&tightenBounds[j]) {
     412                  lbs.insert(j,CoinMax(tightLower[j],lower[j]));
     413                  ubs.insert(j,CoinMin(tightUpper[j],upper[j]));
     414                  if (tightLower[j]>solution[j]+primalTolerance||
     415                      tightUpper[j]<solution[j]-primalTolerance)
     416                    ifCut=true;
     417                }
     418              }
    389419            }
    390420          }
    391         }
    392         if (numberChanged) {
    393           OsiColCut cc;
    394           cc.setUbs(ubs);
    395           cc.setLbs(lbs);
    396           if (ifCut) {
    397             cc.setEffectiveness(100.0);
    398           } else {
    399             cc.setEffectiveness(1.0e-5);
    400           }
    401           cs.insert(cc);
     421          if (numberChanged) {
     422            OsiColCut cc;
     423            cc.setUbs(ubs);
     424            cc.setLbs(lbs);
     425            if (ifCut) {
     426              cc.setEffectiveness(100.0);
     427            } else {
     428              cc.setEffectiveness(1.0e-5);
     429            }
     430            cs.insert(cc);
     431          }
    402432        }
    403433      }
     
    596626          }
    597627          int kkk = CoinMin(nCuts,k+5);
     628          double testValue = (depth>1) ? 0.9 : 0.99999;
    598629          for (int kk=k+1;kk<kkk;kk++) {
    599630            int jj=which[kk];
     
    612643              product += value*element2[columnB[i]];
    613644            }
    614             if (product>0.0&&product*product>0.99999*norm*normB) {
     645            if (product>0.0&&product*product>testValue*norm*normB) {
    615646              bool parallel=true;
    616647              double lbB = thisCut2->lb();
  • trunk/Cbc/src/CbcModel.cpp

    r1013 r1015  
    15271527  delete [] walkback_ ;
    15281528  walkback_ = new CbcNodeInfo * [maximumDepth_] ;
     1529#ifdef NODE_LAST
     1530  lastDepth_=0;
     1531  delete [] lastNodeInfo_ ;
     1532  lastNodeInfo_ = new CbcNodeInfo * [maximumDepth_] ;
     1533  delete [] lastNumberCuts_ ;
     1534  lastNumberCuts_ = new int [maximumDepth_] ;
     1535  maximumCuts_ = 100;
     1536  lastNumberCuts2_=0;
     1537  delete [] lastCut_;
     1538  lastCut_ = new const OsiRowCut * [maximumCuts_];
     1539#endif
    15291540/*
    15301541  Used to generate bound edits for CbcPartialNodeInfo.
     
    37263737  delete [] walkback_ ;
    37273738  walkback_ = NULL ;
     3739#ifdef NODE_LAST
     3740  delete [] lastNodeInfo_ ;
     3741  lastNodeInfo_ = NULL;
     3742  delete [] lastNumberCuts_ ;
     3743  lastNumberCuts_ = NULL;
     3744  delete [] lastCut_;
     3745  lastCut_ = NULL;
     3746#endif
    37283747  delete [] addedCuts_ ;
    37293748  addedCuts_ = NULL ;
     
    39263945  numberSolutions_(0),
    39273946  stateOfSearch_(0),
     3947  whenCuts_(-1),
    39283948  hotstartSolution_(NULL),
    39293949  hotstartPriorities_(NULL),
     
    39413961  maximumDepth_(0),
    39423962  walkback_(NULL),
     3963#ifdef NODE_LAST
     3964  lastNodeInfo_(NULL),
     3965  lastCut_(NULL),
     3966  lastDepth_(0),
     3967  lastNumberCuts2_(0),
     3968  maximumCuts_(0),
     3969  lastNumberCuts_(NULL),
     3970#endif
    39433971  addedCuts_(NULL),
    39443972  nextRowCut_(NULL),
     
    40774105  numberSolutions_(0),
    40784106  stateOfSearch_(0),
     4107  whenCuts_(-1),
    40794108  hotstartSolution_(NULL),
    40804109  hotstartPriorities_(NULL),
     
    40914120  maximumDepth_(0),
    40924121  walkback_(NULL),
     4122#ifdef NODE_LAST
     4123  lastNodeInfo_(NULL),
     4124  lastCut_(NULL),
     4125  lastDepth_(0),
     4126  lastNumberCuts2_(0),
     4127  maximumCuts_(0),
     4128  lastNumberCuts_(NULL),
     4129#endif
    40934130  addedCuts_(NULL),
    40944131  nextRowCut_(NULL),
     
    43334370  numberSolutions_(rhs.numberSolutions_),
    43344371  stateOfSearch_(rhs.stateOfSearch_),
     4372  whenCuts_(rhs.whenCuts_),
    43354373  numberHeuristicSolutions_(rhs.numberHeuristicSolutions_),
    43364374  numberNodes_(rhs.numberNodes_),
     
    45564594  nextRowCut_ = NULL;
    45574595  currentNode_ = NULL;
    4558   if (maximumDepth_)
     4596  if (maximumDepth_) {
    45594597    walkback_ = new CbcNodeInfo * [maximumDepth_];
    4560   else
     4598#ifdef NODE_LAST
     4599    lastNodeInfo_ = new CbcNodeInfo * [maximumDepth_] ;
     4600    lastNumberCuts_ = new int [maximumDepth_] ;
     4601#endif
     4602  } else {
    45614603    walkback_ = NULL;
     4604#ifdef NODE_LAST
     4605    lastNodeInfo_ = NULL;
     4606    lastNumberCuts_ = NULL;
     4607#endif
     4608  }
     4609#ifdef NODE_LAST
     4610  maximumCuts_ = rhs.maximumCuts_;
     4611  if (maximumCuts_) {
     4612    lastCut_ = new const OsiRowCut * [maximumCuts_] ;
     4613  } else {
     4614    lastCut_ = NULL;
     4615  }
     4616#endif
    45624617  synchronizeModel();
    45634618  if (cloneHandler) {
     
    46394694    numberSolutions_=rhs.numberSolutions_;
    46404695    stateOfSearch_= rhs.stateOfSearch_;
     4696    whenCuts_ = rhs.whenCuts_;
    46414697    numberHeuristicSolutions_=rhs.numberHeuristicSolutions_;
    46424698    numberNodes_ = rhs.numberNodes_;
     
    48394895      addedCuts_ = NULL;
    48404896    }
     4897#ifdef NODE_LAST
     4898    delete [] lastNodeInfo_ ;
     4899    delete [] lastNumberCuts_ ;
     4900    delete [] lastCut_;
     4901#endif
    48414902    bestSolutionBasis_ = rhs.bestSolutionBasis_;
    48424903    nextRowCut_ = NULL;
    48434904    currentNode_ = NULL;
    4844     if (maximumDepth_)
     4905    if (maximumDepth_) {
    48454906      walkback_ = new CbcNodeInfo * [maximumDepth_];
    4846     else
     4907#ifdef NODE_LAST
     4908      lastNodeInfo_ = new CbcNodeInfo * [maximumDepth_] ;
     4909      lastNumberCuts_ = new int [maximumDepth_] ;
     4910#endif
     4911    } else {
    48474912      walkback_ = NULL;
     4913#ifdef NODE_LAST
     4914      lastNodeInfo_ = NULL;
     4915      lastNumberCuts_ = NULL;
     4916#endif
     4917    }
     4918#ifdef NODE_LAST
     4919    maximumCuts_ = rhs.maximumCuts_;
     4920    if (maximumCuts_) {
     4921      lastCut_ = new const OsiRowCut * [maximumCuts_] ;
     4922    } else {
     4923      lastCut_ = NULL;
     4924    }
     4925#endif
    48484926    synchronizeModel();
    48494927    cbcColLower_ = NULL;
     
    49605038  delete [] walkback_;
    49615039  walkback_=NULL;
     5040#ifdef NODE_LAST
     5041  delete [] lastNodeInfo_ ;
     5042  lastNodeInfo_ = NULL;
     5043  delete [] lastNumberCuts_ ;
     5044  lastNumberCuts_ = NULL;
     5045  delete [] lastCut_;
     5046  lastCut_ = NULL;
     5047#endif
    49625048  delete [] whichGenerator_;
    49635049  whichGenerator_ = NULL;
     
    51005186    branchingMethod_=NULL;
    51015187  messageHandler()->setLogLevel(rhs.messageHandler()->logLevel());
     5188  whenCuts_ = rhs.whenCuts_;
    51025189  synchronizeModel();
    51035190}
     
    53415428  point in passing in a valid basis --- an empty basis will do just fine.
    53425429*/
    5343 void CbcModel::addCuts1 (CbcNode * node, CoinWarmStartBasis *&lastws)
    5344 { int i;
     5430bool CbcModel::addCuts1 (CbcNode * node, CoinWarmStartBasis *&lastws)
     5431{
     5432#if 0
    53455433  int nNode=0;
    53465434  int numberColumns = getNumCols();
     
    53485436
    53495437/*
    5350   Remove all cuts from the constraint system.
    5351   (original comment includes ``see note below for later efficiency'', but
    5352   the reference isn't clear to me).
    5353 */
    5354   int currentNumberCuts ;
    5355   if (numberThreads_<=0) {
    5356     solver_->restoreBaseModel(numberRowsAtContinuous_);
    5357   } else {
    5358     // *** Fix later
    5359     currentNumberCuts = solver_->getNumRows()-numberRowsAtContinuous_;
    5360     int *which = new int[currentNumberCuts];
    5361     for (i = 0 ; i < currentNumberCuts ; i++)
    5362       which[i] = i+numberRowsAtContinuous_;
    5363     solver_->deleteRows(currentNumberCuts,which);
    5364     delete [] which;
    5365   }
    5366 /*
    53675438  Accumulate the path from node to the root in walkback_, and accumulate a
    53685439  cut count in currentNumberCuts.
     
    53715442  old node (for cuts?)
    53725443*/
    5373   currentNumberCuts = 0;
     5444  int currentNumberCuts = 0;
    53745445  while (nodeInfo) {
    53755446    //printf("nNode = %d, nodeInfo = %x\n",nNode,nodeInfo);
     
    53785449    nodeInfo = nodeInfo->parent() ;
    53795450    if (nNode==maximumDepth_) {
    5380       maximumDepth_ *= 2;
    5381       CbcNodeInfo ** temp = new CbcNodeInfo * [maximumDepth_];
    5382       for (i=0;i<nNode;i++)
    5383         temp[i] = walkback_[i];
    5384       delete [] walkback_;
    5385       walkback_ = temp;
    5386     }
    5387   }
    5388 /*
    5389   Create an empty basis with sufficient capacity for the constraint system
    5390   we'll construct: original system plus cuts. Make sure we have capacity to
    5391   record those cuts in addedCuts_.
    5392 
    5393   The method of adjusting the basis at a FullNodeInfo object (the root, for
    5394   example) is to use a copy constructor to duplicate the basis held in the
    5395   nodeInfo, then resize it and return the new basis object. Guaranteed,
    5396   lastws will point to a different basis when it returns. We pass in a basis
    5397   because we need the parameter to return the allocated basis, and it's an
    5398   easy way to pass in the size. But we take a hit for memory allocation.
    5399 */
     5451      redoWalkBack();
     5452    }
     5453  }
    54005454  currentNumberCuts_=currentNumberCuts;
    54015455  if (currentNumberCuts > maximumNumberCuts_) {
     
    54045458    addedCuts_ = new CbcCountRowCut * [maximumNumberCuts_];
    54055459  }
    5406   lastws->setSize(numberColumns,numberRowsAtContinuous_+currentNumberCuts);
    54075460/*
    54085461  This last bit of code traverses the path collected in walkback_ from the
     
    54155468  applyToModel does all the heavy lifting.
    54165469*/
    5417   currentNumberCuts=0;
    54185470  //#define CBC_PRINT2
    54195471#ifdef CBC_PRINT2
    54205472  printf("Starting bounds at node %d\n",numberNodes_);
    54215473#endif
     5474  bool sameProblem=false;
     5475#ifdef NODE_LAST
     5476  {
     5477    {
     5478      int n1=numberRowsAtContinuous_;
     5479      for (int i=0;i<lastDepth_;i++)
     5480        n1 += lastNumberCuts_[i];
     5481      int n2=numberRowsAtContinuous_;
     5482      for (int i=0;i<nNode;i++)
     5483        n2 += walkback_[i]->numberCuts();
     5484      //printf("ROWS a %d - old thinks %d new %d\n",solver_->getNumRows(),n1,n2);
     5485    }
     5486    int nDel=0;
     5487    int nAdd=0;
     5488    int n=CoinMin(lastDepth_,nNode);
     5489    int i;
     5490    int difference=lastDepth_-nNode;
     5491    int iZ=lastDepth_;
     5492    int iN=0;
     5493    // Last is reversed to minimize copying
     5494    if (difference>0) {
     5495      for (i=0;i<difference;i++) {
     5496        // delete rows
     5497        nDel += lastNumberCuts_[--iZ];
     5498      }
     5499    } else if (difference<0) {
     5500      for (i=0;i<-difference;i++) {
     5501        // add rows
     5502        nAdd += walkback_[i]->numberCuts();
     5503      }
     5504      iN=-difference;
     5505    }
     5506    for (i=0;i<n;i++) {
     5507      iZ--;
     5508      if (lastNodeInfo_[iZ]==walkback_[iN]) {
     5509        break;
     5510      } else {
     5511        // delete rows
     5512        nDel += lastNumberCuts_[iZ];
     5513        // add rows
     5514        nAdd += walkback_[iN++]->numberCuts();
     5515      }
     5516    }
     5517    assert (i<n||lastDepth_==0);
     5518    //printf("lastDepth %d thisDepth %d match at %d, rows+-= %d %d\n",
     5519    //   lastDepth_,nNode,n-i,nAdd,nDel);
     5520    sameProblem = (!nAdd)&&(!nDel);
     5521    if (lastDepth_) {
     5522      while (iN>=0) {
     5523        lastNumberCuts_[iZ] = walkback_[iN]->numberCuts();
     5524        lastNodeInfo_[iZ++]=walkback_[iN--];
     5525      }
     5526    } else {
     5527      lastNumberCuts_[0]=walkback_[0]->numberCuts();
     5528      lastNodeInfo_[0]=walkback_[0];
     5529    }
     5530    lastDepth_=nNode;
     5531  }
     5532#endif
    54225533  currentDepth_=nNode;
     5534/*
     5535  Remove all cuts from the constraint system.
     5536  (original comment includes ``see note below for later efficiency'', but
     5537  the reference isn't clear to me).
     5538*/
     5539/*
     5540  Create an empty basis with sufficient capacity for the constraint system
     5541  we'll construct: original system plus cuts. Make sure we have capacity to
     5542  record those cuts in addedCuts_.
     5543
     5544  The method of adjusting the basis at a FullNodeInfo object (the root, for
     5545  example) is to use a copy constructor to duplicate the basis held in the
     5546  nodeInfo, then resize it and return the new basis object. Guaranteed,
     5547  lastws will point to a different basis when it returns. We pass in a basis
     5548  because we need the parameter to return the allocated basis, and it's an
     5549  easy way to pass in the size. But we take a hit for memory allocation.
     5550*/
     5551  lastws->setSize(numberColumns,numberRowsAtContinuous_+currentNumberCuts);
     5552  currentNumberCuts=0;
    54235553  while (nNode) {
    54245554    --nNode;
    5425     walkback_[nNode]->applyToModel(this,lastws,addedCuts_,currentNumberCuts);
     5555    walkback_[nNode]->applyToModel(this,lastws,
     5556                                   addedCuts_,currentNumberCuts);
    54265557  }
    54275558  if (!lastws->fullBasis()) {
     
    55115642    delete [] debugValues;
    55125643  }
     5644  return sameProblem;
     5645#else
     5646  int i;
     5647  int nNode=0;
     5648  int numberColumns = getNumCols();
     5649  CbcNodeInfo * nodeInfo = node->nodeInfo();
     5650
     5651/*
     5652  Accumulate the path from node to the root in walkback_, and accumulate a
     5653  cut count in currentNumberCuts.
     5654
     5655  original comment: when working then just unwind until where new node joins
     5656  old node (for cuts?)
     5657*/
     5658  int currentNumberCuts = 0;
     5659  while (nodeInfo) {
     5660    //printf("nNode = %d, nodeInfo = %x\n",nNode,nodeInfo);
     5661    walkback_[nNode++]=nodeInfo;
     5662    currentNumberCuts += nodeInfo->numberCuts() ;
     5663    nodeInfo = nodeInfo->parent() ;
     5664    if (nNode==maximumDepth_) {
     5665      maximumDepth_ *= 2;
     5666      CbcNodeInfo ** temp = new CbcNodeInfo * [maximumDepth_];
     5667      for (i=0;i<nNode;i++)
     5668        temp[i] = walkback_[i];
     5669      delete [] walkback_;
     5670      walkback_ = temp;
     5671    }
     5672  }
     5673/*
     5674  Create an empty basis with sufficient capacity for the constraint system
     5675  we'll construct: original system plus cuts. Make sure we have capacity to
     5676  record those cuts in addedCuts_.
     5677
     5678  The method of adjusting the basis at a FullNodeInfo object (the root, for
     5679  example) is to use a copy constructor to duplicate the basis held in the
     5680  nodeInfo, then resize it and return the new basis object. Guaranteed,
     5681  lastws will point to a different basis when it returns. We pass in a basis
     5682  because we need the parameter to return the allocated basis, and it's an
     5683  easy way to pass in the size. But we take a hit for memory allocation.
     5684*/
     5685  currentNumberCuts_=currentNumberCuts;
     5686  if (currentNumberCuts > maximumNumberCuts_) {
     5687    maximumNumberCuts_ = currentNumberCuts;
     5688    delete [] addedCuts_;
     5689    addedCuts_ = new CbcCountRowCut * [maximumNumberCuts_];
     5690  }
     5691  lastws->setSize(numberColumns,numberRowsAtContinuous_+currentNumberCuts);
     5692/*
     5693  This last bit of code traverses the path collected in walkback_ from the
     5694  root back to node. At the end of the loop,
     5695   * lastws will be an appropriate basis for node;
     5696   * variable bounds in the constraint system will be set to be correct for
     5697     node; and
     5698   * addedCuts_ will be set to a list of cuts that need to be added to the
     5699     constraint system at node.
     5700  applyToModel does all the heavy lifting.
     5701*/
     5702  currentNumberCuts=0;
     5703  //#define CBC_PRINT2
     5704#ifdef CBC_PRINT2
     5705  printf("Starting bounds at node %d\n",numberNodes_);
     5706#endif
     5707  currentDepth_=nNode;
     5708  while (nNode) {
     5709    --nNode;
     5710    walkback_[nNode]->applyToModel(this,lastws,addedCuts_,currentNumberCuts);
     5711  }
     5712  if (!lastws->fullBasis()) {
     5713#ifdef COIN_DEVELOP
     5714    printf("******* bad basis\n");
     5715#endif
     5716    int numberRows = lastws->getNumArtificial();
     5717    int i;
     5718    for (i=0;i<numberRows;i++)
     5719      lastws->setArtifStatus(i,CoinWarmStartBasis::basic);
     5720    int numberColumns = lastws->getNumStructural();
     5721    for (i=0;i<numberColumns;i++) {
     5722      if (lastws->getStructStatus(i)==CoinWarmStartBasis::basic)
     5723        lastws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
     5724    }
     5725#if 0
     5726  } else {
     5727    // OPTION - take off slack cuts
     5728    // First see if any cuts are slack
     5729    int numberAdded = currentNumberCuts;
     5730    if (saveNode<2&&false) {
     5731      printf("nNode %d cuts %d\n",saveNode,currentNumberCuts);
     5732      for (int i=0;i<currentNumberCuts;i++)
     5733        addedCuts_[i]->print();
     5734    }
     5735    if (numberAdded&&saveNode<5&&!parentModel_) {
     5736#if 0
     5737      currentNumberCuts=0;
     5738      for (int j=numberRowsAtContinuous_;
     5739           j<numberAdded+numberRowsAtContinuous_;j++) {
     5740        CoinWarmStartBasis::Status status = lastws->getArtifStatus(j);
     5741        if (status!=CoinWarmStartBasis::basic) {
     5742          lastws->setArtifStatus(currentNumberCuts+numberRowsAtContinuous_,
     5743                                 status);
     5744          addedCuts_[currentNumberCuts++]=addedCuts_[j-numberRowsAtContinuous_];
     5745        }
     5746      }
     5747      if (currentNumberCuts<numberAdded) {
     5748        printf("deleting %d rows\n",numberAdded-currentNumberCuts);
     5749        lastws->resize(currentNumberCuts+numberRowsAtContinuous_,
     5750                       lastws->getNumStructural());
     5751        currentNumberCuts_=currentNumberCuts;
     5752      }
     5753#else
     5754      int nDelete=0;
     5755      for (int j=numberRowsAtContinuous_;
     5756           j<numberAdded+numberRowsAtContinuous_;j++) {
     5757        CoinWarmStartBasis::Status status = lastws->getArtifStatus(j);
     5758        if (status==CoinWarmStartBasis::basic)
     5759          nDelete++;
     5760      }
     5761      if (nDelete)
     5762        printf("depth %d can delete %d\n",saveNode-1,nDelete);
     5763#endif
     5764    }
     5765#endif
     5766  }
     5767  if (0) {
     5768    int numberDebugValues=18;
     5769    double * debugValues = new double[numberDebugValues];
     5770    CoinZeroN(debugValues,numberDebugValues);
     5771    debugValues[1]=6.0;
     5772    debugValues[3]=60.0;
     5773    debugValues[4]=6.0;
     5774    debugValues[6]=60.0;
     5775    debugValues[7]=16.0;
     5776    debugValues[9]=70.0;
     5777    debugValues[10]=7.0;
     5778    debugValues[12]=70.0;
     5779    debugValues[13]=12.0;
     5780    debugValues[15]=75.0;
     5781    int nBad=0;
     5782    for (int j=0;j<numberColumns;j++) {
     5783      if (integerInfo_[j]) {
     5784        if(solver_->getColLower()[j]>debugValues[j]||
     5785           solver_->getColUpper()[j]<debugValues[j]) {
     5786          printf("** (%g) ** ",debugValues[j]);
     5787          nBad++;
     5788        }
     5789        printf("%d bounds %g %g\n",j,solver_->getColLower()[j],solver_->getColUpper()[j]);
     5790      }
     5791    }
     5792    if (nBad)
     5793      printf("%d BAD\n",nBad);
     5794    else
     5795      printf("OKAY\n");
     5796    delete [] debugValues;
     5797  }
     5798  return false;
     5799#endif
    55135800}
    55145801
     
    55265813  comments there.
    55275814*/
    5528   addCuts1(node,lastws);
     5815#ifdef NODE_LAST
     5816  bool sameProblem=
     5817#endif
     5818    addCuts1(node,lastws);
    55295819  int i;
    55305820  int numberColumns = getNumCols();
     
    56425932      lastws->compressRows(numberToDrop,cutsToDrop) ;
    56435933      lastws->resize(numberRowsNow,numberColumns);
    5644       solver_->applyRowCuts(numberToAdd,addCuts);
     5934#ifdef NODE_LAST
     5935      bool canMissStuff=false;
     5936      bool redoCuts=true;
     5937      if (CoinAbs(lastNumberCuts2_-numberToAdd)<5) {
     5938        int numberToCheck=CoinMin(lastNumberCuts2_,numberToAdd);
     5939        int i1=0;
     5940        int i2=0;
     5941        int nDiff=0;
     5942        int nSame=0;
     5943        if (lastNumberCuts2_==numberToAdd) {
     5944          for (int i=0;i<numberToCheck;i++) {
     5945            if (lastCut_[i1++]!=addCuts[i2++]) {
     5946              nDiff++;
     5947            } else {
     5948              nSame++;
     5949            }
     5950          }
     5951        } else if (lastNumberCuts2_>numberToAdd) {
     5952          int nDiff2 = lastNumberCuts2_-numberToAdd;
     5953          for (int i=0;i<numberToCheck;i++) {
     5954            if (lastCut_[i1]!=addCuts[i2]) {
     5955              nDiff++;
     5956              while (nDiff2) {
     5957                i1++;
     5958                nDiff2--;
     5959                if (lastCut_[i1]==addCuts[i2]) {
     5960                  nSame++;
     5961                  break;
     5962                } else {
     5963                  nDiff++;
     5964                }
     5965              }
     5966            } else {
     5967              nSame++;
     5968            }
     5969          }
     5970          nDiff += nDiff2;
     5971        } else {
     5972          int nDiff2 = numberToAdd-lastNumberCuts2_;
     5973          for (int i=0;i<numberToCheck;i++) {
     5974            if (lastCut_[i1]!=addCuts[i2]) {
     5975              nDiff++;
     5976              while (nDiff2) {
     5977                i2++;
     5978                nDiff2--;
     5979                if (lastCut_[i1]==addCuts[i2]) {
     5980                  nSame++;
     5981                  break;
     5982                } else {
     5983                  nDiff++;
     5984                }
     5985              }
     5986            } else {
     5987              nSame++;
     5988            }
     5989          }
     5990          nDiff += nDiff2;
     5991        }
     5992#ifdef COIN_DEVELOP
     5993        printf("add now %d add last %d - same %d, diff %d %s\n",
     5994             numberToAdd,lastNumberCuts2_,nSame,nDiff,
     5995             !nDiff ? "YES" : "NO1");
     5996#endif
     5997        canMissStuff=!nDiff&&sameProblem;
     5998        // But only if number of rows looks OK
     5999        if (numberRowsAtContinuous_+numberToAdd!=solver_->getNumRows())
     6000          canMissStuff=false;
     6001      } else {
     6002        //printf("add now %d add last %d NO2\n",numberToAdd,lastNumberCuts2_);
     6003      }
     6004      assert (lastws->fullBasis()&&
     6005              numberRowsAtContinuous_+numberToAdd==numberRowsNow);
     6006      if (redoCuts) {
     6007        if (numberToAdd>maximumCuts_) {
     6008          delete [] lastCut_;
     6009          maximumCuts_ = 2*numberToAdd+10;
     6010          lastCut_=new const OsiRowCut * [maximumCuts_];
     6011        }
     6012        lastNumberCuts2_=numberToAdd;
     6013        for (int i=0;i<numberToAdd;i++)
     6014          lastCut_[i]=addCuts[i];
     6015      }
     6016#else
     6017      //solver_->applyRowCuts(numberToAdd,addCuts);
     6018#endif
     6019#ifdef NODE_LAST
     6020      if (!canMissStuff) {
     6021        //if (canMissStuff)
     6022        //solver_->writeMps("before");
     6023        //printf("Not Skipped\n");
     6024        //int n1=solver_->getNumRows();
     6025#endif
     6026        if (numberThreads_<=0) {
     6027          solver_->restoreBaseModel(numberRowsAtContinuous_);
     6028        } else {
     6029          // *** Fix later
     6030          int numberCuts = solver_->getNumRows()-numberRowsAtContinuous_;
     6031          int *which = new int[numberCuts];
     6032          for (i = 0 ; i < numberCuts ; i++)
     6033            which[i] = i+numberRowsAtContinuous_;
     6034          solver_->deleteRows(numberCuts,which);
     6035          delete [] which;
     6036        }
     6037        //int n2=solver_->getNumRows();
     6038        //for (int j=0;j<numberToAdd;j++)
     6039        //addCuts[j]->print();
     6040        solver_->applyRowCuts(numberToAdd,addCuts);
     6041        //int n3=solver_->getNumRows();
     6042        //printf("NBefore %d, after del %d, now %d\n",n1,n2,n3);
     6043#ifdef NODE_LAST
     6044      } else {
     6045#ifdef COIN_HAS_CLP
     6046#ifdef COIN_DEVELOP
     6047        OsiClpSolverInterface * clpSolver
     6048          = dynamic_cast<OsiClpSolverInterface *> (solver_);
     6049        if (clpSolver) {
     6050          printf("Skipped - whatschanged %d\n",clpSolver->getModelPtr()->whatsChanged());
     6051        }
     6052#endif
     6053#endif
     6054      }
     6055#endif
    56456056#     ifdef CBC_CHECK_BASIS
    56466057      printf("addCuts: stripped basis; rows %d + %d\n",
     
    63386749      }
    63396750# endif
    6340       int whenCuts = (continuousSolver_->getNumRows()+continuousSolver_->getNumCols()<=500) ? -1 :0;
    6341       if (parentModel_)
    6342         whenCuts=0;
    63436751      for (i = 0;i<numberCutGenerators_;i++) {
    63446752        int numberRowCutsBefore = theseCuts.sizeRowCuts() ;
     
    63546762        if (generator_[i]->switchedOff())
    63556763          generate=false;;
    6356         if (node&&node->depth()>10&&(node->depth()&1)==whenCuts&&!fullScan) {
     6764        if (!doCutsNow(1)&&!fullScan) {
     6765          //if (node)
     6766          //assert (node->depth()+1==currentDepth_);
     6767          //if (node&&node->depth()>10&&(node->depth()&1)==whenCuts&&!fullScan) {
    63576768          // switch off if default
    63586769          if (generator_[i]->howOften()==1&&generator_[i]->whatDepth()<0)
     
    70207431    if (feasible)
    70217432    { int cutIterations = solver_->getIterationCount() ;
    7022       if (numberOldActiveCuts_+numberNewCuts_) {
     7433      if (numberOldActiveCuts_+numberNewCuts_
     7434#ifdef NODE_LAST
     7435          &&(numberNewCuts_||doCutsNow(1))
     7436#endif
     7437          ) {
    70237438        OsiCuts * saveCuts = node ? NULL : &slackCuts;
     7439#ifdef NODE_LAST
     7440        int nDel=takeOffCuts(cuts,resolveAfterTakeOffCuts_,saveCuts,numberToAdd,addCuts) ;
     7441        if (nDel)
     7442          lastNumberCuts2_=0;
     7443#else
    70247444        takeOffCuts(cuts,resolveAfterTakeOffCuts_,saveCuts,numberToAdd,addCuts) ;
     7445#endif
    70257446        if (solver_->isDualObjectiveLimitReached()&&resolveAfterTakeOffCuts_)
    70267447          { feasible = false ;
     
    72617682      if (thisObjective-startObjective<1.0e-5&&numberElementsAdded>0.2*numberElementsAtStart)
    72627683        willBeCutsInTree=-1;
     7684      int whenC=whenCuts_;
     7685      if (whenC==999999|whenC==999998) {
     7686        int size = continuousSolver_->getNumRows()+continuousSolver_->getNumCols();
     7687        bool small = size<=550;
     7688        small=false;
     7689#ifdef CLP_INVESTIGATE
     7690        int maxPass=maximumCutPasses_;
     7691#endif
     7692        if (thisObjective-startObjective<1.0e-5) {
     7693          // No change in objective function
     7694          if(numberElementsAdded>0.2*numberElementsAtStart) {
     7695            if (whenCuts_==999999) {
     7696              whenCuts_=5000010;
     7697              if (!small)
     7698                maximumCutPasses_=CoinMax(maximumCutPasses_>>1,1);
     7699            } else if (whenCuts_==999998) {
     7700              whenCuts_=5000010;
     7701              if (!small)
     7702                maximumCutPasses_=CoinMax(maximumCutPasses_>>1,1);
     7703            }
     7704#if 0
     7705          } else if (currentPassNumber_<CoinMin(CoinAbs(maximumCutPassesAtRoot_),8)) {
     7706            if (whenCuts_==999999) {
     7707              whenCuts_=8000008;
     7708              maximumCutPasses_=1;
     7709            } else if (whenCuts_==999998) {
     7710              whenCuts_=10000008;
     7711              maximumCutPasses_=1;
     7712            }
     7713          } else if (currentPassNumber_<CoinMin(CoinAbs(maximumCutPassesAtRoot_),50)) {
     7714            if (whenCuts_==999999) {
     7715              whenCuts_=8000008;
     7716              maximumCutPasses_=1;
     7717            } else if (whenCuts_==999998) {
     7718              whenCuts_=10000006;
     7719              maximumCutPasses_=1;
     7720            }
     7721          } else if (currentPassNumber_<CoinAbs(maximumCutPassesAtRoot_)) {
     7722            if (whenCuts_==999999) {
     7723              whenCuts_=8000008;
     7724              maximumCutPasses_=1;
     7725            } else if (whenCuts_==999998) {
     7726              whenCuts_=10000004;
     7727              maximumCutPasses_=1;
     7728            }
     7729#endif
     7730          } else {
     7731            if (whenCuts_==999999) {
     7732              whenCuts_=8000008;
     7733              if (!small)
     7734                maximumCutPasses_=CoinMax(maximumCutPasses_>>1,1);
     7735            } else if (whenCuts_==999998) {
     7736              whenCuts_=10000004;
     7737              if (!small)
     7738                maximumCutPasses_=CoinMax(maximumCutPasses_>>1,1);
     7739            }
     7740          }
     7741        } else {
     7742          // Objective changed
     7743#if 0
     7744          if (currentPassNumber_<CoinMin(CoinAbs(maximumCutPassesAtRoot_),8)) {
     7745            if (whenCuts_==999999) {
     7746              whenCuts_=8000008;
     7747              maximumCutPasses_=1;
     7748            } else if (whenCuts_==999998) {
     7749              whenCuts_=10000008;
     7750              maximumCutPasses_=1;
     7751            }
     7752          } else if (currentPassNumber_<CoinMin(CoinAbs(maximumCutPassesAtRoot_),50)) {
     7753            if (whenCuts_==999999) {
     7754              whenCuts_=8000008;
     7755              maximumCutPasses_=1;
     7756            } else if (whenCuts_==999998) {
     7757              whenCuts_=10000004;
     7758              maximumCutPasses_=1;
     7759            }
     7760          } else
     7761#endif
     7762          if (currentPassNumber_<CoinAbs(maximumCutPassesAtRoot_)) {
     7763            if (whenCuts_==999999) {
     7764              whenCuts_=8000008;
     7765              if (!small)
     7766                maximumCutPasses_=CoinMax(maximumCutPasses_>>1,1);
     7767            } else if (whenCuts_==999998) {
     7768              whenCuts_=10000004;
     7769              if (!small)
     7770                maximumCutPasses_=CoinMax(maximumCutPasses_>>1,1);
     7771            }
     7772          } else {
     7773            if (whenCuts_==999999) {
     7774              whenCuts_=10000004;
     7775              maximumCutPasses_=CoinMax(maximumCutPasses_,2);
     7776            } else if (whenCuts_==999998) {
     7777              whenCuts_=11000002;
     7778              maximumCutPasses_=CoinMax(maximumCutPasses_,2);
     7779            }
     7780          }
     7781        }
     7782        //// end
     7783#ifdef CLP_INVESTIGATE
     7784        printf("changing whenCuts from %d to %d and cutPasses from %d to %d objchange %g\n",
     7785               whenC,whenCuts_,maxPass,maximumCutPasses_,thisObjective-startObjective);
     7786#endif
     7787      }
    72637788    }
    72647789    if ((numberRowsAdded>100+0.5*numberRowsAtStart
     
    76348159*/
    76358160
    7636 void
     8161int
    76378162CbcModel::takeOffCuts (OsiCuts &newCuts,
    76388163                       bool allowResolve, OsiCuts * saveCuts,
     
    76408165
    76418166{ // int resolveIterations = 0 ;
     8167  int numberDropped=0;
    76428168  int firstOldCut = numberRowsAtContinuous_ ;
    76438169  int totalNumberCuts = numberNewCuts_+numberOldActiveCuts_ ;
     
    77588284      solver_->deleteRows(numberTotalToDelete,
    77598285                            solverCutIndices) ;
     8286      numberDropped+= numberTotalToDelete;
    77608287      numberNewCuts_ -= numberNewToDelete ;
    77618288      assert (numberNewCuts_==newCuts.sizeRowCuts());
     
    77918318  delete [] solverCutIndices ;
    77928319  delete [] newCutIndices ;
     8320  return numberDropped;
    77938321}
    7794 
    7795 
    77968322
    77978323int
     
    1054611072        delete [] walkback_;
    1054711073        walkback_ = new CbcNodeInfo * [maximumDepth_];
     11074#ifdef NODE_LAST
     11075        lastDepth_=0;
     11076        delete [] lastNodeInfo_ ;
     11077        lastNodeInfo_ = new CbcNodeInfo * [maximumDepth_] ;
     11078        delete [] lastNumberCuts_ ;
     11079        lastNumberCuts_ = new int [maximumDepth_] ;
     11080        maximumCuts_ = 100;
     11081        delete [] lastCut_;
     11082        lastCut_ = new const OsiRowCut * [maximumCuts_];
     11083#endif
    1054811084       
    1054911085        OsiCuts cuts;
     
    1114511681  delete [] walkback_ ;
    1114611682  walkback_ = NULL ;
     11683#ifdef NODE_LAST
     11684  delete [] lastNodeInfo_ ;
     11685  lastNodeInfo_ = NULL;
     11686  delete [] lastNumberCuts_ ;
     11687  lastNumberCuts_ = NULL;
     11688  delete [] lastCut_;
     11689  lastCut_ = NULL;
     11690#endif
    1114711691  delete [] addedCuts_ ;
    1114811692  addedCuts_ = NULL ;
     
    1241112955  maximumDepth_ = baseModel->maximumDepth_;
    1241212956  walkback_ = baseModel->walkback_;
     12957#ifdef NODE_LAST
     12958  lastNodeInfo_ = baseModel->lastNodeInfo_;
     12959  lastNumberCuts_ = baseModel->lastNumberCuts_;
     12960  lastCut_ = baseModel->lastCut_;
     12961  lastNumberCuts2_ = baseModel->lastNumberCuts2_;
     12962#endif
    1241312963#endif
    1241412964#ifndef CBC_DETERMINISTIC_THREAD
     
    1242612976    baseModel->maximumDepth_ = maximumDepth_;
    1242712977    baseModel->walkback_ = walkback_;
     12978#ifdef NODE_LAST
     12979    baseModel->lastNodeInfo_ = lastNodeInfo_;
     12980    baseModel->lastNumberCuts_ = lastNumberCuts_;
     12981    baseModel->lastCut_ = lastCut_;
     12982    baseModel->lastNumberCuts2_ = lastNumberCuts2_;
     12983#endif
    1242812984  }
    1242912985#endif
     
    1341113967        //while (nodeInfo&&!nodeInfo->marked()) {
    1341213968          if (nAffected==maximumDepth_) {
    13413             maximumDepth_ *= 2;
    13414             CbcNodeInfo ** temp = new CbcNodeInfo * [maximumDepth_];
    13415             for (i=0;i<nAffected;i++)
    13416               temp[i] = walkback_[i];
    13417             delete [] walkback_;
    13418             walkback_ = temp;
     13969            redoWalkBack();
    1341913970          }
    1342013971          nodeInfo->mark();
     
    1357914130#ifndef CBC_DETERMINISTIC_THREAD
    1358014131    walkback_ = NULL;
     14132#ifdef NODE_LAST
     14133    lastNodeInfo_ = NULL;
     14134    lastNumberCuts_ = NULL;
     14135    lastCut_ = NULL;
     14136#endif
    1358114137    //addedCuts_ = NULL;
    1358214138    tree_ = NULL;
     
    1361014166    walkback_ = NULL;
    1361114167    //addedCuts_ = NULL;
     14168#ifdef NODE_LAST
     14169    delete [] lastNodeInfo_ ;
     14170    lastNodeInfo_ = NULL;
     14171    delete [] lastNumberCuts_ ;
     14172    lastNumberCuts_ = NULL;
     14173    delete [] lastCut_ ;
     14174    lastCut_ = NULL;
     14175#endif
    1361214176    delete tree_;
    1361314177    tree_ = NULL;
     
    1412714691    nodeInfo = nodeInfo->parent() ;
    1412814692    if (nNode==maximumDepth_) {
    14129       maximumDepth_ *= 2;
    14130       CbcNodeInfo ** temp = new CbcNodeInfo * [maximumDepth_];
    14131       for (i=0;i<nNode;i++)
    14132         temp[i] = walkback_[i];
    14133       delete [] walkback_;
    14134       walkback_ = temp;
     14693      redoWalkBack();
    1413514694    }
    1413614695    if (nodeInfo==where)
     
    1422114780  delete [] back;
    1422214781}
     14782// Redo walkback arrays
     14783void
     14784CbcModel::redoWalkBack()
     14785{
     14786  int nNode = maximumDepth_;
     14787  maximumDepth_ *= 2;
     14788  CbcNodeInfo ** temp = new CbcNodeInfo * [maximumDepth_];
     14789#ifdef NODE_LAST
     14790  CbcNodeInfo ** temp2 = new CbcNodeInfo * [maximumDepth_];
     14791  int * temp3 = new int [maximumDepth_];
     14792#endif
     14793  for (int i=0;i<nNode;i++) {
     14794    temp[i] = walkback_[i];
     14795#ifdef NODE_LAST
     14796    temp2[i] = lastNodeInfo_[i];
     14797    temp3[i] = lastNumberCuts_[i];
     14798#endif
     14799  }
     14800  delete [] walkback_;
     14801  walkback_ = temp;
     14802#ifdef NODE_LAST
     14803  delete [] lastNodeInfo_ ;
     14804  lastNodeInfo_ = temp2;
     14805  delete [] lastNumberCuts_ ;
     14806  lastNumberCuts_ = temp3;
     14807#endif
     14808}
     14809/* Return true if we want to do cuts
     14810   If allowForTopOfTree zero then just does on multiples of depth
     14811   if 1 then allows for doing at top of tree
     14812   if 2 then says if cuts allowed anywhere apart from root
     14813   if 3 then gives smallest valid depth >shallow
     14814*/
     14815bool
     14816CbcModel::doCutsNow(int allowForTopOfTree) const
     14817{
     14818  int size = continuousSolver_->getNumRows()+continuousSolver_->getNumCols();
     14819
     14820  if (whenCuts_<0||size<=500) {
     14821    int whenCuts = (size<=500) ? -1 :1;
     14822    if (parentModel_)
     14823      whenCuts=1;
     14824    //int nodeDepth = currentDepth_-1;
     14825    bool doCuts2 =  !(currentDepth_>11&&(currentDepth_&1)==whenCuts);
     14826    //printf("when %d node %d depth %d size %d doing cuts %s\n",whenCuts_,
     14827    //   numberNodes_,currentDepth_,size,doCuts2 ? "yes" : "no");
     14828    return doCuts2;
     14829  }
     14830  //if (!parentModel_&&currentDepth_==7)
     14831  //printf("q\n");
     14832  int top=whenCuts_/1000000;
     14833  int shallow = top ? (top-1) : 9;
     14834  int when = whenCuts_ -1000000*top;
     14835  if ((when>15||(top&&top<5))&&currentDepth_>when)
     14836    when=100000; // off
     14837  bool doCuts =when ? ((currentDepth_%when)==0)||(when==1) : false;
     14838  if (allowForTopOfTree==1&&currentDepth_<=shallow) {
     14839    doCuts=true;
     14840  } else if (allowForTopOfTree==2&&shallow>=1) {
     14841    doCuts=true;
     14842  } else if (allowForTopOfTree==3&&doCuts) {
     14843    // only if first
     14844    if(currentDepth_<=shallow||currentDepth_-when>shallow)
     14845      doCuts=false;
     14846  }
     14847  //if (!doCuts&&currentDepth_&&!parentModel_)
     14848  //printf("zzz\n");
     14849  return doCuts;
     14850}
  • trunk/Cbc/src/CbcModel.hpp

    r1013 r1015  
    16581658    If saveCuts then slack cuts will be saved
    16591659    On input current cuts are cuts and newCuts
    1660     on exit current cuts will be correct
    1661   */
    1662   void takeOffCuts(OsiCuts &cuts,
     1660    on exit current cuts will be correct.  Returns number dropped
     1661  */
     1662  int takeOffCuts(OsiCuts &cuts,
    16631663                   bool allowResolve,OsiCuts * saveCuts,
    16641664                   int numberNewCuts=0, const OsiRowCut ** newCuts=NULL) ;
     
    16881688    accommodate them) is constructed.
    16891689
     1690    Returns true if new problem similar to old
     1691
    16901692    \todo addCuts1() is called in contexts where it's known in advance that
    16911693          all that's desired is to determine a list of cuts and do the
     
    16931695          bounds and building a basis goes to waste.
    16941696  */
    1695   void addCuts1(CbcNode * node, CoinWarmStartBasis *&lastws);
     1697  bool addCuts1(CbcNode * node, CoinWarmStartBasis *&lastws);
    16961698  /** Returns bounds just before where - initially original bounds.
    16971699      Also sets downstream nodes (lower if force 1, upper if 2)
     
    18071809  inline void setBestSolutionBasis(const CoinWarmStartBasis & bestSolutionBasis)
    18081810  { bestSolutionBasis_ = bestSolutionBasis;}
     1811  /// Redo walkback arrays
     1812  void redoWalkBack();
    18091813  //@}
    18101814
     
    19611965  */
    19621966  CbcNodeInfo ** walkback_;
     1967  //#define NODE_LAST
     1968#ifdef NODE_LAST
     1969  CbcNodeInfo ** lastNodeInfo_;
     1970  const OsiRowCut ** lastCut_;
     1971  int lastDepth_;
     1972  int lastNumberCuts2_;
     1973  int maximumCuts_;
     1974  int * lastNumberCuts_;
     1975#endif
    19631976
    19641977  /** The list of cuts initially collected for this subproblem
  • trunk/Cbc/src/CbcSolver.cpp

    r1013 r1015  
    63216321                }
    63226322                if (cutPassInTree==-1234567)
    6323                   babModel_->setMaximumCutPasses(1);
     6323                  babModel_->setMaximumCutPasses(2);
    63246324                else
    63256325                  babModel_->setMaximumCutPasses(cutPassInTree);
     
    64416441                }
    64426442              }
     6443              {
     6444                int extra1 = parameters_[whichParam(EXTRA1,numberParameters_,parameters_)].intValue();
     6445                if (extra1!=-1) {
     6446                  if (extra1<0) {
     6447                    if (extra1==-7777)
     6448                      extra1=-1;
     6449                    babModel_->setWhenCuts(-extra1);
     6450                  } else if (extra1<19000) {
     6451                    babModel_->setSearchStrategy(extra1);
     6452                    printf("XXXXX searchStrategy %d\n",extra1);
     6453                  } else {
     6454                    int n=extra1-20000;
     6455                    if (!n)
     6456                      n--;
     6457                    babModel_->setNumberAnalyzeIterations(n);
     6458                    printf("XXXXX analyze %d\n",extra1);
     6459                  }
     6460                }
     6461              }
    64436462              if (type==BAB) {
    64446463#if NEW_STYLE_SOLVER
     
    74277446                if (denseCode>=lpSolver->numberRows()) {
    74287447                  lpSolver->factorization()->goDense();
    7429                 }
    7430                 {
    7431                   int extra1 = parameters_[whichParam(EXTRA1,numberParameters_,parameters_)].intValue();
    7432                   if (extra1!=-1) {
    7433                     if (extra1<19000) {
    7434                       babModel_->setSearchStrategy(extra1);
    7435                       printf("XXXXX searchStrategy %d\n",extra1);
    7436                     } else {
    7437                       int n=extra1-20000;
    7438                       if (!n)
    7439                         n--;
    7440                       babModel_->setNumberAnalyzeIterations(n);
    7441                       printf("XXXXX analyze %d\n",extra1);
    7442                     }
    7443                   }
    74447448                }
    74457449#ifdef CLIQUE_ANALYSIS
Note: See TracChangeset for help on using the changeset viewer.