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

add ifdefs for future exploration

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.