Changeset 940


Ignore:
Timestamp:
May 14, 2008 7:55:20 AM (11 years ago)
Author:
forrest
Message:

for my experiments

Location:
trunk/Cbc/src
Files:
7 edited

Legend:

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

    r931 r940  
    2626#include "OsiPresolve.hpp"
    2727#include "CbcBranchActual.hpp"
     28#include "CbcCutGenerator.hpp"
    2829//==============================================================================
    2930
     
    109110  runNodes_(),
    110111  numCouldRun_(0),
    111   numberSolutionsFound_(0)
     112  numberSolutionsFound_(0),
     113  inputSolution_(NULL)
    112114{
    113115  // As CbcHeuristic virtual need to modify .cpp if above change
     
    133135  runNodes_(),
    134136  numCouldRun_(0),
    135   numberSolutionsFound_(0)
     137  numberSolutionsFound_(0),
     138  inputSolution_(NULL)
    136139{}
    137140
     
    158161  runNodes_ = rhs.runNodes_;
    159162  numberSolutionsFound_ = rhs.numberSolutionsFound_;
     163  if (rhs.inputSolution_) {
     164    int numberColumns = model_->getNumCols();
     165    setInputSolution(rhs.inputSolution_,rhs.inputSolution_[numberColumns]);
     166  }
    160167}
    161168// Copy constructor
    162169CbcHeuristic::CbcHeuristic(const CbcHeuristic & rhs)
    163170{
     171  inputSolution_ = NULL;
    164172  gutsOfCopy(rhs);
    165173}
     
    509517      delete presolvedModel;
    510518      double after = 2*afterRows+afterCols;
    511       if (after>fractionSmall*before&&after>300) {
     519      if (after>fractionSmall*before&&after>300&&numberNodes>=0) {
    512520        // Need code to try again to compress further using used
    513521        const int * used =  model_->usedInSolution();
     
    561569            delete presolvedModel;
    562570            double after = 2*afterRows2+afterCols2;
    563             if (after>fractionSmall*before&&after>300) {
     571            if (after>fractionSmall*before&&(after>300||numberNodes<0)) {
    564572              sprintf(generalPrint,"Full problem %d rows %d columns, reduced to %d rows %d columns - %d fixed gives %d, %d - still too large",
    565573                      solver->getNumRows(),solver->getNumCols(),
     
    613621      //double before = 2*solver->getNumRows()+solver->getNumCols();
    614622      double after = 2*solver2->getNumRows()+solver2->getNumCols();
    615       if (after>fractionSmall*before&&after>300) {
     623      if (after>fractionSmall*before&&(after>300||numberNodes<0)) {
    616624        sprintf(generalPrint,"Full problem %d rows %d columns, reduced to %d rows %d columns - too large",
    617625                solver->getNumRows(),solver->getNumCols(),
     
    632640        solver2->resolve();
    633641        CbcModel model(*solver2);
    634         if (logLevel<=1)
    635           model.setLogLevel(0);
    636         else
    637           model.setLogLevel(logLevel);
    638         if (feasibilityPumpOptions_>=0) {
    639           CbcHeuristicFPump heuristic4;
    640           int pumpTune=feasibilityPumpOptions_;
    641           if (pumpTune>0) {
    642             /*
    643               >=10000000 for using obj
    644               >=1000000 use as accumulate switch
    645               >=1000 use index+1 as number of large loops
    646               >=100 use 0.05 objvalue as increment
    647               >=10 use +0.1 objvalue for cutoff (add)
    648               1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds
    649               4 and static continuous, 5 as 3 but no internal integers
    650               6 as 3 but all slack basis!
    651             */
    652             double value = solver2->getObjSense()*solver2->getObjValue();
    653             int w = pumpTune/10;
    654             int c = w % 10;
    655             w /= 10;
    656             int i = w % 10;
    657             w /= 10;
    658             int r = w;
    659             int accumulate = r/1000;
    660             r -= 1000*accumulate;
    661             if (accumulate>=10) {
    662               int which = accumulate/10;
    663               accumulate -= 10*which;
    664               which--;
    665               // weights and factors
    666               double weight[]={0.1,0.1,0.5,0.5,1.0,1.0,5.0,5.0};
    667               double factor[] = {0.1,0.5,0.1,0.5,0.1,0.5,0.1,0.5};
    668               heuristic4.setInitialWeight(weight[which]);
    669               heuristic4.setWeightFactor(factor[which]);
     642        if (numberNodes>=0) {
     643          // normal
     644          if (logLevel<=1)
     645            model.setLogLevel(0);
     646          else
     647            model.setLogLevel(logLevel);
     648          // No small fathoming
     649          model.setFastNodeDepth(-1);
     650          model.setCutoff(cutoff);
     651          model.setMaximumNodes(numberNodes);
     652          model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
     653          // Lightweight
     654          CbcStrategyDefaultSubTree strategy(model_,true,5,1,0);
     655          model.setStrategy(strategy);
     656          model.solver()->setIntParam(OsiMaxNumIterationHotStart,10);
     657          model.setMaximumCutPassesAtRoot(CoinMin(20,model_->getMaximumCutPassesAtRoot()));
     658        } else {
     659          // going for full search and copy across more stuff
     660          model.gutsOfCopy(*model_,2);
     661          for (int i=0;i<model.numberCutGenerators();i++)
     662            model.cutGenerator(i)->setTiming(true);
     663          model.setCutoff(cutoff);
     664          bool takeHint;
     665          OsiHintStrength strength;
     666          // Switch off printing if asked to
     667          model_->solver()->getHintParam(OsiDoReducePrint,takeHint,strength);
     668          model.solver()->setHintParam(OsiDoReducePrint,takeHint,strength);
     669          CbcStrategyDefault strategy(true,model_->numberStrong(),
     670                                      model_->numberBeforeTrust());
     671          // Set up pre-processing - no
     672          strategy.setupPreProcessing(0); // was (4);
     673          model.setStrategy(strategy);
     674        }
     675        if (inputSolution_) {
     676          // translate and add a serendipity heuristic
     677          int numberColumns = solver2->getNumCols();
     678          const int * which = process.originalColumns();
     679          OsiSolverInterface * solver3 = solver2->clone();
     680          for (int i=0;i<numberColumns;i++) {
     681            if (solver3->isInteger(i)) {
     682              int k=which[i];
     683              double value = inputSolution_[k];
     684              solver3->setColLower(i,value);
     685              solver3->setColUpper(i,value);
    670686            }
    671             // fake cutoff
    672             if (c) {
    673               double cutoff;
    674               solver2->getDblParam(OsiDualObjectiveLimit,cutoff);
    675               cutoff = CoinMin(cutoff,value + 0.1*fabs(value)*c);
    676               heuristic4.setFakeCutoff(cutoff);
    677             }
    678             if (i||r) {
    679               // also set increment
    680               //double increment = (0.01*i+0.005)*(fabs(value)+1.0e-12);
    681               double increment = 0.0;
    682               heuristic4.setAbsoluteIncrement(increment);
    683               heuristic4.setAccumulate(accumulate);
    684               heuristic4.setMaximumRetries(r+1);
    685             }
    686             pumpTune = pumpTune%100;
    687             if (pumpTune==6)
    688               pumpTune =13;
    689             heuristic4.setWhen(pumpTune+10);
    690687          }
    691           heuristic4.setHeuristicName("feasibility pump");
    692           model.addHeuristic(&heuristic4);
     688          solver3->setDblParam(OsiDualObjectiveLimit,COIN_DBL_MAX);
     689          solver3->resolve();
     690          if (solver3->isProvenOptimal()) {
     691            // good
     692            CbcSerendipity heuristic(model);
     693            double value = solver3->getObjSense()*solver3->getObjValue();
     694            heuristic.setInputSolution(solver3->getColSolution(),value);
     695            model.setCutoff(value+1.0e-7*(1.0+fabs(value)));
     696            model.addHeuristic(&heuristic,"previous solution");
     697          }
     698          delete solver3;
    693699        }
    694         model.setCutoff(cutoff);
    695         model.setMaximumNodes(numberNodes);
    696         model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
    697         // Lightweight
    698         CbcStrategyDefaultSubTree strategy(model_,true,5,1,0);
    699         model.setStrategy(strategy);
    700         model.solver()->setIntParam(OsiMaxNumIterationHotStart,10);
    701700        // Do search
    702701        if (logLevel>1)
     
    716715        }
    717716#endif
    718         model.setMaximumCutPassesAtRoot(CoinMin(20,model_->getMaximumCutPassesAtRoot()));
    719717        model.setParentModel(*model_);
    720718        model.setOriginalColumns(process.originalColumns());
    721719        model.setSearchStrategy(-1);
     720        // If no feasibility pump then insert a lightweight one
     721        if (feasibilityPumpOptions_>=0) {
     722          bool gotPump=false;
     723          for (int i=0;i<model.numberHeuristics();i++) {
     724            const CbcHeuristicFPump* pump =
     725              dynamic_cast<const CbcHeuristicFPump*>(model_->heuristic(i));
     726            if (pump)
     727              gotPump=true;
     728          }
     729          if (!gotPump) {
     730            CbcHeuristicFPump heuristic4;
     731            int pumpTune=feasibilityPumpOptions_;
     732            if (pumpTune>0) {
     733              /*
     734                >=10000000 for using obj
     735                >=1000000 use as accumulate switch
     736                >=1000 use index+1 as number of large loops
     737                >=100 use 0.05 objvalue as increment
     738                >=10 use +0.1 objvalue for cutoff (add)
     739                1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds
     740                4 and static continuous, 5 as 3 but no internal integers
     741                6 as 3 but all slack basis!
     742              */
     743              double value = solver2->getObjSense()*solver2->getObjValue();
     744              int w = pumpTune/10;
     745              int c = w % 10;
     746              w /= 10;
     747              int i = w % 10;
     748              w /= 10;
     749              int r = w;
     750              int accumulate = r/1000;
     751              r -= 1000*accumulate;
     752              if (accumulate>=10) {
     753                int which = accumulate/10;
     754                accumulate -= 10*which;
     755                which--;
     756                // weights and factors
     757                double weight[]={0.1,0.1,0.5,0.5,1.0,1.0,5.0,5.0};
     758                double factor[] = {0.1,0.5,0.1,0.5,0.1,0.5,0.1,0.5};
     759                heuristic4.setInitialWeight(weight[which]);
     760                heuristic4.setWeightFactor(factor[which]);
     761              }
     762              // fake cutoff
     763              if (c) {
     764                double cutoff;
     765                solver2->getDblParam(OsiDualObjectiveLimit,cutoff);
     766                cutoff = CoinMin(cutoff,value + 0.1*fabs(value)*c);
     767                heuristic4.setFakeCutoff(cutoff);
     768              }
     769              if (i||r) {
     770                // also set increment
     771                //double increment = (0.01*i+0.005)*(fabs(value)+1.0e-12);
     772                double increment = 0.0;
     773                heuristic4.setAbsoluteIncrement(increment);
     774                heuristic4.setAccumulate(accumulate);
     775                heuristic4.setMaximumRetries(r+1);
     776              }
     777              pumpTune = pumpTune%100;
     778              if (pumpTune==6)
     779                pumpTune =13;
     780              heuristic4.setWhen(pumpTune+10);
     781            }
     782            model.addHeuristic(&heuristic4,"feasibility pump",0);
     783          }
     784        }
    722785        if (model_->searchStrategy()==2) {
    723786          model.setNumberStrong(5);
     
    725788        }
    726789        if (model.getNumCols()) {
    727           setCutAndHeuristicOptions(model);
     790          if (numberNodes>=0)
     791            setCutAndHeuristicOptions(model);
    728792          model.branchAndBound();
     793          if (numberNodes<0) {
     794            for (int iGenerator=0;iGenerator<model.numberCutGenerators();iGenerator++) {
     795              CbcCutGenerator * generator = model.cutGenerator(iGenerator);
     796              printf("%s was tried %d times and created %d cuts of which %d were active after adding rounds of cuts",
     797                      generator->cutGeneratorName(),
     798                      generator->numberTimesEntered(),
     799                      generator->numberCutsInTotal()+
     800                      generator->numberColumnCuts(),
     801                      generator->numberCutsActive());
     802              printf(" (%.3f seconds)\n)",generator->timeInCutGenerator());
     803            }
     804          }
    729805        } else {
    730806          // empty model
     
    794870  solver->setHintParam(OsiDoReducePrint,takeHint,strength);
    795871  return returnCode;
     872}
     873// Set input solution
     874void
     875CbcHeuristic::setInputSolution(const double * solution, double objValue)
     876{
     877  delete [] inputSolution_;
     878  inputSolution_=NULL;
     879  if (model_&&solution) {
     880    int numberColumns = model_->getNumCols();
     881    inputSolution_ = new double [numberColumns+1];
     882    memcpy(inputSolution_,solution,numberColumns*sizeof(double));
     883    inputSolution_[numberColumns]=objValue;
     884  }
    796885}
    797886
     
    19001989  if (model_&&when()<10) {
    19011990    if (model_->numberIntegers()!=
    1902         model_->numberObjects())
     1991        model_->numberObjects()&&(model_->numberObjects()||
     1992                                  (model_->specialOptions()&1024)==0))
    19031993      setWhen(0);
    19041994  }
     
    21682258  if (!model_)
    21692259    return 0;
    2170   // get information on solver type
    2171   OsiAuxInfo * auxInfo = model_->solver()->getAuxiliaryInfo();
    2172   OsiBabSolver * auxiliaryInfo = dynamic_cast< OsiBabSolver *> (auxInfo);
    2173   if (auxiliaryInfo)
    2174     return auxiliaryInfo->solution(solutionValue,betterSolution,model_->solver()->getNumCols());
    2175   else
    2176     return 0;
     2260  if (!inputSolution_) {
     2261    // get information on solver type
     2262    OsiAuxInfo * auxInfo = model_->solver()->getAuxiliaryInfo();
     2263    OsiBabSolver * auxiliaryInfo = dynamic_cast< OsiBabSolver *> (auxInfo);
     2264    if (auxiliaryInfo) {
     2265      return auxiliaryInfo->solution(solutionValue,betterSolution,model_->solver()->getNumCols());
     2266    } else {
     2267      return 0;
     2268    }
     2269  } else {
     2270    int numberColumns = model_->getNumCols();
     2271    double value =inputSolution_[numberColumns];
     2272    int returnCode=0;
     2273    if (value<solutionValue) {
     2274      solutionValue = value;
     2275      memcpy(betterSolution,inputSolution_,numberColumns*sizeof(double));
     2276      returnCode=1;
     2277    }
     2278    delete [] inputSolution_;
     2279    inputSolution_=NULL;
     2280    model_ = NULL; // switch off
     2281    return returnCode;
     2282  }
    21772283}
    21782284// update model
  • trunk/Cbc/src/CbcHeuristic.hpp

    r931 r940  
    184184  /// Set random number generator seed
    185185  void setSeed(int value);
     186  /// Set input solution
     187  void setInputSolution(const double * solution, double objValue);
    186188
    187189  /** Check whether the heuristic should run */
     
    252254  int numberSolutionsFound_;
    253255
     256  // Input solution - so can be used as seed
     257  double * inputSolution_;
     258
    254259
    255260#if 0
  • trunk/Cbc/src/CbcModel.cpp

    r937 r940  
    47924792  dblParam_[CbcCurrentMinimizationObjectiveValue] = 1.0e100;
    47934793}
     4794/* Most of copy constructor
     4795      mode - 0 copy but don't delete before
     4796             1 copy and delete before
     4797             2 copy and delete before (but use virgin generators)
     4798*/
     4799void
     4800CbcModel::gutsOfCopy(const CbcModel & rhs,int mode)
     4801{
     4802  minimumDrop_ = rhs.minimumDrop_;
     4803  specialOptions_ = rhs.specialOptions_;
     4804  numberStrong_ = rhs.numberStrong_;
     4805  numberBeforeTrust_ = rhs.numberBeforeTrust_;
     4806  numberPenalties_ = rhs.numberPenalties_;
     4807  printFrequency_ = rhs.printFrequency_;
     4808# ifdef COIN_HAS_CLP
     4809  fastNodeDepth_ = rhs.fastNodeDepth_;
     4810#endif
     4811  howOftenGlobalScan_ = rhs.howOftenGlobalScan_;
     4812  maximumCutPassesAtRoot_ = rhs.maximumCutPassesAtRoot_;
     4813  maximumCutPasses_ =  rhs.maximumCutPasses_;
     4814  preferredWay_ = rhs.preferredWay_;
     4815  resolveAfterTakeOffCuts_ = rhs.resolveAfterTakeOffCuts_;
     4816  numberThreads_ = rhs.numberThreads_;
     4817  threadMode_ = rhs.threadMode_;
     4818  memcpy(intParam_,rhs.intParam_,sizeof(intParam_));
     4819  memcpy(dblParam_,rhs.dblParam_,sizeof(dblParam_));
     4820  int i;
     4821  if (mode) {
     4822    for (i=0;i<numberCutGenerators_;i++) {
     4823      delete generator_[i];
     4824      delete virginGenerator_[i];
     4825    }
     4826    delete [] generator_;
     4827    delete [] virginGenerator_;
     4828    for (i=0;i<numberHeuristics_;i++) {
     4829      delete heuristic_[i];
     4830    }
     4831    delete [] heuristic_;
     4832    delete eventHandler_;
     4833    delete branchingMethod_;
     4834  }
     4835  numberCutGenerators_ = rhs.numberCutGenerators_;
     4836  if (numberCutGenerators_) {
     4837    generator_ = new CbcCutGenerator * [numberCutGenerators_];
     4838    virginGenerator_ = new CbcCutGenerator * [numberCutGenerators_];
     4839    int i;
     4840    for (i=0;i<numberCutGenerators_;i++) {
     4841      if (mode<2)
     4842        generator_[i]=new CbcCutGenerator(*rhs.generator_[i]);
     4843      else
     4844        generator_[i]=new CbcCutGenerator(*rhs.virginGenerator_[i]);
     4845      virginGenerator_[i]=new CbcCutGenerator(*rhs.virginGenerator_[i]);
     4846    }
     4847  } else {
     4848    generator_=NULL;
     4849    virginGenerator_=NULL;
     4850  }
     4851  numberHeuristics_ = rhs.numberHeuristics_;
     4852  if (numberHeuristics_) {
     4853    heuristic_ = new CbcHeuristic * [numberHeuristics_];
     4854    int i;
     4855    for (i=0;i<numberHeuristics_;i++) {
     4856      heuristic_[i]=rhs.heuristic_[i]->clone();
     4857    }
     4858  } else {
     4859    heuristic_=NULL;
     4860  }
     4861  if (rhs.eventHandler_)
     4862    eventHandler_ = rhs.eventHandler_->clone() ;
     4863  else
     4864    eventHandler_ = NULL ;
     4865  if (rhs.branchingMethod_)
     4866    branchingMethod_=rhs.branchingMethod_->clone();
     4867  else
     4868    branchingMethod_=NULL;
     4869  messageHandler()->setLogLevel(rhs.messageHandler()->logLevel());
     4870  synchronizeModel();
     4871}
    47944872// Move status, nodes etc etc across
    47954873void
     
    49895067// Add one heuristic
    49905068void
    4991 CbcModel::addHeuristic(CbcHeuristic * generator, const char *name)
     5069CbcModel::addHeuristic(CbcHeuristic * generator, const char *name,
     5070                       int before)
    49925071{
    49935072  CbcHeuristic ** temp = heuristic_;
     
    49955074  memcpy(heuristic_,temp,numberHeuristics_*sizeof(CbcHeuristic *));
    49965075  delete [] temp;
    4997   heuristic_[numberHeuristics_]=generator->clone();
     5076  int where;
     5077  if (before<0||before>=numberHeuristics_) {
     5078    where=numberHeuristics_;
     5079  } else {
     5080    // move up
     5081    for (int i=numberHeuristics_;i>before;i--)
     5082      heuristic_[i]=heuristic_[i-1];
     5083    where=before;
     5084  }
     5085  heuristic_[where]=generator->clone();
    49985086  if (name)
    4999   { heuristic_[numberHeuristics_]->setHeuristicName(name) ; }
    5000   heuristic_[numberHeuristics_]->setSeed(987654321+numberHeuristics_);
     5087    heuristic_[where]->setHeuristicName(name) ;
     5088  heuristic_[where]->setSeed(987654321+where);
    50015089  numberHeuristics_++ ;
    50025090}
     
    1150711595}
    1150811596void
    11509 CbcModel::setBestSolution(const double * solution,int numberColumns,double objectiveValue)
     11597CbcModel::setBestSolution(const double * solution,int numberColumns,
     11598                          double objectiveValue, bool checkSolution)
    1151011599{
     11600  // May be odd discontinuities - so only chaeck if asked
     11601  if (checkSolution) {
     11602    assert (numberColumns==solver_->getNumCols());
     11603    double * saveLower = CoinCopyOfArray(solver_->getColLower(),numberColumns);
     11604    double * saveUpper = CoinCopyOfArray(solver_->getColUpper(),numberColumns);
     11605    // Fix integers
     11606    for (int i=0;i<numberColumns;i++) {
     11607      if (solver_->isInteger(i)) {
     11608        double value = solution[i];
     11609        double intValue = floor(value+0.5);
     11610        assert (fabs(value-intValue)<1.0e-4);
     11611        solver_->setColLower(i,intValue);
     11612        solver_->setColUpper(i,intValue);
     11613      }
     11614    }
     11615    // Save basis
     11616    CoinWarmStart * saveBasis = solver_->getWarmStart();
     11617    // Solve
     11618    solver_->initialSolve();
     11619    char printBuffer[200];
     11620    bool looksGood = solver_->isProvenOptimal();
     11621    if (looksGood) {
     11622      double direction = solver_->getObjSense() ;
     11623      double objValue =direction*solver_->getObjValue();
     11624      if (objValue>objectiveValue + 1.0e-8*(1.0+fabs(objectiveValue))) {
     11625        sprintf(printBuffer,"Given objective value %g, computed %g",
     11626                objectiveValue,objValue);
     11627        messageHandler()->message(CBC_FPUMP1,messages())
     11628          << printBuffer << CoinMessageEol ;
     11629      }
     11630      // Use this as objective value and solution
     11631      objectiveValue = objValue;
     11632      solution = solver_->getColSolution();
     11633      // Save current basis
     11634      CoinWarmStartBasis* ws =
     11635        dynamic_cast <CoinWarmStartBasis*>(solver_->getWarmStart()) ;
     11636      assert(ws);
     11637      setBestSolutionBasis(*ws);
     11638      delete ws;
     11639    }
     11640    // Restore basis
     11641    solver_->setWarmStart(saveBasis);
     11642    delete saveBasis;
     11643    // Restore bounds
     11644    solver_->setColLower(saveLower);
     11645    delete [] saveLower;
     11646    solver_->setColUpper(saveUpper);
     11647    delete [] saveUpper;
     11648    // Return if no good
     11649    if (!looksGood) {
     11650      messageHandler()->message(CBC_FPUMP1,messages())
     11651        << "Error solution not saved as not feasible" << CoinMessageEol ;
     11652      return;
     11653    } else {
     11654      // message
     11655      sprintf(printBuffer,"Solution with objective value %g saved",
     11656              objectiveValue);
     11657      messageHandler()->message(CBC_FPUMP1,messages())
     11658        << printBuffer << CoinMessageEol ;
     11659    }
     11660  }
    1151111661  bestObjective_ = objectiveValue;
    1151211662  int n = CoinMax(numberColumns,solver_->getNumCols());
  • trunk/Cbc/src/CbcModel.hpp

    r934 r940  
    10941094  inline double * bestSolution() const
    10951095  { return bestSolution_;}
    1096   void setBestSolution(const double * solution,int numberColumns,double objectiveValue);
     1096  /** User callable setBestSolution.
     1097      If check false does not check valid
     1098      If true then sees if feasible and warns if objective value
     1099      worse than given (so just set to COIN_DBL_MAX if you don't care).
     1100      If check true then does not save solution if not feasible
     1101  */
     1102  void setBestSolution(const double * solution,int numberColumns,
     1103                       double objectiveValue,bool check=false);
    10971104 
    10981105  /// Get number of solutions
     
    13351342    The name is just used for print messages.
    13361343  */
    1337   void addHeuristic(CbcHeuristic * generator, const char *name = NULL);
     1344  void addHeuristic(CbcHeuristic * generator, const char *name = NULL,
     1345                    int before=-1);
    13381346  ///Get the specified heuristic
    13391347  inline CbcHeuristic * heuristic(int i) const
     
    14561464      7 bit (128) - SOS type 1 but all declared integer
    14571465      8 bit (256) - Set to say solution just found, unset by doing cuts
     1466      9 bit (512) - Try reduced model after 100 nodes
     1467      10 bit (1024) - Switch on some heuristics even if seems unlikely
    14581468  */
    14591469  /// Set special options
     
    15741584   */
    15751585  void resetModel();
     1586  /** Most of copy constructor
     1587      mode - 0 copy but don't delete before
     1588             1 copy and delete before
     1589             2 copy and delete before (but use virgin generators)
     1590  */
     1591  void gutsOfCopy(const CbcModel & rhs,int mode=0);
    15761592  /// Move status, nodes etc etc across
    15771593  void moveInfo(const CbcModel & rhs);
  • trunk/Cbc/src/CbcNode.hpp

    r931 r940  
    342342  /// Clone
    343343  virtual CbcNodeInfo * clone() const;
     344  /// Lower bounds
     345  inline const double * lower() const
     346  { return lower_;}
     347  /// Upper bounds
     348  inline const double * upper() const
     349  { return upper_;}
    344350protected:
    345351  // Data
  • trunk/Cbc/src/CbcTree.cpp

    r931 r940  
    77#include "CbcCountRowCut.hpp"
    88#include "CbcCompareActual.hpp"
     9#include "CbcBranchActual.hpp"
    910
    1011CbcTree::CbcTree()
    1112{
    1213  maximumNodeNumber_=0;
     14  numberBranching_=0;
     15  maximumBranching_=0;
     16  branched_=NULL;
     17  newBound_=NULL;
    1318}
    1419CbcTree::~CbcTree()
    1520{
     21  delete [] branched_;
     22  delete [] newBound_;
    1623}
    1724// Copy constructor
     
    2027  nodes_=rhs.nodes_;
    2128  maximumNodeNumber_=rhs.maximumNodeNumber_;
     29  numberBranching_=rhs.numberBranching_;
     30  maximumBranching_=rhs.maximumBranching_;
     31  if (maximumBranching_>0) {
     32    branched_=CoinCopyOfArray(rhs.branched_,maximumBranching_);
     33    newBound_=CoinCopyOfArray(rhs.newBound_,maximumBranching_);
     34  } else {
     35    branched_=NULL;
     36    newBound_=NULL;
     37  }
    2238}
    2339// Assignment operator
     
    2844    nodes_=rhs.nodes_;
    2945    maximumNodeNumber_=rhs.maximumNodeNumber_;
     46    delete [] branched_;
     47    delete [] newBound_;
     48    numberBranching_=rhs.numberBranching_;
     49    maximumBranching_=rhs.maximumBranching_;
     50    if (maximumBranching_>0) {
     51      branched_=CoinCopyOfArray(rhs.branched_,maximumBranching_);
     52      newBound_=CoinCopyOfArray(rhs.newBound_,maximumBranching_);
     53    } else {
     54      branched_=NULL;
     55      newBound_=NULL;
     56    }
    3057  }
    3158  return *this;
     59}
     60// Adds branching information to complete state
     61void
     62CbcTree::addBranchingInformation(const CbcModel * model, const CbcNodeInfo * nodeInfo,
     63                                 const double * currentLower,
     64                                 const double * currentUpper)
     65{
     66  const OsiBranchingObject * objA  = nodeInfo->owner()->branchingObject();
     67  const CbcIntegerBranchingObject * objBranch  = dynamic_cast<const CbcIntegerBranchingObject *> (objA);
     68  if (objBranch) {
     69    const CbcObject * objB = objBranch->object();
     70    const CbcSimpleInteger * obj = dynamic_cast<const CbcSimpleInteger *> (objB);
     71    assert (obj);
     72    int iColumn = obj->columnNumber();
     73    const double * down = objBranch->downBounds();
     74    const double * up = objBranch->upBounds();
     75    assert (currentLower[iColumn]==down[0]);
     76    assert (currentUpper[iColumn]==up[1]);
     77    if (dynamic_cast<const CbcPartialNodeInfo *> (nodeInfo)) {
     78      const CbcPartialNodeInfo * info = dynamic_cast<const CbcPartialNodeInfo *> (nodeInfo);
     79      const double * newBounds = info->newBounds();
     80      const int * variables = info->variables();
     81      int numberChanged = info->numberChangedBounds();
     82      for (int i=0;i<numberChanged;i++) {
     83        int jColumn = variables[i];
     84        int kColumn = jColumn&(~0x80000000);
     85        if (iColumn==kColumn) {
     86          jColumn |= 0x40000000;
     87          double value = newBounds[i];
     88          if ((jColumn&0x80000000)==0) {
     89            assert (value==up[0]);
     90          } else {
     91            assert (value==down[1]);
     92          }
     93        }
     94        if (numberBranching_==maximumBranching_)
     95          increaseSpace();
     96        newBound_[numberBranching_]=(int) newBounds[i];
     97        branched_[numberBranching_++]=jColumn;
     98      }
     99    } else {
     100      const CbcFullNodeInfo * info = dynamic_cast<const CbcFullNodeInfo *> (nodeInfo);
     101      int numberIntegers = model->numberIntegers();
     102      const int * which = model->integerVariable();
     103      const double * newLower = info->lower();
     104      const double * newUpper = info->upper();
     105      if (numberBranching_==maximumBranching_)
     106        increaseSpace();
     107      assert (newLower[iColumn]==up[0]||
     108              newUpper[iColumn]==down[1]);
     109      int jColumn=iColumn|0x40000000;
     110      if (newLower[iColumn]==up[0]) {
     111        newBound_[numberBranching_]=(int) up[0];
     112      } else {
     113        newBound_[numberBranching_]=(int) down[1];
     114        jColumn|= 0x80000000;
     115      }
     116      branched_[numberBranching_++]=jColumn;
     117      for (int i=0;i<numberIntegers;i++) {
     118        int jColumn=which[i];
     119        assert (currentLower[jColumn]==newLower[jColumn]||
     120                currentUpper[jColumn]==newUpper[jColumn]);
     121        if (jColumn!=iColumn) {
     122          bool changed=false;
     123          double value;
     124          if (newLower[jColumn]>currentLower[jColumn]) {
     125            value=newLower[jColumn];
     126            changed=true;
     127          } else if (newUpper[jColumn]<currentUpper[jColumn]) {
     128            value=newUpper[jColumn];
     129            jColumn|= 0x80000000;
     130            changed=true;
     131          }
     132          if (changed) {
     133            if (numberBranching_==maximumBranching_)
     134              increaseSpace();
     135            newBound_[numberBranching_]=(int) value;
     136            branched_[numberBranching_++]=jColumn;
     137          }
     138        }
     139      }
     140    }
     141  } else {
     142    // switch off
     143    delete [] branched_;
     144    delete [] newBound_;
     145    maximumBranching_=-1;
     146    branched_=NULL;
     147    newBound_=NULL;
     148  }
     149}
     150// Increase space for data
     151void
     152CbcTree::increaseSpace()
     153{
     154  assert (numberBranching_==maximumBranching_);
     155  maximumBranching_ = (3*maximumBranching_+10)>>1;
     156  unsigned int * temp1 = CoinCopyOfArrayPartial(branched_,maximumBranching_,numberBranching_);
     157  delete [] branched_;
     158  branched_ = temp1;
     159  int * temp2 = CoinCopyOfArrayPartial(newBound_,maximumBranching_,numberBranching_);
     160  delete [] newBound_;
     161  newBound_ = temp2;
    32162}
    33163// Clone
  • trunk/Cbc/src/CbcTree.hpp

    r931 r940  
    102102  inline void resetNodeNumbers()
    103103  { maximumNodeNumber_=0;}
     104  /// Set number of branches
     105  inline void setNumberBranching(int value)
     106  { numberBranching_=value;}
     107  /// Get number of branches
     108  inline int getNumberBranching() const
     109  { return numberBranching_;}
     110  /// Set maximum branches
     111  inline void setMaximumBranching(int value)
     112  { maximumBranching_=value;}
     113  /// Get maximum branches
     114  inline int getMaximumBranching() const
     115  { return maximumBranching_;}
     116  /// Get branched variables
     117  inline unsigned int * branched() const
     118  { return branched_;}
     119  /// Get bounds
     120  inline int * newBounds() const
     121  { return newBound_;}
     122  /// Adds branching information to complete state
     123  void addBranchingInformation(const CbcModel * model,const CbcNodeInfo * nodeInfo,
     124                               const double * currentLower,
     125                               const double * currentUpper);
     126  /// Increase space for data
     127  void increaseSpace();
    104128//@}
    105129protected:
     
    108132  /// Maximum "node" number so far to split ties
    109133  int maximumNodeNumber_;
     134  /// Size of variable list
     135  int numberBranching_;
     136  /// Maximum size of variable list
     137  int maximumBranching_;
     138  /** Integer variables branched or bounded
     139      top bit set if new upper bound
     140      next bit set if a branch
     141  */
     142  unsigned int * branched_;
     143  /// New bound
     144  int * newBound_;
    110145};
    111146
Note: See TracChangeset for help on using the changeset viewer.