Changeset 931 for trunk


Ignore:
Timestamp:
Apr 28, 2008 11:41:02 AM (12 years ago)
Author:
forrest
Message:

changes to try and improve performance

Location:
trunk/Cbc/src
Files:
24 edited

Legend:

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

    r912 r931  
    343343    members_(NULL),
    344344    weights_(NULL),
     345    shadowEstimateDown_(1.0),
     346    shadowEstimateUp_(1.0),
     347    downDynamicPseudoRatio_(0.0),
     348    upDynamicPseudoRatio_(0.0),
     349    numberTimesDown_(0),
     350    numberTimesUp_(0),
    345351    numberMembers_(0),
    346352    sosType_(-1),
     
    353359           const int * which, const double * weights, int identifier,int type)
    354360  : CbcObject(model),
     361    shadowEstimateDown_(1.0),
     362    shadowEstimateUp_(1.0),
     363    downDynamicPseudoRatio_(0.0),
     364    upDynamicPseudoRatio_(0.0),
     365    numberTimesDown_(0),
     366    numberTimesUp_(0),
    355367    numberMembers_(numberMembers),
    356368    sosType_(type)
     
    401413  :CbcObject(rhs)
    402414{
     415  shadowEstimateDown_ = rhs.shadowEstimateDown_;
     416  shadowEstimateUp_ = rhs.shadowEstimateUp_;
     417  downDynamicPseudoRatio_ = rhs.downDynamicPseudoRatio_;
     418  upDynamicPseudoRatio_ = rhs.upDynamicPseudoRatio_;
     419  numberTimesDown_ = rhs.numberTimesDown_;
     420  numberTimesUp_ = rhs.numberTimesUp_;
    403421  numberMembers_ = rhs.numberMembers_;
    404422  sosType_ = rhs.sosType_;
     
    430448    delete [] members_;
    431449    delete [] weights_;
     450    shadowEstimateDown_ = rhs.shadowEstimateDown_;
     451    shadowEstimateUp_ = rhs.shadowEstimateUp_;
     452    downDynamicPseudoRatio_ = rhs.downDynamicPseudoRatio_;
     453    upDynamicPseudoRatio_ = rhs.upDynamicPseudoRatio_;
     454    numberTimesDown_ = rhs.numberTimesDown_;
     455    numberTimesUp_ = rhs.numberTimesUp_;
    432456    numberMembers_ = rhs.numberMembers_;
    433457    sosType_ = rhs.sosType_;
     
    507531    double value = lastNonZero-firstNonZero+1;
    508532    value *= 0.5/((double) numberMembers_);
     533    // adjust??
    509534    return value;
     535  } else {
     536    return 0.0; // satisfied
     537  }
     538}
     539// Infeasibility - large is 0.5
     540double
     541CbcSOS::infeasibility(const OsiBranchingInformation * info,
     542                      int & preferredWay) const
     543{
     544  int j;
     545  int firstNonZero=-1;
     546  int lastNonZero = -1;
     547  OsiSolverInterface * solver = model_->solver();
     548  const double * solution = model_->testSolution();
     549  //const double * lower = solver->getColLower();
     550  const double * upper = solver->getColUpper();
     551  //double largestValue=0.0;
     552  double integerTolerance =
     553    model_->getDblParam(CbcModel::CbcIntegerTolerance);
     554  double weight = 0.0;
     555  double sum =0.0;
     556
     557  // check bounds etc
     558  double lastWeight=-1.0e100;
     559  for (j=0;j<numberMembers_;j++) {
     560    int iColumn = members_[j];
     561    if (lastWeight>=weights_[j]-1.0e-7)
     562      throw CoinError("Weights too close together in SOS","infeasibility","CbcSOS");
     563    double value = CoinMax(0.0,solution[iColumn]);
     564    sum += value;
     565    if (value>integerTolerance&&upper[iColumn]) {
     566      // Possibly due to scaling a fixed variable might slip through
     567      if (value>upper[iColumn]) {
     568        value=upper[iColumn];
     569        // Could change to #ifdef CBC_DEBUG
     570#ifndef NDEBUG
     571        if (model_->messageHandler()->logLevel()>2)
     572          printf("** Variable %d (%d) has value %g and upper bound of %g\n",
     573                 iColumn,j,value,upper[iColumn]);
     574#endif
     575      }
     576      weight += weights_[j]*value;
     577      if (firstNonZero<0)
     578        firstNonZero=j;
     579      lastNonZero=j;
     580    }
     581  }
     582  preferredWay=1;
     583  if (lastNonZero-firstNonZero>=sosType_) {
     584    // find where to branch
     585    assert (sum>0.0);
     586    weight /= sum;
     587    if (info->defaultDual_>=0.0&&info->usefulRegion_) {
     588      assert (sosType_==1);
     589      int iWhere;
     590      for (iWhere=firstNonZero;iWhere<lastNonZero-1;iWhere++) {
     591        if (weight<weights_[iWhere+1]) {
     592          break;
     593        }
     594      }
     595      int jColumnDown = members_[iWhere];
     596      int jColumnUp = members_[iWhere+1];
     597      int n=0;
     598      CoinBigIndex j;
     599      double objMove = info->objective_[jColumnDown];
     600      for (j=info->columnStart_[jColumnDown];
     601           j<info->columnStart_[jColumnDown]+info->columnLength_[jColumnDown];j++) {
     602        double value = info->elementByColumn_[j];
     603        int iRow = info->row_[j];
     604        info->indexRegion_[n++]=iRow;
     605        info->usefulRegion_[iRow]=value;
     606      }
     607      for (iWhere=firstNonZero;iWhere<lastNonZero;iWhere++) {
     608        int jColumn = members_[iWhere];
     609        double solValue = info->solution_[jColumn];
     610        objMove -= info->objective_[jColumn]*solValue;
     611        for (j=info->columnStart_[jColumn];
     612             j<info->columnStart_[jColumn]+info->columnLength_[jColumn];j++) {
     613          double value = -info->elementByColumn_[j]*solValue;
     614          int iRow = info->row_[j];
     615          double oldValue = info->usefulRegion_[iRow];
     616          if (!oldValue) {
     617            info->indexRegion_[n++]=iRow;
     618          } else {
     619            value += oldValue;
     620            if (!value)
     621              value = 1.0e-100;
     622          }
     623          info->usefulRegion_[iRow]=value;
     624        }
     625      }
     626      const double * pi = info->pi_;
     627      const double * activity = info->rowActivity_;
     628      const double * lower = info->rowLower_;
     629      const double * upper = info->rowUpper_;
     630      double tolerance = info->primalTolerance_;
     631      double direction = info->direction_;
     632      shadowEstimateDown_ = objMove*direction;
     633      bool infeasible=false;
     634      for (int k=0;k<n;k++) {
     635        int iRow = info->indexRegion_[k];
     636        double movement=info->usefulRegion_[iRow];
     637        // not this time info->usefulRegion_[iRow]=0.0;
     638        if (lower[iRow]<-1.0e20)
     639          assert (pi[iRow]<=1.0e-3);
     640        if (upper[iRow]>1.0e20)
     641          assert (pi[iRow]>=-1.0e-3);
     642        double valueP = pi[iRow]*direction;
     643        // if move makes infeasible then make at least default
     644        double newValue = activity[iRow] + movement;
     645        if (newValue>upper[iRow]+tolerance||newValue<lower[iRow]-tolerance) {
     646          shadowEstimateDown_ += fabs(movement)*CoinMax(fabs(valueP),info->defaultDual_);
     647          infeasible=true;
     648        }
     649      }
     650      if (shadowEstimateDown_<info->integerTolerance_) {
     651        if (!infeasible) {
     652          shadowEstimateDown_=1.0e-10;
     653#ifdef COIN_DEVELOP
     654          printf("zero pseudoShadowPrice\n");
     655#endif
     656        } else
     657          shadowEstimateDown_ = info->integerTolerance_;
     658      }
     659      // And other way
     660      // take off
     661      objMove -= info->objective_[jColumnDown];
     662      for (j=info->columnStart_[jColumnDown];
     663           j<info->columnStart_[jColumnDown]+info->columnLength_[jColumnDown];j++) {
     664        double value = -info->elementByColumn_[j];
     665        int iRow = info->row_[j];
     666        double oldValue = info->usefulRegion_[iRow];
     667        if (!oldValue) {
     668          info->indexRegion_[n++]=iRow;
     669          } else {
     670          value += oldValue;
     671          if (!value)
     672            value = 1.0e-100;
     673        }
     674        info->usefulRegion_[iRow]=value;
     675      }
     676      // add on
     677      objMove += info->objective_[jColumnUp];
     678      for (j=info->columnStart_[jColumnUp];
     679           j<info->columnStart_[jColumnUp]+info->columnLength_[jColumnUp];j++) {
     680        double value = info->elementByColumn_[j];
     681        int iRow = info->row_[j];
     682        double oldValue = info->usefulRegion_[iRow];
     683        if (!oldValue) {
     684          info->indexRegion_[n++]=iRow;
     685          } else {
     686          value += oldValue;
     687          if (!value)
     688            value = 1.0e-100;
     689        }
     690        info->usefulRegion_[iRow]=value;
     691      }
     692      shadowEstimateUp_ = objMove*direction;
     693      infeasible=false;
     694      for (int k=0;k<n;k++) {
     695        int iRow = info->indexRegion_[k];
     696        double movement=info->usefulRegion_[iRow];
     697        info->usefulRegion_[iRow]=0.0;
     698        if (lower[iRow]<-1.0e20)
     699          assert (pi[iRow]<=1.0e-3);
     700        if (upper[iRow]>1.0e20)
     701          assert (pi[iRow]>=-1.0e-3);
     702        double valueP = pi[iRow]*direction;
     703        // if move makes infeasible then make at least default
     704        double newValue = activity[iRow] + movement;
     705        if (newValue>upper[iRow]+tolerance||newValue<lower[iRow]-tolerance) {
     706          shadowEstimateUp_ += fabs(movement)*CoinMax(fabs(valueP),info->defaultDual_);
     707          infeasible=true;
     708        }
     709      }
     710      if (shadowEstimateUp_<info->integerTolerance_) {
     711        if (!infeasible) {
     712          shadowEstimateUp_=1.0e-10;
     713#ifdef COIN_DEVELOP
     714          printf("zero pseudoShadowPrice\n");
     715#endif
     716        } else
     717          shadowEstimateUp_ = info->integerTolerance_;
     718      }
     719      // adjust
     720      double downCost = shadowEstimateDown_;
     721      double upCost = shadowEstimateUp_;
     722      if (numberTimesDown_)
     723        downCost *= downDynamicPseudoRatio_/
     724          ((double) numberTimesDown_);
     725      if (numberTimesUp_)
     726        upCost *= upDynamicPseudoRatio_/
     727          ((double) numberTimesUp_);
     728#define WEIGHT_AFTER 0.7
     729#define WEIGHT_BEFORE 0.1
     730      int stateOfSearch = model_->stateOfSearch()%10;
     731      double returnValue=0.0;
     732      double minValue = CoinMin(downCost,upCost);
     733      double maxValue = CoinMax(downCost,upCost);
     734      if (stateOfSearch<=2) {
     735        // no branching solution
     736        returnValue = WEIGHT_BEFORE*minValue + (1.0-WEIGHT_BEFORE)*maxValue;
     737      } else {
     738        returnValue = WEIGHT_AFTER*minValue + (1.0-WEIGHT_AFTER)*maxValue;
     739      }
     740#ifdef PRINT_SHADOW
     741      printf("%d id - down %d %g up %d %g shadow %g, %g returned %g\n",
     742             id_,numberTimesDown_,downDynamicPseudoRatio_,
     743             numberTimesUp_,upDynamicPseudoRatio_,shadowEstimateDown_,
     744             shadowEstimateUp_,returnValue);
     745#endif
     746      return returnValue;
     747    } else {
     748      double value = lastNonZero-firstNonZero+1;
     749      value *= 0.5/((double) numberMembers_);
     750      return value;
     751    }
    510752  } else {
    511753    return 0.0; // satisfied
     
    630872  CbcBranchingObject * branch;
    631873  branch = new CbcSOSBranchingObject(model_,this,way,separator);
     874  branch->setOriginalObject(this);
    632875  return branch;
     876}
     877/* Pass in information on branch just done and create CbcObjectUpdateData instance.
     878   If object does not need data then backward pointer will be NULL.
     879   Assumes can get information from solver */
     880CbcObjectUpdateData
     881CbcSOS::createUpdateInformation(const OsiSolverInterface * solver,
     882                                const CbcNode * node,
     883                                const CbcBranchingObject * branchingObject)
     884{
     885  double originalValue=node->objectiveValue();
     886  int originalUnsatisfied = node->numberUnsatisfied();
     887  double objectiveValue = solver->getObjValue()*solver->getObjSense();
     888  int unsatisfied=0;
     889  int i;
     890  //might be base model - doesn't matter
     891  int numberIntegers = model_->numberIntegers();;
     892  const double * solution = solver->getColSolution();
     893  //const double * lower = solver->getColLower();
     894  //const double * upper = solver->getColUpper();
     895  double change = CoinMax(0.0,objectiveValue-originalValue);
     896  int iStatus;
     897  if (solver->isProvenOptimal())
     898    iStatus=0; // optimal
     899  else if (solver->isIterationLimitReached()
     900           &&!solver->isDualObjectiveLimitReached())
     901    iStatus=2; // unknown
     902  else
     903    iStatus=1; // infeasible
     904
     905  bool feasible = iStatus!=1;
     906  if (feasible) {
     907    double integerTolerance =
     908      model_->getDblParam(CbcModel::CbcIntegerTolerance);
     909    const int * integerVariable = model_->integerVariable();
     910    for (i=0;i<numberIntegers;i++) {
     911      int j=integerVariable[i];
     912      double value = solution[j];
     913      double nearest = floor(value+0.5);
     914      if (fabs(value-nearest)>integerTolerance)
     915        unsatisfied++;
     916    }
     917  }
     918  int way = branchingObject->way();
     919  way = - way; // because after branch so moved on
     920  double value = branchingObject->value();
     921  CbcObjectUpdateData newData (this, way,
     922                               change, iStatus,
     923                               originalUnsatisfied-unsatisfied,value);
     924  newData.originalObjective_ = originalValue;
     925  // Solvers know about direction
     926  double direction = solver->getObjSense();
     927  solver->getDblParam(OsiDualObjectiveLimit,newData.cutoff_);
     928  newData.cutoff_ *= direction;
     929  return newData;
     930}
     931// Update object by CbcObjectUpdateData
     932void
     933CbcSOS::updateInformation(const CbcObjectUpdateData & data)
     934{
     935  bool feasible = data.status_!=1;
     936  int way = data.way_;
     937  //double value = data.branchingValue_;
     938  double originalValue = data.originalObjective_;
     939  double change = data.change_;
     940  if (way<0) {
     941    // down
     942    if (!feasible) {
     943      double distanceToCutoff=0.0;
     944      //double objectiveValue = model_->getCurrentMinimizationObjValue();
     945      distanceToCutoff =  model_->getCutoff()  - originalValue;
     946      if (distanceToCutoff<1.0e20)
     947        change = distanceToCutoff*2.0;
     948      else
     949        change = (downDynamicPseudoRatio_*shadowEstimateDown_+1.0e-3)*10.0;
     950    }
     951    change = CoinMax(1.0e-12*(1.0+fabs(originalValue)),change);
     952#ifdef PRINT_SHADOW
     953    if (numberTimesDown_)
     954      printf("Updating id %d - down change %g (true %g) - ndown %d estimated change %g - raw shadow estimate %g\n",
     955             id_,change,data.change_,numberTimesDown_,shadowEstimateDown_*
     956             (downDynamicPseudoRatio_/((double) numberTimesDown_)),
     957             shadowEstimateDown_);
     958    else
     959      printf("Updating id %d - down change %g (true %g) - shadow estimate %g\n",
     960             id_,change,data.change_,shadowEstimateDown_);
     961#endif
     962    numberTimesDown_++;
     963    downDynamicPseudoRatio_ += change/shadowEstimateDown_;
     964  } else {
     965    // up
     966    if (!feasible) {
     967      double distanceToCutoff=0.0;
     968      //double objectiveValue = model_->getCurrentMinimizationObjValue();
     969      distanceToCutoff =  model_->getCutoff()  - originalValue;
     970      if (distanceToCutoff<1.0e20)
     971        change = distanceToCutoff*2.0;
     972      else
     973        change = (upDynamicPseudoRatio_*shadowEstimateUp_+1.0e-3)*10.0;
     974    }
     975    change = CoinMax(1.0e-12*(1.0+fabs(originalValue)),change);
     976#ifdef PRINT_SHADOW
     977    if (numberTimesUp_)
     978      printf("Updating id %d - up change %g (true %g) - nup %d estimated change %g - raw shadow estimate %g\n",
     979             id_,change,data.change_,numberTimesUp_,shadowEstimateUp_*
     980             (upDynamicPseudoRatio_/((double) numberTimesUp_)),
     981             shadowEstimateUp_);
     982    else
     983      printf("Updating id %d - up change %g (true %g) - shadow estimate %g\n",
     984             id_,change,data.change_,shadowEstimateUp_);
     985#endif
     986    numberTimesUp_++;
     987    upDynamicPseudoRatio_ += change/shadowEstimateUp_;
     988  }
    633989}
    634990
     
    8241180{
    8251181  double value = info->solution_[columnNumber_];
     1182#ifdef COIN_DEVELOP
     1183  if (fabs(value-floor(value+0.5))>1.0e-5)
     1184    printf("value for %d away from integer %g\n",columnNumber_,value);
     1185#endif
    8261186  double newValue = CoinMax(value, info->lower_[columnNumber_]);
    8271187  newValue = CoinMin(newValue, info->upper_[columnNumber_]);
     
    12311591#endif
    12321592  return 0.0;
     1593}
     1594/* Update bounds in solver as in 'branch' and update given bounds.
     1595   branchState is -1 for 'down' +1 for 'up' */
     1596void
     1597CbcIntegerBranchingObject::fix(OsiSolverInterface * solver,
     1598                               double * lower, double * upper,
     1599                               int branchState) const
     1600{
     1601  int iColumn = originalCbcObject_->columnNumber();
     1602  assert (variable_==iColumn);
     1603  if (branchState<0) {
     1604    model_->solver()->setColLower(iColumn,down_[0]);
     1605    lower[iColumn]=down_[0];
     1606    model_->solver()->setColUpper(iColumn,down_[1]);
     1607    upper[iColumn]=down_[1];
     1608  } else {
     1609    model_->solver()->setColLower(iColumn,up_[0]);
     1610    lower[iColumn]=up_[0];
     1611    model_->solver()->setColUpper(iColumn,up_[1]);
     1612    upper[iColumn]=up_[1];
     1613  }
    12331614}
    12341615#ifdef FUNNY_BRANCHING
     
    23282709  computeNonzeroRange();
    23292710  return 0.0;
     2711}
     2712/* Update bounds in solver as in 'branch' and update given bounds.
     2713   branchState is -1 for 'down' +1 for 'up' */
     2714void
     2715CbcSOSBranchingObject::fix(OsiSolverInterface * solver,
     2716                               double * lower, double * upper,
     2717                               int branchState) const
     2718{
     2719  int numberMembers = set_->numberMembers();
     2720  const int * which = set_->members();
     2721  const double * weights = set_->weights();
     2722  //const double * lower = solver->getColLower();
     2723  //const double * upper = solver->getColUpper();
     2724  // *** for way - up means fix all those in down section
     2725  if (branchState<0) {
     2726    int i;
     2727    for ( i=0;i<numberMembers;i++) {
     2728      if (weights[i] > separator_)
     2729        break;
     2730    }
     2731    assert (i<numberMembers);
     2732    for (;i<numberMembers;i++) {
     2733      solver->setColUpper(which[i],0.0);
     2734      upper[which[i]]=0.0;
     2735    }
     2736  } else {
     2737    int i;
     2738    for ( i=0;i<numberMembers;i++) {
     2739      if (weights[i] >= separator_) {
     2740        break;
     2741      } else {
     2742        solver->setColUpper(which[i],0.0);
     2743        upper[which[i]]=0.0;
     2744      }
     2745    }
     2746    assert (i<numberMembers);
     2747  }
    23302748}
    23312749// Print what would happen 
     
    40004418}
    40014419
     4420// Default Constructor
     4421CbcGeneral::CbcGeneral()
     4422  : CbcObject()
     4423{
     4424}
     4425
     4426// Constructor from model
     4427CbcGeneral::CbcGeneral(CbcModel * model)
     4428  : CbcObject(model)
     4429{
     4430}
     4431
     4432
     4433// Destructor
     4434CbcGeneral::~CbcGeneral ()
     4435{
     4436}
     4437
     4438// Copy constructor
     4439CbcGeneral::CbcGeneral ( const CbcGeneral & rhs)
     4440  : CbcObject(rhs)
     4441{
     4442}
     4443#ifdef COIN_HAS_CLP
     4444#include "OsiClpSolverInterface.hpp"
     4445#include "CoinWarmStartBasis.hpp"
     4446#include "ClpNode.hpp"
     4447#include "CbcBranchDynamic.hpp"
     4448// Assignment operator
     4449CbcGeneral &
     4450CbcGeneral::operator=( const CbcGeneral& rhs)
     4451{
     4452  if (this!=&rhs) {
     4453    CbcObject::operator=(rhs);
     4454  }
     4455  return *this;
     4456}
     4457
     4458// Default Constructor
     4459CbcGeneralDepth::CbcGeneralDepth ()
     4460  : CbcGeneral(),
     4461    maximumDepth_(-1),
     4462    whichSolution_(-1),
     4463    numberNodes_(0),
     4464    nodeInfo_(NULL)
     4465{
     4466}
     4467
     4468// Useful constructor (which are integer indices)
     4469CbcGeneralDepth::CbcGeneralDepth (CbcModel * model, int maximumDepth)
     4470  : CbcGeneral(model),
     4471    maximumDepth_(maximumDepth),
     4472    whichSolution_(-1),
     4473    numberNodes_(0),
     4474    nodeInfo_(NULL)
     4475{
     4476  if (maximumDepth_>=0) {
     4477    nodeInfo_ = new ClpNodeStuff();
     4478    ClpNodeStuff * info = nodeInfo_;
     4479    info->nDepth_=maximumDepth_;
     4480    int n = (1<<maximumDepth_)+1+maximumDepth_;
     4481    ClpNode ** nodeInfo = new ClpNode * [n];
     4482    for (int i=0;i<n;i++)
     4483      nodeInfo[i]=NULL;
     4484    info->nodeInfo_ = nodeInfo;
     4485  } else {
     4486    nodeInfo_ = NULL;
     4487  }
     4488}
     4489
     4490// Copy constructor
     4491CbcGeneralDepth::CbcGeneralDepth ( const CbcGeneralDepth & rhs)
     4492  :CbcGeneral(rhs)
     4493{
     4494  maximumDepth_ = rhs.maximumDepth_;
     4495  whichSolution_ = -1;
     4496  numberNodes_ = 0;
     4497  if (maximumDepth_>=0) {
     4498    assert (rhs.nodeInfo_);
     4499    nodeInfo_ = new ClpNodeStuff(*rhs.nodeInfo_);
     4500    ClpNodeStuff * info = nodeInfo_;
     4501    info->nDepth_=maximumDepth_;
     4502    if (!info->nodeInfo_) {
     4503      int n = (1<<maximumDepth_)+1+maximumDepth_;
     4504      ClpNode ** nodeInfo = new ClpNode * [n];
     4505      for (int i=0;i<n;i++)
     4506        nodeInfo[i]=NULL;
     4507      info->nodeInfo_ = nodeInfo;
     4508    }
     4509  } else {
     4510    nodeInfo_ = NULL;
     4511  }
     4512}
     4513
     4514// Clone
     4515CbcObject *
     4516CbcGeneralDepth::clone() const
     4517{
     4518  return new CbcGeneralDepth(*this);
     4519}
     4520
     4521// Assignment operator
     4522CbcGeneralDepth &
     4523CbcGeneralDepth::operator=( const CbcGeneralDepth& rhs)
     4524{
     4525  if (this!=&rhs) {
     4526    CbcGeneral::operator=(rhs);
     4527    delete nodeInfo_;
     4528    maximumDepth_ = rhs.maximumDepth_;
     4529    whichSolution_ = -1;
     4530    numberNodes_ = 0;
     4531    if (maximumDepth_>=0) {
     4532      assert (rhs.nodeInfo_);
     4533      nodeInfo_ = new ClpNodeStuff(*rhs.nodeInfo_);
     4534    } else {
     4535      nodeInfo_ = NULL;
     4536    }
     4537  }
     4538  return *this;
     4539}
     4540
     4541// Destructor
     4542CbcGeneralDepth::~CbcGeneralDepth ()
     4543{
     4544  delete nodeInfo_;
     4545}
     4546
     4547// Infeasibility - large is 0.5
     4548double
     4549CbcGeneralDepth::infeasibility(int & preferredWay) const
     4550{
     4551  whichSolution_ = -1;
     4552  // should use genuine OsiBranchingInformation usefulInfo = model_->usefulInformation();
     4553  // for now assume only called when correct
     4554  //if (usefulInfo.depth_>=4&&!model_->parentModel()
     4555  //     &&(usefulInfo.depth_%2)==0) {
     4556  if (true) {
     4557    OsiSolverInterface * solver = model_->solver();
     4558    OsiClpSolverInterface * clpSolver
     4559      = dynamic_cast<OsiClpSolverInterface *> (solver);
     4560    if (clpSolver) {
     4561      ClpNodeStuff * info = nodeInfo_;
     4562      info->integerTolerance_=model_->getIntegerTolerance();
     4563      info->integerIncrement_=model_->getCutoffIncrement();
     4564      int numberIntegers = model_->numberIntegers();
     4565      double * down = new double[numberIntegers];
     4566      double * up = new double[numberIntegers];
     4567      int * numberDown = new int[numberIntegers];
     4568      int * numberUp = new int[numberIntegers];
     4569      int * numberDownInfeasible = new int[numberIntegers];
     4570      int * numberUpInfeasible = new int[numberIntegers];
     4571      model_->fillPseudoCosts(down,up,numberDown,numberUp,
     4572                      numberDownInfeasible,numberUpInfeasible);
     4573      info->fillPseudoCosts(down,up,numberDown,numberUp,
     4574                            numberDownInfeasible,
     4575                            numberUpInfeasible,numberIntegers);
     4576      info->presolveType_= 1; //1 later
     4577      delete [] down;
     4578      delete [] up;
     4579      delete [] numberDown;
     4580      delete [] numberUp;
     4581      delete [] numberDownInfeasible;
     4582      delete [] numberUpInfeasible;
     4583      bool takeHint;
     4584      OsiHintStrength strength;
     4585      solver->getHintParam(OsiDoReducePrint,takeHint,strength);
     4586      ClpSimplex * simplex = clpSolver->getModelPtr();
     4587      int saveLevel = simplex->logLevel();
     4588      if (strength!=OsiHintIgnore&&takeHint&&saveLevel==1)
     4589        simplex->setLogLevel(0);
     4590      clpSolver->setBasis();
     4591      whichSolution_ = simplex->fathomMany(info);
     4592      model_->incrementExtra(info->numberNodesExplored_,
     4593                             info->numberIterations_);
     4594      // update pseudo costs
     4595      double smallest=1.0e50;
     4596      double largest=-1.0;
     4597      OsiObject ** objects = model_->objects();
     4598#ifndef NDEBUG
     4599      const int * integerVariable = model_->integerVariable();
     4600#endif
     4601      for (int i=0;i<numberIntegers;i++) {
     4602        CbcSimpleIntegerDynamicPseudoCost * obj =
     4603          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(objects[i]) ;
     4604        assert (obj&&obj->columnNumber()==integerVariable[i]);
     4605        if (info->numberUp_[i]>0) {
     4606          if (info->downPseudo_[i]>largest)
     4607            largest=info->downPseudo_[i];
     4608          if (info->downPseudo_[i]<smallest)
     4609            smallest=info->downPseudo_[i];
     4610          if (info->upPseudo_[i]>largest)
     4611            largest=info->upPseudo_[i];
     4612          if (info->upPseudo_[i]<smallest)
     4613            smallest=info->upPseudo_[i];
     4614          obj->updateAfterMini(info->numberDown_[i],
     4615                               info->numberDownInfeasible_[i],
     4616                               info->downPseudo_[i],
     4617                               info->numberUp_[i],
     4618                               info->numberUpInfeasible_[i],
     4619                               info->upPseudo_[i]);
     4620        }
     4621      }
     4622      //printf("range of costs %g to %g\n",smallest,largest);
     4623      simplex->setLogLevel(saveLevel);
     4624      numberNodes_ = info->nNodes_;
     4625      int numberDo = numberNodes_;
     4626      if (whichSolution_>=0)
     4627        numberDo--;
     4628      if (numberDo>0) {
     4629        return 0.5;
     4630      } else {
     4631        // no solution
     4632        return COIN_DBL_MAX; // say infeasible
     4633      }
     4634    } else {
     4635      return -1.0;
     4636    }
     4637  } else {
     4638    return -1.0;
     4639  }
     4640}
     4641
     4642// This looks at solution and sets bounds to contain solution
     4643void
     4644CbcGeneralDepth::feasibleRegion()
     4645{
     4646  // Other stuff should have done this
     4647}
     4648// Redoes data when sequence numbers change
     4649void
     4650CbcGeneralDepth::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
     4651{
     4652}
     4653
     4654//#define CHECK_PATH
     4655#ifdef CHECK_PATH
     4656extern const double * debuggerSolution_Z;
     4657extern int numberColumns_Z;
     4658extern int gotGoodNode_Z;
     4659#endif
     4660
     4661// Creates a branching object
     4662CbcBranchingObject *
     4663CbcGeneralDepth::createBranch(int way)
     4664{
     4665  int numberDo = numberNodes_;
     4666  if (whichSolution_>=0)
     4667    numberDo--;
     4668  assert (numberDo>0);
     4669  // create object
     4670  CbcGeneralBranchingObject * branch = new CbcGeneralBranchingObject(model_);
     4671  // skip solution
     4672  branch->numberSubProblems_ = numberDo;
     4673  branch->setNumberBranches(numberDo);
     4674  CbcSubProblem * sub = new CbcSubProblem[numberDo];
     4675  int iProb=0;
     4676  branch->subProblems_ = sub;
     4677  branch->numberRows_ = model_->solver()->getNumRows();
     4678  int iNode;
     4679  OsiSolverInterface * solver = model_->solver();
     4680  OsiClpSolverInterface * clpSolver
     4681    = dynamic_cast<OsiClpSolverInterface *> (solver);
     4682  assert (clpSolver);
     4683  ClpSimplex * simplex = clpSolver->getModelPtr();
     4684  int numberColumns = simplex->numberColumns();
     4685  double * lowerBefore=CoinCopyOfArray(simplex->getColLower(),
     4686                                       numberColumns);
     4687  double * upperBefore=CoinCopyOfArray(simplex->getColUpper(),
     4688                                       numberColumns);
     4689  ClpNodeStuff * info = nodeInfo_;
     4690  double * weight = new double[numberNodes_];
     4691  int * whichNode = new int [numberNodes_];
     4692  // Sort
     4693  for (iNode=0;iNode<numberNodes_;iNode++) {
     4694    if (iNode!=whichSolution_) {
     4695      double objectiveValue = info->nodeInfo_[iNode]->objectiveValue();
     4696      double sumInfeasibilities = info->nodeInfo_[iNode]->sumInfeasibilities();
     4697      int numberInfeasibilities = info->nodeInfo_[iNode]->numberInfeasibilities();
     4698      double thisWeight = 0.0;
     4699#if 1
     4700      // just closest
     4701      thisWeight = 1.0e9*numberInfeasibilities;
     4702      thisWeight += sumInfeasibilities;
     4703      thisWeight += 1.0e-7*objectiveValue;
     4704      // Try estimate
     4705      thisWeight = info->nodeInfo_[iNode]->estimatedSolution();
     4706#else
     4707      thisWeight = 1.0e-3*numberInfeasibilities;
     4708      thisWeight += 1.0e-5*sumInfeasibilities;
     4709      thisWeight += objectiveValue;
     4710#endif
     4711      whichNode[iProb]=iNode;
     4712      weight[iProb++]=thisWeight;
     4713    }
     4714  }
     4715  assert (iProb==numberDo);
     4716  CoinSort_2(weight,weight+numberDo,whichNode);
     4717  for (iProb=0;iProb<numberDo;iProb++) {
     4718    iNode = whichNode[iProb];
     4719    ClpNode * node = info->nodeInfo_[iNode];
     4720    // move bounds
     4721    node->applyNode(simplex,3);
     4722    // create subproblem
     4723    sub[iProb]=CbcSubProblem(clpSolver,lowerBefore,upperBefore,
     4724                             node->statusArray());
     4725    sub[iProb].objectiveValue_ = node->objectiveValue();
     4726    sub[iProb].sumInfeasibilities_ = node->sumInfeasibilities();
     4727    sub[iProb].numberInfeasibilities_ = node->numberInfeasibilities();
     4728#ifdef CHECK_PATH
     4729    if (simplex->numberColumns()==numberColumns_Z) {
     4730      bool onOptimal=true;
     4731      const double * columnLower = simplex->columnLower();
     4732      const double * columnUpper = simplex->columnUpper();
     4733      for (int i=0;i<numberColumns_Z;i++) {
     4734        if (iNode==gotGoodNode_Z)
     4735          printf("good %d %d %g %g\n",iNode,i,columnLower[i],columnUpper[i]);
     4736        if (columnUpper[i]<debuggerSolution_Z[i]||columnLower[i]>debuggerSolution_Z[i]&&simplex->isInteger(i)) {
     4737          onOptimal=false;
     4738          break;
     4739        }
     4740      }
     4741      if (onOptimal) {
     4742        printf("adding to node %x as %d - objs\n",this,iProb);
     4743        for (int j=0;j<=iProb;j++)
     4744          printf("%d %g\n",j,sub[j].objectiveValue_);
     4745      }
     4746    }
     4747#endif
     4748  }
     4749  delete [] weight;
     4750  delete [] whichNode;
     4751  const double * lower = solver->getColLower();
     4752  const double * upper = solver->getColUpper();
     4753  // restore bounds
     4754  for ( int j=0;j<numberColumns;j++) {
     4755    if (lowerBefore[j] != lower[j])
     4756      solver->setColLower(j,lowerBefore[j]);
     4757    if (upperBefore[j] != upper[j])
     4758      solver->setColUpper(j,upperBefore[j]);
     4759  }
     4760  delete [] upperBefore;
     4761  delete [] lowerBefore;
     4762  return branch;
     4763}
     4764
     4765// Default Constructor
     4766CbcGeneralBranchingObject::CbcGeneralBranchingObject()
     4767  :CbcBranchingObject(),
     4768   subProblems_(NULL),
     4769   node_(NULL),
     4770   numberSubProblems_(0),
     4771   numberRows_(0)
     4772{
     4773}
     4774
     4775// Useful constructor
     4776CbcGeneralBranchingObject::CbcGeneralBranchingObject (CbcModel * model)
     4777  :CbcBranchingObject(model,-1,-1,0.5),
     4778   subProblems_(NULL),
     4779   node_(NULL),
     4780   numberSubProblems_(0),
     4781   numberRows_(0)
     4782{
     4783}
     4784
     4785// Copy constructor
     4786CbcGeneralBranchingObject::CbcGeneralBranchingObject ( const CbcGeneralBranchingObject & rhs)
     4787  :CbcBranchingObject(rhs),
     4788   subProblems_(NULL),
     4789   node_(rhs.node_),
     4790   numberSubProblems_(rhs.numberSubProblems_),
     4791   numberRows_(rhs.numberRows_)
     4792{
     4793  if (numberSubProblems_) {
     4794    subProblems_ = new CbcSubProblem[numberSubProblems_];
     4795    for (int i=0;i<numberSubProblems_;i++)
     4796      subProblems_[i]=rhs.subProblems_[i];
     4797  }
     4798}
     4799
     4800// Assignment operator
     4801CbcGeneralBranchingObject &
     4802CbcGeneralBranchingObject::operator=( const CbcGeneralBranchingObject& rhs)
     4803{
     4804  if (this != &rhs) {
     4805    CbcBranchingObject::operator=(rhs);
     4806    delete [] subProblems_;
     4807    numberSubProblems_ = rhs.numberSubProblems_;
     4808    numberRows_ = rhs.numberRows_;
     4809    if (numberSubProblems_) {
     4810      subProblems_ = new CbcSubProblem[numberSubProblems_];
     4811      for (int i=0;i<numberSubProblems_;i++)
     4812        subProblems_[i]=rhs.subProblems_[i];
     4813    } else {
     4814      subProblems_ = NULL;
     4815    }
     4816    node_ = rhs.node_;
     4817  }
     4818  return *this;
     4819}
     4820CbcBranchingObject *
     4821CbcGeneralBranchingObject::clone() const
     4822{
     4823  return (new CbcGeneralBranchingObject(*this));
     4824}
     4825
     4826
     4827// Destructor
     4828CbcGeneralBranchingObject::~CbcGeneralBranchingObject ()
     4829{
     4830  delete [] subProblems_;
     4831}
     4832bool doingDoneBranch=false;
     4833double
     4834CbcGeneralBranchingObject::branch()
     4835{
     4836  assert (node_);
     4837  double cutoff=model_->getCutoff();
     4838  bool applied=false;
     4839  while (numberBranchesLeft()) {
     4840    int which = branchIndex();
     4841    decrementNumberBranchesLeft();
     4842    CbcSubProblem * thisProb = subProblems_+which;
     4843    if (thisProb->objectiveValue_<cutoff) {
     4844      //printf("branch %x (sub %x) which now %d\n",this,
     4845      //     subProblems_,which);
     4846      OsiSolverInterface * solver = model_->solver();
     4847      thisProb->apply(solver);
     4848      OsiClpSolverInterface * clpSolver
     4849        = dynamic_cast<OsiClpSolverInterface *> (solver);
     4850      assert (clpSolver);
     4851      // Move status to basis
     4852      clpSolver->setWarmStart(NULL);
     4853      //ClpSimplex * simplex = clpSolver->getModelPtr();
     4854      node_->setObjectiveValue(thisProb->objectiveValue_);
     4855      node_->setSumInfeasibilities(thisProb->sumInfeasibilities_);
     4856      node_->setNumberUnsatisfied(thisProb->numberInfeasibilities_);
     4857      applied=true;
     4858      doingDoneBranch=true;
     4859      break;
     4860    } else if (numberBranchesLeft()) {
     4861      node_->nodeInfo()->branchedOn() ;
     4862    }
     4863  }
     4864  if (!applied) {
     4865    // no good one
     4866    node_->setObjectiveValue(cutoff+1.0e20);
     4867    node_->setSumInfeasibilities(1.0);
     4868    node_->setNumberUnsatisfied(1);
     4869  }
     4870  return 0.0;
     4871}
     4872/* Double checks in case node can change its mind!
     4873   Can change objective etc */
     4874void
     4875CbcGeneralBranchingObject::checkIsCutoff(double cutoff)
     4876{
     4877  assert (node_);
     4878  int first = branchIndex();
     4879  int last = first + numberBranchesLeft();
     4880  for (int which=first;which<last;which++) {
     4881    CbcSubProblem * thisProb = subProblems_+which;
     4882    if (thisProb->objectiveValue_<cutoff) {
     4883      node_->setObjectiveValue(thisProb->objectiveValue_);
     4884      node_->setSumInfeasibilities(thisProb->sumInfeasibilities_);
     4885      node_->setNumberUnsatisfied(thisProb->numberInfeasibilities_);
     4886      break;
     4887    }
     4888  }
     4889}
     4890// Print what would happen 
     4891void
     4892CbcGeneralBranchingObject::print()
     4893{
     4894  printf("CbcGeneralObject has %d subproblems\n",numberSubProblems_);
     4895}
     4896// Fill in current objective etc
     4897void
     4898CbcGeneralBranchingObject::state(double & objectiveValue,
     4899                                 double & sumInfeasibilities,
     4900                                 int & numberUnsatisfied,int which) const
     4901{
     4902  assert (which>=0&&which<numberSubProblems_);
     4903  const CbcSubProblem * thisProb = subProblems_+which;
     4904  objectiveValue = thisProb->objectiveValue_;
     4905  sumInfeasibilities = thisProb->sumInfeasibilities_;
     4906  numberUnsatisfied = thisProb->numberInfeasibilities_;
     4907}
     4908/** Compare the original object of \c this with the original object of \c
     4909    brObj. Assumes that there is an ordering of the original objects.
     4910    This method should be invoked only if \c this and brObj are of the same
     4911    type.
     4912    Return negative/0/positive depending on whether \c this is
     4913    smaller/same/larger than the argument.
     4914*/
     4915int
     4916CbcGeneralBranchingObject::compareOriginalObject
     4917(const CbcBranchingObject* brObj) const
     4918{
     4919  throw("must implement");
     4920}
     4921
     4922/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
     4923    same type and must have the same original object, but they may have
     4924    different feasible regions.
     4925    Return the appropriate CbcRangeCompare value (first argument being the
     4926    sub/superset if that's the case). In case of overlap (and if \c
     4927    replaceIfOverlap is true) replace the current branching object with one
     4928    whose feasible region is the overlap.
     4929*/
     4930CbcRangeCompare
     4931CbcGeneralBranchingObject::compareBranchingObject
     4932(const CbcBranchingObject* brObj, const bool replaceIfOverlap)
     4933{
     4934  throw("must implement");
     4935}
     4936// Default Constructor
     4937CbcSubProblem::CbcSubProblem()
     4938  : objectiveValue_(0.0),
     4939    sumInfeasibilities_(0.0),
     4940    variables_(NULL),
     4941    newBounds_(NULL),
     4942    statusDifference_(NULL),
     4943    numberChangedBounds_(0),
     4944    numberInfeasibilities_(0)
     4945{
     4946}
     4947
     4948// Useful constructor
     4949CbcSubProblem::CbcSubProblem (const OsiSolverInterface * solver,
     4950                              const double * lastLower,
     4951                              const double * lastUpper,
     4952                              const unsigned char * status)
     4953  : objectiveValue_(0.0),
     4954    sumInfeasibilities_(0.0),
     4955    variables_(NULL),
     4956    newBounds_(NULL),
     4957    statusDifference_(NULL),
     4958    numberChangedBounds_(0),
     4959    numberInfeasibilities_(0)
     4960{
     4961  const double * lower = solver->getColLower();
     4962  const double * upper = solver->getColUpper();
     4963
     4964  numberChangedBounds_=0;
     4965  int numberColumns = solver->getNumCols();
     4966  int i;
     4967  for (i=0;i<numberColumns;i++) {
     4968    if (lower[i]!=lastLower[i])
     4969      numberChangedBounds_++;
     4970    if (upper[i]!=lastUpper[i])
     4971      numberChangedBounds_++;
     4972  }
     4973  if (numberChangedBounds_) {
     4974    newBounds_ = new double [numberChangedBounds_] ;
     4975    variables_ = new int [numberChangedBounds_] ;
     4976    numberChangedBounds_=0;
     4977    for (i=0;i<numberColumns;i++) {
     4978      if (lower[i]!=lastLower[i]) {
     4979        variables_[numberChangedBounds_]=i;
     4980        newBounds_[numberChangedBounds_++]=lower[i];
     4981      }
     4982      if (upper[i]!=lastUpper[i]) {
     4983        variables_[numberChangedBounds_]=i|0x80000000;
     4984        newBounds_[numberChangedBounds_++]=upper[i];
     4985      }
     4986#ifdef CBC_DEBUG
     4987      if (lower[i] != lastLower[i]) {
     4988        std::cout
     4989          << "lower on " << i << " changed from "
     4990          << lastLower[i] << " to " << lower[i] << std::endl ;
     4991      }
     4992      if (upper[i] != lastUpper[i]) {
     4993        std::cout
     4994          << "upper on " << i << " changed from "
     4995          << lastUpper[i] << " to " << upper[i] << std::endl ;
     4996      }
     4997#endif
     4998    }
     4999#ifdef CBC_DEBUG
     5000    std::cout << numberChangedBounds_ << " changed bounds." << std::endl ;
     5001#endif
     5002  }
     5003  const OsiClpSolverInterface * clpSolver
     5004    = dynamic_cast<const OsiClpSolverInterface *> (solver);
     5005  assert (clpSolver);
     5006  // Do difference
     5007  statusDifference_ = clpSolver->getBasisDiff(status);
     5008}
     5009
     5010// Copy constructor
     5011CbcSubProblem::CbcSubProblem ( const CbcSubProblem & rhs)
     5012  : objectiveValue_(rhs.objectiveValue_),
     5013    sumInfeasibilities_(rhs.sumInfeasibilities_),
     5014    variables_(NULL),
     5015    newBounds_(NULL),
     5016    statusDifference_(NULL),
     5017    numberChangedBounds_(rhs.numberChangedBounds_),
     5018    numberInfeasibilities_(rhs.numberInfeasibilities_)
     5019{
     5020  if (numberChangedBounds_) {
     5021    variables_ = CoinCopyOfArray(rhs.variables_,numberChangedBounds_);
     5022    newBounds_ = CoinCopyOfArray(rhs.newBounds_,numberChangedBounds_);
     5023  }
     5024  if (rhs.statusDifference_) {
     5025    statusDifference_ = rhs.statusDifference_->clone();
     5026  }
     5027}
     5028
     5029// Assignment operator
     5030CbcSubProblem &
     5031CbcSubProblem::operator=( const CbcSubProblem& rhs)
     5032{
     5033  if (this != &rhs) {
     5034    delete [] variables_;
     5035    delete [] newBounds_;
     5036    delete statusDifference_;
     5037    objectiveValue_ = rhs.objectiveValue_;
     5038    sumInfeasibilities_ = rhs.sumInfeasibilities_;
     5039    numberChangedBounds_ = rhs.numberChangedBounds_;
     5040    numberInfeasibilities_ = rhs.numberInfeasibilities_;
     5041    if (numberChangedBounds_) {
     5042      variables_ = CoinCopyOfArray(rhs.variables_,numberChangedBounds_);
     5043      newBounds_ = CoinCopyOfArray(rhs.newBounds_,numberChangedBounds_);
     5044    } else {
     5045      variables_ = NULL;
     5046      newBounds_ = NULL;
     5047    }
     5048    if (rhs.statusDifference_) {
     5049      statusDifference_ = rhs.statusDifference_->clone();
     5050    } else {
     5051      statusDifference_ = NULL;
     5052    }
     5053  }
     5054  return *this;
     5055}
     5056
     5057// Destructor
     5058CbcSubProblem::~CbcSubProblem ()
     5059{
     5060  delete [] variables_;
     5061  delete [] newBounds_;
     5062  delete statusDifference_;
     5063}
     5064// Apply subproblem
     5065void
     5066CbcSubProblem::apply(OsiSolverInterface * solver)
     5067{
     5068  int i;
     5069  for (i=0;i<numberChangedBounds_;i++) {
     5070    int variable = variables_[i];
     5071    int k = variable&0x3fffffff;
     5072    if ((variable&0x80000000)==0) {
     5073      // lower bound changing
     5074      //#define CBC_PRINT2
     5075#ifdef CBC_PRINT2
     5076      if(solver->getColLower()[k]!=newBounds_[i])
     5077        printf("lower change for column %d - from %g to %g\n",k,solver->getColLower()[k],newBounds_[i]);
     5078#endif
     5079#ifndef NDEBUG
     5080      if ((variable&0x40000000)==0&&true) {
     5081        double oldValue = solver->getColLower()[k];
     5082        assert (newBounds_[i]>oldValue-1.0e-8);
     5083        if (newBounds_[i]<oldValue+1.0e-8)
     5084          printf("bad null lower change for column %d - bound %g\n",k,oldValue);
     5085      }
     5086#endif
     5087      solver->setColLower(k,newBounds_[i]);
     5088    } else {
     5089      // upper bound changing
     5090#ifdef CBC_PRINT2
     5091      if(solver->getColUpper()[k]!=newBounds_[i])
     5092        printf("upper change for column %d - from %g to %g\n",k,solver->getColUpper()[k],newBounds_[i]);
     5093#endif
     5094#ifndef NDEBUG
     5095      if ((variable&0x40000000)==0&&true) {
     5096        double oldValue = solver->getColUpper()[k];
     5097        assert (newBounds_[i]<oldValue+1.0e-8);
     5098        if (newBounds_[i]>oldValue-1.0e-8)
     5099          printf("bad null upper change for column %d - bound %g\n",k,oldValue);
     5100      }
     5101#endif
     5102      solver->setColUpper(k,newBounds_[i]);
     5103    }
     5104  }
     5105  OsiClpSolverInterface * clpSolver
     5106    = dynamic_cast<OsiClpSolverInterface *> (solver);
     5107  assert (clpSolver);
     5108  // Current basis
     5109  CoinWarmStartBasis * basis=clpSolver->getPointerToWarmStart();
     5110  basis->applyDiff(statusDifference_);
     5111  clpSolver->setBasis(*basis);
     5112}
     5113#endif
     5114
    40025115/** Compare the original object of \c this with the original object of \c
    40035116    brObj. Assumes that there is an ordering of the original objects.
     
    40285141  throw("must implement");
    40295142}
    4030 
  • trunk/Cbc/src/CbcBranchActual.hpp

    r912 r931  
    129129  /// Infeasibility - large is 0.5
    130130  virtual double infeasibility(int & preferredWay) const;
     131  /// Infeasibility - large is 0.5
     132  virtual double infeasibility(const OsiBranchingInformation * info,
     133                               int & preferredWay) const;
    131134
    132135  using CbcObject::feasibleRegion ;
     
    138141  virtual CbcBranchingObject * createBranch(int way) ;
    139142
     143
     144
     145  /** Pass in information on branch just done and create CbcObjectUpdateData instance.
     146      If object does not need data then backward pointer will be NULL.
     147      Assumes can get information from solver */
     148  virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver,
     149                                                        const CbcNode * node,
     150                                                        const CbcBranchingObject * branchingObject);
     151  /// Update object by CbcObjectUpdateData
     152  virtual void updateInformation(const CbcObjectUpdateData & data) ;
    140153  using CbcObject::solverBranch ;
    141154  /** Create an OsiSolverBranch object
     
    160173  inline int sosType() const
    161174  {return sosType_;}
     175  /// Down number times
     176  inline int numberTimesDown() const
     177  { return numberTimesDown_;}
     178  /// Up number times
     179  inline int numberTimesUp() const
     180  { return numberTimesUp_;}
    162181
    163182  /** Array of weights */
     
    191210  /// Weights
    192211  double * weights_;
    193 
     212  /// Current pseudo-shadow price estimate down
     213  mutable double shadowEstimateDown_;
     214  /// Current pseudo-shadow price estimate up
     215  mutable double shadowEstimateUp_;
     216  /// Down pseudo ratio
     217  double downDynamicPseudoRatio_;
     218  /// Up pseudo ratio
     219  double upDynamicPseudoRatio_;
     220  /// Number of times we have gone down
     221  int numberTimesDown_;
     222  /// Number of times we have gone up
     223  int numberTimesUp_;
    194224  /// Number of members
    195225  int numberMembers_;
    196226  /// SOS type
    197    int sosType_;
     227  int sosType_;
    198228  /// Whether integer valued
    199229  bool integerValued_;
     
    449479  */
    450480  virtual double branch();
     481  /** Update bounds in solver as in 'branch' and update given bounds.
     482      branchState is -1 for 'down' +1 for 'up' */
     483  virtual void fix(OsiSolverInterface * solver,
     484                   double * lower, double * upper,
     485                   int branchState) const ;
    451486
    452487#if 0
     
    516551#ifdef FUNNY_BRANCHING
    517552  /** Which variable (top bit if upper bound changing)
    518       next bit if chnaging on down branch only */
     553      next bit if changing on down branch only */
    519554  int * variables_;
    520555  // New bound
     
    897932  /// Does next branch and updates state
    898933  virtual double branch();
     934  /** Update bounds in solver as in 'branch' and update given bounds.
     935      branchState is -1 for 'down' +1 for 'up' */
     936  virtual void fix(OsiSolverInterface * solver,
     937                   double * lower, double * upper,
     938                   int branchState) const ;
    899939
    900940  /** Reset every information so that the branching object appears to point to
     
    13801420};
    13811421
    1382 
     1422/** Define a catch all class.
     1423    This will create a list of subproblems
     1424*/
     1425
     1426
     1427class CbcGeneral : public CbcObject {
     1428
     1429public:
     1430
     1431  // Default Constructor
     1432  CbcGeneral ();
     1433
     1434  /** Useful constructor
     1435      Just needs to point to model.
     1436  */
     1437  CbcGeneral (CbcModel * model);
     1438 
     1439  // Copy constructor
     1440  CbcGeneral ( const CbcGeneral &);
     1441   
     1442  /// Clone
     1443  virtual CbcObject * clone() const=0;
     1444
     1445  // Assignment operator
     1446  CbcGeneral & operator=( const CbcGeneral& rhs);
     1447
     1448  // Destructor
     1449  ~CbcGeneral ();
     1450 
     1451  using CbcObject::infeasibility ;
     1452  /// Infeasibility - large is 0.5
     1453  virtual double infeasibility(int & preferredWay) const=0;
     1454
     1455  using CbcObject::feasibleRegion ;
     1456  /// This looks at solution and sets bounds to contain solution
     1457  virtual void feasibleRegion()=0;
     1458
     1459  using CbcObject::createBranch ;
     1460  /// Creates a branching object
     1461  virtual CbcBranchingObject * createBranch(int way)=0 ;
     1462
     1463  /// Redoes data when sequence numbers change
     1464  virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)=0;
     1465
     1466protected:
     1467  /// data
     1468};
     1469#ifdef COIN_HAS_CLP
     1470
     1471/** Define a catch all class.
     1472    This will create a list of subproblems using partial evaluation
     1473*/
     1474#include "ClpSimplex.hpp"
     1475#include "ClpNode.hpp"
     1476
     1477class CbcGeneralDepth : public CbcGeneral {
     1478
     1479public:
     1480
     1481  // Default Constructor
     1482  CbcGeneralDepth ();
     1483
     1484  /** Useful constructor
     1485      Just needs to point to model.
     1486      Initial version does evaluation to depth N
     1487      This is stored in CbcModel but may be
     1488      better here
     1489  */
     1490  CbcGeneralDepth (CbcModel * model, int maximumDepth);
     1491 
     1492  // Copy constructor
     1493  CbcGeneralDepth ( const CbcGeneralDepth &);
     1494   
     1495  /// Clone
     1496  virtual CbcObject * clone() const;
     1497
     1498  // Assignment operator
     1499  CbcGeneralDepth & operator=( const CbcGeneralDepth& rhs);
     1500
     1501  // Destructor
     1502  ~CbcGeneralDepth ();
     1503 
     1504  using CbcObject::infeasibility ;
     1505  /// Infeasibility - large is 0.5
     1506  virtual double infeasibility(int & preferredWay) const;
     1507
     1508  using CbcObject::feasibleRegion ;
     1509  /// This looks at solution and sets bounds to contain solution
     1510  virtual void feasibleRegion();
     1511
     1512  using CbcObject::createBranch ;
     1513  /// Creates a branching object
     1514  virtual CbcBranchingObject * createBranch(int way) ;
     1515  /// Get maximum depth
     1516  inline int maximumDepth() const
     1517  {return maximumDepth_;}
     1518  /// Set maximum depth
     1519  inline void setMaximumDepth(int value)
     1520  {maximumDepth_ = value;}
     1521  /// Get which solution
     1522  inline int whichSolution() const
     1523  {return whichSolution_;}
     1524  /// Get ClpNode info
     1525  inline ClpNode * nodeInfo(int which)
     1526  { return nodeInfo_->nodeInfo_[which];}
     1527
     1528  /// Redoes data when sequence numbers change
     1529  virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns);
     1530
     1531protected:
     1532  /// data
     1533  /// Maximum depth
     1534  int maximumDepth_;
     1535  /// Which node has solution (or -1)
     1536  mutable int whichSolution_;
     1537  /// Number of valid nodes (including whichSolution_)
     1538  mutable int numberNodes_;
     1539  /// For solving nodes
     1540  mutable ClpNodeStuff * nodeInfo_;
     1541};
     1542
     1543/** Defines a general subproblem
     1544    Basis will be made more compact later
     1545*/
     1546class CoinWarmStartDiff;
     1547class CbcSubProblem {
     1548
     1549public:
     1550
     1551  /// Default constructor
     1552  CbcSubProblem ();
     1553
     1554  /// Constructor from model
     1555  CbcSubProblem (const OsiSolverInterface * solver,
     1556                 const double * lowerBefore,
     1557                 const double * upperBefore,
     1558                 const unsigned char * status);
     1559
     1560  /// Copy constructor
     1561  CbcSubProblem ( const CbcSubProblem &);
     1562   
     1563  /// Assignment operator
     1564  CbcSubProblem & operator= (const CbcSubProblem& rhs);
     1565
     1566  /// Destructor
     1567  virtual ~CbcSubProblem ();
     1568
     1569  /// Apply subproblem
     1570  void apply(OsiSolverInterface * model);
     1571
     1572public:
     1573  /// Value of objective
     1574  double objectiveValue_;
     1575  /// Sum of infeasibilities
     1576  double sumInfeasibilities_;
     1577  /** Which variable (top bit if upper bound changing)
     1578      next bit if changing on down branch only */
     1579  int * variables_;
     1580  /// New bound
     1581  double * newBounds_;
     1582  /// Status as diff
     1583  CoinWarmStartDiff * statusDifference_;
     1584  /// Number of Extra bound changes
     1585  int numberChangedBounds_;
     1586  /// Number of infeasibilities
     1587  int numberInfeasibilities_;
     1588};
     1589
     1590/** Branching object for general objects
     1591
     1592 */
     1593class CbcNode;
     1594class CbcGeneralBranchingObject : public CbcBranchingObject {
     1595
     1596public:
     1597
     1598  // Default Constructor
     1599  CbcGeneralBranchingObject ();
     1600
     1601  // Useful constructor
     1602  CbcGeneralBranchingObject (CbcModel * model);
     1603 
     1604  // Copy constructor
     1605  CbcGeneralBranchingObject ( const CbcGeneralBranchingObject &);
     1606   
     1607  // Assignment operator
     1608  CbcGeneralBranchingObject & operator=( const CbcGeneralBranchingObject& rhs);
     1609
     1610  /// Clone
     1611  virtual CbcBranchingObject * clone() const;
     1612
     1613  // Destructor
     1614  virtual ~CbcGeneralBranchingObject ();
     1615 
     1616  using CbcBranchingObject::branch ;
     1617  /// Does next branch and updates state
     1618  virtual double branch();
     1619  /** Double checks in case node can change its mind!
     1620      Can change objective etc */
     1621  virtual void checkIsCutoff(double cutoff);
     1622
     1623  using CbcBranchingObject::print ;
     1624  /** \brief Print something about branch - only if log level high
     1625  */
     1626  virtual void print();
     1627  /// Fill in current objective etc
     1628  void state(double & objectiveValue,double & sumInfeasibilities,
     1629             int & numberUnsatisfied,int which) const;
     1630  /// Set CbcNode
     1631  inline void setNode(CbcNode * node)
     1632  { node_ = node;}
     1633  /** Return the type (an integer identifier) of \c this */
     1634  virtual int type() const { return 108; }
     1635
     1636  /** Compare the original object of \c this with the original object of \c
     1637      brObj. Assumes that there is an ordering of the original objects.
     1638      This method should be invoked only if \c this and brObj are of the same
     1639      type.
     1640      Return negative/0/positive depending on whether \c this is
     1641      smaller/same/larger than the argument.
     1642  */
     1643  virtual int compareOriginalObject(const CbcBranchingObject* brObj) const;
     1644
     1645  /** Compare the \c this with \c brObj. \c this and \c brObj must be os the
     1646      same type and must have the same original object, but they may have
     1647      different feasible regions.
     1648      Return the appropriate CbcRangeCompare value (first argument being the
     1649      sub/superset if that's the case). In case of overlap (and if \c
     1650      replaceIfOverlap is true) replace the current branching object with one
     1651      whose feasible region is the overlap.
     1652   */
     1653  virtual CbcRangeCompare compareBranchingObject
     1654  (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false);
     1655
     1656public:
     1657  /// data
     1658  // Sub problems
     1659  CbcSubProblem * subProblems_;
     1660  /// Node
     1661  CbcNode * node_;
     1662  /// Number of subproblems
     1663  int numberSubProblems_;
     1664  /// Number of rows
     1665  int numberRows_;
     1666};
    13831667#endif
     1668#endif
  • trunk/Cbc/src/CbcBranchBase.hpp

    r912 r931  
    292292  inline void resetNumberBranchesLeft()
    293293  { branchIndex_=0;}
     294  /// Set number of branches to do
     295  inline void setNumberBranches(int value)
     296  { branchIndex_=0;numberBranches_=value;}
    294297
    295298  /** \brief Execute the actions required to branch, as specified by the
     
    308311  virtual double branch(OsiSolverInterface * solver)
    309312  { return branch();}
     313  /** Update bounds in solver as in 'branch' and update given bounds.
     314      branchState is -1 for 'down' +1 for 'up' */
     315  virtual void fix(OsiSolverInterface * solver,
     316                   double * lower, double * upper,
     317                   int branchState) const {};
    310318
    311319  /** Reset every information so that the branching object appears to point to
  • trunk/Cbc/src/CbcBranchDynamic.cpp

    r904 r931  
    259259  sumDownChange_ = 0.0;
    260260  numberTimesDown_ = 0;
     261  sumUpCost_ = 1.0e-4*upDynamicPseudoCost_;
     262  sumDownCost_ = 1.0e-4*downDynamicPseudoCost_;
    261263#else
    262264  sumUpCost_ = 1.0*upDynamicPseudoCost_;
     
    452454  //printf("XX %d down %d %d %g up %d %d %g\n",columnNumber_,numberTimesDown_,numberTimesDownInfeasible_,downDynamicPseudoCost_,
    453455  // numberTimesUp_,numberTimesUpInfeasible_,upDynamicPseudoCost_);
     456  assert (downDynamicPseudoCost_>1.0e-40&&upDynamicPseudoCost_>1.0e-40);
    454457}
    455458// Same - returns true if contents match(ish)
     
    577580CbcSimpleIntegerDynamicPseudoCost::infeasibility(int & preferredWay) const
    578581{
     582  assert (downDynamicPseudoCost_>1.0e-40&&upDynamicPseudoCost_>1.0e-40);
    579583  const double * solution = model_->testSolution();
    580584  const double * lower = model_->getCbcColLower();
     
    12221226#endif
    12231227  //print(1,0.5);
     1228  assert (downDynamicPseudoCost_>1.0e-40&&upDynamicPseudoCost_>1.0e-40);
     1229}
     1230// Updates stuff like pseudocosts after mini branch and bound
     1231void
     1232CbcSimpleIntegerDynamicPseudoCost::updateAfterMini(int numberDown,int numberDownInfeasible,
     1233                                                   double sumDown, int numberUp,
     1234                                                   int numberUpInfeasible,double sumUp)
     1235{
     1236#ifdef CBC_INSTRUMENT
     1237  int difference = numberDown-numberTimesDown_;
     1238  difference += numberUp-numberTimesUp_;
     1239  numberTimesInfeasible_ += 2*difference;
     1240#endif
     1241  numberTimesDown_ = numberDown;
     1242  numberTimesDownInfeasible_ = numberDownInfeasible;
     1243  sumDownCost_ = sumDown;
     1244  numberTimesUp_ = numberUp;
     1245  numberTimesUpInfeasible_ = numberUpInfeasible;
     1246  sumUpCost_ = sumUp;
     1247  if (numberTimesDown_+numberTimesDownInfeasible_>0) {
     1248    setDownDynamicPseudoCost(sumDownCost_/(double) (numberTimesDown_+numberTimesDownInfeasible_));
     1249    assert (downDynamicPseudoCost_>0.0&&downDynamicPseudoCost_<1.0e50);
     1250  }
     1251  if (numberTimesUp_+numberTimesUpInfeasible_>0) {
     1252    setUpDynamicPseudoCost(sumUpCost_/(double) (numberTimesUp_+numberTimesUpInfeasible_));
     1253    assert (upDynamicPseudoCost_>0.0&&upDynamicPseudoCost_<1.0e50);
     1254  }
     1255  assert (downDynamicPseudoCost_>1.0e-40&&upDynamicPseudoCost_>1.0e-40);
    12241256}
    12251257// Pass in probing information
     
    15031535{
    15041536  OsiBranchingObject * obj = object->clone();
     1537  CbcBranchingObject * obj2 =
     1538    dynamic_cast<CbcBranchingObject *>(obj);
     1539  assert (obj2);
    15051540  CbcDynamicPseudoCostBranchingObject * branchingObject =
    15061541    dynamic_cast<CbcDynamicPseudoCostBranchingObject *>(obj);
    1507   assert (branchingObject);
    1508   object_=branchingObject;
     1542#if COIN_DEVELOP>1
     1543  if (!branchingObject)
     1544    printf("no dynamic branching object Dynamic Decision\n");
     1545#endif
     1546  //object_=branchingObject;
     1547  object_ = obj2;
    15091548}
    15101549/* Pass in information on branch just done.
     
    18041843    CbcDynamicPseudoCostBranchingObject * branchingObject =
    18051844      dynamic_cast<CbcDynamicPseudoCostBranchingObject *>(thisOne);
    1806     assert (branchingObject);
    1807     CbcSimpleIntegerDynamicPseudoCost *  object = branchingObject->object();
    1808     assert (object);
    1809     hist.where_='C';
    1810     hist.status_=' ';
    1811     hist.sequence_=object->columnNumber();
    1812     hist.numberUp_=object->numberTimesUp();
    1813     hist.numberUpInf_=numInfUp;
    1814     hist.sumUp_=object->sumUpCost();
    1815     hist.upEst_=changeUp;
    1816     hist.numberDown_=object->numberTimesDown();
    1817     hist.numberDownInf_=numInfDown;
    1818     hist.sumDown_=object->sumDownCost();
    1819     hist.downEst_=changeDown;
     1845    if (branchingObject) {
     1846      CbcSimpleIntegerDynamicPseudoCost *  object = branchingObject->object();
     1847      assert (object);
     1848      hist.where_='C';
     1849      hist.status_=' ';
     1850      hist.sequence_=object->columnNumber();
     1851      hist.numberUp_=object->numberTimesUp();
     1852      hist.numberUpInf_=numInfUp;
     1853      hist.sumUp_=object->sumUpCost();
     1854      hist.upEst_=changeUp;
     1855      hist.numberDown_=object->numberTimesDown();
     1856      hist.numberDownInf_=numInfDown;
     1857      hist.sumDown_=object->sumDownCost();
     1858      hist.downEst_=changeDown;
     1859    }
    18201860  }
    18211861#endif
  • trunk/Cbc/src/CbcBranchDynamic.hpp

    r912 r931  
    8585  /// Updates stuff like pseudocosts after threads finished
    8686  virtual void updateAfter(const OsiObject * rhs, const OsiObject * baseObject) ;
     87  /// Updates stuff like pseudocosts after mini branch and bound
     88  void updateAfterMini(int numberDown,int numberDownInfeasible,double sumDown,
     89                       int numberUp,int numberUpInfeasible,double sumUp);
    8790
    8891  using CbcSimpleInteger::solverBranch ;
  • trunk/Cbc/src/CbcCutGenerator.cpp

    r904 r931  
    166166*/
    167167bool
    168 CbcCutGenerator::generateCuts( OsiCuts & cs , bool fullScan, OsiSolverInterface * solver, CbcNode * node)
     168CbcCutGenerator::generateCuts( OsiCuts & cs , int fullScan, OsiSolverInterface * solver, CbcNode * node)
    169169{
    170170  int howOften = whenCutGenerator_;
     
    205205  // Switch off if special setting
    206206  if (whenCutGeneratorInSub_==-200) {
    207     fullScan=false;
     207    fullScan=0;
    208208    doThis=false;
    209209  }
     
    214214    //#define CBC_DEBUG
    215215    int numberRowCutsBefore = cs.sizeRowCuts() ;
     216    int numberColumnCutsBefore = cs.sizeColCuts() ;
     217#if 0
    216218    int cutsBefore = cs.sizeCuts();
     219#endif
    217220    CglTreeInfo info;
    218221    info.level = depth;
     
    395398      }
    396399    }
     400    {
     401      int numberRowCutsAfter = cs.sizeRowCuts() ;
     402      if (numberRowCutsBefore<numberRowCutsAfter) {
     403#if 0
     404        printf("generator %s generated %d row cuts\n",
     405               generatorName_,numberRowCutsAfter-numberRowCutsBefore);
     406#endif
     407        numberCuts_ += numberRowCutsAfter-numberRowCutsBefore;
     408      }
     409      int numberColumnCutsAfter = cs.sizeColCuts() ;
     410      if (numberColumnCutsBefore<numberColumnCutsAfter) {
     411#if 0
     412        printf("generator %s generated %d column cuts\n",
     413               generatorName_,numberColumnCutsAfter-numberColumnCutsBefore);
     414#endif
     415        numberColumnCuts_ += numberColumnCutsAfter-numberColumnCutsBefore;
     416      }
     417    }
    397418#ifdef CBC_DEBUG
    398419    {
     
    446467 
    447468  if (howOften>=1000000) {
    448     // leave Probing every 10
     469    // leave Probing every SCANCUTS_PROBING
    449470    howOften = howOften % 1000000;
    450471    CglProbing* generator =
    451472      dynamic_cast<CglProbing*>(generator_);
    452473   
    453     if (generator&&howOften>10)
    454       howOften=10+1000000;
     474    if (generator&&howOften>SCANCUTS_PROBING)
     475      howOften=SCANCUTS_PROBING+1000000;
    455476    else
    456477      howOften += 1000000;
  • trunk/Cbc/src/CbcCutGenerator.hpp

    r838 r931  
    5555    \p cs.
    5656
    57     If \p fullScan is true, the generator is obliged to call the CGL
     57    If \p fullScan is >0, the generator is obliged to call the CGL
    5858    \c generateCuts routine.  Otherwise, it is free to make a local decision.
    5959    The current implementation uses \c whenCutGenerator_ to decide.
     
    6464    If node then can find out depth
    6565  */
    66   bool generateCuts( OsiCuts &cs, bool fullScan,OsiSolverInterface * solver,
     66  bool generateCuts( OsiCuts &cs, int fullScan,OsiSolverInterface * solver,
    6767                     CbcNode * node);
    6868  //@}
     
    391391  int firstOdd_;
    392392};
     393// How often to do if mostly switched off (A)
     394# define SCANCUTS 1000 
     395// How often to do if mostly switched off (probing B)
     396# define SCANCUTS_PROBING 1000 
    393397
    394398#endif
  • trunk/Cbc/src/CbcHeuristic.cpp

    r915 r931  
    108108  minDistanceToRun_(1),
    109109  runNodes_(),
    110   numCouldRun_(0)
     110  numCouldRun_(0),
     111  numberSolutionsFound_(0)
    111112{
    112113  // As CbcHeuristic virtual need to modify .cpp if above change
     
    131132  minDistanceToRun_(1),
    132133  runNodes_(),
    133   numCouldRun_(0)
     134  numCouldRun_(0),
     135  numberSolutionsFound_(0)
    134136{}
    135137
     
    155157  minDistanceToRun_ = rhs.minDistanceToRun_;
    156158  runNodes_ = rhs.runNodes_;
     159  numberSolutionsFound_ = rhs.numberSolutionsFound_;
    157160}
    158161// Copy constructor
     
    346349    double probability = numerator / denominator;
    347350    double randomNumber = randomNumberGenerator_.randomDouble();
     351    if (when_>2&&when_<7) {
     352      /* JJF adjustments
     353         3 only at root and if no solution
     354         4 only at root and if this heuristic has not got solution
     355         5 only at depth <4
     356         6 decay
     357      */
     358      switch(when_) {
     359      case 3:
     360        if (model_->bestSolution())
     361          probability=-1.0;
     362        break;
     363      case 4:
     364        if (numberSolutionsFound_)
     365          probability=-1.0;
     366        break;
     367      case 5:
     368        if (depth>=4)
     369          probability=-1.0;
     370        break;
     371      case 6:
     372        if (depth>=4) {
     373          if (numberSolutionsFound_*howOften_<numCouldRun_)
     374            howOften_ = (int) (howOften_*1.1);
     375          probability = 1.0/howOften_;
     376          if (model_->bestSolution())
     377            probability *= 0.5;
     378        }
     379        break;
     380      }
     381    }
    348382    if (randomNumber>probability)
    349383      return false;
     
    412446                                  double cutoff, std::string name) const
    413447{
     448  // size before
     449  double before = 2*solver->getNumRows()+solver->getNumCols();
     450  // Use this fraction
     451  double fractionSmall = fractionSmall_;
     452  if (before>80000.0) {
     453    // fairly large - be more conservative
     454    double multiplier = (0.7*200000.0)/CoinMin(before,200000.0);
     455    if (multiplier<1.0)
     456      fractionSmall *= multiplier;
     457#ifdef COIN_DEVELOP
     458    printf("changing fractionSmall from %g to %g for %s\n",
     459           fractionSmall_,fractionSmall,name.c_str());
     460#endif
     461  }
    414462#ifdef COIN_HAS_CLP
    415463  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
     
    456504    delete pinfo;
    457505    // see if too big
    458     double before = 2*solver->getNumRows()+solver->getNumCols();
    459506    if (presolvedModel) {
    460507      int afterRows = presolvedModel->getNumRows();
     
    462509      delete presolvedModel;
    463510      double after = 2*afterRows+afterCols;
    464       if (after>fractionSmall_*before&&after>300) {
     511      if (after>fractionSmall*before&&after>300) {
    465512        // Need code to try again to compress further using used
    466513        const int * used =  model_->usedInSolution();
     
    514561            delete presolvedModel;
    515562            double after = 2*afterRows2+afterCols2;
    516             if (after>fractionSmall_*before&&after>300) {
     563            if (after>fractionSmall*before&&after>300) {
    517564              sprintf(generalPrint,"Full problem %d rows %d columns, reduced to %d rows %d columns - %d fixed gives %d, %d - still too large",
    518565                      solver->getNumRows(),solver->getNumCols(),
     
    544591  }
    545592  // Reduce printout
     593  bool takeHint;
     594  OsiHintStrength strength;
     595  solver->getHintParam(OsiDoReducePrint,takeHint,strength);
    546596  solver->setHintParam(OsiDoReducePrint,true,OsiHintTry);
    547597  solver->setHintParam(OsiDoPresolveInInitial,false,OsiHintTry);
     
    561611    } else {
    562612      // see if too big
    563       double before = 2*solver->getNumRows()+solver->getNumCols();
     613      //double before = 2*solver->getNumRows()+solver->getNumCols();
    564614      double after = 2*solver2->getNumRows()+solver2->getNumCols();
    565       if (after>fractionSmall_*before&&after>300) {
     615      if (after>fractionSmall*before&&after>300) {
    566616        sprintf(generalPrint,"Full problem %d rows %d columns, reduced to %d rows %d columns - too large",
    567617                solver->getNumRows(),solver->getNumCols(),
     
    669719        model.setParentModel(*model_);
    670720        model.setOriginalColumns(process.originalColumns());
     721        model.setSearchStrategy(-1);
     722        if (model_->searchStrategy()==2) {
     723          model.setNumberStrong(5);
     724          model.setNumberBeforeTrust(5);
     725        }
    671726        if (model.getNumCols()) {
    672727          setCutAndHeuristicOptions(model);
     
    737792  }
    738793#endif
     794  solver->setHintParam(OsiDoReducePrint,takeHint,strength);
    739795  return returnCode;
    740796}
     
    793849  } else {
    794850    numObjects_ = 0;
    795     CbcBranchingObject* br;
     851    CbcBranchingObject* br=NULL; // What should this be?
    796852    for (int i = 1; i < cnt; ++i) {
    797853      if (compare3BranchingObjects(brObj_[numObjects_], brObj_[i]) == 0) {
  • trunk/Cbc/src/CbcHeuristic.hpp

    r915 r931  
    152152  inline double fractionSmall() const
    153153  { return fractionSmall_;}
     154  /// Get how many solutions the heuristic thought it got
     155  inline int numberSolutionsFound() const
     156  { return numberSolutionsFound_;}
     157  /// Increment how many solutions the heuristic thought it got
     158  inline void incrementNumberSolutionsFound()
     159  { numberSolutionsFound_++;}
    154160
    155161  /** Do mini branch and bound - return
     
    184190  void debugNodes();
    185191  void printDistanceToNodes();
     192  /// how many times the heuristic has actually run
     193  inline int numRuns() const
     194  { return numRuns_;}
     195
     196  /// How many times the heuristic could run
     197  inline int numCouldRun() const
     198  { return numCouldRun_;}
    186199
    187200protected:
     
    236249  int numCouldRun_;
    237250
     251  /// How many solutions the heuristic thought it got
     252  int numberSolutionsFound_;
     253
    238254
    239255#if 0
  • trunk/Cbc/src/CbcHeuristicFPump.cpp

    r904 r931  
    3333   weightFactor_(0.1),
    3434   artificialCost_(COIN_DBL_MAX),
     35   iterationRatio_(0.0),
    3536   maximumPasses_(100),
    3637   maximumRetries_(1),
     
    5556   weightFactor_(0.1),
    5657   artificialCost_(COIN_DBL_MAX),
     58   iterationRatio_(0.0),
    5759   maximumPasses_(100),
    5860   maximumRetries_(1),
     
    143145  weightFactor_(rhs.weightFactor_),
    144146  artificialCost_(rhs.artificialCost_),
     147  iterationRatio_(rhs.iterationRatio_),
    145148  maximumPasses_(rhs.maximumPasses_),
    146149  maximumRetries_(rhs.maximumRetries_),
     
    166169    weightFactor_ = rhs.weightFactor_;
    167170    artificialCost_ = rhs.artificialCost_;
     171    iterationRatio_ = rhs.iterationRatio_;
    168172    maximumPasses_ = rhs.maximumPasses_;
    169173    maximumRetries_ = rhs.maximumRetries_;
     
    215219  int numberIntegers = model_->numberIntegers();
    216220  const int * integerVariableOrig = model_->integerVariable();
    217 
     221  double iterationLimit = -1.0;
     222  //iterationRatio_=1.0;
     223  if (iterationRatio_>0.0)
     224    iterationLimit = (2*model_->solver()->getNumRows()+2*numberColumns)*
     225      iterationRatio_;
     226  double totalNumberIterations=0.0;
    218227  // 1. initially check 0-1
    219228  int i,j;
     
    324333    int numberPasses=0;
    325334    artificialFactor *= 10.0;
     335    int lastMove= (!numberTries) ? -10 : 1000000;
     336    double lastSumInfeas=COIN_DBL_MAX;
    326337    numberTries++;
    327338    // Clone solver - otherwise annoys root node computations
     
    467478        }
    468479      }
    469       if (numberPasses>=maximumPasses_) {
     480      if (iterationLimit<0.0) {
     481        if (numberPasses>=maximumPasses_) {
     482          // If going well then keep going if maximumPasses_ small
     483          if (lastMove<numberPasses-4||lastMove==1000000)
     484            break;
     485          if (maximumPasses_>20||numberPasses>=40)
     486            break;
     487        }
     488      } else if (totalNumberIterations>iterationLimit&&numberPasses>15) {
     489          // exiting on iteration count
     490        break;
     491      } else if (maximumPasses_<30&&numberPasses>100) {
     492        // too many passes anyway
    470493        break;
    471494      }
     
    548571                model_->setBestSolution(betterSolution,numberColumns,newSolutionValue);
    549572                int action = handler->event(CbcEventHandler::heuristicSolution);
    550                 if (saveOldSolution) {
     573                if (saveOldSolution&&saveObjectiveValue<model_->getMinimizationObjValue())
    551574                  model_->setBestSolution(saveOldSolution,numberColumns,saveObjectiveValue);
    552                   delete [] saveOldSolution;
    553                 }
     575                delete [] saveOldSolution;
    554576                if (!action||model_->getCurrentSeconds()>model_->getMaximumSeconds()) {
    555577                  exitAll=true; // exit
     
    780802                  model_->setBestSolution(betterSolution,numberColumns,newSolutionValue);
    781803                  int action = handler->event(CbcEventHandler::heuristicSolution);
    782                   if (saveOldSolution) {
     804                  if (saveOldSolution&&saveObjectiveValue<model_->getMinimizationObjValue())
    783805                    model_->setBestSolution(saveOldSolution,numberColumns,saveObjectiveValue);
    784                     delete [] saveOldSolution;
    785                   }
     806                  delete [] saveOldSolution;
    786807                  if (!action||model_->getCurrentSeconds()>model_->getMaximumSeconds()) {
    787808                    exitAll=true; // exit
     
    854875            }
    855876            newTrueSolutionValue *= direction;
     877          }
     878          if (false) {
    856879            OsiSolverInterface * saveSolver = model_->swapSolver(solver);
    857880            CbcRounding heuristic1(*model_);
    858881            heuristic1.setHeuristicName("rounding in feaspump!");
    859882            heuristic1.setWhen(1);
     883            roundingObjective = newTrueSolutionValue;
    860884            double testObjectiveValue = CoinMin(solutionValue,roundingObjective);
    861885            int returnCode = heuristic1.solution(testObjectiveValue,roundingSolution,newTrueSolutionValue) ;
     
    863887              assert(testObjectiveValue < CoinMin(solutionValue,roundingObjective));
    864888              roundingObjective = testObjectiveValue;
     889            } else {
     890              roundingObjective = COIN_DBL_MAX;
    865891            }
    866892            model_->swapSolver(saveSolver);
     
    951977          }
    952978        }
     979        if (lastMove!=1000000) {
     980          if (newSumInfeas<lastSumInfeas) {
     981            lastMove=numberPasses;
     982            lastSumInfeas=newSumInfeas;
     983          } else if (newSumInfeas>lastSumInfeas+1.0e-5) {
     984            lastMove=1000000; // going up
     985          }
     986        }
     987        totalNumberIterations += solver->getIterationCount();
    953988        if (solver->getNumRows()<3000)
    954989          sprintf(pumpPrint,"Pass %3d: suminf. %10.5f obj. %g iterations %d", numberPasses+totalNumberPasses,
     
    9821017      sprintf(pumpPrint,"Rounding solution of %g is better than previous of %g !\n",
    9831018              roundingObjective,solutionValue);
     1019      model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
     1020        << pumpPrint
     1021        <<CoinMessageEol;
    9841022      solutionValue=roundingObjective;
    9851023      memcpy(betterSolution,roundingSolution,numberColumns*sizeof(double));
     
    10851123        returnCode &= ~2;
    10861124      }
     1125      // recompute solution value
     1126      if (returnCode&&true) {
     1127        delete newSolver;
     1128        newSolver = model_->continuousSolver()->clone();
     1129        newSolutionValue = -saveOffset;
     1130        double newSumInfeas=0.0;
     1131        const double * obj = newSolver->getObjCoefficients();
     1132        for (int i=0 ; i<numberColumns ; i++ ) {
     1133          if (newSolver->isInteger(i)) {
     1134            double value = newSolution[i];
     1135            double nearest = floor(value+0.5);
     1136            newSumInfeas += fabs(value-nearest);
     1137          }
     1138          newSolutionValue += obj[i]*newSolution[i];
     1139        }
     1140        newSolutionValue *= direction;
     1141      }
    10871142      if (returnCode&&newSolutionValue<saveValue) {
    10881143        sprintf(pumpPrint,"Mini branch and bound improved solution from %g to %g (%.2f seconds)",
     
    11101165            double value = newSolver->getObjValue()*newSolver->getObjSense();
    11111166            if (value<newSolutionValue) {
     1167              //newSolver->writeMps("query","mps");
     1168#if 0
     1169              {
     1170                double saveOffset;
     1171                newSolver->getDblParam(OsiObjOffset,saveOffset);
     1172                const double * obj = newSolver->getObjCoefficients();
     1173                double newTrueSolutionValue = -saveOffset;
     1174                double newSumInfeas=0.0;
     1175                int numberColumns = newSolver->getNumCols();
     1176                const double * solution = newSolver->getColSolution();
     1177                for (int  i=0 ; i<numberColumns ; i++ ) {
     1178                  if (newSolver->isInteger(i)) {
     1179                    double value = solution[i];
     1180                    double nearest = floor(value+0.5);
     1181                    newSumInfeas += fabs(value-nearest);
     1182                  }
     1183                  if (solution[i])
     1184                    printf("%d obj %g val %g - total %g\n",i,obj[i],solution[i],
     1185                           newTrueSolutionValue);
     1186                  newTrueSolutionValue += obj[i]*solution[i];
     1187                }
     1188                printf("obj %g - inf %g\n",newTrueSolutionValue,
     1189                       newSumInfeas);
     1190              }
     1191#endif
    11121192              sprintf(pumpPrint,"Freeing continuous variables gives a solution of %g", value);
    11131193              model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
     
    11401220            model_->setBestSolution(betterSolution,numberColumns,newSolutionValue);
    11411221            int action = handler->event(CbcEventHandler::heuristicSolution);
    1142             if (saveOldSolution) {
     1222            printf("cutoff %g\n",model_->getCutoff());
     1223            if (saveOldSolution&&saveObjectiveValue<model_->getMinimizationObjValue())
    11431224              model_->setBestSolution(saveOldSolution,numberColumns,saveObjectiveValue);
    1144               delete [] saveOldSolution;
    1145             }
     1225            delete [] saveOldSolution;
    11461226            if (!action||model_->getCurrentSeconds()>model_->getMaximumSeconds()) {
    11471227              exitAll=true; // exit
     
    12491329    model_->setNumberHeuristicSolutions(1);
    12501330  }
     1331#ifdef COIN_DEVELOP
     1332  {
     1333    double ncol = model_->solver()->getNumCols();
     1334    double nrow = model_->solver()->getNumRows();
     1335    printf("XXX total iterations %g ratios - %g %g %g\n",
     1336           totalNumberIterations,
     1337           totalNumberIterations/nrow,
     1338           totalNumberIterations/ncol,
     1339           totalNumberIterations/(2*nrow+2*ncol));
     1340  }
     1341#endif
    12511342  return finalReturnCode;
    12521343}
  • trunk/Cbc/src/CbcHeuristicFPump.hpp

    r833 r931  
    104104  inline double artificialCost() const
    105105  { return artificialCost_;}
     106  /// Get iteration to size ratio
     107  inline double iterationRatio() const
     108  { return iterationRatio_;}
     109  /// Set iteration to size ratio
     110  inline void setIterationRatio(double value)
     111  { iterationRatio_ = value;}
    106112  /// Set maximum passes (default 100)
    107113  inline void setMaximumPasses(int value)
     
    160166  /// Threshold cost for using original cost - even on continuous
    161167  double artificialCost_;
     168  /** If iterationRatio >0 use instead of maximumPasses_
     169      test is iterations > ratio*(2*nrow+ncol) */
     170  double iterationRatio_;
    162171  /// Maximum number of passes
    163172  int maximumPasses_;
  • trunk/Cbc/src/CbcMessage.cpp

    r715 r931  
    3535  {CBC_TREE_SOL,24,1,"Integer solution of %g found by subtree after %d iterations and %d nodes (%.2f seconds)"},
    3636  {CBC_ROOT,13,1,"At root node, %d cuts changed objective from %g to %g in %d passes"},
    37   {CBC_GENERATOR,14,1,"Cut generator %d (%s) - %d row cuts (%d active), %d column cuts %? in %.3f seconds - new frequency is %d"},
     37  {CBC_GENERATOR,14,1,"Cut generator %d (%s) - %d row cuts, %d column cuts (%d active) %? in %.3f seconds - new frequency is %d"},
    3838  {CBC_BRANCH,15,2,"Node %d Obj %g Unsat %d depth %d"},
    3939  {CBC_STRONGSOL,16,1,"Integer solution of %g found by strong branching after %d iterations and %d nodes (%.2f seconds)"},
     
    5959  {CBC_FPUMP1,38,1,"%s"},
    6060  {CBC_FPUMP2,39,2,"%s"},
     61  {CBC_STATUS3,40,1,"%d nodes (+%d), %d on tree, best %g - possible %g depth %d unsat %d its %d (+%d) (%.2f seconds)"},
     62  {CBC_OTHER_STATS2,41,1,"Maximum depth %d, %g variables fixed on reduced cost (%d nodes in complete fathoming taking %d iterations)"},
     63  {CBC_RELAXED1,42,1,"Possible objective of %.18g but variable %d is %g from integer value, integer tolerance %g"},
     64  {CBC_RELAXED2,43,1,"Possible objective of %.18g but variables are up to %g away from bound (within tolerance of %g) - might be able to fudge solution - but do you want to?"},
    6165  {CBC_DUMMY_END,999999,0,""}
    6266};
  • trunk/Cbc/src/CbcMessage.hpp

    r687 r931  
    6363  CBC_FPUMP1,
    6464  CBC_FPUMP2,
     65  CBC_STATUS3,
     66  CBC_OTHER_STATS2,
     67  CBC_RELAXED1,
     68  CBC_RELAXED2,
    6569  CBC_DUMMY_END
    6670};
  • trunk/Cbc/src/CbcModel.cpp

    r903 r931  
    55#  pragma warning(disable:4786)
    66#endif
     7//#define COIN_DEVELOP
    78
    89#include "CbcConfig.h"
     
    2425#include <cfloat>
    2526
    26 
    2727#ifdef COIN_HAS_CLP
    2828// include Presolve from Clp
    2929#include "ClpPresolve.hpp"
    3030#include "OsiClpSolverInterface.hpp"
     31#include "ClpNode.hpp"
     32#include "ClpDualRowDantzig.hpp"
     33#include "ClpSimplexPrimal.hpp"
    3134#endif
    3235
     
    7275//#define CBC_DETERMINISTIC_THREAD
    7376#ifdef CBC_THREAD
    74 
    7577#ifdef CBC_DETERMINISTIC_THREAD
    7678//#define DELETE_OUTSIDE
     
    8688        long            status;
    8789};
     90
    8891#ifndef CLP_FAST_CODE
    8992#define CBC_THREAD_DEBUG 1
     
    120123  int numberTimesWaitingToStart;
    121124  int saveStuff[2];
     125  int dantzigState; // 0 unset, -1 waiting to be set, 1 set
    122126  struct timespec absTime;
    123127  bool locked;
     
    170174  return b;
    171175}
     176
    172177
    173178
     
    266271
    267272
     273
    268274#ifdef CHECK_CUT_COUNTS
    269275
     
    324330    delete debugws ; }
    325331/*
    326   The moment of truth: We've tallied up the references by direct scan of the
    327   search tree. Check for agreement with the count in the cut.
     332  The moment of truth: We've tallied up the references by direct scan of the  search tree. Check for agreement with the count in the cut.
    328333
    329334  TODO: Rewrite to check and print mismatch only when tempNumber_ == 0?
     
    351356
    352357
     358
    353359//#define CHECK_CUT_SIZE
    354360#ifdef CHECK_CUT_SIZE
     
    387393
    388394 /* End unnamed namespace for CbcModel.cpp */
     395
    389396
    390397
     
    576583      }
    577584      if ((possible==2||possible==4)&&!unitRhs) {
    578 #ifdef COIN_DEVELOP
     585#if COIN_DEVELOP>1
    579586        printf("XXXXXX Continuous all +1 but different rhs\n");
    580587#endif
     
    589596        else
    590597          continuousMultiplier=0.0; // 0.5 was incorrect;
    591 #ifdef COIN_DEVELOP
     598#if COIN_DEVELOP>1
    592599        if (continuousMultiplier)
    593600          printf("XXXXXX multiplier of %g\n",continuousMultiplier);
     
    619626        // all integer
    620627        problemType_= problemType;
    621 #ifdef COIN_DEVELOP
     628#if COIN_DEVELOP>1
    622629        printf("Problem type is %d\n",problemType_);
    623630#endif
     
    751758      delete [] count;
    752759      if (allGood) {
    753 #ifdef COIN_DEVELOP
     760#if COIN_DEVELOP>1
    754761        if (numberObj)
    755762          printf("YYYY analysis says all continuous with costs will be integer\n");
     
    850857
    851858
     859
    852860/**
    853861  \todo
     
    875883  system held by the solver.
    876884*/
     885//#define CHECK_PATH
     886#ifdef CHECK_PATH
     887extern const double * debuggerSolution_Z;
     888extern int numberColumns_Z;
     889#endif
    877890void CbcModel::branchAndBound(int doStatistics)
    878891
     
    899912#ifndef NDEBUG
    900913  {
    901 #ifdef COIN_DEVELOP
    902     double big = 1.0e10;
     914#if COIN_DEVELOP>1
     915    double big = 1.0e12;
    903916#else
    904917    double big = 1.0e20;
     
    957970        // try and redo debugger
    958971        OsiRowCutDebugger * debugger = const_cast<OsiRowCutDebugger *> (solver_->getRowCutDebuggerAlways());
    959         if (debugger)
    960           debugger->redoSolution(numberColumns,originalColumns);
     972        if (debugger) 
     973          debugger->redoSolution(numberColumns,originalColumns);
    961974        originalObject = object_;
    962975        // object number or -1
     
    12211234    feasible=false; // pretend infeasible
    12221235  }
     1236  int saveNumberStrong = numberStrong_;
     1237  int saveNumberBeforeTrust = numberBeforeTrust_;
    12231238/*
    12241239  If the linear relaxation of the root is infeasible, bail out now. Otherwise,
     
    13051320  }
    13061321  // take off heuristics if have to
    1307   if (numberHeuristics_) {
     1322  {
    13081323    int numberOdd=0;
     1324    int numberSOS=0;
    13091325    for (int i=0;i<numberObjects_;i++) {
    13101326      if (!object_[i]->canDoHeuristics())
    13111327        numberOdd++;
     1328      CbcSOS * obj =
     1329        dynamic_cast <CbcSOS *>(object_[i]) ;
     1330      if (obj)
     1331        numberSOS++;
    13121332    }
    13131333    if (numberOdd) {
    1314       int k=0;
    1315       for (int i=0;i<numberHeuristics_;i++) {
    1316         if (!heuristic_[i]->canDealWithOdd())
    1317           delete heuristic_[i];
    1318         else
    1319           heuristic_[k++]=heuristic_[i];
    1320       }
    1321       if (!k) {
    1322         delete [] heuristic_;
    1323         heuristic_=NULL;
    1324       }
    1325       numberHeuristics_=k;
    1326       handler_->message(CBC_HEURISTICS_OFF,messages_)<< numberOdd<<CoinMessageEol ;
     1334      if (numberHeuristics_) {
     1335        int k=0;
     1336        for (int i=0;i<numberHeuristics_;i++) {
     1337          if (!heuristic_[i]->canDealWithOdd())
     1338            delete heuristic_[i];
     1339          else
     1340            heuristic_[k++]=heuristic_[i];
     1341        }
     1342        if (!k) {
     1343          delete [] heuristic_;
     1344          heuristic_=NULL;
     1345        }
     1346        numberHeuristics_=k;
     1347        handler_->message(CBC_HEURISTICS_OFF,messages_)<< numberOdd<<CoinMessageEol ;
     1348      }
     1349    } else if (numberSOS) {
     1350      specialOptions_ |= 128; // say can do SOS in dynamic mode
     1351      // switch off fast nodes for now
     1352      fastNodeDepth_ = -1;
     1353    }
     1354    if (numberThreads_>0) {
     1355      // switch off fast nodes for now
     1356      fastNodeDepth_ = -1;
    13271357    }
    13281358  }
     
    13381368*/
    13391369  // If debugger exists set specialOptions_ bit
    1340   if (solver_->getRowCutDebuggerAlways())
     1370  if (solver_->getRowCutDebuggerAlways()) {
     1371#ifdef CHECK_PATH
     1372    if (numberColumns_Z==-1) {
     1373      // If not -1 then in nested B&B
     1374      OsiRowCutDebugger * debugger =
     1375        const_cast<OsiRowCutDebugger *> (solver_->getRowCutDebuggerAlways());
     1376      debuggerSolution_Z = debugger->optimalSolution();
     1377      numberColumns_Z = getNumCols();
     1378    }
     1379  } else {
     1380    debuggerSolution_Z = NULL;
     1381    numberColumns_Z = -1;
     1382#else
    13411383    specialOptions_ |= 1;
     1384#endif
     1385  }
    13421386
    13431387# ifdef CBC_DEBUG
     
    14101454#endif
    14111455#endif
     1456     ClpSimplex * clpSimplex = clpSolver->getModelPtr();
    14121457     if ((specialOptions_&32)==0) {
    1413        ClpSimplex * clpSimplex = clpSolver->getModelPtr();
    14141458       // take off names
    14151459       clpSimplex->dropNames();
     
    14201464     if (numberColumns>1000&&numberIntegers_*4<numberColumns)
    14211465       clpSolver->setSpecialOptions(clpSolver->specialOptions()&(~1));
     1466     //#define NO_CRUNCH
     1467#ifdef NO_CRUNCH
     1468     printf("TEMP switching off crunch\n");
     1469     clpSolver->setSpecialOptions(clpSolver->specialOptions()&(~1));
     1470#endif
    14221471   }
    14231472 }
     
    14381487  if(solverCharacteristics_->reducedCostsAccurate())
    14391488    analyzeObjective() ;
     1489#ifdef COIN_HAS_CLP
     1490  // Possible save of pivot method
     1491  ClpDualRowPivot * savePivotMethod=NULL;
     1492  {
     1493    // pass tolerance and increment to solver
     1494    OsiClpSolverInterface * clpSolver
     1495      = dynamic_cast<OsiClpSolverInterface *> (solver_);
     1496    if (clpSolver)
     1497      clpSolver->setStuff(getIntegerTolerance(),getCutoffIncrement());
     1498  }
     1499#endif
    14401500/*
    14411501  Set up for cut generation. addedCuts_ holds the cuts which are relevant for
     
    15801640  if (eventHappened_)
    15811641    feasible=false;
     1642  if(fastNodeDepth_>=0&&!parentModel_) {
     1643    // add in a general depth object
     1644    CbcObject * obj =
     1645      new CbcGeneralDepth(this,fastNodeDepth_);
     1646    addObjects(1,&obj);
     1647    // mark as done
     1648    fastNodeDepth_ += 1000000;
     1649    delete obj;
     1650    // fake number of objects
     1651    numberObjects_--;
     1652  }
     1653#ifdef COIN_HAS_CLP
     1654#ifdef NO_CRUNCH
     1655 {
     1656   OsiClpSolverInterface * clpSolver
     1657     = dynamic_cast<OsiClpSolverInterface *> (solver_);
     1658   if (clpSolver&&!parentModel_) {
     1659     ClpSimplex * clpSimplex = clpSolver->getModelPtr();
     1660     clpSimplex->setSpecialOptions(clpSimplex->specialOptions()|131072);
     1661     //clpSimplex->startPermanentArrays();
     1662     clpSimplex->setPersistenceFlag(2);
     1663   }
     1664 }
     1665#endif
     1666#endif
    15821667/*
    15831668  We've taken the continuous relaxation as far as we can. Time to branch.
     
    17861871  numberLongStrong_=0;
    17871872  double totalTime = 0.0;
     1873  CbcNode * createdNode=NULL;
    17881874#ifdef CBC_THREAD
    1789   CbcNode * createdNode=NULL;
    17901875  CbcModel ** threadModel = NULL;
    17911876  Coin_pthread_t * threadId = NULL;
     
    18331918      pthread_mutex_init(mutex2+i,NULL);
    18341919      pthread_cond_init(condition2+i,NULL);
    1835       threadId[i].status =0;
     1920      threadId[i].status=0;
    18361921      threadInfo[i].baseModel=this;
    18371922      threadModel[i]=new CbcModel(*this);
     
    18491934      threadInfo[i].node=NULL;
    18501935      threadInfo[i].createdNode=NULL;
    1851           threadInfo[i].threadIdOfBase.thr =pthread_self();
     1936      threadInfo[i].threadIdOfBase.thr=pthread_self();
    18521937      threadInfo[i].mutex=&mutex;
    18531938      threadInfo[i].mutex2=mutex2+i;
     
    18611946      threadInfo[i].numberTimesUnlocked=0;
    18621947      threadInfo[i].numberTimesWaitingToStart=0;
     1948      threadInfo[i].dantzigState=0; // 0 unset, -1 waiting to be set, 1 set
    18631949      threadInfo[i].locked=false;
    18641950#if CBC_THREAD_DEBUG
     
    18721958      threadInfo[i].iterationsThisTime=0;
    18731959#endif
    1874           pthread_create(&(threadId[i].thr),NULL,doNodesThread,threadInfo+i);
    1875           threadId[i].status = 1;
     1960      pthread_create(&(threadId[i].thr),NULL,doNodesThread,threadInfo+i);
     1961      threadId[i].status = 1;
    18761962    }
    18771963    strategy_ = saveStrategy;
     
    18941980  }
    18951981#endif
     1982#ifdef COIN_HAS_CLP
     1983  {
     1984    OsiClpSolverInterface * clpSolver
     1985      = dynamic_cast<OsiClpSolverInterface *> (solver_);
     1986    if (clpSolver&&!parentModel_) {
     1987      clpSolver->computeLargestAway();
     1988    }
     1989  }
     1990#endif
    18961991/*
    18971992  At last, the actual branch-and-cut search loop, which will iterate until
     
    19392034      lockThread();
    19402035      locked=true;
     2036    }
     2037#endif
     2038#ifdef COIN_HAS_CLP
     2039    // Possible change of pivot method
     2040    if(!savePivotMethod&&!parentModel_) {
     2041      OsiClpSolverInterface * clpSolver
     2042        = dynamic_cast<OsiClpSolverInterface *> (solver_);
     2043      if (clpSolver&&numberNodes_>=100&&numberNodes_<200) {
     2044        if (numberIterations_<numberNodes_*20) {
     2045          ClpSimplex * simplex = clpSolver->getModelPtr();
     2046          ClpDualRowPivot * pivotMethod=simplex->dualRowPivot();
     2047          ClpDualRowDantzig * pivot =
     2048            dynamic_cast< ClpDualRowDantzig*>(pivotMethod);
     2049          if (!pivot) {
     2050            savePivotMethod = pivotMethod->clone(true);
     2051            ClpDualRowDantzig dantzig;
     2052            simplex->setDualRowPivotAlgorithm(dantzig);
     2053#ifdef COIN_DEVELOP
     2054            printf("%d node, %d iterations ->Dantzig\n",numberNodes_,
     2055                   numberIterations_);
     2056#endif
     2057#ifdef CBC_THREAD
     2058            for (int i=0;i<numberThreads_;i++) {
     2059              threadInfo[i].dantzigState=-1;
     2060            }
     2061#endif
     2062          }
     2063        }
     2064      }
    19412065    }
    19422066#endif
     
    19852109          threadModel[iThread]->moveToModel(this,1);
    19862110          assert (threadInfo[iThread].returnCode==1);
     2111          if (threadInfo[iThread].dantzigState==-1) {
     2112            // 0 unset, -1 waiting to be set, 1 set
     2113            threadInfo[iThread].dantzigState=1;
     2114            CbcModel * model = threadInfo[iThread].thisModel;
     2115            OsiClpSolverInterface * clpSolver2
     2116              = dynamic_cast<OsiClpSolverInterface *> (model->solver());
     2117            assert (clpSolver2);
     2118            ClpSimplex * simplex2 = clpSolver2->getModelPtr();
     2119            ClpDualRowDantzig dantzig;
     2120            simplex2->setDualRowPivotAlgorithm(dantzig);
     2121          }
    19872122          // say available
    19882123          threadInfo[iThread].returnCode=-1;
     
    21292264      lockThread();
    21302265#endif
     2266#ifdef COIN_HAS_CLP
     2267      // Possible change of pivot method
     2268      if(!savePivotMethod&&!parentModel_) {
     2269        OsiClpSolverInterface * clpSolver
     2270          = dynamic_cast<OsiClpSolverInterface *> (solver_);
     2271        if (clpSolver&&numberNodes_>=1000&&numberNodes_<2000) {
     2272          if (numberIterations_<numberNodes_*20) {
     2273            ClpSimplex * simplex = clpSolver->getModelPtr();
     2274            ClpDualRowPivot * pivotMethod=simplex->dualRowPivot();
     2275            ClpDualRowDantzig * pivot =
     2276              dynamic_cast< ClpDualRowDantzig*>(pivotMethod);
     2277            if (!pivot) {
     2278              savePivotMethod = pivotMethod->clone(true);
     2279              ClpDualRowDantzig dantzig;
     2280              simplex->setDualRowPivotAlgorithm(dantzig);
     2281#ifdef COIN_DEVELOP
     2282              printf("%d node, %d iterations ->Dantzig\n",numberNodes_,
     2283                     numberIterations_);
     2284#endif
     2285#ifdef CBC_THREAD
     2286              for (int i=0;i<numberThreads_;i++) {
     2287                threadInfo[i].dantzigState=-1;
     2288              }
     2289#endif
     2290            }
     2291          }
     2292        }
     2293      }
     2294#endif
    21312295      lastEvery1000 = numberNodes_ + 1000;
    21322296      bool redoTree=nodeCompare_->every1000Nodes(this, numberNodes_) ;
     
    21842348          <<getCurrentSeconds()
    21852349          << CoinMessageEol ;
    2186       } else {
     2350      } else if (intParam_[CbcPrinting]==1) {
    21872351        messageHandler()->message(CBC_STATUS2,messages())
    21882352          << numberNodes_<< nNodes<< bestObjective_<< bestPossibleObjective_
    21892353          <<lastDepth<<lastUnsatisfied<<numberIterations_
     2354          <<getCurrentSeconds()
     2355          << CoinMessageEol ;
     2356      } else if (!numberExtraIterations_) {
     2357        messageHandler()->message(CBC_STATUS2,messages())
     2358          << numberNodes_<< nNodes<< bestObjective_<< bestPossibleObjective_
     2359          <<lastDepth<<lastUnsatisfied<<numberIterations_
     2360          <<getCurrentSeconds()
     2361          << CoinMessageEol ;
     2362      } else {
     2363        messageHandler()->message(CBC_STATUS3,messages())
     2364          << numberNodes_<<numberExtraNodes_<< nNodes<< bestObjective_<< bestPossibleObjective_
     2365          <<lastDepth<<lastUnsatisfied<<numberIterations_<<numberExtraIterations_
    21902366          <<getCurrentSeconds()
    21912367          << CoinMessageEol ;
     
    22032379    }
    22042380   
    2205 #   ifdef CHECK_NODE_FULL
     2381#ifdef CHECK_NODE_FULL
    22062382    verifyTreeNodes(tree_,*this) ;
    22072383#   endif
     
    22152391  active subproblem.
    22162392*/
    2217 #ifndef CBC_THREAD
     2393#ifdef BACK_TO_OLD_WAY //old way without threads #ifndef CBC_THREAD
    22182394    CbcNode *node = tree_->bestNode(cutoff) ;
    22192395    // Possible one on tree worse than cutoff
     
    23792555      if ((specialOptions_&1)!=0&&onOptimalPath) {
    23802556        if (!solver_->getRowCutDebugger()) {
    2381           // dj fix did something???
    2382           solver_->writeMps("infeas2");
    2383           assert (solver_->getRowCutDebugger()) ;
     2557          if (solver_->getRowCutDebuggerAlways()->optimalValue()<
     2558              getCutoff()-1.0e-5) {
     2559            // dj fix did something???
     2560            solver_->writeMpsNative("infeas2.mps",NULL,NULL,2);
     2561            solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     2562            assert (solver_->getRowCutDebugger()) ;
     2563          }
    23842564        }
    23852565      }
     
    24092589          if (!feasible && !objLim) {
    24102590            printf("infeas2\n");
    2411             solver_->writeMps("infeas");
     2591            solver_->writeMpsNative("infeas.mps",NULL,NULL,2);
     2592            solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
    24122593            CoinWarmStartBasis *slack =
    24132594              dynamic_cast<CoinWarmStartBasis *>(solver_->getEmptyWarmStart()) ;
     
    25012682                generate=false; // only special cuts
    25022683              if (generate) {
    2503                 generator_[i]->generateCuts(theseCuts,true,solver_,NULL) ;
     2684                generator_[i]->generateCuts(theseCuts,1,solver_,NULL) ;
    25042685                int numberRowCutsAfter = theseCuts.sizeRowCuts() ;
    25052686                if (numberRowCutsAfter) {
     
    25402721              if (ifSol > 0) {
    25412722                // new solution found
     2723                heuristic_[iHeur]->incrementNumberSolutionsFound();
    25422724                found = iHeur ;
    25432725                incrementUsed(newSolution);
     
    26292811      CbcNode *node = tree_->bestNode(cutoff) ;
    26302812      // Possible one on tree worse than cutoff
    2631       if (!node||node->objectiveValue()>cutoff)
     2813      if (!node||node->objectiveValue()>cutoff) 
    26322814        continue;
    26332815    if (!numberThreads_) {
     
    26392821        continue;
    26402822#endif
    2641         doOneNode(this,node,createdNode);
     2823      doOneNode(this,node,createdNode);
    26422824#ifdef CBC_DETERMINISTIC_THREAD
    26432825        assert (createdNode);
     
    27842966        abort();
    27852967#endif
     2968#ifdef CBC_THREAD
    27862969        int saveTreeSize = tree_->size();
    27872970        goneParallel=true;
     
    28983081        // later remember random may not be thread neutral
    28993082#endif
     3083#endif
    29003084      }
    29013085      //lastDepth=node->depth();
     
    29543138      //pthread_join(threadId[i],NULL);
    29553139      int returnCode;
    2956           returnCode=pthread_join(threadId[i].thr,NULL);
     3140      returnCode=pthread_join(threadId[i].thr,NULL);
     3141      threadId[i].status = 0;
    29573142      assert (!returnCode);
    2958           threadId[i].status = 0;
    29593143        //else
    29603144        //pthread_kill(threadId[i]); // kill rather than try and synchronize
     
    30713255      << strongInfo_[0] << numberStrongIterations_ << strongInfo_[2]
    30723256      << strongInfo_[1] << CoinMessageEol ;
    3073   handler_->message(CBC_OTHER_STATS,messages_)
     3257  if (!numberExtraNodes_) 
     3258    handler_->message(CBC_OTHER_STATS,messages_)
    30743259      << maximumDepthActual_
    30753260      << numberDJFixed_ << CoinMessageEol ;
     3261  else
     3262    handler_->message(CBC_OTHER_STATS2,messages_)
     3263      << maximumDepthActual_
     3264      << numberDJFixed_ << numberExtraNodes_<<numberExtraIterations_
     3265      <<CoinMessageEol ;
    30763266  if (doStatistics==100) {
    30773267    for (int i=0;i<numberObjects_;i++) {
     
    32673457    if ((specialOptions_&4)==0)
    32683458      bestObjective_ += 100.0*increment+1.0e-3; // only set if we are going to solve
    3269     setBestSolution(CBC_END_SOLUTION,bestObjective_,bestSolution_,true) ;
     3459    setBestSolution(CBC_END_SOLUTION,bestObjective_,bestSolution_,1) ;
    32703460    continuousSolver_->resolve() ;
    32713461    if (!continuousSolver_->isProvenOptimal())
     
    32873477    delete [] saveObjects;
    32883478  }
     3479  numberStrong_ = saveNumberStrong;
     3480  numberBeforeTrust_ = saveNumberBeforeTrust;
    32893481  delete [] whichGenerator_ ;
    32903482  whichGenerator_=NULL;
     
    33163508    solver_->initialSolve();
    33173509  }
     3510#ifdef COIN_HAS_CLP
     3511  {
     3512    OsiClpSolverInterface * clpSolver
     3513      = dynamic_cast<OsiClpSolverInterface *> (solver_);
     3514    if (clpSolver) {
     3515      // Possible restore of pivot method
     3516      if(savePivotMethod) {
     3517        clpSolver->getModelPtr()->setDualRowPivotAlgorithm(*savePivotMethod);
     3518        delete savePivotMethod;
     3519      }
     3520      clpSolver->setLargestAway(-1.0);
     3521    }
     3522  }
     3523#endif
     3524  if(fastNodeDepth_>=1000000&&!parentModel_) {
     3525    // delete object off end
     3526    delete object_[numberObjects_];
     3527    fastNodeDepth_ -= 1000000;
     3528  }
     3529#if COIN_DEVELOP>1
     3530  void print_fac_stats();
     3531  //if (!parentModel_)
     3532  //  print_fac_stats();
     3533#endif
    33183534  if (strategy_&&strategy_->preProcessState()>0) {
    33193535    // undo preprocessing
     
    33733589  return ;
    33743590 }
     3591
    33753592
    33763593
     
    35083725  heuristic_(NULL),
    35093726  lastHeuristic_(NULL),
    3510   eventHandler_(0),
     3727# ifdef COIN_HAS_CLP
     3728  fastNodeDepth_(-1),
     3729#endif
     3730  eventHandler_(NULL),
    35113731  numberObjects_(0),
    35123732  object_(NULL),
     
    35153735  howOftenGlobalScan_(1),
    35163736  numberGlobalViolations_(0),
     3737  numberExtraIterations_(0),
     3738  numberExtraNodes_(0),
    35173739  continuousObjective_(COIN_DBL_MAX),
    35183740  originalContinuousObjective_(COIN_DBL_MAX),
     
    36483870  heuristic_(NULL),
    36493871  lastHeuristic_(NULL),
    3650   eventHandler_(0),
     3872# ifdef COIN_HAS_CLP
     3873  fastNodeDepth_(-1),
     3874#endif
     3875  eventHandler_(NULL),
    36513876  numberObjects_(0),
    36523877  object_(NULL),
     
    36553880  howOftenGlobalScan_(1),
    36563881  numberGlobalViolations_(0),
     3882  numberExtraIterations_(0),
     3883  numberExtraNodes_(0),
    36573884  continuousObjective_(COIN_DBL_MAX),
    36583885  originalContinuousObjective_(COIN_DBL_MAX),
     
    38794106  problemType_(rhs.problemType_),
    38804107  printFrequency_(rhs.printFrequency_),
     4108# ifdef COIN_HAS_CLP
     4109  fastNodeDepth_(rhs.fastNodeDepth_),
     4110#endif
    38814111  howOftenGlobalScan_(rhs.howOftenGlobalScan_),
    38824112  numberGlobalViolations_(rhs.numberGlobalViolations_),
     4113  numberExtraIterations_(rhs.numberExtraIterations_),
     4114  numberExtraNodes_(rhs.numberExtraNodes_),
    38834115  continuousObjective_(rhs.continuousObjective_),
    38844116  originalContinuousObjective_(rhs.originalContinuousObjective_),
     
    42034435    howOftenGlobalScan_=rhs.howOftenGlobalScan_;
    42044436    numberGlobalViolations_=rhs.numberGlobalViolations_;
     4437    numberExtraIterations_ = rhs.numberExtraIterations_;
     4438    numberExtraNodes_ = rhs.numberExtraNodes_;
    42054439    continuousObjective_=rhs.continuousObjective_;
    42064440    originalContinuousObjective_ = rhs.originalContinuousObjective_;
     
    42934527    else
    42944528    { eventHandler_ = NULL ; }
     4529# ifdef COIN_HAS_CLP
     4530    fastNodeDepth_ = rhs.fastNodeDepth_;
     4531#endif
    42954532    if (ownObjects_) {
    42964533      for (i=0;i<numberObjects_;i++)
     
    45344771  numberInfeasibleNodes_=0;
    45354772  numberGlobalViolations_=0;
     4773  numberExtraIterations_ = 0;
     4774  numberExtraNodes_ = 0;
    45364775  continuousObjective_=0.0;
    45374776  originalContinuousObjective_=0.0;
     
    47374976                        normal,atSolution,whenInfeasible,howOftenInSub,
    47384977                        whatDepth, whatDepthInSub);
    4739   // and before any cahnges
     4978  // and before any changes
    47404979  temp = virginGenerator_;
    47414980  virginGenerator_ = new CbcCutGenerator * [numberCutGenerators_+1];
     
    47935032  the reference isn't clear to me).
    47945033*/
    4795   solver_->restoreBaseModel(numberRowsAtContinuous_);
    4796 #if 0
    4797   int currentNumberCuts = solver_->getNumRows()-numberRowsAtContinuous_;
    4798   int *which = new int[currentNumberCuts];
    4799   for (i = 0 ; i < currentNumberCuts ; i++)
    4800     which[i] = i+numberRowsAtContinuous_;
    4801   solver_->deleteRows(currentNumberCuts,which);
    4802   delete [] which;
    4803 #endif
     5034  int currentNumberCuts ;
     5035  if (numberThreads_<=0) {
     5036    solver_->restoreBaseModel(numberRowsAtContinuous_);
     5037  } else {
     5038    // *** Fix later
     5039    currentNumberCuts = solver_->getNumRows()-numberRowsAtContinuous_;
     5040    int *which = new int[currentNumberCuts];
     5041    for (i = 0 ; i < currentNumberCuts ; i++)
     5042      which[i] = i+numberRowsAtContinuous_;
     5043    solver_->deleteRows(currentNumberCuts,which);
     5044    delete [] which;
     5045  }
    48045046/*
    48055047  Accumulate the path from node to the root in walkback_, and accumulate a
     
    48095051  old node (for cuts?)
    48105052*/
    4811   int currentNumberCuts = 0;
     5053  currentNumberCuts = 0;
    48125054  while (nodeInfo) {
    48135055    //printf("nNode = %d, nodeInfo = %x\n",nNode,nodeInfo);
     
    48615103    --nNode;
    48625104    walkback_[nNode]->applyToModel(this,lastws,addedCuts_,currentNumberCuts);
     5105  }
     5106  if (!lastws->fullBasis()) {
     5107    printf("******* bad basis\n");
     5108    int numberRows = lastws->getNumArtificial();
     5109    int i;
     5110    for (i=0;i<numberRows;i++)
     5111      lastws->setArtifStatus(i,CoinWarmStartBasis::basic);
     5112    int numberColumns = lastws->getNumStructural();
     5113    for (i=0;i<numberColumns;i++) {
     5114      if (lastws->getStructStatus(i)==CoinWarmStartBasis::basic)
     5115        lastws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
     5116    }
     5117#if 0
     5118  } else {
     5119    // OPTION - take off slack cuts
     5120    // First see if any cuts are slack
     5121    int numberAdded = currentNumberCuts;
     5122    if (saveNode<2&&false) {
     5123      printf("nNode %d cuts %d\n",saveNode,currentNumberCuts);
     5124      for (int i=0;i<currentNumberCuts;i++)
     5125        addedCuts_[i]->print();
     5126    }
     5127    if (numberAdded&&saveNode<5&&!parentModel_) {
     5128#if 0
     5129      currentNumberCuts=0;
     5130      for (int j=numberRowsAtContinuous_;
     5131           j<numberAdded+numberRowsAtContinuous_;j++) {
     5132        CoinWarmStartBasis::Status status = lastws->getArtifStatus(j);
     5133        if (status!=CoinWarmStartBasis::basic) {
     5134          lastws->setArtifStatus(currentNumberCuts+numberRowsAtContinuous_,
     5135                                 status);
     5136          addedCuts_[currentNumberCuts++]=addedCuts_[j-numberRowsAtContinuous_];
     5137        }
     5138      }
     5139      if (currentNumberCuts<numberAdded) {
     5140        printf("deleting %d rows\n",numberAdded-currentNumberCuts);
     5141        lastws->resize(currentNumberCuts+numberRowsAtContinuous_,
     5142                       lastws->getNumStructural());
     5143        currentNumberCuts_=currentNumberCuts;
     5144      }
     5145#else
     5146      int nDelete=0;
     5147      for (int j=numberRowsAtContinuous_;
     5148           j<numberAdded+numberRowsAtContinuous_;j++) {
     5149        CoinWarmStartBasis::Status status = lastws->getArtifStatus(j);
     5150        if (status==CoinWarmStartBasis::basic)
     5151          nDelete++;
     5152      }
     5153      if (nDelete)
     5154        printf("depth %d can delete %d\n",saveNode-1,nDelete);
     5155#endif
     5156    }
     5157#endif
    48635158  }
    48645159  if (0) {
     
    49765271  if (node->objectiveValue() < cutoff||numberThreads_)
    49775272  {
     5273    //#   define CBC_CHECK_BASIS
    49785274#   ifdef CBC_CHECK_BASIS
    49795275    printf("addCuts: expanded basis; rows %d+%d\n",
     
    50945390  solver_->getDblParam(OsiDualTolerance,tolerance) ;
    50955391  if (gap<=0.0)
    5096     return 0;
     5392    gap = tolerance; //return 0;
    50975393  gap += 100.0*tolerance;
    50985394  double integerTolerance = getDblParam(CbcIntegerTolerance) ;
     
    51125408    clpSimplex = clpSolver->getModelPtr();
    51135409# endif
    5114   for (int i = 0 ; i < numberIntegers_ ; i++)
    5115   { int iColumn = integerVariable_[i] ;
     5410  for (int i = 0 ; i < numberIntegers_ ; i++) {
     5411    int iColumn = integerVariable_[i] ;
    51165412    double djValue = direction*reducedCost[iColumn] ;
    5117     if (upper[iColumn]-lower[iColumn] > integerTolerance)
    5118     { if (solution[iColumn] < lower[iColumn]+integerTolerance && djValue > gap)
    5119       { solver_->setColUpper(iColumn,lower[iColumn]) ;
     5413    if (upper[iColumn]-lower[iColumn] > integerTolerance) {
     5414      if (solution[iColumn] < lower[iColumn]+integerTolerance && djValue > gap) {
    51205415#ifdef COIN_HAS_CLP
    5121       // may just have been fixed before
    5122       if (clpSimplex)
    5123         assert(clpSimplex->getColumnStatus(iColumn)==ClpSimplex::atLowerBound||
    5124                clpSimplex->getColumnStatus(iColumn)==ClpSimplex::isFixed);
    5125 #endif
    5126       numberFixed++ ; }
    5127       else
    5128       if (solution[iColumn] > upper[iColumn]-integerTolerance && -djValue > gap)
    5129       { solver_->setColLower(iColumn,upper[iColumn]) ;
     5416        // may just have been fixed before
     5417        if (clpSimplex) {
     5418          if (clpSimplex->getColumnStatus(iColumn)==ClpSimplex::basic) {
     5419#ifdef COIN_DEVELOP
     5420            printf("DJfix %d has status of %d, dj of %g gap %g, bounds %g %g\n",
     5421                   iColumn,clpSimplex->getColumnStatus(iColumn),
     5422                   djValue,gap,lower[iColumn],upper[iColumn]);
     5423#endif
     5424          } else {         
     5425            assert(clpSimplex->getColumnStatus(iColumn)==ClpSimplex::atLowerBound||
     5426                   clpSimplex->getColumnStatus(iColumn)==ClpSimplex::isFixed);
     5427          }
     5428        }
     5429#endif
     5430        solver_->setColUpper(iColumn,lower[iColumn]) ;
     5431        numberFixed++ ;
     5432      } else if (solution[iColumn] > upper[iColumn]-integerTolerance && -djValue > gap) {
    51305433#ifdef COIN_HAS_CLP
    5131       // may just have been fixed before
    5132       if (clpSimplex)
    5133         assert(clpSimplex->getColumnStatus(iColumn)==ClpSimplex::atUpperBound||
    5134                clpSimplex->getColumnStatus(iColumn)==ClpSimplex::isFixed);
    5135 #endif
    5136       numberFixed++ ; } } }
     5434        // may just have been fixed before
     5435        if (clpSimplex) {
     5436          if (clpSimplex->getColumnStatus(iColumn)==ClpSimplex::basic) {
     5437#ifdef COIN_DEVELOP
     5438            printf("DJfix %d has status of %d, dj of %g gap %g, bounds %g %g\n",
     5439                   iColumn,clpSimplex->getColumnStatus(iColumn),
     5440                   djValue,gap,lower[iColumn],upper[iColumn]);
     5441#endif
     5442          } else {         
     5443            assert(clpSimplex->getColumnStatus(iColumn)==ClpSimplex::atUpperBound||
     5444                   clpSimplex->getColumnStatus(iColumn)==ClpSimplex::isFixed);
     5445          }
     5446        }
     5447#endif
     5448        solver_->setColLower(iColumn,upper[iColumn]) ;
     5449        numberFixed++ ;
     5450      }
     5451    }
     5452  }
    51375453  numberDJFixed_ += numberFixed;
    51385454  return numberFixed; }
     
    51755491    node: (i)     So we can update dynamic pseudo costs
    51765492*/
    5177 
     5493                       
    51785494
    51795495{
     
    52075523      pthread_mutex_init(mutex2+i,NULL);
    52085524      pthread_cond_init(condition2+i,NULL);
    5209       threadId[i].status =0;
     5525      threadId[i].status=0;
    52105526      threadModel[i]=new CbcModel;
    52115527      threadModel[i]->generator_ = new CbcCutGenerator * [1];
     
    52165532      threadInfo[i].thisModel=(CbcModel *) threadModel[i];
    52175533      threadInfo[i].baseModel=this;
    5218           threadInfo[i].threadIdOfBase.thr=pthread_self();
     5534      threadInfo[i].threadIdOfBase.thr=pthread_self();
    52195535      threadInfo[i].mutex2=mutex2+i;
    52205536      threadInfo[i].condition2=condition2+i;
    52215537      threadInfo[i].returnCode=-1;
    5222           pthread_create(&threadId[i].thr,NULL,doCutsThread,threadInfo+i);
    5223           threadId[i].status = 1;
    5224 
     5538      pthread_create(&(threadId[i].thr),NULL,doCutsThread,threadInfo+i);
     5539      threadId[i].status = 1;
    52255540    }
    52265541    // Do a partial one for base model
     
    52335548  bool feasible = true ;
    52345549  int lastNumberCuts = 0 ;
    5235   double lastObjective = -1.0e100 ;
    52365550  int violated = 0 ;
    52375551  int numberRowsAtStart = solver_->getNumRows() ;
     
    52655579    objectiveValue= node->objectiveValue();
    52665580  int returnCode = resolve(node ? node->nodeInfo() : NULL,1);
    5267 #ifdef COIN_DEVELOP
     5581#if COIN_DEVELOP>1
    52685582  //if (!solver_->getIterationCount()&&solver_->isProvenOptimal())
    52695583  //printf("zero iterations on first solve of branch\n");
    52705584#endif
     5585  double lastObjective = solver_->getObjValue()*solver_->getObjSense();
     5586  //double firstObjective = lastObjective+1.0e-8+1.0e-12*fabs(lastObjective);
    52715587  if (node&&node->nodeInfo()&&!node->nodeInfo()->numberBranchesLeft())
    52725588    node->nodeInfo()->allBranchesGone(); // can clean up
     
    53955711    if (onOptimalPath && !solver_->isDualObjectiveLimitReached()) {
    53965712      if (!feasible) {
    5397         solver_->writeMps("infeas");
     5713        solver_->writeMpsNative("infeas.mps",NULL,NULL,2);
     5714        solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
    53985715        CoinWarmStartBasis *slack =
    53995716          dynamic_cast<CoinWarmStartBasis *>(solver_->getEmptyWarmStart()) ;
     
    54355752  Do reduced cost fixing.
    54365753*/
     5754  int xxxxxx=0;
     5755  if(xxxxxx)
     5756  solver_->resolve();
    54375757  reducedCostFix() ;
    54385758/*
     
    54495769  up to do it.
    54505770*/
    5451 # define SCANCUTS 100 
    5452   int *countColumnCuts = NULL ;
    5453   // Always accumulate row cut counts
    5454   int * countRowCuts =new int[numberCutGenerators_+numberHeuristics_] ;
    5455   memset(countRowCuts,0,
    5456          (numberCutGenerators_+numberHeuristics_)*sizeof(int)) ;
    5457   bool fullScan = false ;
    5458   if ((numberNodes_%SCANCUTS) == 0)
    5459   { fullScan = true ;
    5460     countColumnCuts = new int[numberCutGenerators_+numberHeuristics_] ;
    5461     memset(countColumnCuts,0,
    5462            (numberCutGenerators_+numberHeuristics_)*sizeof(int)) ; }
     5771  int fullScan = 0 ;
     5772  if ((numberNodes_%SCANCUTS) == 0||(specialOptions_&256)!=0)
     5773  { fullScan = 1 ;
     5774    if (!numberNodes_||(specialOptions_&256)!=0)
     5775      fullScan=2;
     5776    specialOptions_ &= ~256; // mark as full scan done
     5777  }
    54635778
    54645779  double direction = solver_->getObjSense() ;
     
    55895904    int i;
    55905905    if ((threadMode_&2)==0||numberNodes_) {
    5591       for (i = 0;i<numberCutGenerators_;i++) {
     5906      int nGen = numberCutGenerators_;
     5907      if (node&&node->depth()>10&&(node->depth()&1)==0&&!fullScan)
     5908        nGen=0;
     5909# ifdef COIN_HAS_CLP
     5910      if (!node&&!parentModel_&& intParam_[CbcMaxNumNode] == -123456) {
     5911        OsiClpSolverInterface * clpSolver
     5912          = dynamic_cast<OsiClpSolverInterface *> (solver_);
     5913        if (clpSolver) {
     5914          clpSolver->lexSolve();
     5915        }
     5916      }
     5917# endif
     5918      for (i = 0;i<nGen;i++) {
    55925919        int numberRowCutsBefore = theseCuts.sizeRowCuts() ;
    55935920        int numberColumnCutsBefore = theseCuts.sizeColCuts() ;
     
    55955922        int numberColumnCutsAfter = numberColumnCutsBefore;
    55965923        bool generate = generator_[i]->normal();
     5924        //if (i!=1)
     5925        //continue;
    55975926        // skip if not optimal and should be (maybe a cut generator has fixed variables)
    55985927        if (generator_[i]->needsOptimalBasis()&&!solver_->basisIsAvailable())
     
    56045933            generator_[i]->generateCuts(theseCuts,fullScan,solver_,node) ;
    56055934          numberRowCutsAfter = theseCuts.sizeRowCuts() ;
     5935          if (fullScan&&generator_[i]->howOften()==1000000+SCANCUTS_PROBING) {
     5936            CglProbing * probing =
     5937              dynamic_cast<CglProbing*>(generator_[i]->generator());
     5938            if (probing&&(numberRowCutsBefore < numberRowCutsAfter||
     5939                          numberColumnCutsBefore<theseCuts.sizeColCuts())) {
     5940              // switch on
     5941#ifdef COIN_DEVELOP
     5942              printf("Switching on probing\n");
     5943#endif
     5944              generator_[i]->setHowOften(1);
     5945            }
     5946          }
    56065947          if(numberRowCutsBefore < numberRowCutsAfter &&
    56075948             generator_[i]->mustCallAgain())
     
    56545995        numberRowCutsAfter = theseCuts.sizeRowCuts() ;
    56555996        numberColumnCutsAfter = theseCuts.sizeColCuts() ;
    5656 
     5997       
    56575998        if ((specialOptions_&1)!=0) {
    56585999          if (onOptimalPath) {
     
    56606001            for (k = numberRowCutsBefore;k<numberRowCutsAfter;k++) {
    56616002              OsiRowCut thisCut = theseCuts.rowCut(k) ;
    5662               if(debugger->invalidCut(thisCut)) {
    5663                 solver_->writeMps("badCut");
    5664 #ifdef NDEBUG
     6003              if(debugger->invalidCut(thisCut)) {       
     6004                solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     6005                solver_->writeMpsNative("badCut.mps",NULL,NULL,2);
     6006#if 1 //#ifdef NDEBUG
    56656007                printf("Cut generator %d (%s) produced invalid cut (%dth in this go)\n",
    56666008                       i,generator_[i]->cutGeneratorName(),k-numberRowCutsBefore);
     
    56936035        resizeWhichGenerator(numberBefore, numberAfter);
    56946036        int j ;
    5695         if (fullScan) {
    5696           // counts
    5697           countColumnCuts[i] += numberColumnCutsAfter-numberColumnCutsBefore ;
    5698         }
    5699         countRowCuts[i] += numberRowCutsAfter-numberRowCutsBefore ;
    5700 
     6037       
    57016038        bool dodgyCuts=false;
    57026039        for (j = numberRowCutsBefore;j<numberRowCutsAfter;j++) {
     
    59276264              OsiRowCut thisCut = theseCuts.rowCut(k) ;
    59286265              if(debugger->invalidCut(thisCut)) {
    5929                 solver_->writeMps("badCut");
     6266                solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     6267                solver_->writeMpsNative("badCut.mps",NULL,NULL,2);
    59306268#ifdef NDEBUG
    59316269                printf("Cut generator %d (%s) produced invalid cut (%dth in this go)\n",
     
    59586296        // possibly extend whichGenerator
    59596297        resizeWhichGenerator(numberBefore, numberAfter);
    5960         if (fullScan) {
    5961           // counts
    5962           countColumnCuts[i] += numberColumnCutsAfter-numberColumnCutsBefore ;
    5963         }
    5964         countRowCuts[i] += numberRowCutsAfter-numberRowCutsBefore ;
    5965 
     6298       
    59666299        for (j = numberRowCutsBefore;j<numberRowCutsAfter;j++) {
    59676300          whichGenerator_[numberBefore++] = i ;
     
    59786311        }
    59796312        for (j = numberColumnCutsBefore;j<numberColumnCutsAfter;j++) {
    5980           whichGenerator_[numberBefore++] = i ;
     6313          //whichGenerator_[numberBefore++] = i ;
    59816314          const OsiColCut * thisCut = theseCuts.colCutPtr(j) ;
    59826315          if (thisCut->globallyValid()) {
     
    60276360        if (ifSol>0) {
    60286361          // better solution found
     6362          heuristic_[i]->incrementNumberSolutionsFound();
    60296363          found = i ;
    60306364          incrementUsed(newSolution);
     
    61906524  TODO: Any reason why the three loops can't be consolidated?
    61916525*/
     6526    const OsiRowCut ** addCuts = NULL;
    61926527    if (numberRowCuts > 0 || numberColumnCuts > 0)
    61936528    { if (numberToAdd > 0)
    61946529      { int i ;
    61956530        // Faster to add all at once
    6196         const OsiRowCut ** addCuts = new const OsiRowCut * [numberToAdd] ;
     6531        addCuts = new const OsiRowCut * [numberToAdd] ;
    61976532        for (i = 0 ; i < numberToAdd ; i++)
    61986533        { addCuts[i] = &theseCuts.rowCut(i) ; }
    61996534        solver_->applyRowCuts(numberToAdd,addCuts) ;
    6200         // AJK this caused a memory fault on Win32
    6201         // may be okay now with ** form
    6202         delete [] addCuts ;
    6203         for (i = 0 ; i < numberToAdd ; i++)
    6204         { cuts.insert(theseCuts.rowCut(i)) ; }
    62056535        CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis*>(solver_->getWarmStart()) ;
    62066536        assert(basis != NULL); // make sure not volume
     
    62626592      if (numberOldActiveCuts_+numberNewCuts_) {
    62636593        OsiCuts * saveCuts = node ? NULL : &slackCuts;
    6264         takeOffCuts(cuts,resolveAfterTakeOffCuts_,saveCuts) ;
     6594        takeOffCuts(cuts,resolveAfterTakeOffCuts_,saveCuts,numberToAdd,addCuts) ;
    62656595        if (solver_->isDualObjectiveLimitReached()&&resolveAfterTakeOffCuts_)
    62666596          { feasible = false ;
     
    62736603          }
    62746604      }
     6605      delete [] addCuts ;
    62756606      if (feasible) {
    62766607        numberRowsAtStart = numberOldActiveCuts_+numberRowsAtContinuous_ ;
    62776608        lastNumberCuts = numberNewCuts_ ;
    62786609        if (direction*solver_->getObjValue() < lastObjective+minimumDrop &&
    6279             currentPassNumber_ >= 3 && !keepGoing)
     6610            currentPassNumber_ >= 10
     6611            //&&(currentPassNumber_>=10||lastObjective>firstObjective)
     6612            && !keepGoing)
    62806613          { numberTries = 0 ; }
    62816614        if (numberRowCuts+numberColumnCuts == 0 || cutIterations == 0)
     
    62866619        }
    62876620      }
     6621    } else {
     6622      // not feasible
     6623      delete [] addCuts ;
    62886624    }
    62896625/*
     
    64296765      if (ifSol>0) {
    64306766        // better solution found
     6767        heuristic_[i]->incrementNumberSolutionsFound();
    64316768        found = i ;
    64326769        incrementUsed(newSolution);
     
    64676804  class.
    64686805
    6469   TODO: Can the loop that scans over whichGenerator to accumulate per generator
    6470         counts be replaced by values in countRowCuts and countColumnCuts?
    64716806*/
    64726807#ifdef NODE_LOG
     
    65306865    for (i = 0;i<numberNewCuts_;i++) {
    65316866      int iGenerator = whichGenerator_[i];
    6532       if (iGenerator>=0&&iGenerator<numberCutGenerators_)
     6867      if (iGenerator>=0&&iGenerator<numberCutGenerators_) 
    65336868        count[iGenerator]++ ;
    65346869    }
     
    65366871    //#define JUST_ACTIVE
    65376872    for (i = 0;i<numberCutGenerators_;i++) {
    6538       if (countRowCuts[i]||countColumnCuts[i])
     6873      if (generator_[i]->numberCutsInTotal()||generator_[i]->numberColumnCuts())
    65396874        numberActiveGenerators++;
    65406875#ifdef JUST_ACTIVE
    6541       totalCuts += count[i] + 5.0*countColumnCuts[i] ;
     6876      totalCuts += count[i] + 5.0*generator_[i]->numberColumnCuts() ;
    65426877#else
    6543       totalCuts += countRowCuts[i] + 5.0*countColumnCuts[i] ;
     6878      totalCuts += generator_[i]->numberCutsInTotal() + 5.0*generator_[i]->numberColumnCuts() ;
    65446879#endif
    65456880    }
    65466881    int iProbing=-1;
    6547     double small = (0.5* totalCuts) /
     6882    double small = (0.2* totalCuts) /
    65486883      ((double) numberActiveGenerators) ;
    65496884    for (i = 0;i<numberCutGenerators_;i++) {
     6885     
    65506886      int howOften = generator_[i]->howOften() ;
    65516887      /*  Probing can be set to just do column cuts in treee.
     
    65636899      if (willBeCutsInTree<0&&howOften==-98)
    65646900        howOften =-99;
    6565       if (howOften==-98&&generator_[i]->switchOffIfLessThan()<0) {
     6901      if (howOften==-98&&generator_[i]->switchOffIfLessThan()>0) {
    65666902        if (thisObjective-startObjective<0.005*fabs(startObjective)+1.0e-5)
    65676903          howOften=-99; // switch off
     
    65766912          // If small number switch mostly off
    65776913#ifdef JUST_ACTIVE
    6578           double thisCuts = count[i] + 5.0*countColumnCuts[i] ;
     6914          double thisCuts = count[i] + 5.0*generator_[i]->numberColumnCuts() ;
    65796915#else
    6580           double thisCuts = countRowCuts[i] + 5.0*countColumnCuts[i] ;
    6581 #endif
     6916          double thisCuts = generator_[i]->numberCutsInTotal() + 5.0*generator_[i]->numberColumnCuts() ;
     6917#endif
     6918          // Allow on smaller number if <-1
     6919          if (generator_[i]->switchOffIfLessThan()<0) {
     6920            double multiplier = -generator_[i]->switchOffIfLessThan()+1.0;
     6921            thisCuts *= multiplier;
     6922          }
    65826923          if (!thisCuts||howOften == -99) {
    65836924            if (howOften == -99||howOften == -98)
     
    66206961        if (howOften==1)
    66216962          generator_[i]->setWhatDepth(1);
    6622 
     6963       
    66236964        if (howOften>=0&&generator_[i]->generator()->mayGenerateRowCutsInTree())
    66246965          willBeCutsInTree=1;
     
    66376978      int newFrequency = generator_[i]->howOften()%1000000 ;
    66386979      // increment cut counts
    6639       generator_[i]->incrementNumberCutsInTotal(countRowCuts[i]);
    66406980      generator_[i]->incrementNumberCutsActive(count[i]);
    66416981      CglStored * stored = dynamic_cast<CglStored*>(generator_[i]->generator());
    6642       if (stored&&!countRowCuts[i])
     6982      if (stored&&!generator_[i]->numberCutsInTotal())
    66436983        continue;
    66446984      if (handler_->logLevel()>1||!numberNodes_) {
     
    66466986          <<i
    66476987          <<generator_[i]->cutGeneratorName()
    6648           //<<countRowCuts[i]<<count[i]
    6649           << generator_[i]->numberCutsInTotal()<<generator_[i]->numberCutsActive()
    6650           <<countColumnCuts[i];
     6988          //<<generator_[i]->numberCutsInTotal()<<count[i]
     6989          << generator_[i]->numberCutsInTotal()
     6990          <<generator_[i]->numberColumnCuts()
     6991          <<generator_[i]->numberCutsActive();
    66516992        handler_->printing(!numberNodes_&&generator_[i]->timing())
    66526993          <<generator_[i]->timeInCutGenerator();
     
    67437084    if (numberCutGenerators_) {
    67447085      int i;
    6745       // add to counts anyway
    6746       for (i = 0;i<numberCutGenerators_;i++)
    6747         generator_[i]->incrementNumberCutsInTotal(countRowCuts[i]);
    67487086      // What if not feasible as cuts may have helped
    67497087      if (feasible) {
     
    67567094    }
    67577095  }
    6758 
    6759   delete [] countRowCuts ;
    6760   delete [] countColumnCuts ;
    67617096
    67627097
     
    68007135      pthread_cond_signal(threadInfo[i].condition2); // unlock
    68017136      pthread_join(threadId[i].thr,NULL);
    6802           threadId[i].status = 0;
    6803 
     7137      threadId[i].status = 0;
    68047138      pthread_mutex_destroy (threadInfo[i].mutex2);
    68057139      pthread_cond_destroy (threadInfo[i].condition2);
     
    68727206void
    68737207CbcModel::takeOffCuts (OsiCuts &newCuts,
    6874                        bool allowResolve, OsiCuts * saveCuts)
     7208                       bool allowResolve, OsiCuts * saveCuts,
     7209                       int numberNewCuts, const OsiRowCut ** addedCuts)
    68757210
    68767211{ // int resolveIterations = 0 ;
     
    69397274    int firstNewCut = firstOldCut+numberOldActiveCuts_ ;
    69407275    int k = 0 ;
    6941     for (i = 0 ; i < numberNewCuts_ ; i++)
     7276    int nCuts = newCuts.sizeRowCuts();
     7277    for (i = 0 ; i < nCuts ; i++)
    69427278    { status = ws->getArtifStatus(i+firstNewCut) ;
    69437279      if (status == CoinWarmStartBasis::basic&&whichGenerator_[i]!=-2)
     
    69467282      else
    69477283      { // save which generator did it
     7284        assert (whichGenerator_[i]!=-2); // ?? what if it is - memory leak?
    69487285        whichGenerator_[k++] = whichGenerator_[i] ; } }
     7286    int baseRow = firstNewCut+nCuts;
     7287    //OsiRowCut ** mutableAdded = const_cast<OsiRowCut **>(addedCuts);
     7288    int numberTotalToDelete=numberNewToDelete+numberOldToDelete;
     7289    for (i = 0 ; i < numberNewCuts ; i++) {
     7290      status = ws->getArtifStatus(i+baseRow) ;
     7291      if (status != CoinWarmStartBasis::basic) {
     7292        newCuts.insert(*addedCuts[i]) ;
     7293        //newCuts.insert(mutableAdded[i]) ;
     7294        //mutableAdded[i]=NULL;
     7295        if (status == CoinWarmStartBasis::basic&&whichGenerator_[i]!=-2) {
     7296          // save which generator did it
     7297          whichGenerator_[k++] = whichGenerator_[i+nCuts] ;
     7298        }
     7299      } else {
     7300        solverCutIndices[numberTotalToDelete++] = i+baseRow ;
     7301      }
     7302    }
     7303    numberNewCuts=0;
     7304    numberNewCuts_ = newCuts.sizeRowCuts();
    69497305    delete ws ;
    69507306    for (i = numberNewToDelete-1 ; i >= 0 ; i--)
     
    69527308      if (saveCuts) {
    69537309        // send to cut pool
    6954         OsiRowCut * slackCut = newCuts.rowCutPtr(iCut);
     7310        OsiRowCut * slackCut = newCuts.rowCutPtrAndZap(iCut);
    69557311        if (slackCut->effectiveness()!=-1.234) {
    69567312          slackCut->setEffectiveness(-1.234);
    6957           saveCuts->insert(*slackCut);
    6958         }
    6959       }
    6960       newCuts.eraseRowCut(iCut) ; }
     7313          saveCuts->insert(slackCut);
     7314        } else {
     7315          delete slackCut;
     7316        }
     7317      } else {
     7318        newCuts.eraseRowCut(iCut) ; }
     7319    }
    69617320/*
    69627321  Did we delete anything? If so, delete the cuts from the constraint system
     
    69657324  basic slacks. Repeat the purging loop.
    69667325*/
    6967     if (numberNewToDelete+numberOldToDelete > 0)
    6968     { solver_->deleteRows(numberNewToDelete+numberOldToDelete,
    6969                           solverCutIndices) ;
     7326    if (numberTotalToDelete > 0 ) {
     7327      solver_->deleteRows(numberTotalToDelete,
     7328                            solverCutIndices) ;
    69707329      numberNewCuts_ -= numberNewToDelete ;
     7330      assert (numberNewCuts_==newCuts.sizeRowCuts());
    69717331      numberOldActiveCuts_ -= numberOldToDelete ;
    69727332#     ifdef CBC_DEBUG
     
    70767436        OsiClpSolverInterface * clpSolver
    70777437          = dynamic_cast<OsiClpSolverInterface *> (solver_);
     7438        if ((specialOptions_&1)!=0&&onOptimalPath) {
     7439          solver_->writeMpsNative("before-tighten.mps",NULL,NULL,2);
     7440        }
    70787441        if (clpSolver&&(!currentNode_||(currentNode_->depth()&2)!=0))
    70797442          nTightened=clpSolver->tightenBounds();
     
    70847447            if (!debugger) {
    70857448              // tighten did something???
    7086               solver_->writeMps("infeas4");
     7449              solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     7450              solver_->writeMpsNative("infeas4.mps",NULL,NULL,2);
    70877451              printf("Not on optimalpath aaaa\n");
    7088               abort();
     7452              //abort();
     7453              onOptimalPath=false;
    70897454            }
    70907455          }
     
    70977462        feasible = (solver_->isProvenOptimal() &&
    70987463                    !solver_->isDualObjectiveLimitReached()) ;
     7464#ifdef COIN_HAS_CLP
     7465        OsiClpSolverInterface * clpSolver
     7466          = dynamic_cast<OsiClpSolverInterface *> (solver_);
     7467        if (clpSolver&&feasible&&!numberNodes_&&false) {
     7468          double direction = solver_->getObjSense() ;
     7469          double tolerance;
     7470          solver_->getDblParam(OsiDualTolerance,tolerance) ;
     7471          double primalTolerance;
     7472          solver_->getDblParam(OsiPrimalTolerance,primalTolerance) ;
     7473
     7474          const double *lower = solver_->getColLower() ;
     7475          const double *upper = solver_->getColUpper() ;
     7476          const double *solution = solver_->getColSolution() ;
     7477          const double *reducedCost = solver_->getReducedCost() ;
     7478          ClpSimplex * clpSimplex=clpSolver->getModelPtr();
     7479          double * rowLower = clpSimplex->rowLower();
     7480          double * rowUpper = clpSimplex->rowUpper();
     7481          int numberRows=clpSimplex->numberRows();
     7482          double * saveRowLower = CoinCopyOfArray(rowLower,numberRows);
     7483          double * saveRowUpper = CoinCopyOfArray(rowUpper,numberRows);
     7484          {
     7485            const double * dual = clpSimplex->dualRowSolution();
     7486            const double * rowActivity = clpSimplex->primalRowSolution();
     7487            for (int iRow = 0 ; iRow < numberRows ; iRow++) {
     7488              double djValue = direction*dual[iRow] ;
     7489              double lowerValue = rowLower[iRow];
     7490              double upperValue = rowUpper[iRow];
     7491              if (rowActivity[iRow] < lowerValue+primalTolerance && djValue > tolerance) {
     7492                rowUpper[iRow]=lowerValue;
     7493                assert (clpSimplex->getRowStatus(iRow)!=ClpSimplex::basic);
     7494              } else if (rowActivity[iRow] > upperValue-primalTolerance && djValue < -tolerance) {
     7495                rowLower[iRow]=upperValue;
     7496                assert (clpSimplex->getRowStatus(iRow)!=ClpSimplex::basic);
     7497              }
     7498            }
     7499          }
     7500          int numberColumns = solver_->getNumCols();
     7501          double * objective = clpSimplex->objective();
     7502          double * saveObj = CoinCopyOfArray(objective,numberColumns);
     7503          double objValue=0.01;
     7504          bool someFree=false;
     7505          for (int iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
     7506            double djValue = direction*reducedCost[iColumn] ;
     7507            double lowerValue = lower[iColumn];
     7508            double upperValue = upper[iColumn];
     7509            if (solution[iColumn] < lowerValue+primalTolerance && djValue > tolerance) {
     7510              objective[iColumn]=1.0e8*direction;
     7511              assert (clpSimplex->getColumnStatus(iColumn)!=ClpSimplex::basic);
     7512            } else if (solution[iColumn] > upperValue-primalTolerance && djValue < -tolerance) {
     7513              objective[iColumn]=-1.0e8*direction;
     7514              assert (clpSimplex->getColumnStatus(iColumn)!=ClpSimplex::basic);
     7515            } else if (lowerValue>-1.0e20||upperValue<1.0e20) {
     7516              assert (fabs(djValue)<=tolerance);
     7517              if (fabs(lowerValue)<fabs(upperValue))
     7518                objective[iColumn]=objValue*direction;
     7519              else
     7520                objective[iColumn]=-objValue*direction;
     7521              objValue += 0.01;
     7522            } else {
     7523              objective[iColumn]=0.0;
     7524              someFree=true;
     7525            }
     7526          }
     7527          if (!someFree)
     7528            clpSimplex->primal(1);
     7529          memcpy(objective,saveObj,numberColumns*sizeof(double));
     7530          delete [] saveObj;
     7531          memcpy(rowLower,saveRowLower,numberRows*sizeof(double));
     7532          delete [] saveRowLower;
     7533          memcpy(rowUpper,saveRowUpper,numberRows*sizeof(double));
     7534          delete [] saveRowUpper;
     7535          if (!someFree) {
     7536            clpSimplex->primal(1);
     7537            //assert (clpSimplex->numberIterations()<10);
     7538          }
     7539          //clpSimplex->writeMps("xx");
     7540          //clpSimplex->primal(1);
     7541          clpSolver->setWarmStart(NULL);
     7542        }
     7543#endif
    70997544        if ((specialOptions_&1)!=0&&onOptimalPath) {
    71007545          if (!solver_->getRowCutDebugger()) {
    71017546            // tighten did something???
    7102             solver_->writeMps("infeas4");
    7103             assert (solver_->getRowCutDebugger()) ;
     7547            solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     7548            solver_->writeMpsNative("infeas4.mps",NULL,NULL,2);
     7549            //assert (solver_->getRowCutDebugger()) ;
    71047550            printf("Not on optimalpath e\n");
    7105             abort();
     7551            //abort();
    71067552          }
    71077553        }
     
    74297875  delete [] type;
    74307876  delete [] lookup;
    7431 #ifdef COIN_DEVELOP
     7877#if COIN_DEVELOP>1
    74327878  if (numberCliques<0) {
    74337879    printf("*** Problem infeasible\n");
     
    78388284      CbcSimpleIntegerDynamicPseudoCost * newObject =
    78398285        new CbcSimpleIntegerDynamicPseudoCost(this,iColumn,1.0e0*downCost,1.0e0*upCost);
    7840       newObject->setNumberBeforeTrust(numberBeforeTrust_);
     8286      //newObject->setNumberBeforeTrust(numberBeforeTrust_);
    78418287      newObject->setPriority(priority);
    78428288      newObject->setPreferredWay(preferredWay);
     
    78468292    } else {
    78478293      // synchronize trust
    7848       obj2->setNumberBeforeTrust(numberBeforeTrust_);
     8294      //obj2->setNumberBeforeTrust(numberBeforeTrust_);
    78498295    }
    78508296  }
     
    78618307    // create one
    78628308    branchingMethod_ = new CbcBranchDynamicDecision();
     8309  }
     8310  synchronizeNumberBeforeTrust();
     8311}
     8312// Set numberBeforeTrust in all objects
     8313void
     8314CbcModel::synchronizeNumberBeforeTrust()
     8315{
     8316  int iObject;
     8317  for (iObject = 0;iObject<numberObjects_;iObject++) {
     8318    CbcSimpleIntegerDynamicPseudoCost * obj2 =
     8319      dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object_[iObject]) ;
     8320    if (obj2) {
     8321      // synchronize trust
     8322      obj2->setNumberBeforeTrust(numberBeforeTrust_);
     8323    }
    78638324  }
    78648325}
     
    79118372  delete [] integerVariable_;
    79128373  integerVariable_=NULL;
    7913 #ifdef COIN_DEVELOP
     8374#if COIN_DEVELOP>1
    79148375  if (newIntegers!=numberIntegers_)
    79158376    printf("changing number of integers from %d to %d\n",
     
    79388399    }
    79398400  }
    7940 #ifdef COIN_DEVELOP
     8401#if COIN_DEVELOP>1
    79418402  if (newIntegers)
    79428403    printf("%d variables were declared integer\n",newIntegers);
     
    80278488  delete [] integerVariable_;
    80288489  integerVariable_=NULL;
    8029 #ifdef COIN_DEVELOP
     8490#if COIN_DEVELOP>1
    80308491  if (newIntegers!=numberIntegers_)
    80318492    printf("changing number of integers from %d to %d\n",
     
    80548515    }
    80558516  }
    8056 #ifdef COIN_DEVELOP
     8517#if COIN_DEVELOP>1
    80578518  if (newIntegers)
    80588519    printf("%d variables were declared integer\n",newIntegers);
     
    81498610double
    81508611CbcModel::checkSolution (double cutoff, double *solution,
    8151                          bool fixVariables, double objectiveValue)
     8612                         int fixVariables, double objectiveValue)
    81528613
    81538614{
     
    81948655    */
    81958656    int i;
    8196     for (i=0;i<numberObjects_;i++)
     8657    for (i=0;i<numberObjects_;i++) 
    81978658      object_[i]->feasibleRegion(solver_,&usefulInfo);
     8659      // If relaxed then leave bounds on basic variables
     8660    if (fixVariables==-1) {
     8661      CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis*>(saveSolver->getWarmStart()) ;
     8662      assert(basis != NULL);
     8663      for (i=0;i<numberObjects_;i++) {
     8664        CbcSimpleInteger * obj =
     8665          dynamic_cast <CbcSimpleInteger *>(object_[i]) ;
     8666        if (obj) {
     8667          int iColumn = obj->columnNumber();
     8668          if (basis->getStructStatus(iColumn)==CoinWarmStartBasis::basic) {
     8669            solver_->setColLower(iColumn,saveLower[iColumn]);
     8670            solver_->setColUpper(iColumn,saveUpper[iColumn]);
     8671          }
     8672        }
     8673      }
     8674      delete basis;
     8675    }
    81988676    // We can switch off check
    81998677    if ((specialOptions_&4)==0) {
     
    82258703      if (!solver_->isProvenOptimal())
    82268704        {
    8227 #ifdef COIN_DEVELOP
     8705#if COIN_DEVELOP>1
    82288706          printf("checkSolution infeas! Retrying with primal.\n");
    82298707#endif
     
    82478725            solver_->setWarmStart(slack);
    82488726            delete slack ;
    8249 #ifdef COIN_DEVELOP
     8727#if COIN_DEVELOP>1
    82508728            printf("checkSolution infeas! Retrying wihout basis and with primal.\n");
    82518729#endif
    82528730            solver_->initialSolve();
    8253 #ifdef COIN_DEVELOP
     8731#if COIN_DEVELOP>1
    82548732            if (!solver_->isProvenOptimal()) {
    82558733              printf("checkSolution still infeas!\n");
     
    82848762      double integerTolerance = getIntegerTolerance() ;
    82858763#endif
    8286 #ifdef COIN_DEVELOP
     8764#if COIN_DEVELOP>1
    82878765      const double * dj = solver_->getReducedCost();
    82888766      const double * colLower = saveSolver->getColLower();
     
    83048782        if (solver_->isInteger(iColumn)) {
    83058783          assert(fabs(value-solution[iColumn]) <= integerTolerance) ;
    8306 #ifdef COIN_DEVELOP
     8784#if COIN_DEVELOP>1
    83078785          double value2 = floor(value+0.5);
    83088786          if (dj[iColumn]<-1.0e-6) {
     
    83558833        solution[iColumn] = value ;
    83568834      }
    8357 #ifdef COIN_DEVELOP
     8835#if COIN_DEVELOP>1
    83588836      printf("nAtLbNat %d,nAtUbNat %d,nAtLbNatZero %d,nAtUbNatZero %d,nAtLbFixed %d,nAtUbFixed %d,nAtOther %d,nAtOtherNat %d, useless %d\n",
    83598837             nAtLbNatural,
     
    84018879      prevents us from simply reversing the memcpy used to make these snapshots.
    84028880    */
    8403     if (!fixVariables)
     8881    if (fixVariables<=0)
    84048882      { for (int iColumn = 0 ; iColumn < numberColumns ; iColumn++)
    84058883        { solver_->setColLower(iColumn,saveLower[iColumn]) ;
     
    84268904    if(! solutionComesFromNlp)//Otherwise solution already comes from ipopt and cuts are known
    84278905      {
    8428         if(fixVariables)//Will temporarily fix all integer valued var
     8906        if(fixVariables>0)//Will temporarily fix all integer valued var
    84298907          {
    84308908            // save original bounds
     
    84668944            if (generator_[i]->atSolution())
    84678945              {
    8468                 generator_[i]->generateCuts(theseCuts,true,solver_,NULL);
     8946                generator_[i]->generateCuts(theseCuts,1,solver_,NULL);
    84698947                int numberCuts = theseCuts.sizeRowCuts();
    84708948                for (int j=lastNumberCuts;j<numberCuts;j++)
     
    85218999        objectiveValue = 2e50;
    85229000      }
    8523     if (!solutionComesFromNlp && fixVariables)
     9001    if (!solutionComesFromNlp && fixVariables>0)
    85249002      {
    85259003        for (int iColumn = 0 ; iColumn < numberColumns ; iColumn++)
     
    85339011    //If the variables were fixed the cutting plane procedure may have believed that the node could be fathomed
    85349012    //re-establish truth.- should do no harm for non nlp
    8535     if(!solutionComesFromNlp && fixVariables)
     9013    if(!solutionComesFromNlp && fixVariables>0)
    85369014      solverCharacteristics_->setMipBound(-COIN_DBL_MAX);
    85379015    return objectiveValue;
     
    85609038CbcModel::setBestSolution (CBC_Message how,
    85619039                           double & objectiveValue, const double *solutionIn,
    8562                            bool fixVariables)
     9040                           int fixVariables)
    85639041
    85649042{
    85659043  double * solution=CoinCopyOfArray(solutionIn,solver_->getNumCols());
     9044#if 0
     9045  {
     9046    double saveOffset;
     9047    solver_->getDblParam(OsiObjOffset,saveOffset);
     9048    const double * obj = solver_->getObjCoefficients();
     9049    double newTrueSolutionValue = -saveOffset;
     9050    double newSumInfeas=0.0;
     9051    int numberColumns = solver_->getNumCols();
     9052    for (int  i=0 ; i<numberColumns ; i++ ) {
     9053      if (solver_->isInteger(i)) {
     9054        double value = solution[i];
     9055        double nearest = floor(value+0.5);
     9056        newSumInfeas += fabs(value-nearest);
     9057      }
     9058      if (solution[i])
     9059        printf("%d obj %g val %g - total %g true\n",i,obj[i],solution[i],
     9060               newTrueSolutionValue);
     9061      newTrueSolutionValue += obj[i]*solution[i];
     9062    }
     9063    printf("obj %g\n",newTrueSolutionValue);
     9064  }
     9065#endif
    85669066  if (!solverCharacteristics_->solutionAddsCuts()) {
    85679067    // Can trust solution
     
    85749074    */
    85759075    double saveObjectiveValue = objectiveValue;
     9076    // save basis
     9077    CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis*>(solver_->getWarmStart()) ;
     9078    assert(basis != NULL);
    85769079    objectiveValue =checkSolution(cutoff,solution,fixVariables,objectiveValue);
     9080    if (saveObjectiveValue+1.0e-5<objectiveValue) {
     9081#if COIN_DEVELOP>1
     9082      printf("First try at solution had objective %.16g, rechecked as %.16g\n",
     9083                 saveObjectiveValue,objectiveValue);
     9084#endif
     9085      // try again with basic variables with original bounds
     9086      // save basis
     9087      CoinWarmStartBasis * basis2 =
     9088        dynamic_cast<CoinWarmStartBasis*>(solver_->getWarmStart()) ;
     9089      assert(basis2 != NULL);
     9090      solver_->setWarmStart(basis);
     9091      int numberColumns = solver_->getNumCols();
     9092      double * solution2 = CoinCopyOfArray(solutionIn,numberColumns);
     9093      double objectiveValue2 = saveObjectiveValue;
     9094      objectiveValue2 =checkSolution(cutoff,solution2,-1,objectiveValue2);
     9095#if COIN_DEVELOP>1
     9096      printf("Relaxed second try had objective of %.16g\n",
     9097             objectiveValue2);
     9098#endif
     9099      if (objectiveValue2+1.0e-7<objectiveValue) {
     9100        // Now check tolerances
     9101        double integerTolerance = dblParam_[CbcIntegerTolerance];
     9102        double tolerance;
     9103        solver_->getDblParam(OsiPrimalTolerance,tolerance) ;
     9104        double largestAway = 0.0;
     9105        int iAway=-1;
     9106        double largestInfeasibility = tolerance;
     9107        int iInfeas=-1;
     9108        const double * columnLower = continuousSolver_->getColLower();
     9109        const double * columnUpper = continuousSolver_->getColUpper();
     9110        int i;
     9111        for (i=0;i<numberColumns;i++) {
     9112          double value=solution2[i];
     9113          if (value>columnUpper[i]+largestInfeasibility) {
     9114            iInfeas=i;
     9115            largestInfeasibility = value-columnUpper[i];
     9116          } else if (value<columnLower[i]-largestInfeasibility) {
     9117            iInfeas=i;
     9118            largestInfeasibility = columnLower[i]-value;
     9119          }
     9120        }
     9121        for (i=0;i<numberObjects_;i++) {
     9122          CbcSimpleInteger * obj =
     9123            dynamic_cast <CbcSimpleInteger *>(object_[i]) ;
     9124          if (obj) {
     9125            int iColumn = obj->columnNumber();
     9126            double value = solution2[iColumn];
     9127            value = fabs(floor(value+0.5)-value);
     9128            if (value>largestAway) {
     9129              iAway=iColumn;
     9130              largestAway=value;
     9131            }
     9132          }
     9133        }
     9134#if COIN_DEVELOP>1
     9135        if (iInfeas>=0)
     9136          printf("Largest infeasibility of %g on column %d - tolerance %g\n",
     9137                 largestInfeasibility,iInfeas,tolerance);
     9138#endif
     9139#if COIN_DEVELOP<2
     9140        if (largestAway<1.0e-3)
     9141#endif
     9142        if (largestAway>integerTolerance)
     9143          handler_->message(CBC_RELAXED1, messages_)
     9144            << objectiveValue2
     9145            << iAway
     9146            << largestAway
     9147            << integerTolerance
     9148            << CoinMessageEol ;
     9149        else
     9150          handler_->message(CBC_RELAXED2, messages_)
     9151            << objectiveValue2
     9152            << largestAway
     9153            << integerTolerance
     9154            << CoinMessageEol ;
     9155      }
     9156      delete [] solution2;
     9157      solver_->setWarmStart(basis2);
     9158      delete basis2 ;
     9159    }
     9160    delete basis ;
    85779161    if (objectiveValue>cutoff&&objectiveValue<cutoff+1.0e-8+1.0e-8*fabs(cutoff))
    85789162      cutoff = objectiveValue; // relax
     
    85899173        good news.
    85909174      */
     9175      specialOptions_ |= 256; // mark as full cut scan should be done
    85919176      bestObjective_ = objectiveValue;
    85929177      int numberColumns = solver_->getNumCols();
     
    85989183      // But allow for rounding errors
    85999184      if (dblParam_[CbcCutoffIncrement] == 1e-5) {
    8600 #ifdef COIN_DEVELOP
     9185#if COIN_DEVELOP>5
    86019186        if (saveObjectiveValue+1.0e-7<bestObjective_)
    86029187          printf("First try at solution had objective %.16g, rechecked as %.16g\n",
     
    86489233          generate=false;
    86499234        if (generate) {
    8650           generator_[i]->generateCuts(theseCuts,true,solver_,NULL);
     9235          generator_[i]->generateCuts(theseCuts,1,solver_,NULL);
    86519236          int numberCuts = theseCuts.sizeRowCuts();
    86529237          for (int j=lastNumberCuts;j<numberCuts;j++) {
     
    87129297    //if in strongBranching or heuristic will do only one cut generation iteration
    87139298    // by fixing variables.
    8714     fixVariables = fixVariables || (how==CBC_ROUNDING) || (how==CBC_STRONGSOL);
     9299    if (!fixVariables&&((how==CBC_ROUNDING) || (how==CBC_STRONGSOL)))
     9300      fixVariables = 1;
    87159301    double * candidate = new double[numberColBefore];
    87169302    CoinCopyN(solution, numberColBefore, candidate);
     
    91179703          numberTightened++;
    91189704        int saveFixed=numberFixed;
    9119 
     9705       
    91209706        int jColumn;
    91219707        if (generator) {
     
    948310069          if (ifSol>0) {
    948410070            // better solution found
     10071            heuristic_[iHeuristic]->incrementNumberSolutionsFound();
    948510072            found=iHeuristic;
    948610073            incrementUsed(newSolution);
     
    951310100        delete [] addedCuts_;
    951410101        addedCuts_ = NULL;
    9515 
     10102       
    951610103        // maximum depth for tree walkback
    951710104        maximumDepth_=10;
    951810105        delete [] walkback_;
    951910106        walkback_ = new CbcNodeInfo * [maximumDepth_];
    9520 
     10107       
    952110108        OsiCuts cuts;
    952210109        numberOldActiveCuts_=0;
     
    1050611093    //branchingState=1;
    1050711094    if (!branchingMethod_||!branchingMethod_->chooseMethod()) {
     11095#ifdef COIN_HAS_CLP
     11096      if (oldNode&&fastNodeDepth_>=0&&oldNode->depth()>=4&&!parentModel_
     11097          &&(oldNode->depth()%2)==0) {
     11098        OsiClpSolverInterface * clpSolver
     11099          = dynamic_cast<OsiClpSolverInterface *> (solver_);
     11100        if (clpSolver) {
     11101          anyAction = newNode->chooseClpBranch(this,oldNode) ;
     11102          if (anyAction!=-1)
     11103            break;
     11104        }
     11105      }
     11106#endif
    1050811107      if (numberBeforeTrust_==0 ) {
    1050911108        anyAction = newNode->chooseBranch(this,oldNode,numberPassesLeft) ;
     
    1059311192      // bool needValidSolution = (newNode->branchingObject() == NULL) ;
    1059411193      bool needValidSolution = true ;
    10595       takeOffCuts(cuts,needValidSolution,NULL) ;
     11194      takeOffCuts(cuts,needValidSolution ,NULL) ;
    1059611195#             ifdef CHECK_CUT_COUNTS
    1059711196      {
     
    1061211211    if (newNode->numberUnsatisfied()) {
    1061311212      maximumDepthActual_ = CoinMax(maximumDepthActual_,newNode->depth());
     11213      // Number of branches is in oldNode!
    1061411214      newNode->initializeInfo() ;
    1061511215      if (cuts.sizeRowCuts()) {
     
    1094611546      if (ifSol>0) {
    1094711547        // better solution found
     11548        heuristic_[i]->incrementNumberSolutionsFound();
    1094811549        found = i ;
    1094911550        incrementUsed(newSolution);
     
    1120411805  cutModifier_ = modifier.clone();
    1120511806}
    11206 #ifdef CBC_THREAD
    1120711807/* Do one node - broken out for clarity?
    1120811808   also for parallel (when baseModel!=this)
     
    1138411984        // point to useful information
    1138511985        OsiBranchingInformation usefulInfo=usefulInformation();
    11386 
     11986       
    1138711987        for (iObject = 0 ; iObject < numberObjects_ ; iObject++) {
    1138811988          double infeasibility =
     
    1140812008    } else {
    1140912009      // normal
     12010      if (false) {
     12011        const double * lower = solver_->getColLower();
     12012        const double * upper = solver_->getColUpper();
     12013        printf("STATE before solve\n");
     12014        for (int i=0;i<100;i++)
     12015          if (lower[i]||!upper[i])
     12016            printf("%d fixed to %g\n",i,lower[i]);
     12017      }
     12018#ifdef COIN_HAS_CLP
     12019      bool fathomDone=false;
     12020      OsiClpSolverInterface * clpSolver
     12021        = dynamic_cast<OsiClpSolverInterface *> (solver_);
     12022      if (clpSolver&&fastNodeDepth_<-1) {
     12023#define FATHOM_BIAS 1
     12024        //#ifdef COIN_DEVELOP
     12025        if (numberNodes_==1) {
     12026          int numberNodesBeforeFathom = 500;
     12027          if (fastNodeDepth_<-1000001) {
     12028            numberNodesBeforeFathom = (-fastNodeDepth_)/1000000;
     12029            numberNodesBeforeFathom = 250*numberNodesBeforeFathom;
     12030          }
     12031#ifdef COIN_DEVELOP
     12032          int fastNodeDepth1 = -fastNodeDepth_ % 1000000;
     12033          printf("initial depth %d after %d nodes\n",
     12034                 FATHOM_BIAS+fastNodeDepth1,numberNodesBeforeFathom);
     12035#endif
     12036        }
     12037        //#endif
     12038        ClpNodeStuff stuff;
     12039        ClpNodeStuff * info = &stuff;
     12040        /*
     12041          Used to generate bound edits for CbcPartialNodeInfo.
     12042        */
     12043        //double * lowerBefore = NULL;
     12044        //double * upperBefore = NULL;
     12045        int fastNodeDepth1 = -fastNodeDepth_ % 1000000;
     12046        int numberNodesBeforeFathom = 500;
     12047        if (fastNodeDepth_<-1000001) {
     12048          numberNodesBeforeFathom = (-fastNodeDepth_)/1000000;
     12049          numberNodesBeforeFathom = 250*numberNodesBeforeFathom;
     12050        }
     12051        int go_fathom = FATHOM_BIAS+fastNodeDepth1;
     12052        if (node->depth()>=go_fathom &&!parentModel_
     12053            //if (node->depth()>=FATHOM_BIAS-fastNodeDepth_&&!parentModel_
     12054            &&numberNodes_>numberNodesBeforeFathom) {
     12055          info->integerTolerance_=getIntegerTolerance();
     12056          info->integerIncrement_=getCutoffIncrement();
     12057          double * down = new double[numberIntegers_];
     12058          double * up = new double[numberIntegers_];
     12059          int * numberDown = new int[numberIntegers_];
     12060          int * numberUp = new int[numberIntegers_];
     12061          int * numberDownInfeasible = new int[numberIntegers_];
     12062          int * numberUpInfeasible = new int[numberIntegers_];
     12063          fillPseudoCosts(down,up,numberDown,numberUp,
     12064                          numberDownInfeasible,numberUpInfeasible);
     12065          info->fillPseudoCosts(down,up,numberDown,numberUp,
     12066                                numberDownInfeasible,
     12067                                numberUpInfeasible,numberIntegers_);
     12068          info->presolveType_=1;
     12069          delete [] down;
     12070          delete [] up;
     12071          delete [] numberDown;
     12072          delete [] numberUp;
     12073          delete [] numberDownInfeasible;
     12074          delete [] numberUpInfeasible;
     12075          bool takeHint;
     12076          OsiHintStrength strength;
     12077          solver_->getHintParam(OsiDoReducePrint,takeHint,strength);
     12078          ClpSimplex * simplex = clpSolver->getModelPtr();
     12079          int saveLevel = simplex->logLevel();
     12080          if (strength!=OsiHintIgnore&&takeHint&&saveLevel==1)
     12081            simplex->setLogLevel(0);
     12082          clpSolver->setBasis();
     12083          feasible = simplex->fathom(info)!=0;
     12084          numberExtraNodes_ += info->numberNodesExplored_;
     12085          numberExtraIterations_ += info->numberIterations_;
     12086          if (info->nNodes_<0) {
     12087            // we gave up
     12088            //abort();
     12089            fastNodeDepth_ -= 2;
     12090#ifdef COIN_DEVELOP
     12091            printf("fastNodeDepth now %d - so at depth >= %d\n",
     12092                   fastNodeDepth_,FATHOM_BIAS-fastNodeDepth_);
     12093#endif
     12094            if (feasible) {
     12095              clpSolver->setWarmStart(NULL);
     12096              // try and do solution
     12097              double value = simplex->objectiveValue()*
     12098                simplex->optimizationDirection();
     12099              double * newSolution =
     12100                CoinCopyOfArray(simplex->primalColumnSolution(),
     12101                                numberColumns);
     12102              setBestSolution(CBC_STRONGSOL,value,newSolution) ;
     12103              delete [] newSolution;
     12104            }
     12105            // say feasible so will redo node
     12106            feasible=true;
     12107          } else {
     12108            if (feasible) {
     12109              clpSolver->setWarmStart(NULL);
     12110              // try and do solution
     12111              double value = simplex->objectiveValue()*
     12112                simplex->optimizationDirection();
     12113              double * newSolution =
     12114                CoinCopyOfArray(simplex->primalColumnSolution(),
     12115                                numberColumns);
     12116              setBestSolution(CBC_STRONGSOL,value,newSolution) ;
     12117              delete [] newSolution;
     12118            }
     12119            // update pseudo costs
     12120            double smallest=1.0e50;
     12121            double largest=-1.0;
     12122            for (int i=0;i<numberIntegers_-000000;i++) {
     12123              CbcSimpleIntegerDynamicPseudoCost * obj =
     12124                dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object_[i]) ;
     12125              assert (obj&&obj->columnNumber()==integerVariable_[i]);
     12126              if (info->numberUp_[i]>0) {
     12127                if (info->downPseudo_[i]>largest)
     12128                  largest=info->downPseudo_[i];
     12129                if (info->downPseudo_[i]<smallest)
     12130                  smallest=info->downPseudo_[i];
     12131                if (info->upPseudo_[i]>largest)
     12132                  largest=info->upPseudo_[i];
     12133                if (info->upPseudo_[i]<smallest)
     12134                  smallest=info->upPseudo_[i];
     12135                obj->updateAfterMini(info->numberDown_[i],
     12136                                     info->numberDownInfeasible_[i],
     12137                                     info->downPseudo_[i],
     12138                                     info->numberUp_[i],
     12139                                     info->numberUpInfeasible_[i],
     12140                                     info->upPseudo_[i]);
     12141              }
     12142            }
     12143            //printf("range of costs %g to %g\n",smallest,largest);
     12144            // If value of objective borderline then may not be feasible
     12145            double value = simplex->objectiveValue()*simplex->optimizationDirection();
     12146            if (value-getCutoff()<-1.0e-1)
     12147              fathomDone=true;
     12148          }
     12149          simplex->setLogLevel(saveLevel);
     12150        }
     12151      }
     12152      if (feasible) {
     12153        feasible = solveWithCuts(cuts,maximumCutPasses_,node);
     12154        if (fathomDone)
     12155          assert (feasible);
     12156      }
     12157#else
    1141012158      feasible = solveWithCuts(cuts,maximumCutPasses_,node);
     12159#endif
    1141112160    }
    1141212161    if ((specialOptions_&1)!=0&&onOptimalPath) {
    1141312162      if (!solver_->getRowCutDebugger()||!feasible) {
    1141412163        // dj fix did something???
    11415         solver_->writeMps("infeas2");
     12164        solver_->writeMpsNative("infeas2.mps",NULL,NULL,2);
     12165        solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
    1141612166        assert (solver_->getRowCutDebugger()) ;
    1141712167        assert (feasible);
     
    1144312193      if (!feasible && !objLim) {
    1144412194        printf("infeas2\n");
    11445         solver_->writeMps("infeas");
     12195        solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     12196        solver_->writeMpsNative("infeas.mps",NULL,NULL,2);
    1144612197        CoinWarmStartBasis *slack =
    1144712198          dynamic_cast<CoinWarmStartBasis *>(solver_->getEmptyWarmStart()) ;
     
    1158712338                  } else {
    1158812339                    inBetween=true;
    11589                   }
     12340                  }            
    1159012341                } else {
    1159112342                  // must have been up branch
     
    1178312534              generate=false; // only special cuts
    1178412535            if (generate) {
    11785               generator_[i]->generateCuts(theseCuts,true,solver_,NULL) ;
     12536              generator_[i]->generateCuts(theseCuts,1,solver_,NULL) ;
    1178612537              int numberRowCutsAfter = theseCuts.sizeRowCuts() ;
    1178712538              if (numberRowCutsAfter) {
     
    1182412575            if (ifSol > 0) {
    1182512576              // new solution found
     12577              heuristic_[iHeur]->incrementNumberSolutionsFound();
    1182612578              found = iHeur ;
    1182712579#ifndef CBC_DETERMINISTIC_THREAD
     
    1203812790      if (j!=data.objectNumber_) {
    1203912791        printf("bad number\n");
    12040       }
     12792      } 
    1204112793      break;
    1204212794    }
     
    1205512807}
    1205612808#endif
     12809#ifdef CBC_THREAD
    1205712810// Split up nodes - returns number of CbcNodeInfo's affected
    1205812811int
     
    1232813081    solverCharacteristics_ = new OsiBabSolver (*baseModel->solverCharacteristics_);
    1232913082    solverCharacteristics_->setSolver(solver_);
    12330     setMaximumNodes(INT_MAX);
     13083    setMaximumNodes(COIN_INT_MAX);
    1233113084#ifndef CBC_DETERMINISTIC_THREAD
    1233213085    delete [] walkback_;
     
    1262413377      // normal
    1262513378      assert (stuff->returnCode==0);
    12626       bool fullScan = thisModel->getNodeCount()>0;
     13379      int fullScan = thisModel->getNodeCount()==0 ? 1 : 0; //? was >0
    1262713380      CbcCutGenerator * generator = thisModel->cutGenerator(0);
    1262813381      OsiCuts * cuts = (OsiCuts *) thisModel->objects();
     
    1290913662*/
    1291013663void
    12911 CbcModel::fillPseudoCosts(double * downCosts, double * upCosts) const
     13664CbcModel::fillPseudoCosts(double * downCosts, double * upCosts,
     13665                          int * numberDown, int * numberUp,
     13666                          int * numberDownInfeasible,
     13667                          int * numberUpInfeasible) const
    1291213668{
    1291313669  CoinZeroN(downCosts,numberIntegers_);
     
    1293113687    downCosts[iColumn]=obj->downDynamicPseudoCost();
    1293213688    upCosts[iColumn]=obj->upDynamicPseudoCost();
     13689    if (numberDown) {
     13690      numberDown[iColumn]=obj->numberTimesDown();
     13691      numberUp[iColumn]=obj->numberTimesUp();
     13692    }
     13693    if (numberDownInfeasible) {
     13694      numberDownInfeasible[iColumn]=obj->numberTimesDownInfeasible();
     13695      numberUpInfeasible[iColumn]=obj->numberTimesUpInfeasible();
     13696    }
    1293313697  }
    1293413698  delete [] back;
  • trunk/Cbc/src/CbcModel.hpp

    r871 r931  
    3131class CbcEventHandler ;
    3232class CglPreProcess;
    33 
     33# ifdef COIN_HAS_CLP
     34class ClpNodeStuff;
     35#endif
    3436// #define CBC_CHECK_BASIS 1
    3537
     
    10031005  void setBestSolution(CBC_Message how,
    10041006                       double & objectiveValue, const double *solution,
    1005                        bool fixVariables=false);
     1007                       int fixVariables=0);
    10061008  /// Just update objectiveValue
    10071009  void setBestObjectiveValue( double objectiveValue);
     
    10141016 */
    10151017  double checkSolution(double cutoff, double * solution,
    1016                        bool fixVariables, double originalObjValue);
     1018                       int fixVariables, double originalObjValue);
    10171019  /** Test the current solution for feasiblility.
    10181020
     
    14521454      5 bit (32) - keep names
    14531455      6 bit (64) - try for dominated columns
     1456      7 bit (128) - SOS type 1 but all declared integer
     1457      8 bit (256) - Set to say solution just found, unset by doing cuts
    14541458  */
    14551459  /// Set special options
     
    16161620    reoptimisation.
    16171621    If saveCuts then slack cuts will be saved
     1622    On input current cuts are cuts and newCuts
     1623    on exit current cuts will be correct
    16181624  */
    16191625  void takeOffCuts(OsiCuts &cuts,
    1620                      bool allowResolve,OsiCuts * saveCuts) ;
     1626                   bool allowResolve,OsiCuts * saveCuts,
     1627                   int numberNewCuts=0, const OsiRowCut ** newCuts=NULL) ;
    16211628
    16221629  /** Determine and install the active cuts that need to be added for
     
    16651672  */
    16661673  void convertToDynamic();
     1674  /// Set numberBeforeTrust in all objects
     1675  void synchronizeNumberBeforeTrust();
    16671676  /// Zap integer information in problem (may leave object info)
    16681677  void zapIntegerInformation(bool leaveObjects=true);
     
    16771686      User must allocate arrays before call
    16781687  */
    1679   void fillPseudoCosts(double * downCosts, double * upCosts) const;
     1688  void fillPseudoCosts(double * downCosts, double * upCosts,
     1689                       int * numberDown=NULL, int * numberUp=NULL,
     1690                       int * numberDownInfeasible=NULL,
     1691                       int * numberUpInfeasible=NULL) const;
    16801692  /** Do heuristics at root.
    16811693      0 - don't delete
     
    17141726  inline int numberStrongIterations() const
    17151727  { return numberStrongIterations_;}
     1728# ifdef COIN_HAS_CLP
     1729  /// Set depth for fast nodes
     1730  inline void setFastNodeDepth(int value)
     1731  { fastNodeDepth_ = value;}
     1732  /// Get depth for fast nodes
     1733  inline int fastNodeDepth() const
     1734  { return fastNodeDepth_;}
     1735  inline void incrementExtra(int nodes, int iterations)
     1736  { numberExtraNodes_ += nodes; numberExtraIterations_ += iterations;}
     1737#endif
    17161738  /// Increment strong info
    17171739  void incrementStrongInfo(int numberTimes, int numberIterations,
     
    20072029  /// Pointer to heuristic solver which found last solution (or NULL)
    20082030  CbcHeuristic * lastHeuristic_;
     2031# ifdef COIN_HAS_CLP
     2032  /// Depth for fast nodes
     2033  int fastNodeDepth_;
     2034#endif
    20092035  /*! Pointer to the event handler */
    20102036# ifdef CBC_ONLY_CLP
     
    20382064      should be kept for each cut and type of cut */
    20392065  int numberGlobalViolations_;
     2066  /// Number of extra iterations in fast lp
     2067  int numberExtraIterations_;
     2068  /// Number of extra nodes in fast lp
     2069  int numberExtraNodes_;
    20402070  /** Value of objective at continuous
    20412071      (Well actually after initial round of cuts)
  • trunk/Cbc/src/CbcNode.cpp

    r915 r931  
    587587    basis = dynamic_cast<CoinWarmStartBasis *>(basis_->clone()) ;
    588588    basis->resize(numberRows,numberColumns);
     589#ifdef CBC_CHECK_BASIS
     590    std::cout << "Basis (after applying root " <<this<<") "<< std::endl ;
     591    basis->print() ;
     592#endif   
    589593  } else {
    590594    // We have a solver without a basis
     
    720724  if ((active_&4)!=0) {
    721725    basis->applyDiff(basisDiff_) ;
     726#ifdef CBC_CHECK_BASIS
     727    std::cout << "Basis (after applying " <<this<<") "<< std::endl ;
     728    basis->print() ;
     729#endif   
    722730  }
    723731
     
    10411049    lastws->print() ;
    10421050#endif   
     1051    assert (expanded->getNumArtificial()>=lastws->getNumArtificial());
     1052    if (!expanded->fullBasis()) {
     1053      int iFull = numberRowsAtContinuous+currentNumberCuts+numberNewCuts;
     1054      printf("cont %d old %d new %d current %d full inc %d full %d\n",
     1055             numberRowsAtContinuous,numberOldActiveCuts,numberNewCuts,
     1056             currentNumberCuts,iFull,iFull-numberNewCuts);
     1057    }
     1058    assert (lastws->fullBasis());
    10431059
    10441060/*
     
    23602376    auxiliaryInfo = model->solverCharacteristics();
    23612377  }
     2378  int numberObjects = model->numberObjects();
     2379  bool checkFeasibility = numberObjects>model->numberIntegers();
     2380  if ((model->specialOptions()&128)!=0)
     2381    checkFeasibility=false; // allow
     2382  // For now return if not simple
     2383  if (checkFeasibility)
     2384    return -3;
    23622385  // point to useful information
    23632386  OsiBranchingInformation usefulInfo = model->usefulInformation();
    23642387  // and modify
    23652388  usefulInfo.depth_=depth_;
     2389  if ((model->specialOptions()&128)!=0) {
     2390    // SOS - shadow prices
     2391    int numberRows = solver->getNumRows();
     2392    const double * pi = usefulInfo.pi_;
     2393    double sumPi=0.0;
     2394    for (int i=0;i<numberRows;i++)
     2395      sumPi += fabs(pi[i]);
     2396    sumPi /= ((double) numberRows);
     2397    // and scale back
     2398    sumPi *= 0.01;
     2399    usefulInfo.defaultDual_ = sumPi; // switch on
     2400    int numberColumns = solver->getNumCols();
     2401    int size = CoinMax(numberColumns,2*numberRows);
     2402    usefulInfo.usefulRegion_ = new double [size];
     2403    CoinZeroN(usefulInfo.usefulRegion_,size);
     2404    usefulInfo.indexRegion_ = new int [size];
     2405    // pi may change
     2406    usefulInfo.pi_=CoinCopyOfArray(usefulInfo.pi_,numberRows);
     2407  }
    23662408  assert (auxiliaryInfo);
    23672409  //assert(objectiveValue_ == solver->getObjSense()*solver->getObjValue());
     
    23862428  // Use minimum of this and one stored in objects
    23872429  //int numberBeforeTrust = model->numberBeforeTrust();
    2388   int numberObjects = model->numberObjects();
    2389   bool checkFeasibility = numberObjects>model->numberIntegers();
    2390   // For now return if not simple
    2391   if (checkFeasibility)
    2392     return -3;
    23932430  // Return if doing hot start (in BAB sense)
    23942431  if (model->hotstartSolution())
     
    25062543  const CglTreeProbingInfo * probingInfo = model->probingInfo();
    25072544  int saveSearchStrategy2 = model->searchStrategy();
     2545#define NODE_NEW  2
     2546#ifdef RANGING
     2547  bool useRanging;
     2548#if NODE_NEW !=3
     2549  useRanging = false;
     2550#else
     2551  useRanging = true;
     2552#endif
     2553  if (saveSearchStrategy2!=2)
     2554    useRanging=false;
     2555#endif
    25082556  if (saveSearchStrategy2<999) {
     2557#if NODE_NEW ==4
     2558    if (saveSearchStrategy2!=2) {
     2559#endif
    25092560    // Get average up and down costs
    25102561    double averageUp=0.0;
     
    25182569        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    25192570          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2520         assert(dynamicObject);
    2521         if (dynamicObject->numberTimesUp()) {
    2522           numberUp++;
    2523           averageUp += dynamicObject->upDynamicPseudoCost();
    2524         }
    2525         if (dynamicObject->numberTimesDown()) {
    2526           numberDown++;
    2527           averageDown += dynamicObject->downDynamicPseudoCost();
    2528         }
     2571        if (dynamicObject) {
     2572          if (dynamicObject->numberTimesUp()) {
     2573            numberUp++;
     2574            averageUp += dynamicObject->upDynamicPseudoCost();
     2575          }
     2576          if (dynamicObject->numberTimesDown()) {
     2577            numberDown++;
     2578            averageDown += dynamicObject->downDynamicPseudoCost();
     2579          }
     2580        }
    25292581      }
    25302582      if (numberUp)
     
    25402592        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    25412593          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2542         assert(dynamicObject);
    2543         if (!dynamicObject->numberTimesUp())
    2544           dynamicObject->setUpDynamicPseudoCost(averageUp);
    2545       if (!dynamicObject->numberTimesDown())
    2546         dynamicObject->setDownDynamicPseudoCost(averageDown);
    2547       }
    2548     }
     2594        if (dynamicObject) {
     2595          if (!dynamicObject->numberTimesUp())
     2596            dynamicObject->setUpDynamicPseudoCost(averageUp);
     2597          if (!dynamicObject->numberTimesDown())
     2598            dynamicObject->setDownDynamicPseudoCost(averageDown);
     2599        }
     2600      }
     2601    }
     2602#if NODE_NEW ==4
     2603    } else {
     2604    // pseudo shadow prices
     2605    model->pseudoShadow(NULL,NULL);
     2606    }
     2607#endif
    25492608  } else if (saveSearchStrategy2<1999) {
    25502609    // pseudo shadow prices
     
    26602719        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    26612720          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2662         assert(dynamicObject);
    26632721        int preferredWay;
    26642722        double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
     
    26762734#endif
    26772735        if (infeasibility) {
     2736          int iColumn = numberColumns+i;
     2737          bool gotDown=false;
     2738          int numberThisDown = 0;
     2739          bool gotUp=false;
     2740          int numberThisUp = 0;
    26782741          // check branching method
    2679           if (branchingMethod!=dynamicObject->method()) {
    2680             if (branchingMethod==-1)
    2681               branchingMethod = dynamicObject->method();
    2682             else
    2683               branchingMethod = 100;
     2742          if (dynamicObject) {
     2743            if (branchingMethod!=dynamicObject->method()) {
     2744              if (branchingMethod==-1)
     2745                branchingMethod = dynamicObject->method();
     2746              else
     2747                branchingMethod = 100;
     2748            }
     2749            iColumn = dynamicObject->columnNumber();
     2750            //double gap = saveUpper[iColumn]-saveLower[iColumn];
     2751            // Give precedence to ones with gap of 1.0
     2752            //assert(gap>0.0);
     2753            //infeasibility /= CoinMin(gap,100.0);
     2754            if (!depth_&&false) {
     2755              // try closest to 0.5
     2756              double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
     2757              infeasibility = fabs(0.5-part);
     2758            }
     2759            if (problemType>0&&problemType<4&&false) {
     2760              // try closest to 0.5
     2761              double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
     2762              infeasibility = 0.5-fabs(0.5-part);
     2763            }
     2764            if (probingInfo) {
     2765              int iSeq = backward[iColumn];
     2766              assert (iSeq>=0);
     2767              infeasibility = 1.0 + (toZero[iSeq+1]-toZero[iSeq])+
     2768                5.0*CoinMin(toOne[iSeq]-toZero[iSeq],toZero[iSeq+1]-toOne[iSeq]);
     2769              if (toZero[iSeq+1]>toZero[iSeq]) {
     2770                numberUnsatisProbed++;
     2771              } else {
     2772                numberUnsatisNotProbed++;
     2773              }
     2774            }
     2775            gotDown=false;
     2776            numberThisDown = dynamicObject->numberTimesDown();
     2777            if (numberThisDown>=numberBeforeTrust)
     2778              gotDown=true;
     2779            gotUp=false;
     2780            numberThisUp = dynamicObject->numberTimesUp();
     2781            if (numberThisUp>=numberBeforeTrust)
     2782              gotUp=true;
     2783            if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
     2784              printf("%d down %d %g up %d %g - infeas %g\n",
     2785                     i,numberThisDown,object->downEstimate(),numberThisUp,object->upEstimate(),
     2786                     infeasibility);
     2787          } else {
     2788            // see if SOS
     2789            CbcSOS * sosObject =
     2790              dynamic_cast <CbcSOS *>(object) ;
     2791            assert (sosObject);
     2792            gotDown=false;
     2793            numberThisDown = sosObject->numberTimesDown();
     2794            if (numberThisDown>=numberBeforeTrust)
     2795              gotDown=true;
     2796            gotUp=false;
     2797            numberThisUp = sosObject->numberTimesUp();
     2798            if (numberThisUp>=numberBeforeTrust)
     2799              gotUp=true;
    26842800          }
    2685           int iColumn = dynamicObject->columnNumber();
    2686           //double gap = saveUpper[iColumn]-saveLower[iColumn];
    2687           // Give precedence to ones with gap of 1.0
    2688           //assert(gap>0.0);
    2689           //infeasibility /= CoinMin(gap,100.0);
    2690           if (!depth_&&false) {
    2691             // try closest to 0.5
    2692             double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
    2693             infeasibility = fabs(0.5-part);
    2694           }
    2695           if (problemType>0&&problemType<4&&false) {
    2696             // try closest to 0.5
    2697             double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
    2698             infeasibility = 0.5-fabs(0.5-part);
    2699           }
    2700           if (probingInfo) {
    2701             int iSeq = backward[iColumn];
    2702             assert (iSeq>=0);
    2703             infeasibility = 1.0 + (toZero[iSeq+1]-toZero[iSeq])+
    2704               5.0*CoinMin(toOne[iSeq]-toZero[iSeq],toZero[iSeq+1]-toOne[iSeq]);
    2705             if (toZero[iSeq+1]>toZero[iSeq]) {
    2706               numberUnsatisProbed++;
    2707             } else {
    2708               numberUnsatisNotProbed++;
    2709             }
    2710           }
    2711           bool gotDown=false;
    2712           int numberThisDown = dynamicObject->numberTimesDown();
    2713           if (numberThisDown>=numberBeforeTrust)
    2714             gotDown=true;
    2715           bool gotUp=false;
    2716           int numberThisUp = dynamicObject->numberTimesUp();
    2717           if (numberThisUp>=numberBeforeTrust)
    2718             gotUp=true;
    2719           if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
    2720             printf("%d down %d %g up %d %g - infeas %g\n",
    2721                    i,numberThisDown,object->downEstimate(),numberThisUp,object->upEstimate(),
    2722                    infeasibility);
    27232801          // Increase estimated degradation to solution
    27242802          estimatedDegradation += CoinMin(object->upEstimate(),object->downEstimate());
     
    27482826          } else {
    27492827            objectMark[neededPenalties]=numberToDo;
    2750             which[neededPenalties++]=dynamicObject->columnNumber();
    2751             int iColumn = dynamicObject->columnNumber();
    2752             double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
     2828            which[neededPenalties++]=iColumn;
    27532829            sort[numberToDo]=-10.0*infeasibility;
    27542830            if (!(numberThisUp+numberThisDown))
    27552831              sort[numberToDo] *= 100.0; // make even more likely
    2756             if (1.0-fabs(part-0.5)>bestNot) {
    2757               iBestNot=numberToDo;
    2758               bestNot = 1.0-fabs(part-0.5);
    2759             }
     2832            if (iColumn<numberColumns) {
     2833              double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
     2834              if (1.0-fabs(part-0.5)>bestNot) {
     2835                iBestNot=numberToDo;
     2836                bestNot = 1.0-fabs(part-0.5);
     2837              }
     2838            } else {
     2839              // SOS
     2840              if (-sort[numberToDo]>bestNot) {
     2841                iBestNot=numberToDo;
     2842                bestNot = -sort[numberToDo];
     2843              }
     2844            }
    27602845          }
    27612846          if (model->messageHandler()->logLevel()>3) {
    2762             int iColumn = dynamicObject->columnNumber();
    27632847            printf("%d (%d) down %d %g up %d %g - infeas %g - sort %g solution %g\n",
    27642848                   i,iColumn,numberThisDown,object->downEstimate(),numberThisUp,object->upEstimate(),
     
    28452929    bool doneHotStart=false;
    28462930    int searchStrategy = saveSearchStrategy>=0 ? (saveSearchStrategy%10) : -1;
     2931    if (0) {
     2932      int numberIterations = model->getIterationCount();
     2933      int numberStrongIterations = model->numberStrongIterations();
     2934      printf("node %d saveSearch %d search %d - its %d strong %d\n",
     2935             numberNodes,saveSearchStrategy,searchStrategy,
     2936             numberIterations,numberStrongIterations);
     2937    }
    28472938#ifndef CBC_WEAK_STRONG
    28482939    if (((numberNodes%20)==0&&searchStrategy!=2)||(model->specialOptions()&8)!=0)
     
    29663057      int iDo;
    29673058#ifdef RANGING
     3059      if (useRanging) {
    29683060      if ((skipAll&&numberBeforeTrust&&saveSearchStrategy<20)||saveSearchStrategy<10)
    29693061        numberPenalties=0;
     
    30543146          sort[iBestGot]=-1.0e120;
    30553147      }
    3056 #else           /* RANGING */
     3148      } else {
     3149#endif          /* RANGING */
    30573150      if (!skipAll) {
    30583151        // Mark hot start
     
    30653158      if (iBestGot>=0)
    30663159        sort[iBestGot]=-COIN_DBL_MAX;
     3160#ifdef RANGING
     3161      }
    30673162#endif          /* RANGING */
    30683163      // Actions 0 - exit for repeat, 1 resolve and try old choice,2 exit for continue
     
    30793174      if (!numberStrong)
    30803175        numberToDo=CoinMin(numberToDo,1);
     3176#if NODE_NEW
     3177      if (searchStrategy==2)
     3178        numberToDo=CoinMin(numberToDo,20);
     3179#endif
    30813180      iDo=0;
    30823181      int saveLimit2;
     
    31673266      }
    31683267      } else {
     3268        if (!depth_&&numberToDo<200&&solver->getNumRows()<2000&&
     3269            numberColumns<2000&&false) {
     3270          numberStrong = numberToDo;
     3271          doQuickly = false;
     3272        }
    31693273      int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
    31703274      int numberTest2 = 2*numberStrong;
     
    32023306      }
    32033307      }
    3204 #if 0
    32053308      // temp - always switch off
    32063309      if (0) {
    32073310        int numberIterations = model->getIterationCount();
    32083311        int numberStrongIterations = model->numberStrongIterations();
    3209         if (numberStrongIterations>numberIterations+10000&&depth_>=5) {
     3312        int numberRows = solver->getNumRows();
     3313        if (numberStrongIterations>numberIterations+CoinMin(100,10*numberRows)&&depth_>=5) {
    32103314          skipAll=true;
    32113315          newWay=false;
     
    32143318        }
    32153319      }
     3320#if 0
    32163321      // temp - always switch on
    32173322      if (0) {
     
    32503355      bool couldChooseFirst = false ; //(skipAll&&numberTest==0&&doQuickly);
    32513356      //skipAll=false;
     3357      int realMaxHotIterations=999999;
     3358#if 0
     3359      if (saveSearchStrategy==-1&&!model->parentModel()&&
     3360          !depth_&&saveLimit==100) {
     3361        realMaxHotIterations=saveLimit;
     3362        saveLimit2=200;
     3363        solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit2);
     3364      }
     3365#endif
    32523366      for ( iDo=0;iDo<numberToDo;iDo++) {
    32533367        int iObject = whichObject[iDo];
     
    32553369        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    32563370          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    3257         int iColumn = dynamicObject->columnNumber();
     3371        int iColumn = dynamicObject ? dynamicObject->columnNumber() : numberColumns+iObject;
    32583372        int preferredWay;
    32593373        double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
     
    32913405          maxChange = COIN_DBL_MAX;
    32923406        //maxChange *= 5.0;
    3293         if (dynamicObject->method()==1)
     3407        if (dynamicObject&&dynamicObject->method()==1)
    32943408          maxChange *= 0.1; // probing
    32953409        // see if can skip strong branching
     
    33323446        }
    33333447#endif
    3334         if (model->messageHandler()->logLevel()>3&&numberBeforeTrust)
     3448        if (model->messageHandler()->logLevel()>3&&numberBeforeTrust&&dynamicObject)
    33353449          dynamicObject->print(1,choice.possibleBranch->value());
    33363450        // was if (!canSkip)
     
    33523466          numberTest2--;
    33533467          // just do a few
     3468#if NODE_NEW == 5  || NODE_NEW == 2
    33543469          //if (canSkip)
    3355           //solver->setIntParam(OsiMaxNumIterationHotStart,10);
     3470          if (searchStrategy==2)
     3471            solver->setIntParam(OsiMaxNumIterationHotStart,10);
     3472#endif
    33563473          double objectiveChange ;
    33573474          double newObjectiveValue=1.0e100;
     
    33963513          else
    33973514            iStatus=1; // infeasible
     3515          if (iStatus!=2&&solver->getIterationCount()>
     3516              realMaxHotIterations)
     3517            numberUnfinished++;
    33983518          newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    33993519          choice.numItersDown = solver->getIterationCount();
     
    34063526          if (cbcobj) {
    34073527            CbcObject * object = cbcobj->object();
     3528            assert (object);
    34083529            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
    34093530            object->updateInformation(update);
     
    34153536          if (cbcobj) {
    34163537            CbcObject * object = cbcobj->object();
     3538            assert (object) ;
    34173539            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
    34183540            update.objectNumber_ = choice.objectNumber;
     
    35243646          else
    35253647            iStatus=1; // infeasible
     3648          if (iStatus!=2&&solver->getIterationCount()>
     3649              realMaxHotIterations)
     3650            numberUnfinished++;
    35263651          newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    35273652          choice.numItersUp = solver->getIterationCount();
     
    35433668          if (cbcobj) {
    35443669            CbcObject * object = cbcobj->object();
     3670            assert (object) ;
    35453671            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
    35463672            update.objectNumber_ = choice.objectNumber;
     
    37943920              choice.fix=1;
    37953921              fixObject[numberToFix++]=choice;
     3922#define FIXNOW
     3923#ifdef FIXNOW
     3924#if 0
     3925              double value = ceil(saveSolution[iColumn]);
     3926              saveLower[iColumn]=value;
     3927              solver->setColLower(iColumn,value);
     3928#else
     3929              choice.possibleBranch->fix(solver,saveLower,saveUpper,1);
     3930#endif
     3931#endif
    37963932              if (!choiceObject) {
    37973933                choice.possibleBranch=NULL;
     
    38003936                choice.possibleBranch=choiceObject;
    38013937              }
    3802 #define FIXNOW
    38033938#ifdef FIXNOW
    3804               double value = ceil(saveSolution[iColumn]);
    3805               saveLower[iColumn]=value;
    3806               solver->setColLower(iColumn,value);
    38073939              assert(doneHotStart);
    38083940              solver->unmarkHotStart();
     
    38523984              choice.fix=-1;
    38533985              fixObject[numberToFix++]=choice;
     3986#ifdef FIXNOW
     3987#if 0
     3988              double value = floor(saveSolution[iColumn]);
     3989              saveUpper[iColumn]=value;
     3990              solver->setColUpper(iColumn,value);
     3991#else
     3992              choice.possibleBranch->fix(solver,saveLower,saveUpper,-1);
     3993#endif
     3994#endif
    38543995              if (!choiceObject) {
    38553996                choice.possibleBranch=NULL;
     
    38594000              }
    38604001#ifdef FIXNOW
    3861               double value = floor(saveSolution[iColumn]);
    3862               saveUpper[iColumn]=value;
    3863               solver->setColUpper(iColumn,value);
    38644002              assert(doneHotStart);
    38654003              solver->unmarkHotStart();
     
    39074045            CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    39084046              dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    3909             dynamicObject->setNumberBeforeTrust(0);
     4047            if (dynamicObject)
     4048              dynamicObject->setNumberBeforeTrust(0);
    39104049          }
    39114050          numberTest=0;
     
    39334072          CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    39344073            dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    3935           int iColumn = dynamicObject->columnNumber();
    3936           printf("choosing %d (column %d) iChosenWhen %d numberToDo %d\n",bestChoice,
    3937                  iColumn,whichChoice,numberToDo);
     4074          if (dynamicObject) {
     4075            int iColumn = dynamicObject->columnNumber();
     4076            printf("choosing %d (column %d) iChosenWhen %d numberToDo %d\n",bestChoice,
     4077                   iColumn,whichChoice,numberToDo);
     4078          }
    39384079        }
    39394080      }
     
    40274168  if (!newWay) {
    40284169  if (((model->searchStrategy()+1)%1000)==0) {
     4170#ifndef COIN_DEVELOP
    40294171    if (solver->messageHandler()->logLevel()>1)
     4172#endif
    40304173      printf("%d strong, %d iters, %d inf, %d not finished, %d not trusted\n",
    40314174             numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
     
    40334176    // decide what to do
    40344177    int strategy=1;
    4035     if (numberUnfinished*4>numberStrongDone&&numberStrongInfeasible*10<numberStrongDone) {
     4178    if ((numberUnfinished*4>numberStrongDone&&
     4179         numberStrongInfeasible*40<numberStrongDone)||
     4180        numberStrongInfeasible<0) {
    40364181      strategy=2;
    4037       if (model->logLevel()>1)
     4182#ifdef COIN_DEVELOP
     4183      //if (model->logLevel()>1)
    40384184        printf("going to strategy 2\n");
     4185#endif
     4186#if NODE_NEW==1
     4187      // Basically off
     4188      model->setNumberStrong(0);
     4189      model->setNumberBeforeTrust(-2);
     4190#elif NODE_NEW==2
     4191      // Weaken
     4192      model->setNumberStrong(2);
     4193      model->setNumberBeforeTrust(1);
     4194#elif NODE_NEW==3
     4195      // Off and ranging
     4196      model->setNumberStrong(0);
     4197      model->setNumberBeforeTrust(-1);
     4198#elif NODE_NEW==4
     4199      // Off and pseudo shadow prices
     4200      model->setNumberStrong(0);
     4201      model->setNumberBeforeTrust(-2);
     4202#elif NODE_NEW==5
     4203      // Just fewer iterations
     4204#endif
     4205      model->synchronizeNumberBeforeTrust();
    40394206    }
    40404207    if (numberNodes)
     
    40424209    if (model->searchStrategy()<999)
    40434210      model->setSearchStrategy(strategy);
     4211  }
     4212  if (model->searchStrategy()==1&&numberNodes>500&&numberNodes<-510) {
     4213#ifndef COIN_DEVELOP
     4214    if (solver->messageHandler()->logLevel()>1)
     4215#endif
     4216      printf("after %d nodes - %d strong, %d iters, %d inf, %d not finished, %d not trusted\n",
     4217             numberNodes,numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
     4218             numberNotTrusted);
     4219    // decide what to do
     4220    if (numberUnfinished*10>numberStrongDone+1||
     4221        !numberStrongInfeasible) {
     4222      //if (model->logLevel()>1)
     4223        printf("going to strategy 2\n");
     4224#if NODE_NEW==1
     4225      // Basically off
     4226      model->setNumberStrong(0);
     4227      model->setNumberBeforeTrust(-2);
     4228#elif NODE_NEW==2
     4229      // Weaken
     4230      model->setNumberStrong(2);
     4231      model->setNumberBeforeTrust(1);
     4232#elif NODE_NEW==3
     4233      // Off and ranging
     4234      model->setNumberStrong(0);
     4235      model->setNumberBeforeTrust(-1);
     4236#elif NODE_NEW==4
     4237      // Off and pseudo shadow prices
     4238      model->setNumberStrong(0);
     4239      model->setNumberBeforeTrust(-2);
     4240#elif NODE_NEW==5
     4241      // Just fewer iterations
     4242#endif
     4243      model->synchronizeNumberBeforeTrust();
     4244      model->setSearchStrategy(2);
     4245    }
    40444246  }
    40454247  }
     
    41014303  model->setStateOfSearch(saveStateOfSearch);
    41024304  model->setLogLevel(saveLogLevel);
     4305  // delete extra regions
     4306  if (usefulInfo.usefulRegion_) {
     4307    delete [] usefulInfo.usefulRegion_;
     4308    delete [] usefulInfo.indexRegion_;
     4309    delete [] usefulInfo.pi_;
     4310    usefulInfo.usefulRegion_ = NULL;
     4311    usefulInfo.indexRegion_ = NULL;
     4312    usefulInfo.pi_ = NULL;
     4313  }
    41034314  return anyAction;
    41044315}
     
    46164827  nodeInfo_->initializeInfo(branch_->numberBranches());
    46174828  assert ((state_&2)!=0);
     4829  assert (nodeInfo_->numberBranchesLeft()==
     4830          branch_->numberBranchesLeft());
    46184831}
    46194832// Nulls out node info
     
    46304843{
    46314844  double changeInGuessed;
     4845  assert (nodeInfo_->numberBranchesLeft()==
     4846          branch_->numberBranchesLeft());
    46324847  if (!solver)
    46334848    changeInGuessed=branch_->branch();
     
    48145029  return returnStatus;
    48155030}
     5031int
     5032CbcNode::chooseClpBranch (CbcModel * model,
     5033                       CbcNode * lastNode)
     5034{
     5035  assert(lastNode);
     5036  depth_ = lastNode->depth_+1;
     5037  delete branch_;
     5038  branch_=NULL;
     5039  OsiSolverInterface * solver = model->solver();
     5040  //double saveObjectiveValue = solver->getObjValue();
     5041  //double objectiveValue = CoinMax(solver->getObjSense()*saveObjectiveValue,objectiveValue_);
     5042  const double * lower = solver->getColLower();
     5043  const double * upper = solver->getColUpper();
     5044  // point to useful information
     5045  OsiBranchingInformation usefulInfo = model->usefulInformation();
     5046  // and modify
     5047  usefulInfo.depth_=depth_;
     5048  int i;
     5049  //bool beforeSolution = model->getSolutionCount()==0;
     5050  int numberObjects = model->numberObjects();
     5051  int numberColumns = model->getNumCols();
     5052  double * saveUpper = new double[numberColumns];
     5053  double * saveLower = new double[numberColumns];
     5054
     5055  // Save solution in case heuristics need good solution later
     5056 
     5057  double * saveSolution = new double[numberColumns];
     5058  memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
     5059  model->reserveCurrentSolution(saveSolution);
     5060  for (i=0;i<numberColumns;i++) {
     5061    saveLower[i] = lower[i];
     5062    saveUpper[i] = upper[i];
     5063  }
     5064  // Save basis
     5065  CoinWarmStart * ws = solver->getWarmStart();
     5066  numberUnsatisfied_ = 0;
     5067  // initialize sum of "infeasibilities"
     5068  sumInfeasibilities_ = 0.0;
     5069  // Note looks as if off end (hidden one)
     5070  OsiObject * object = model->modifiableObject(numberObjects);
     5071  CbcGeneralDepth * thisOne = dynamic_cast <CbcGeneralDepth *> (object);
     5072  assert (thisOne);
     5073  OsiClpSolverInterface * clpSolver
     5074    = dynamic_cast<OsiClpSolverInterface *> (solver);
     5075  assert (clpSolver);
     5076  ClpSimplex * simplex = clpSolver->getModelPtr();
     5077  int preferredWay;
     5078  double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
     5079  if (thisOne->whichSolution()>=0) {
     5080    ClpNode * nodeInfo = thisOne->nodeInfo(thisOne->whichSolution());
     5081    nodeInfo->applyNode(simplex,2);
     5082    simplex->dual();
     5083    double cutoff = model->getCutoff();
     5084    bool goodSolution=true;
     5085    if (simplex->status()) {
     5086      simplex->writeMps("bad7.mps",2);
     5087      if (nodeInfo->objectiveValue()>cutoff-1.0e-2)
     5088        goodSolution=false;
     5089      else
     5090        assert (!simplex->status());
     5091    }
     5092    if (goodSolution) {
     5093      double newObjectiveValue = solver->getObjSense()*solver->getObjValue();
     5094      // See if integer solution
     5095      int numInf;
     5096      int numInf2;
     5097      bool gotSol = model->feasibleSolution(numInf,numInf2);
     5098      if (!gotSol) {
     5099        printf("numinf %d\n",numInf);
     5100        double * sol = simplex->primalColumnSolution();
     5101        for (int i=0;i<numberColumns;i++) {
     5102          if (simplex->isInteger(i)) {
     5103            double value = floor(sol[i]+0.5);
     5104            if (fabs(value-sol[i])>1.0e-7) {
     5105              printf("%d value %g\n",i,sol[i]);
     5106              if (fabs(value-sol[i])<1.0e-3) {
     5107                sol[i]=value;
     5108              }
     5109            }
     5110          }
     5111        }
     5112        simplex->writeMps("bad8.mps",2);
     5113        bool gotSol = model->feasibleSolution(numInf,numInf2);
     5114        if (!gotSol)
     5115          assert (gotSol);
     5116      }
     5117      model->setBestSolution(CBC_STRONGSOL,
     5118                             newObjectiveValue,
     5119                             solver->getColSolution()) ;
     5120      model->setLastHeuristic(NULL);
     5121      model->incrementUsed(solver->getColSolution());
     5122    }
     5123  }
     5124  // restore bounds
     5125  { for (int j=0;j<numberColumns;j++) {
     5126      if (saveLower[j] != lower[j])
     5127        solver->setColLower(j,saveLower[j]);
     5128      if (saveUpper[j] != upper[j])
     5129        solver->setColUpper(j,saveUpper[j]);
     5130    }
     5131  }
     5132  // restore basis
     5133  solver->setWarmStart(ws);
     5134  delete ws;
     5135  int anyAction;
     5136  //#define CHECK_PATH
     5137#ifdef CHECK_PATH
     5138extern int gotGoodNode_Z;
     5139 if (gotGoodNode_Z>=0)
     5140   printf("good node %d %g\n",gotGoodNode_Z,infeasibility);
     5141#endif
     5142  if (infeasibility>0.0) {
     5143    if (infeasibility==COIN_DBL_MAX) {
     5144      anyAction=-2; // infeasible
     5145    } else {
     5146      branch_=thisOne->createBranch(preferredWay);
     5147      // Set to firat one (and change when re-pushing)
     5148      CbcGeneralBranchingObject * branch =
     5149        dynamic_cast <CbcGeneralBranchingObject *> (branch_);
     5150      branch->state(objectiveValue_,sumInfeasibilities_,
     5151                    numberUnsatisfied_,0);
     5152      branch->setNode(this);
     5153      anyAction=0;
     5154    }
     5155  } else {
     5156    anyAction=-1;
     5157  }
     5158#ifdef CHECK_PATH
     5159 gotGoodNode_Z=-1;
     5160#endif
     5161  // Set guessed solution value
     5162  guessedObjectiveValue_ = objectiveValue_+1.0e-5;
     5163  delete [] saveLower;
     5164  delete [] saveUpper;
     5165 
     5166  // restore solution
     5167  solver->setColSolution(saveSolution);
     5168  delete [] saveSolution;
     5169  return anyAction;
     5170}
     5171/* Double checks in case node can change its mind!
     5172   Returns objective value
     5173   Can change objective etc */
     5174double
     5175CbcNode::checkIsCutoff(double cutoff)
     5176{
     5177  branch_->checkIsCutoff(cutoff);
     5178  return objectiveValue_;
     5179}
  • trunk/Cbc/src/CbcNode.hpp

    r915 r931  
    577577                       OsiBranchingInformation * usefulInfo,
    578578                       int branchState);
     579  /** Create a branching object for the node
     580
     581    The routine scans the object list of the model and selects a set of
     582    unsatisfied objects as candidates for branching. It then solves a
     583    series of problems and a CbcGeneral branch object is installed.
     584
     585    If evaluation determines that an object is infeasible,
     586    the routine returns immediately.
     587
     588    Return value:
     589    <ul>
     590      <li>  0: A branching object has been installed
     591      <li> -2: An infeasible object was discovered
     592    </ul>
     593  */
     594  int chooseClpBranch (CbcModel * model,
     595                       CbcNode * lastNode);
    579596  int analyze(CbcModel * model,double * results);
    580597  /// Decrement active cut counts
     
    599616  int branch(OsiSolverInterface * solver);
    600617
     618  /** Double checks in case node can change its mind!
     619      Returns objective value
     620      Can change objective etc */
     621  double checkIsCutoff(double cutoff);
    601622  // Information to make basis and bounds
    602623  inline CbcNodeInfo * nodeInfo() const
     
    627648  /// Get the number of objects unsatisfied at this node.
    628649  inline int numberUnsatisfied() const
    629   {return numberUnsatisfied_;}
    630   /// Sum of "infeasibilities" reported by each object
     650  { return numberUnsatisfied_;}
     651  /// Set the number of objects unsatisfied at this node.
     652  inline void setNumberUnsatisfied(int value)
     653  { numberUnsatisfied_ = value;}
     654  /// Get sum of "infeasibilities" reported by each object
    631655  inline double sumInfeasibilities() const
    632656  { return sumInfeasibilities_;}
     657  /// Set sum of "infeasibilities" reported by each object
     658  inline void setSumInfeasibilities(double value)
     659  { sumInfeasibilities_ = value;}
    633660  // Guessed objective value (for solution)
    634661  inline double guessedObjectiveValue() const
     
    664691  /// Print
    665692  void print() const;
     693  /// Debug
     694  inline void checkInfo() const
     695  { assert (nodeInfo_->numberBranchesLeft()==
     696            branch_->numberBranchesLeft());}
    666697
    667698private:
  • trunk/Cbc/src/CbcSolver.cpp

    r904 r931  
    1616#include "CoinHelperFunctions.hpp"
    1717// Version
    18 #define CBCVERSION "2.00.00"
     18#define CBCVERSION "2.20.00"
    1919
    2020#include "CoinMpsIO.hpp"
     
    4141#include "OsiChooseVariable.hpp"
    4242#include "OsiAuxInfo.hpp"
     43//#define ORBITAL
     44#ifdef ORBITAL
     45#include "CbcOrbital.hpp"
     46#endif
    4347//#define USER_HAS_FAKE_CLP
    4448//#define USER_HAS_FAKE_CBC
     
    479483#endif
    480484  // Set up likely cut generators and defaults
    481   parameters_[whichParam(PREPROCESS,numberParameters_,parameters_)].setCurrentOption("on");
     485  parameters_[whichParam(PREPROCESS,numberParameters_,parameters_)].setCurrentOption("sos");
    482486  parameters_[whichParam(MIPOPTIONS,numberParameters_,parameters_)].setIntValue(128|64|1);
    483487  parameters_[whichParam(MIPOPTIONS,numberParameters_,parameters_)].setIntValue(1);
     
    762766  return new CbcStopNow(*this);
    763767}
    764 //#undef NEW_STYLE_SOLVER
    765 //#define NEW_STYLE_SOLVER
     768#ifdef CLP_FAST_CODE
     769// force new style solver
     770#ifndef NEW_STYLE_SOLVER
     771#define NEW_STYLE_SOLVER 1
     772#endif
     773#else
     774// Not new style solver
     775#ifndef NEW_STYLE_SOLVER
     776#define NEW_STYLE_SOLVER 0
     777#endif
     778#endif
    766779//#undef COIN_HAS_ASL
    767780#ifdef COIN_HAS_ASL
     
    823836FILE * CbcOrClpReadCommand=stdin;
    824837static bool noPrinting=false;
    825 #ifdef NEW_STYLE_SOLVER
     838#if NEW_STYLE_SOLVER
    826839int * CbcSolver::analyze(OsiClpSolverInterface * solverMod, int & numberChanged, double & increment,
    827840                     bool changeInt,  CoinMessageHandler * generalMessageHandler)
     
    831844#endif
    832845{
    833 #ifndef NEW_STYLE_SOLVER
     846#if NEW_STYLE_SOLVER==0
    834847  bool noPrinting_ = noPrinting;
    835848#endif
     
    28482861  if (!babModel->ownObjects())
    28492862    return;
     2863#if COIN_DEVELOP>2
    28502864  //const double *objective = solver->getObjCoefficients() ;
    28512865  const double *columnLower = solver->getColLower() ;
     
    28562870  //double direction = solver->getObjSense();
    28572871  //int iRow,iColumn;
     2872#endif
    28582873
    28592874  // Row copy
     
    28812896      int n=objSOS->numberMembers();
    28822897      const int * which = objSOS->members();
     2898#if COIN_DEVELOP>2
    28832899      const double * weight = objSOS->weights();
     2900#endif
    28842901      int type = objSOS->sosType();
    28852902      // convexity row?
     
    29202937          convex=-2;
    29212938        }
     2939#if COIN_DEVELOP>2
    29222940        printf("col %d has weight %g and value %g, bounds %g %g\n",
    29232941               iColumn,weight[i],solution[iColumn],columnLower[iColumn],
    29242942               columnUpper[iColumn]);
     2943#endif
    29252944      }
    29262945    }
     
    29282947#endif
    29292948}
    2930 #ifndef NEW_STYLE_SOLVER
     2949#if NEW_STYLE_SOLVER==0
    29312950int callCbc1(const char * input2, CbcModel & model, int callBack(CbcModel * currentSolver, int whereFrom))
    29322951{
     
    31613180#endif
    31623181  // Set up likely cut generators and defaults
    3163   parameters[whichParam(PREPROCESS,numberParameters,parameters)].setCurrentOption("on");
     3182  parameters[whichParam(PREPROCESS,numberParameters,parameters)].setCurrentOption("sos");
    31643183  parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].setIntValue(128|64|1);
    31653184  parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].setIntValue(1);
     
    31943213   3 - for miplib test so skip some
    31953214*/
    3196 #ifndef NEW_STYLE_SOLVER
     3215#if NEW_STYLE_SOLVER==0
    31973216static int doHeuristics(CbcModel * model,int type)
    31983217#else
     
    32013220#endif
    32023221{
    3203 #ifndef NEW_STYLE_SOLVER
     3222#if NEW_STYLE_SOLVER==0
    32043223  CbcOrClpParam * parameters_ = parameters;
    32053224  int numberParameters_ = numberParameters;
     
    32273246      heuristic4.setArtificialCost(dextra1);
    32283247    heuristic4.setMaximumPasses(parameters_[whichParam(FPUMPITS,numberParameters_,parameters_)].intValue());
     3248    if (parameters_[whichParam(FPUMPITS,numberParameters_,parameters_)].intValue()==21)
     3249      heuristic4.setIterationRatio(1.0);
    32293250    int pumpTune=parameters_[whichParam(FPUMPTUNE,numberParameters_,parameters_)].intValue();
    32303251    if (pumpTune>0) {
     
    33593380  // change later?
    33603381  if (useDIVING>=kType) {
     3382    int diveOptions=parameters_[whichParam(DIVEOPT,numberParameters_,parameters_)].intValue();
     3383    if (diveOptions<3||diveOptions>6)
     3384      diveOptions=2;
    33613385    if ((useDIVING&1)!=0) {
    33623386      CbcHeuristicDiveVectorLength heuristicDV(*model);
    33633387      heuristicDV.setHeuristicName("DiveVectorLength");
     3388      heuristicDV.setWhen(diveOptions);
    33643389      model->addHeuristic(&heuristicDV) ;
    33653390    }
     
    33673392      CbcHeuristicDiveGuided heuristicDG(*model);
    33683393      heuristicDG.setHeuristicName("DiveGuided");
     3394      heuristicDG.setWhen(diveOptions);
    33693395      model->addHeuristic(&heuristicDG) ;
    33703396    }
     
    33723398      CbcHeuristicDiveFractional heuristicDF(*model);
    33733399      heuristicDF.setHeuristicName("DiveFractional");
     3400      heuristicDF.setWhen(diveOptions);
    33743401      model->addHeuristic(&heuristicDF) ;
    33753402    }
     
    33773404      CbcHeuristicDiveCoefficient heuristicDC(*model);
    33783405      heuristicDC.setHeuristicName("DiveCoefficient");
     3406      heuristicDC.setWhen(diveOptions);
    33793407      model->addHeuristic(&heuristicDC) ;
    33803408    }
     
    34303458
    34313459int CbcClpUnitTest (const CbcModel & saveModel,
    3432                      std::string& dirMiplib, bool unitTestOnly);
    3433 #ifdef NEW_STYLE_SOLVER
     3460                    std::string& dirMiplib, bool unitTestOnly,
     3461                    double * stuff);
     3462#if NEW_STYLE_SOLVER
    34343463/* This takes a list of commands, does "stuff" and returns
    34353464   returnMode -
     
    35033532*/
    35043533
    3505 #ifndef NEW_STYLE_SOLVER
     3534#if NEW_STYLE_SOLVER==0
    35063535int CbcMain1 (int argc, const char *argv[],
    35073536              CbcModel  & model,
     
    35183547#endif
    35193548{
    3520 #ifndef NEW_STYLE_SOLVER
     3549#if NEW_STYLE_SOLVER==0
    35213550  CbcOrClpParam * parameters_ = parameters;
    35223551  int numberParameters_ = numberParameters;
     
    35613590  if (originalSolver->getModelPtr()->logLevel()==0)
    35623591    noPrinting=true;
    3563 #ifndef NEW_STYLE_SOLVER
     3592#if NEW_STYLE_SOLVER==0
    35643593  bool noPrinting_=noPrinting;
    35653594#endif
     
    35683597    if (!strncmp(argv[i],"log",3)) {
    35693598      const char * equals = strchr(argv[i],'=');
    3570       if (equals&&atoi(equals+1)>0)
     3599      if (equals&&atoi(equals+1)!=0)
    35713600        noPrinting_=false;
    35723601      else
     
    35743603      break;
    35753604    } else if (!strncmp(argv[i],"-log",4)&&i<argc-1) {
    3576       if (atoi(argv[i+1])>0)
     3605      if (atoi(argv[i+1])!=0)
    35773606        noPrinting_=false;
    35783607      else
     
    36263655    int * knapsackRow=NULL;
    36273656    int numberKnapsack=0;
    3628 #ifdef NEW_STYLE_SOLVER
     3657#if NEW_STYLE_SOLVER
    36293658    int numberInputs=0;
    36303659    readMode_=CbcOrClpRead_mode;
     
    38593888    // set reasonable defaults
    38603889    int preSolve=5;
    3861     int preProcess=1;
     3890    int preProcess=4;
    38623891    bool useStrategy=false;
    38633892    bool preSolveFile=false;
     
    43544383                       parameters_[iParam].type()==NUMBERBEFORE)
    43554384                strongChanged=true;
     4385              else if (parameters_[iParam].type()==EXPERIMENT) {
     4386                if (value==1) {
     4387                  if (!noPrinting_) {
     4388                    generalMessageHandler->message(CLP_GENERAL,generalMessages)
     4389                      <<"switching on dense factorization if small, and maybe fast fathoming"
     4390                      <<CoinMessageEol;
     4391                    generalMessageHandler->message(CLP_GENERAL,generalMessages)
     4392                      <<"Gomory cuts using tolerance of 0.01 at root"
     4393                      <<CoinMessageEol;
     4394                    generalMessageHandler->message(CLP_GENERAL,generalMessages)
     4395                      <<"extra options - -diving C -diveopt 3 -rins on -tune 6 -probing on -passf 30!"
     4396                      <<CoinMessageEol;
     4397                  }
     4398                  // try changing tolerance at root
     4399                  gomoryGen.setAwayAtRoot(0.01);
     4400                  int iParam;
     4401                  iParam = whichParam(DIVEOPT,numberParameters_,parameters_);
     4402                  parameters_[iParam].setIntValue(3);
     4403                  iParam = whichParam(FPUMPITS,numberParameters_,parameters_);
     4404                  parameters_[iParam].setIntValue(30);
     4405                  iParam = whichParam(PROCESSTUNE,numberParameters_,parameters_);
     4406                  parameters_[iParam].setIntValue(6);
     4407                  tunePreProcess=6;
     4408                  iParam = whichParam(DIVING,numberParameters_,parameters_);
     4409                  parameters_[iParam].setCurrentOption("C");
     4410                  iParam = whichParam(RINS,numberParameters_,parameters_);
     4411                  parameters_[iParam].setCurrentOption("on");
     4412                  iParam = whichParam(PROBINGCUTS,numberParameters_,parameters_);
     4413                  parameters_[iParam].setCurrentOption("on");
     4414                  probingAction=1;
     4415                }
     4416              }
    43564417              int returnCode;
    43574418              const char * message =
     
    49164977                  babModel_->setSecondaryStatus(iStatus2);
    49174978                }
    4918 #ifdef NEW_STYLE_SOLVER
     4979#if NEW_STYLE_SOLVER
    49194980                int returnCode = callBack_->callBack(&model_,1);
    49204981#else
     
    49234984                if (returnCode) {
    49244985                  // exit if user wants
    4925 #ifdef NEW_STYLE_SOLVER
     4986#if NEW_STYLE_SOLVER
    49264987                  updateModel(model2,returnMode);
    49274988#else
     
    49425003                model2=lpSolver;
    49435004              }
    4944 #ifdef NEW_STYLE_SOLVER
     5005#if NEW_STYLE_SOLVER
    49455006              updateModel(model2,returnMode);
    49465007              for (iUser=0;iUser<numberUserFunctions_;iUser++) {
     
    51985259#endif
    51995260              }
    5200 #ifdef NEW_STYLE_SOLVER
     5261#if NEW_STYLE_SOLVER
    52015262              int returnCode = callBack_->callBack(&model_,6);
    52025263#else
     
    52055266              if (returnCode) {
    52065267                // exit if user wants
    5207 #ifdef NEW_STYLE_SOLVER
     5268#if NEW_STYLE_SOLVER
    52085269                updateModel(NULL,returnMode);
    52095270#else
     
    54885549                model_.setSecondaryStatus(iStatus2);
    54895550                si->setWarmStart(NULL);
    5490 #ifdef NEW_STYLE_SOLVER
     5551#if NEW_STYLE_SOLVER
    54915552                int returnCode = callBack_->callBack(&model_,1);
    54925553#else
     
    54955556                if (returnCode) {
    54965557                  // exit if user wants
    5497 #ifdef NEW_STYLE_SOLVER
     5558#if NEW_STYLE_SOLVER
    54985559                  updateModel(NULL,returnMode);
    54995560#else
     
    55255586                }
    55265587                if (clpSolver->dualBound()==1.0e10) {
     5588                  ClpSimplex temp=*clpSolver;
     5589                  temp.dual(0,7);
    55275590                  // user did not set - so modify
    55285591                  // get largest scaled away from bound
    55295592                  double largest=1.0e-12;
    5530                   int numberRows = clpSolver->numberRows();
    5531                   const double * rowPrimal = clpSolver->primalRowSolution();
    5532                   const double * rowLower = clpSolver->rowLower();
    5533                   const double * rowUpper = clpSolver->rowUpper();
    5534                   const double * rowScale = clpSolver->rowScale();
     5593                  double largestScaled=1.0e-12;
     5594                  int numberRows = temp.numberRows();
     5595                  const double * rowPrimal = temp.primalRowSolution();
     5596                  const double * rowLower = temp.rowLower();
     5597                  const double * rowUpper = temp.rowUpper();
     5598                  const double * rowScale = temp.rowScale();
    55355599                  int iRow;
    55365600                  for (iRow=0;iRow<numberRows;iRow++) {
     
    55385602                    double above = value-rowLower[iRow];
    55395603                    double below = rowUpper[iRow]-value;
     5604                    if (above<1.0e12) {
     5605                      largest = CoinMax(largest,above);
     5606                    }
     5607                    if (below<1.0e12) {
     5608                      largest = CoinMax(largest,below);
     5609                    }
    55405610                    if (rowScale) {
    55415611                      double multiplier = rowScale[iRow];
     
    55435613                      below *= multiplier;
    55445614                    }
    5545                     if (above<1.0e12)
    5546                       largest = CoinMax(largest,above);
    5547                     if (below<1.0e12)
    5548                       largest = CoinMax(largest,below);
     5615                    if (above<1.0e12) {
     5616                      largestScaled = CoinMax(largestScaled,above);
     5617                    }
     5618<