Changeset 838


Ignore:
Timestamp:
Dec 13, 2007 10:01:17 AM (12 years ago)
Author:
forrest
Message:

for deterministic parallel

Location:
trunk/Cbc/src
Files:
25 edited

Legend:

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

    r720 r838  
    934934  up_[0] = 0.0;
    935935  up_[1] = 0.0;
    936 }
    937 
     936#ifdef FUNNY_BRANCHING
     937  variables_ = NULL;
     938  newBounds_ = NULL;
     939  numberExtraChangedBounds_ = 0;
     940#endif
     941}
    938942// Useful constructor
    939943CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model,
     
    946950  up_[0] = ceil(value_);
    947951  up_[1] = model->getColUpper()[iColumn];
     952#ifdef FUNNY_BRANCHING
     953  variables_ = NULL;
     954  newBounds_ = NULL;
     955  numberExtraChangedBounds_ = 0;
     956#endif
    948957}
    949958// Useful constructor for fixing
     
    959968  up_[0] = lowerValue;
    960969  up_[1] = upperValue;
     970#ifdef FUNNY_BRANCHING
     971  variables_ = NULL;
     972  newBounds_ = NULL;
     973  numberExtraChangedBounds_ = 0;
     974#endif
    961975}
    962976 
     
    969983  up_[0] = rhs.up_[0];
    970984  up_[1] = rhs.up_[1];
     985#ifdef FUNNY_BRANCHING
     986  numberExtraChangedBounds_ = rhs.numberExtraChangedBounds_;
     987  int size = numberExtraChangedBounds_*(sizeof(double)+sizeof(int));
     988  char * temp = new char [size];
     989  newBounds_ = (double *) temp;
     990  variables_ = (int *) (newBounds_+numberExtraChangedBounds_);
     991
     992  int i ;
     993  for (i=0;i<numberExtraChangedBounds_;i++) {
     994    variables_[i]=rhs.variables_[i];
     995    newBounds_[i]=rhs.newBounds_[i];
     996  }
     997#endif
    971998}
    972999
     
    9811008    up_[0] = rhs.up_[0];
    9821009    up_[1] = rhs.up_[1];
     1010#ifdef FUNNY_BRANCHING
     1011    delete [] newBounds_;
     1012    numberExtraChangedBounds_ = rhs.numberExtraChangedBounds_;
     1013    int size = numberExtraChangedBounds_*(sizeof(double)+sizeof(int));
     1014    char * temp = new char [size];
     1015    newBounds_ = (double *) temp;
     1016    variables_ = (int *) (newBounds_+numberExtraChangedBounds_);
     1017   
     1018    int i ;
     1019    for (i=0;i<numberExtraChangedBounds_;i++) {
     1020      variables_[i]=rhs.variables_[i];
     1021      newBounds_[i]=rhs.newBounds_[i];
     1022    }
     1023#endif
    9831024  }
    9841025  return *this;
     
    9961037  // for debugging threads
    9971038  way_=-23456789;
     1039#ifdef FUNNY_BRANCHING
     1040  delete [] newBounds_;
     1041#endif
    9981042}
    9991043
     
    10191063  }
    10201064  decrementNumberBranchesLeft();
     1065  if (down_[1]==-COIN_DBL_MAX)
     1066    return 0.0;
    10211067  int iColumn = originalCbcObject_->columnNumber();
    10221068  assert (variable_==iColumn);
     
    10441090    model_->solver()->setColLower(iColumn,down_[0]);
    10451091    model_->solver()->setColUpper(iColumn,down_[1]);
     1092    //#define CBC_PRINT2
     1093#ifdef CBC_PRINT2
     1094    printf("%d branching down has bounds %g %g",iColumn,down_[0],down_[1]);
     1095#endif
     1096#ifdef FUNNY_BRANCHING
     1097    // branch - do extra bounds
     1098    for (int i=0;i<numberExtraChangedBounds_;i++) {
     1099      int variable = variables_[i];
     1100      if ((variable&0x40000000)!=0) {
     1101        // for going down
     1102        int k = variable&0x3fffffff;
     1103        assert (k!=iColumn);
     1104        if ((variable&0x80000000)==0) {
     1105          // lower bound changing
     1106#ifdef CBC_PRINT2
     1107          printf(" extra for %d changes lower from %g to %g",
     1108                 k,model_->solver()->getColLower()[k],newBounds_[i]);
     1109#endif
     1110          model_->solver()->setColLower(k,newBounds_[i]);
     1111        } else {
     1112          // upper bound changing
     1113#ifdef CBC_PRINT2
     1114          printf(" extra for %d changes upper from %g to %g",
     1115                 k,model_->solver()->getColUpper()[k],newBounds_[i]);
     1116#endif
     1117          model_->solver()->setColUpper(k,newBounds_[i]);
     1118        }
     1119      }
     1120    }
     1121#endif
     1122#ifdef CBC_PRINT2
     1123    printf("\n");
     1124#endif
    10461125    way_=1;
    10471126  } else {
     
    10551134    model_->solver()->setColLower(iColumn,up_[0]);
    10561135    model_->solver()->setColUpper(iColumn,up_[1]);
     1136#ifdef CBC_PRINT2
     1137    printf("%d branching up has bounds %g %g",iColumn,up_[0],up_[1]);
     1138#endif
     1139#ifdef FUNNY_BRANCHING
     1140    // branch - do extra bounds
     1141    for (int i=0;i<numberExtraChangedBounds_;i++) {
     1142      int variable = variables_[i];
     1143      if ((variable&0x40000000)==0) {
     1144        // for going up
     1145        int k = variable&0x3fffffff;
     1146        assert (k!=iColumn);
     1147        if ((variable&0x80000000)==0) {
     1148          // lower bound changing
     1149#ifdef CBC_PRINT2
     1150          printf(" extra for %d changes lower from %g to %g",
     1151                 k,model_->solver()->getColLower()[k],newBounds_[i]);
     1152#endif
     1153          model_->solver()->setColLower(k,newBounds_[i]);
     1154        } else {
     1155          // upper bound changing
     1156#ifdef CBC_PRINT2
     1157          printf(" extra for %d changes upper from %g to %g",
     1158                 k,model_->solver()->getColUpper()[k],newBounds_[i]);
     1159#endif
     1160          model_->solver()->setColUpper(k,newBounds_[i]);
     1161        }
     1162      }
     1163    }
     1164#endif
     1165#ifdef CBC_PRINT2
     1166    printf("\n");
     1167#endif
    10571168    way_=-1;      // Swap direction
    10581169  }
     
    10731184  }
    10741185#ifndef NDEBUG
    1075   if (nlb<olb+1.0e-8&&nub>oub-1.0e-8)
     1186  if (nlb<olb+1.0e-8&&nub>oub-1.0e-8&&false)
    10761187    printf("bad null change for column %d - bounds %g,%g\n",iColumn,olb,oub);
    10771188#endif
    10781189  return 0.0;
    10791190}
     1191#ifdef FUNNY_BRANCHING
     1192// Deactivate bounds for branching
     1193void
     1194CbcIntegerBranchingObject::deactivate()
     1195{
     1196  down_[1]=-COIN_DBL_MAX;
     1197}
     1198int
     1199CbcIntegerBranchingObject::applyExtraBounds(int iColumn, double lower, double upper, int way)
     1200{
     1201  // branch - do bounds
     1202
     1203  int i;
     1204  int found=0;
     1205  if (variable_==iColumn) {
     1206    printf("odd applyExtra %d\n",iColumn);
     1207    if (way<0) {
     1208      down_[0]=CoinMax(lower,down_[0]);
     1209      down_[1]=CoinMin(upper,down_[1]);
     1210      assert (down_[0]<=down_[1]);
     1211    } else {
     1212      up_[0]=CoinMax(lower,up_[0]);
     1213      up_[1]=CoinMin(upper,up_[1]);
     1214      assert (up_[0]<=up_[1]);
     1215    }
     1216    return 0;
     1217  }
     1218  int check = (way<0) ? 0x40000000 : 0;
     1219  double newLower=lower;
     1220  double newUpper=upper;
     1221  for (i=0;i<numberExtraChangedBounds_;i++) {
     1222    int variable = variables_[i];
     1223    if ((variable&0x40000000)==check) {
     1224      int k = variable&0x3fffffff;
     1225      if (k==iColumn) {
     1226        if ((variable&0x80000000)==0) {
     1227          // lower bound changing
     1228          found |= 1;
     1229          newBounds_[i] = CoinMax(lower,newBounds_[i]);
     1230          newLower = newBounds_[i];
     1231        } else {
     1232          // upper bound changing
     1233          found |= 2;
     1234          newBounds_[i] = CoinMin(upper,newBounds_[i]);
     1235          newUpper = newBounds_[i];
     1236        }
     1237      }
     1238    }
     1239  }
     1240  int nAdd=0;
     1241  if ((found&2)==0) {
     1242    // need to add new upper
     1243    nAdd++;
     1244  }
     1245  if ((found&1)==0) {
     1246    // need to add new lower
     1247    nAdd++;
     1248  }
     1249  if (nAdd) {
     1250    int size = (numberExtraChangedBounds_+nAdd)*(sizeof(double)+sizeof(int));
     1251    char * temp = new char [size];
     1252    double * newBounds = (double *) temp;
     1253    int * variables = (int *) (newBounds+numberExtraChangedBounds_+nAdd);
     1254
     1255    int i ;
     1256    for (i=0;i<numberExtraChangedBounds_;i++) {
     1257      variables[i]=variables_[i];
     1258      newBounds[i]=newBounds_[i];
     1259    }
     1260    delete [] newBounds_;
     1261    newBounds_ = newBounds;
     1262    variables_ = variables;
     1263    if ((found&2)==0) {
     1264      // need to add new upper
     1265      int variable = iColumn | 0x80000000;
     1266      variables_[numberExtraChangedBounds_]=variable;
     1267      newBounds_[numberExtraChangedBounds_++]=newUpper;
     1268    }
     1269    if ((found&1)==0) {
     1270      // need to add new lower
     1271      int variable = iColumn;
     1272      variables_[numberExtraChangedBounds_]=variable;
     1273      newBounds_[numberExtraChangedBounds_++]=newLower;
     1274    }
     1275  }
     1276 
     1277  return (newUpper>=newLower) ? 0 : 1;
     1278}
     1279#endif
    10801280// Print what would happen 
    10811281void
  • trunk/Cbc/src/CbcBranchActual.hpp

    r765 r838  
    451451  virtual void print();
    452452
     453  /// Lower and upper bounds for down branch
     454  inline const double * downBounds() const
     455  { return down_;}
     456  /// Lower and upper bounds for up branch
     457  inline const double * upBounds() const
     458  { return up_;}
     459  /// Set lower and upper bounds for down branch
     460  inline void setDownBounds(const double bounds[2])
     461  { memcpy(down_,bounds,2*sizeof(double));}
     462  /// Set lower and upper bounds for up branch
     463  inline void setUpBounds(const double bounds[2])
     464  { memcpy(up_,bounds,2*sizeof(double));}
     465#ifdef FUNNY_BRANCHING
     466  /** Which variable (top bit if upper bound changing,
     467      next bit if on down branch */
     468  inline const int * variables() const
     469  { return variables_;}
     470  // New bound
     471  inline const double * newBounds() const
     472  { return newBounds_;}
     473  /// Number of bound changes
     474  inline int numberExtraChangedBounds() const
     475  { return numberExtraChangedBounds_;}
     476  /// Just apply extra bounds to one variable - COIN_DBL_MAX ignore
     477  int applyExtraBounds(int iColumn, double lower, double upper, int way) ;
     478  /// Deactivate bounds for branching
     479  void deactivate();
     480  /// Are active bounds for branching
     481  inline bool active() const
     482  { return (down_[1]!=-COIN_DBL_MAX);}
     483#endif
     484
    453485protected:
    454486  /// Lower [0] and upper [1] bounds for the down arm (way_ = -1)
     
    456488  /// Lower [0] and upper [1] bounds for the up arm (way_ = 1)
    457489  double up_[2];
     490#ifdef FUNNY_BRANCHING
     491  /** Which variable (top bit if upper bound changing)
     492      next bit if chnaging on down branch only */
     493  int * variables_;
     494  // New bound
     495  double * newBounds_;
     496  /// Number of Extra bound changes
     497  int numberExtraChangedBounds_;
     498#endif
    458499};
    459500
  • trunk/Cbc/src/CbcBranchDynamic.cpp

    r833 r838  
    351351// Copy some information i.e. just variable stuff
    352352void
    353 CbcSimpleIntegerDynamicPseudoCost::copySome(CbcSimpleIntegerDynamicPseudoCost * otherObject)
     353CbcSimpleIntegerDynamicPseudoCost::copySome(const CbcSimpleIntegerDynamicPseudoCost * otherObject)
    354354{
    355355  downDynamicPseudoCost_=otherObject->downDynamicPseudoCost_;
     
    377377  numberTimesProbingTotal_ = otherObject->numberTimesProbingTotal_;
    378378}
    379 // Creates a branching object
     379// Updates stuff like pseudocosts before threads
     380void
     381CbcSimpleIntegerDynamicPseudoCost::updateBefore(const OsiObject * rhs)
     382{
     383  const CbcSimpleIntegerDynamicPseudoCost * rhsObject =
     384    dynamic_cast <const CbcSimpleIntegerDynamicPseudoCost *>(rhs) ;
     385  assert (rhsObject);
     386  copySome(rhsObject);
     387}
     388  // was 1 - but that looks flakey
     389#define INFEAS 1
     390// Updates stuff like pseudocosts after threads finished
     391void
     392CbcSimpleIntegerDynamicPseudoCost::updateAfter(const OsiObject * rhs, const OsiObject * baseObjectX)
     393{
     394  const CbcSimpleIntegerDynamicPseudoCost * rhsObject =
     395    dynamic_cast <const CbcSimpleIntegerDynamicPseudoCost *>(rhs) ;
     396  assert (rhsObject);
     397  const CbcSimpleIntegerDynamicPseudoCost * baseObject =
     398    dynamic_cast <const CbcSimpleIntegerDynamicPseudoCost *>(baseObjectX) ;
     399  assert (baseObject);
     400  // compute current
     401  double sumDown = downDynamicPseudoCost_*(numberTimesDown_+numberTimesDownInfeasible_);
     402  sumDown -= baseObject->downDynamicPseudoCost_*(baseObject->numberTimesDown_+baseObject->numberTimesDownInfeasible_);
     403  sumDown = CoinMax(sumDown,0.0);
     404  sumDown += rhsObject->downDynamicPseudoCost_*(rhsObject->numberTimesDown_+rhsObject->numberTimesDownInfeasible_);
     405  double sumUp = upDynamicPseudoCost_*(numberTimesUp_+numberTimesUpInfeasible_);
     406  sumUp -= baseObject->upDynamicPseudoCost_*(baseObject->numberTimesUp_+baseObject->numberTimesUpInfeasible_);
     407  sumUp += rhsObject->upDynamicPseudoCost_*(rhsObject->numberTimesUp_+rhsObject->numberTimesUpInfeasible_);
     408  sumUp = CoinMax(sumUp,0.0);
     409  sumDownCost_ += rhsObject->sumDownCost_-baseObject->sumDownCost_;
     410  sumUpCost_ += rhsObject->sumUpCost_-baseObject->sumUpCost_;
     411  sumDownChange_ += rhsObject->sumDownChange_-baseObject->sumDownChange_;
     412  sumUpChange_ += rhsObject->sumUpChange_-baseObject->sumUpChange_;
     413  sumDownCostSquared_ += rhsObject->sumDownCostSquared_-baseObject->sumDownCostSquared_;
     414  sumUpCostSquared_ += rhsObject->sumUpCostSquared_-baseObject->sumUpCostSquared_;
     415  sumDownDecrease_ += rhsObject->sumDownDecrease_-baseObject->sumDownDecrease_;
     416  sumUpDecrease_ += rhsObject->sumUpDecrease_-baseObject->sumUpDecrease_;
     417  lastDownCost_ += rhsObject->lastDownCost_-baseObject->lastDownCost_;
     418  lastUpCost_ += rhsObject->lastUpCost_-baseObject->lastUpCost_;
     419  lastDownDecrease_ += rhsObject->lastDownDecrease_-baseObject->lastDownDecrease_;
     420  lastUpDecrease_ += rhsObject->lastUpDecrease_-baseObject->lastUpDecrease_;
     421  numberTimesDown_ += rhsObject->numberTimesDown_-baseObject->numberTimesDown_;
     422  numberTimesUp_ += rhsObject->numberTimesUp_-baseObject->numberTimesUp_;
     423  numberTimesDownInfeasible_ += rhsObject->numberTimesDownInfeasible_-baseObject->numberTimesDownInfeasible_;
     424  numberTimesUpInfeasible_ += rhsObject->numberTimesUpInfeasible_-baseObject->numberTimesUpInfeasible_;
     425  numberTimesDownLocalFixed_ += rhsObject->numberTimesDownLocalFixed_-baseObject->numberTimesDownLocalFixed_;
     426  numberTimesUpLocalFixed_ += rhsObject->numberTimesUpLocalFixed_-baseObject->numberTimesUpLocalFixed_;
     427  numberTimesDownTotalFixed_ += rhsObject->numberTimesDownTotalFixed_-baseObject->numberTimesDownTotalFixed_;
     428  numberTimesUpTotalFixed_ += rhsObject->numberTimesUpTotalFixed_-baseObject->numberTimesUpTotalFixed_;
     429  numberTimesProbingTotal_ += rhsObject->numberTimesProbingTotal_-baseObject->numberTimesProbingTotal_;
     430  if (numberTimesDown_+numberTimesDownInfeasible_>0) {
     431    setDownDynamicPseudoCost(sumDown/(double) (numberTimesDown_+numberTimesDownInfeasible_));
     432  }
     433  if (numberTimesUp_+numberTimesUpInfeasible_>0) {
     434    setUpDynamicPseudoCost(sumUp/(double) (numberTimesUp_+numberTimesUpInfeasible_));
     435  }
     436  //printf("XX %d down %d %d %g up %d %d %g\n",columnNumber_,numberTimesDown_,numberTimesDownInfeasible_,downDynamicPseudoCost_,
     437  // numberTimesUp_,numberTimesUpInfeasible_,upDynamicPseudoCost_);
     438}
     439// Same - returns true if contents match(ish)
     440bool
     441CbcSimpleIntegerDynamicPseudoCost::same(const CbcSimpleIntegerDynamicPseudoCost * otherObject) const
     442{
     443  bool okay = true;
     444  if (downDynamicPseudoCost_!=otherObject->downDynamicPseudoCost_)
     445    okay=false;
     446  if (upDynamicPseudoCost_!=otherObject->upDynamicPseudoCost_)
     447    okay=false;
     448  if (sumDownCost_!= otherObject->sumDownCost_)
     449    okay=false;
     450  if (sumUpCost_!= otherObject->sumUpCost_)
     451    okay=false;
     452  if (sumDownChange_!= otherObject->sumDownChange_)
     453    okay=false;
     454  if (sumUpChange_!= otherObject->sumUpChange_)
     455    okay=false;
     456  if (sumDownCostSquared_!= otherObject->sumDownCostSquared_)
     457    okay=false;
     458  if (sumUpCostSquared_!= otherObject->sumUpCostSquared_)
     459    okay=false;
     460  if (sumDownDecrease_!= otherObject->sumDownDecrease_)
     461    okay=false;
     462  if (sumUpDecrease_!= otherObject->sumUpDecrease_)
     463    okay=false;
     464  if (lastDownCost_!= otherObject->lastDownCost_)
     465    okay=false;
     466  if (lastUpCost_!= otherObject->lastUpCost_)
     467    okay=false;
     468  if (lastDownDecrease_!= otherObject->lastDownDecrease_)
     469    okay=false;
     470  if (lastUpDecrease_!= otherObject->lastUpDecrease_)
     471    okay=false;
     472  if (numberTimesDown_!= otherObject->numberTimesDown_)
     473    okay=false;
     474  if (numberTimesUp_!= otherObject->numberTimesUp_)
     475    okay=false;
     476  if (numberTimesDownInfeasible_!= otherObject->numberTimesDownInfeasible_)
     477    okay=false;
     478  if (numberTimesUpInfeasible_!= otherObject->numberTimesUpInfeasible_)
     479    okay=false;
     480  if (numberTimesDownLocalFixed_!= otherObject->numberTimesDownLocalFixed_)
     481    okay=false;
     482  if (numberTimesUpLocalFixed_!= otherObject->numberTimesUpLocalFixed_)
     483    okay=false;
     484  if (numberTimesDownTotalFixed_!= otherObject->numberTimesDownTotalFixed_)
     485    okay=false;
     486  if (numberTimesUpTotalFixed_!= otherObject->numberTimesUpTotalFixed_)
     487    okay=false;
     488  if (numberTimesProbingTotal_!= otherObject->numberTimesProbingTotal_)
     489    okay=false;
     490  return okay;
     491}
     492// Creates a branching objecty
    380493CbcBranchingObject *
    381494CbcSimpleIntegerDynamicPseudoCost::createBranch(int way)
     
    443556  return branch;
    444557}
    445  
     558//#define FUNNY_BRANCHING 
    446559// Infeasibility - large is 0.5
    447560double
     
    451564  const double * lower = model_->getCbcColLower();
    452565  const double * upper = model_->getCbcColUpper();
     566#ifdef FUNNY_BRANCHING
     567  const double * dj = model_->getCbcReducedCost();
     568  double djValue = dj[columnNumber_];
     569  lastDownDecrease_++;
     570  if (djValue>1.0e-6) {
     571    // wants to go down
     572    if (true||lower[columnNumber_]>originalLower_) {
     573      // Lower bound active
     574      lastUpDecrease_++;
     575      sumDownCostSquared_ += djValue;
     576    }
     577  } else if (djValue<-1.0e-6) {
     578    // wants to go up
     579    if (true||upper[columnNumber_]<originalUpper_) {
     580      // Upper bound active
     581      lastUpDecrease_++;
     582      sumUpCostSquared_ -= djValue;
     583    }
     584  }
     585#endif
    453586  if (upper[columnNumber_]==lower[columnNumber_]) {
    454587    // fixed
     
    471604    below = above -1;
    472605  }
    473   // was 1 - but that looks flakey
    474 #define INFEAS 1
    475606#if INFEAS==1
    476607  double distanceToCutoff=0.0;
     
    544675    preferredWay = (value-below>=upDownSeparator_) ? 1 : -1;
    545676  }
     677#ifdef FUNNY_BRANCHING
     678  if (fabs(value-nearest)>integerTolerance) {
     679    double ratio = (100.0+lastUpDecrease_)/(100.0+lastDownDecrease_);
     680    downCost *= ratio;
     681    upCost *= ratio;
     682    if ((lastUpDecrease_%100)==-1)
     683      printf("col %d total %d djtimes %d down %g up %g\n",
     684             columnNumber_,lastDownDecrease_,lastUpDecrease_,
     685             sumDownCostSquared_,sumUpCostSquared_);
     686  }
     687#endif
    546688  if (preferredWay_)
    547689    preferredWay=preferredWay_;
     
    598740      returnValue *= 1.0e3;
    599741      if (!numberTimesUp_&&!numberTimesDown_)
    600         returnValue=1.0e50;
     742        returnValue *= 1.0e10;
    601743    }
    602744    //if (fabs(value-0.5)<1.0e-5) {
     
    10291171#endif
    10301172  }
     1173  if (data.way_<0)
     1174    assert (numberTimesDown_+numberTimesDownInfeasible_>0);
     1175  else
     1176    assert (numberTimesUp_+numberTimesUpInfeasible_>0);
     1177  assert (downDynamicPseudoCost_>=0.0&&downDynamicPseudoCost_<1.0e100);
     1178  downDynamicPseudoCost_ = CoinMax(1.0e-10,downDynamicPseudoCost_);
     1179  assert (upDynamicPseudoCost_>=0.0&&upDynamicPseudoCost_<1.0e100);
     1180  upDynamicPseudoCost_ = CoinMax(1.0e-10,upDynamicPseudoCost_);
    10311181#ifdef COIN_DEVELOP
    10321182  hist.sequence_=columnNumber_;
     
    12211371    info.numIntInfeasUp  -= (int) (object_->sumUpDecrease()/
    12221372                                   (1.0e-12+(double) object_->numberTimesUp()));
     1373    info.numIntInfeasUp = CoinMax(info.numIntInfeasUp,0);
    12231374    info.numObjInfeasUp = 0;
    12241375    info.finishedUp = false;
     
    12261377    info.numIntInfeasDown  -= (int) (object_->sumDownDecrease()/
    12271378                                   (1.0e-12+(double) object_->numberTimesDown()));
     1379    info.numIntInfeasDown = CoinMax(info.numIntInfeasDown,0);
    12281380    info.numObjInfeasDown = 0;
    12291381    info.finishedDown = false;
     
    14861638  }
    14871639  if (stateOfSearch<=2) {
    1488 #define TRY_STUFF 1
     1640    //#define TRY_STUFF 1
    14891641#ifdef TRY_STUFF
    14901642    // before solution - choose smallest number
     
    15261678    }
    15271679#else
    1528     // got a solution
     1680    // use pseudo shadow prices modified by locks
     1681    // test testosi
     1682#if 1
     1683    double objectiveValue = model->getCurrentMinimizationObjValue();
     1684    double distanceToCutoff =  model->getCutoff()  - objectiveValue;
     1685    if (distanceToCutoff<1.0e20)
     1686      distanceToCutoff *= 10.0;
     1687    else
     1688      distanceToCutoff = 1.0e2 + fabs(objectiveValue);
     1689    double continuousObjective = model->getContinuousObjective();
     1690    double distanceToCutoffC =  model->getCutoff()  - continuousObjective;
     1691    if (distanceToCutoffC>1.0e20)
     1692      distanceToCutoffC = 1.0e2 + fabs(objectiveValue);
     1693    int numberInfC = model->getContinuousInfeasibilities();
     1694    double perInf = distanceToCutoffC/((double) numberInfC);
     1695    assert (perInf>0.0);
     1696    //int numberIntegers = model->numberIntegers();
     1697    changeDown += perInf * numInfDown;
     1698    changeUp += perInf * numInfUp;
     1699#endif
    15291700    double minValue = CoinMin(changeDown,changeUp);
    15301701    double maxValue = CoinMax(changeDown,changeUp);
     
    15391710#endif
    15401711  } else {
     1712    //#define TRY_STUFF 2
    15411713#if TRY_STUFF > 1
    15421714    // Get current number of infeasibilities, cutoff and current objective
     
    15531725    //maxValue = CoinMin(maxValue,minValue*4.0);
    15541726#else
    1555     maxValue = CoinMin(maxValue,minValue*2.0);
     1727    //maxValue = CoinMin(maxValue,minValue*2.0);
    15561728#endif
    15571729    value = WEIGHT_AFTER*minValue + (1.0-WEIGHT_AFTER)*maxValue;
  • trunk/Cbc/src/CbcBranchDynamic.hpp

    r765 r838  
    7777  virtual void updateInformation(const CbcObjectUpdateData & data) ;
    7878  /// Copy some information i.e. just variable stuff
    79   void copySome(CbcSimpleIntegerDynamicPseudoCost * otherObject);
     79  void copySome(const CbcSimpleIntegerDynamicPseudoCost * otherObject);
     80  /// Updates stuff like pseudocosts before threads
     81  virtual void updateBefore(const OsiObject * rhs) ;
     82  /// Updates stuff like pseudocosts after threads finished
     83  virtual void updateAfter(const OsiObject * rhs, const OsiObject * baseObject) ;
    8084
    8185  using CbcSimpleInteger::solverBranch ;
     
    155159  /// Add to sum down decrease number infeasibilities from strong or actual
    156160  inline void addToSumDownDecrease(double value)
    157   { sumDownDecrease_+=value;lastDownDecrease_ = (int) value;}
     161  { sumDownDecrease_+=value;/*lastDownDecrease_ = (int) value;*/}
    158162
    159163  /// Sum up decrease number infeasibilities from strong or actual
     
    165169  /// Add to sum up decrease number infeasibilities from strong or actual
    166170  inline void addToSumUpDecrease(double value)
    167   { sumUpDecrease_+=value;lastUpDecrease_ = (int) value;}
     171  { sumUpDecrease_+=value;/*lastUpDecrease_ = (int) value;*/}
    168172
    169173  /// Down number times
     
    235239  /// Print - 0 -summary, 1 just before strong
    236240  void print(int type=0, double value=0.0) const;
     241  /// Same - returns true if contents match(ish)
     242  bool same(const CbcSimpleIntegerDynamicPseudoCost * obj) const;
    237243protected:
    238244  /// data
     
    256262  double sumUpChange_;
    257263  /// Sum down cost from strong or actual squared
    258   double sumDownCostSquared_;
     264  mutable double sumDownCostSquared_;
    259265  /// Sum up cost from strong or actual squared
    260   double sumUpCostSquared_;
     266  mutable double sumUpCostSquared_;
    261267  /// Sum down decrease number infeasibilities from strong or actual
    262268  double sumDownDecrease_;
     
    268274  double lastUpCost_;
    269275  /// Last down decrease number infeasibilities from strong (i.e. as computed by last strong)
    270   int lastDownDecrease_;
     276  mutable int lastDownDecrease_;
    271277  /// Last up decrease number infeasibilities from strong (i.e. as computed by last strong)
    272   int lastUpDecrease_;
     278  mutable int lastUpDecrease_;
    273279  /// Number of times we have gone down
    274280  int numberTimesDown_;
  • trunk/Cbc/src/CbcCompareBase.hpp

    r814 r838  
    8989      return (nodeNumberX>nodeNumberY);
    9090    } else {
    91       // doesn't work if threaded
    92       assert (x!=y);
    93       return (x>y);
     91      assert (x->nodeNumber()!=y->nodeNumber());
     92      return (x->nodeNumber()>y->nodeNumber());
    9493    }
    9594  }
  • trunk/Cbc/src/CbcCountRowCut.cpp

    r687 r838  
    1010#include "CbcCountRowCut.hpp"
    1111#include "CbcNode.hpp"
     12//#define CHECK_CUT_COUNTS
    1213// Default Constructor
    1314CbcCountRowCut::CbcCountRowCut ()
     
    1920  whichCutGenerator_(-1)
    2021{
     22#ifdef CBC_DETERMINISTIC_THREAD
     23  numberPointingToThis_=10;
     24#endif
    2125#ifdef CHECK_CUT_COUNTS
    2226  printf("CbcCountRowCut default constructor %x\n",this);
     
    3236    whichCutGenerator_(-1)
    3337{
     38#ifdef CBC_DETERMINISTIC_THREAD
     39  numberPointingToThis_=10;
     40#endif
    3441#ifdef CHECK_CUT_COUNTS
    3542  printf("CbcCountRowCut constructor %x from RowCut\n",this);
     
    4653    whichCutGenerator_(whichGenerator)
    4754{
     55#ifdef CBC_DETERMINISTIC_THREAD
     56  numberPointingToThis_=10;
     57#endif
    4858#ifdef CHECK_CUT_COUNTS
    4959  printf("CbcCountRowCut constructor %x from RowCut and info\n",this);
     
    6575{
    6676  assert(ownerCut_!=-1234567);
     77#ifndef CBC_DETERMINISTIC_THREAD
    6778  numberPointingToThis_+=change;
     79#endif
    6880}
    6981
     
    7385{
    7486  assert(ownerCut_!=-1234567);
     87#ifndef CBC_DETERMINISTIC_THREAD
    7588  //assert(numberPointingToThis_>=change);
    7689  assert(numberPointingToThis_>=0);
     
    8194  }
    8295  numberPointingToThis_-=change;
     96#else
     97  assert (numberPointingToThis_==10);
     98#endif
    8399  return numberPointingToThis_;
    84100}
  • trunk/Cbc/src/CbcCountRowCut.hpp

    r706 r838  
    106106
    107107};
     108//#define CBC_DETERMINISTIC_THREAD
    108109
    109110#endif
  • trunk/Cbc/src/CbcCutGenerator.cpp

    r822 r838  
    55#  pragma warning(disable:4786)
    66#endif
     7#include "CbcConfig.h"
    78#include <cassert>
    89#include <cmath>
    910#include <cfloat>
    1011
     12#ifdef COIN_HAS_CLP
     13#include "OsiClpSolverInterface.hpp"
     14#else
    1115#include "OsiSolverInterface.hpp"
     16#endif
    1217#include "CbcModel.hpp"
    1318#include "CbcMessage.hpp"
     
    180185  int pass=model_->getCurrentPassNumber()-1;
    181186  bool doThis=(model_->getNodeCount()%howOften)==0;
     187  CoinThreadRandom * randomNumberGenerator=NULL;
     188#ifdef COIN_HAS_CLP
     189  {
     190    OsiClpSolverInterface * clpSolver
     191      = dynamic_cast<OsiClpSolverInterface *> (solver);
     192    if (clpSolver)
     193      randomNumberGenerator = clpSolver->getModelPtr()->randomNumberGenerator();
     194  }
     195#endif
    182196  if (depthCutGenerator_>0) {
    183197    doThis = (depth % depthCutGenerator_) ==0;
     
    205219    info.formulation_rows = model_->numberRowsAtContinuous();
    206220    info.inTree = node!=NULL;
     221    info.randomNumberGenerator=randomNumberGenerator;
    207222    incrementNumberTimesEntered();
    208223    CglProbing* generator =
     
    222237        info2->formulation_rows = model_->numberRowsAtContinuous();
    223238        info2->inTree = node!=NULL;
     239        info2->randomNumberGenerator=randomNumberGenerator;
    224240        generator->generateCutsAndModify(*solver,cs,info2);
    225241      } else {
  • trunk/Cbc/src/CbcCutGenerator.hpp

    r706 r838  
    6464    If node then can find out depth
    6565  */
    66   bool generateCuts( OsiCuts &cs, bool fullScan,OsiSolverInterface * solver,CbcNode * node);
     66  bool generateCuts( OsiCuts &cs, bool fullScan,OsiSolverInterface * solver,
     67                     CbcNode * node);
    6768  //@}
    6869
  • trunk/Cbc/src/CbcHeuristic.cpp

    r833 r838  
    5656  feasibilityPumpOptions_(rhs.feasibilityPumpOptions_),
    5757  fractionSmall_(rhs.fractionSmall_),
     58  randomNumberGenerator_(rhs.randomNumberGenerator_),
    5859  heuristicName_(rhs.heuristicName_)
    5960{
     
    6970    feasibilityPumpOptions_ = rhs.feasibilityPumpOptions_;
    7071    fractionSmall_ = rhs.fractionSmall_;
     72    randomNumberGenerator_ = rhs.randomNumberGenerator_;
    7173    heuristicName_ = rhs.heuristicName_ ;
    7274  }
     
    7981{
    8082  model_=model;
     83}
     84// Set seed
     85void
     86CbcHeuristic::setSeed(int value)
     87{
     88  randomNumberGenerator_.setSeed(value);
    8189}
    8290
     
    143151  getHistoryStatistics_=false;
    144152#endif
     153  int status=0;
    145154  int logLevel = model_->logLevel();
    146155  char generalPrint[100];
     
    194203                bool setValue=true;
    195204                if (maxUsed==1) {
    196                   double randomNumber = CoinDrand48();
     205                  double randomNumber = randomNumberGenerator_.randomDouble();
    197206                  if (randomNumber>0.3)
    198207                    setValue=false;
     
    412421        if (model.status()==5)
    413422          returnCode=-2; // stop
     423        if (model.isProvenInfeasible())
     424          status=1;
     425        else if (model.isProvenOptimal())
     426          status=2;
    414427      }
    415428    }
     
    427440#ifdef COIN_DEVELOP
    428441  getHistoryStatistics_=true;
     442  if (returnCode==1||returnCode==2) {
     443    if (status==1)
     444      printf("heuristic could add cut because infeasible (%s)\n",heuristicName_.c_str());
     445    else if (status==2)
     446      printf("heuristic could add cut because optimal (%s)\n",heuristicName_.c_str());
     447  }
    429448#endif
    430449  return returnCode;
     
    437456  // matrix and row copy will automatically be empty
    438457  seed_=1;
     458  down_ = NULL;
     459  up_ = NULL;
     460  equal_ = NULL;
    439461}
    440462
     
    447469  matrix_ = *model.solver()->getMatrixByCol();
    448470  matrixByRow_ = *model.solver()->getMatrixByRow();
     471  validate();
    449472  seed_=1;
    450473}
     
    453476CbcRounding::~CbcRounding ()
    454477{
     478  delete [] down_;
     479  delete [] up_;
     480  delete [] equal_;
    455481}
    456482
     
    475501  fprintf(fp,"3  cbcModel->addHeuristic(&rounding);\n");
    476502}
    477 
     503//#define NEW_ROUNDING
    478504// Copy constructor
    479505CbcRounding::CbcRounding(const CbcRounding & rhs)
     
    484510  seed_(rhs.seed_)
    485511{
     512#ifdef NEW_ROUNDING
     513  int numberColumns = matrix_.getNumCols();
     514  down_ = CoinCopyOfArray(rhs.down_,numberColumns);
     515  up_ = CoinCopyOfArray(rhs.up_,numberColumns);
     516  equal_ = CoinCopyOfArray(rhs.equal_,numberColumns);
     517#else
     518  down_ = NULL;
     519  up_ = NULL;
     520  equal_ = NULL;
     521#endif 
    486522}
    487523
     
    494530    matrix_ = rhs.matrix_;
    495531    matrixByRow_ = rhs.matrixByRow_;
     532#ifdef NEW_ROUNDING
     533    delete [] down_;
     534    delete [] up_;
     535    delete [] equal_;
     536    int numberColumns = matrix_.getNumCols();
     537    down_ = CoinCopyOfArray(rhs.down_,numberColumns);
     538    up_ = CoinCopyOfArray(rhs.up_,numberColumns);
     539    equal_ = CoinCopyOfArray(rhs.equal_,numberColumns);
     540#else
     541    down_ = NULL;
     542    up_ = NULL;
     543    equal_ = NULL;
     544#endif 
    496545    seed_ = rhs.seed_;
    497546  }
     
    508557  matrix_ = *model_->solver()->getMatrixByCol();
    509558  matrixByRow_ = *model_->solver()->getMatrixByRow();
     559  validate();
    510560}
    511561// See if rounding will give solution
     
    517567int
    518568CbcRounding::solution(double & solutionValue,
    519                          double * betterSolution)
     569                      double * betterSolution)
     570{
     571
     572  // See if to do
     573  if (!when()||(when()%10==1&&model_->phase()!=1)||
     574      (when()%10==2&&(model_->phase()!=2&&model_->phase()!=3)))
     575    return 0; // switched off
     576  OsiSolverInterface * solver = model_->solver();
     577  double direction = solver->getObjSense();
     578  double newSolutionValue = direction*solver->getObjValue();
     579  return solution(solutionValue,betterSolution,newSolutionValue);
     580}
     581// See if rounding will give solution
     582// Sets value of solution
     583// Assumes rhs for original matrix still okay
     584// At present only works with integers
     585// Fix values if asked for
     586// Returns 1 if solution, 0 if not
     587int
     588CbcRounding::solution(double & solutionValue,
     589                      double * betterSolution,
     590                      double newSolutionValue)
    520591{
    521592
     
    541612  int i;
    542613  double direction = solver->getObjSense();
    543   double newSolutionValue = direction*solver->getObjValue();
     614  //double newSolutionValue = direction*solver->getObjValue();
    544615  int returnCode = 0;
    545616  // Column copy
     
    605676      } else {
    606677        // won't be able to move unless we can grab another variable
    607         double randomNumber = CoinDrand48();
     678        double randomNumber = randomNumberGenerator_.randomDouble();
    608679        // which way?
    609680        if (randomNumber<0.5)
     
    10551126    //CoinSeedRandom(seed_);
    10561127    // Random number between 0 and 1.
    1057     double randomNumber = CoinDrand48();
     1128    double randomNumber = randomNumberGenerator_.randomDouble();
    10581129    int iPass;
    10591130    int start[2];
     
    11581229    }
    11591230  }
     1231#ifdef NEW_ROUNDING
     1232  if (!returnCode) {
     1233#if 0
     1234    // back to starting point
     1235    memcpy(newSolution,solution,numberColumns*sizeof(double));
     1236    memset(rowActivity,0,numberRows*sizeof(double));
     1237    for (i=0;i<numberColumns;i++) {
     1238      int j;
     1239      double value = newSolution[i];
     1240      if (value<lower[i]) {
     1241        value=lower[i];
     1242        newSolution[i]=value;
     1243      } else if (value>upper[i]) {
     1244        value=upper[i];
     1245        newSolution[i]=value;
     1246      }
     1247      if (value) {
     1248        for (j=columnStart[i];
     1249             j<columnStart[i]+columnLength[i];j++) {
     1250          int iRow=row[j];
     1251          rowActivity[iRow] += value*element[j];
     1252        }
     1253      }
     1254    }
     1255    // check was feasible - if not adjust (cleaning may move)
     1256    for (i=0;i<numberRows;i++) {
     1257      if(rowActivity[i]<rowLower[i]) {
     1258        //assert (rowActivity[i]>rowLower[i]-1000.0*primalTolerance);
     1259        rowActivity[i]=rowLower[i];
     1260      } else if(rowActivity[i]>rowUpper[i]) {
     1261        //assert (rowActivity[i]<rowUpper[i]+1000.0*primalTolerance);
     1262        rowActivity[i]=rowUpper[i];
     1263      }
     1264    }
     1265#endif
     1266    int * candidate = new int [numberColumns];
     1267    int nCandidate=0;
     1268    for (iColumn=0;iColumn<numberColumns;iColumn++) {
     1269      bool isInteger = (integerType[iColumn]!=0);
     1270      if (isInteger) {
     1271        double currentValue = newSolution[iColumn];
     1272        if (fabs(currentValue-floor(currentValue+0.5))>1.0e-8)
     1273          candidate[nCandidate++]=iColumn;
     1274      }
     1275    }
     1276    if (true) {
     1277      // Rounding as in Berthold
     1278      while (nCandidate) {
     1279        double infeasibility =1.0e-7;
     1280        int iRow=-1;
     1281        for (i=0;i<numberRows;i++) {
     1282          double value=0.0;
     1283          if(rowActivity[i]<rowLower[i]) {
     1284            value = rowLower[i]-rowActivity[i];
     1285          } else if(rowActivity[i]>rowUpper[i]) {
     1286            value = rowActivity[i]-rowUpper[i];
     1287          }
     1288          if (value>infeasibility) {
     1289            infeasibility = value;
     1290            iRow=i;
     1291          }
     1292        }
     1293        if (iRow>=0) {
     1294          // infeasible
     1295        } else {
     1296          // feasible
     1297        }
     1298      }
     1299    } else {
     1300      // Shifting as in Berthold
     1301    }
     1302    delete [] candidate;
     1303  }
     1304#endif
    11601305  delete [] newSolution;
    11611306  delete [] rowActivity;
     
    11821327      setWhen(0);
    11831328  }
     1329#ifdef NEW_ROUNDING
     1330  int numberColumns = matrix_.getNumCols();
     1331  down_ = new unsigned short [numberColumns];
     1332  up_ = new unsigned short [numberColumns];
     1333  equal_ = new unsigned short [numberColumns];
     1334  // Column copy
     1335  const double * element = matrix_.getElements();
     1336  const int * row = matrix_.getIndices();
     1337  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
     1338  const int * columnLength = matrix_.getVectorLengths();
     1339  const double * rowLower = model.solver()->getRowLower();
     1340  const double * rowUpper = model.solver()->getRowUpper();
     1341  for (int i=0;i<numberColumns;i++) {
     1342    int down=0;
     1343    int up=0;
     1344    int equal=0;
     1345    if (columnLength[i]>65535) {
     1346      equal[0]=65535;
     1347      break; // unlikely to work
     1348    }
     1349    for (CoinBigIndex j=columnStart[i];
     1350         j<columnStart[i]+columnLength[i];j++) {
     1351      int iRow=row[j];
     1352      if (rowLower[iRow]>-1.0e20&&rowUpper[iRow]<1.0e20) {
     1353        equal++;
     1354      } else if (element[j]>0.0) {
     1355        if (rowUpper[iRow]<1.0e20)
     1356          up++;
     1357        else
     1358          down--;
     1359      } else {
     1360        if (rowLower[iRow]>-1.0e20)
     1361          up++;
     1362        else
     1363          down--;
     1364      }
     1365    }
     1366    down_[i] = (unsigned short) down;
     1367    up_[i] = (unsigned short) up;
     1368    equal_[i] = (unsigned short) equal;
     1369  }
     1370#else
     1371  down_ = NULL;
     1372  up_ = NULL;
     1373  equal_ = NULL;
     1374#endif 
    11841375}
    11851376
  • trunk/Cbc/src/CbcHeuristic.hpp

    r833 r838  
    120120  inline void setHeuristicName(const char *name)
    121121  { heuristicName_ = name;}
     122  /// Set random number generator seed
     123  void setSeed(int value);
    122124
    123125protected:
     
    133135  /// Fraction of new(rows+columns)/old(rows+columns) before doing small branch and bound
    134136  double fractionSmall_;
     137  /// Thread specific random number generator
     138  CoinThreadRandom randomNumberGenerator_;
    135139  /// Name for printing
    136140  std::string heuristicName_;
     
    177181  virtual int solution(double & objectiveValue,
    178182                       double * newSolution);
     183  /** returns 0 if no solution, 1 if valid solution
     184      with better objective value than one passed in
     185      Sets solution values if good, sets objective value (only if good)
     186      This is called after cuts have been added - so can not add cuts
     187      Use solutionValue rather than solvers one
     188  */
     189  virtual int solution(double & objectiveValue,
     190                       double * newSolution,
     191                       double solutionValue);
    179192  /// Validate model i.e. sets when_ to 0 if necessary (may be NULL)
    180193  virtual void validate();
     
    193206  // Original matrix by
    194207  CoinPackedMatrix matrixByRow_;
     208
     209  // Down locks
     210  unsigned short * down_;
     211
     212  // Up locks
     213  unsigned short * up_;
     214
     215  // Equality locks
     216  unsigned short * equal_;
    195217
    196218  // Seed for random stuff
  • trunk/Cbc/src/CbcHeuristicFPump.cpp

    r833 r838  
    189189                         double * betterSolution)
    190190{
     191  double incomingObjective = solutionValue;
    191192#define LEN_PRINT 200
    192193  char pumpPrint[LEN_PRINT];
     
    316317  OsiSolverInterface * solver = NULL;
    317318  double artificialFactor = 0.00001;
     319  // also try rounding!
     320  double * roundingSolution = new double[numberColumns];
     321  double roundingObjective = solutionValue;
    318322  while (!exitAll) {
    319323    int numberPasses=0;
     
    332336        int nFix=solver->reducedCostFix(gap);
    333337        if (nFix) {
    334           sprintf(pumpPrint,"Reduced cost fixing fixed %d variables on pass %d",nFix,numberTries);
     338          sprintf(pumpPrint,"Reduced cost fixing fixed %d variables on major pass %d",nFix,numberTries);
    335339          model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    336340            << pumpPrint
    337341            <<CoinMessageEol;
    338           pumpPrint[0]='\0';
     342          //pumpPrint[0]='\0';
    339343        }
    340344      }
     
    445449#endif
    446450    // 5. MAIN WHILE LOOP
    447     bool newLineNeeded=false;
     451    //bool newLineNeeded=false;
    448452    while (!finished) {
     453      double newTrueSolutionValue=0.0;
     454      double newSumInfeas=0.0;
    449455      returnCode=0;
    450456      if (model_->getCurrentSeconds()>model_->getMaximumSeconds()) {
     
    468474      if (numberPasses==0&&false) {
    469475        // always use same seed
    470         CoinSeedRandom(987654321);
     476        randomNumberGenerator_.setSeed(987654321);
    471477      }
    472478      returnCode = rounds(solver, newSolution,saveObjective,numberIntegers,integerVariable,
     
    475481        // Make sure random will be different
    476482        for (i=1;i<numberTries;i++)
    477           CoinDrand48();
     483          randomNumberGenerator_.randomDouble();
    478484      }
    479485      numberPasses++;
     
    491497          newSolutionValue += saveObjective[i]*newSolution[i];
    492498        newSolutionValue *= direction;
    493         sprintf(pumpPrint+strlen(pumpPrint)," - solution found of %g",newSolutionValue);
    494         newLineNeeded=false;
     499        sprintf(pumpPrint,"Solution found of %g",newSolutionValue);
     500        model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
     501          << pumpPrint
     502          <<CoinMessageEol;
     503        //newLineNeeded=false;
    495504        if (newSolutionValue<solutionValue) {
    496505          double saveValue = solutionValue;
     
    554563            solutionValue=newSolutionValue;
    555564            solutionFound=true;
    556             if (general&&saveValue!=newSolutionValue)
    557               sprintf(pumpPrint+strlen(pumpPrint)," - cleaned solution of %g",solutionValue);
    558             if (pumpPrint[0]!='\0')
     565            if (general&&saveValue!=newSolutionValue) {
     566              sprintf(pumpPrint,"Cleaned solution of %g",solutionValue);
    559567              model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    560568                << pumpPrint
    561569                <<CoinMessageEol;
    562             pumpPrint[0]='\0';
     570            }
    563571          } else {
    564             sprintf(pumpPrint+strlen(pumpPrint)," - mini branch and bound could not fix general integers");
     572            sprintf(pumpPrint,"Mini branch and bound could not fix general integers");
    565573            model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    566574              << pumpPrint
    567575              <<CoinMessageEol;
    568             pumpPrint[0]='\0';
    569576          }
    570577        } else {
    571           sprintf(pumpPrint+strlen(pumpPrint)," - not good enough");
     578          sprintf(pumpPrint,"Not good enough");
    572579          model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    573580            << pumpPrint
    574581            <<CoinMessageEol;
    575           pumpPrint[0]='\0';
    576           newLineNeeded=false;
     582          //newLineNeeded=false;
    577583          returnCode=0;
    578584        }     
     
    597603        if (matched || numberPasses%100 == 0) {
    598604          // perturbation
    599           sprintf(pumpPrint+strlen(pumpPrint)," perturbation applied");
    600           newLineNeeded=true;
     605          //sprintf(pumpPrint+strlen(pumpPrint)," perturbation applied");
     606          //newLineNeeded=true;
    601607          double factorX[10]={0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0};
    602608          double factor=1.0;
     
    604610          double * randomX = new double [numberIntegers];
    605611          for (i=0;i<numberIntegers;i++)
    606             randomX[i] = max(0.0,CoinDrand48()-0.3);
     612            randomX[i] = max(0.0,randomNumberGenerator_.randomDouble()-0.3);
    607613          for (int k=0;k<10;k++) {
    608614#ifdef COIN_DEVELOP_x
     
    755761              newSolutionValue += saveObjective[i]*newSolution[i];
    756762            newSolutionValue *= direction;
    757             sprintf(pumpPrint+strlen(pumpPrint)," - intermediate solution found of %g",newSolutionValue);
     763            sprintf(pumpPrint,"Intermediate solution found of %g",newSolutionValue);
     764            model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
     765              << pumpPrint
     766              <<CoinMessageEol;
    758767            if (newSolutionValue<solutionValue) {
    759768              memcpy(betterSolution,newSolution,numberColumns*sizeof(double));
     
    831840          }
    832841          solver->setHintParam(OsiDoDualInResolve,takeHint);
    833 #ifdef COIN_DEVELOP
     842          newTrueSolutionValue = -saveOffset;
     843          newSumInfeas=0.0;
    834844          {
    835             double newSolutionValue = -saveOffset;
    836845            const double * newSolution = solver->getColSolution();
    837             for (  i=0 ; i<numberColumns ; i++ )
    838               newSolutionValue += saveObjective[i]*newSolution[i];
    839             newSolutionValue *= direction;
    840             printf("took %d iterations - true obj %g\n",solver->getIterationCount(),newSolutionValue);
    841           }
    842 #endif
     846            for (  i=0 ; i<numberColumns ; i++ ) {
     847              if (solver->isInteger(i)) {
     848                double value = newSolution[i];
     849                double nearest = floor(value+0.5);
     850                newSumInfeas += fabs(value-nearest);
     851              }
     852              newTrueSolutionValue += saveObjective[i]*newSolution[i];
     853            }
     854            newTrueSolutionValue *= direction;
     855            OsiSolverInterface * saveSolver = model_->swapSolver(solver);
     856            CbcRounding heuristic1(*model_);
     857            heuristic1.setHeuristicName("rounding in feaspump!");
     858            heuristic1.setWhen(1);
     859            double testObjectiveValue = CoinMin(solutionValue,roundingObjective);
     860            int returnCode = heuristic1.solution(testObjectiveValue,roundingSolution,newTrueSolutionValue) ;
     861            if (returnCode==1) {
     862              assert(testObjectiveValue < CoinMin(solutionValue,roundingObjective));
     863              roundingObjective = testObjectiveValue;
     864            }
     865            model_->swapSolver(saveSolver);
     866          }
    843867          if (!solver->isProvenOptimal()) {
    844868            // presumably max time or some such
     
    926950          }
    927951        }
    928         if (pumpPrint[0]!='\0')
    929           model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    930             << pumpPrint
    931             <<CoinMessageEol;
    932         pumpPrint[0]='\0';
    933952        if (solver->getNumRows()<3000)
    934           sprintf(pumpPrint+strlen(pumpPrint),"Pass %3d: obj. %10.5f --> ", numberPasses+totalNumberPasses,solver->getObjValue());
     953          sprintf(pumpPrint,"Pass %3d: suminf. %10.5f obj. %g iterations %d", numberPasses+totalNumberPasses,
     954                  newSumInfeas,newTrueSolutionValue,solver->getIterationCount());
    935955        else
    936           sprintf(pumpPrint+strlen(pumpPrint),"Pass %3d: (%.2f seconds) obj. %10.5f --> ", numberPasses+totalNumberPasses,
    937                   model_->getCurrentSeconds(),solver->getObjValue());
     956          sprintf(pumpPrint,"Pass %3d: (%.2f seconds) suminf. %10.5f obj. %g iterations %d", numberPasses+totalNumberPasses,
     957                  model_->getCurrentSeconds(),newSumInfeas,newTrueSolutionValue,solver->getIterationCount());
     958        model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
     959          << pumpPrint
     960          <<CoinMessageEol;
    938961        if (closestSolution&&solver->getObjValue()<closestObjectiveValue) {
    939962          int i;
     
    948971          closestObjectiveValue = solver->getObjValue();
    949972        }
    950         newLineNeeded=true;
     973        //newLineNeeded=true;
    951974       
    952975      }
     
    954977      scaleFactor *= weightFactor_;
    955978    } // END WHILE
    956     if (!solutionFound)
    957       sprintf(pumpPrint+strlen(pumpPrint),"No solution found this major pass");
    958     if (strlen(pumpPrint)) {
     979    // see if rounding worked!
     980    if (roundingObjective<solutionValue) {
     981      sprintf(pumpPrint,"Rounding solution of %g is better than previous of %g !\n",
     982              roundingObjective,solutionValue);
     983      solutionValue=roundingObjective;
     984      memcpy(betterSolution,roundingSolution,numberColumns*sizeof(double));
     985      solutionFound=true;
     986    }
     987    if (!solutionFound) {
     988      sprintf(pumpPrint,"No solution found this major pass");
    959989      model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    960990        << pumpPrint
    961991        <<CoinMessageEol;
    962       pumpPrint[0]='\0';
    963     }
     992    }
     993    //}
    964994    delete solver;
    965995    solver=NULL;
     
    10341064        break;
    10351065      }
    1036       sprintf(pumpPrint+strlen(pumpPrint),"Before mini branch and bound, %d integers at bound fixed and %d continuous",
     1066      sprintf(pumpPrint,"Before mini branch and bound, %d integers at bound fixed and %d continuous",
    10371067             nFix,nFixC);
    10381068      if (nFixC2+nFixI!=0)
     
    10421072        << pumpPrint
    10431073        <<CoinMessageEol;
    1044       pumpPrint[0]='\0';
    10451074      double saveValue = newSolutionValue;
    10461075      returnCode = smallBranchAndBound(newSolver,numberNodes_,newSolution,newSolutionValue,
     
    10561085      }
    10571086      if (returnCode&&newSolutionValue<saveValue) {
    1058         sprintf(pumpPrint+strlen(pumpPrint),"Mini branch and bound improved solution from %g to %g (%.2f seconds)",
     1087        sprintf(pumpPrint,"Mini branch and bound improved solution from %g to %g (%.2f seconds)",
    10591088                saveValue,newSolutionValue,model_->getCurrentSeconds());
    10601089        model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    10611090          << pumpPrint
    10621091          <<CoinMessageEol;
    1063         pumpPrint[0]='\0';
    10641092        memcpy(betterSolution,newSolution,numberColumns*sizeof(double));
    10651093        if (fixContinuous) {
     
    10811109            double value = newSolver->getObjValue()*newSolver->getObjSense();
    10821110            if (value<newSolutionValue) {
    1083               sprintf(pumpPrint+strlen(pumpPrint),"Freeing continuous variables gives a solution of %g", value);
     1111              sprintf(pumpPrint,"Freeing continuous variables gives a solution of %g", value);
    10841112              model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    10851113                << pumpPrint
    10861114                <<CoinMessageEol;
    1087               pumpPrint[0]='\0';
    10881115              newSolutionValue=value;
    10891116              memcpy(betterSolution,newSolver->getColSolution(),numberColumns*sizeof(double));
     
    11231150        }
    11241151      } else {
    1125         sprintf(pumpPrint+strlen(pumpPrint),"Mini branch and bound did not improve solution (%.2f seconds)",
     1152        sprintf(pumpPrint,"Mini branch and bound did not improve solution (%.2f seconds)",
    11261153                model_->getCurrentSeconds());
    11271154        model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    11281155          << pumpPrint
    11291156          <<CoinMessageEol;
    1130         pumpPrint[0]='\0';
    11311157      }
    11321158      delete newSolver;
     
    11461172      if (cutoff<continuousObjectiveValue)
    11471173        break;
    1148       sprintf(pumpPrint+strlen(pumpPrint),"Round again with cutoff of %g",cutoff);
     1174      sprintf(pumpPrint,"Round again with cutoff of %g",cutoff);
    11491175      model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    11501176        << pumpPrint
    11511177        <<CoinMessageEol;
    1152       pumpPrint[0]='\0';
    11531178      if ((accumulate_&3)<2&&usedColumn)
    11541179        memset(usedColumn,0,numberColumns);
     
    11991224    delete newSolver;
    12001225  }
     1226  delete [] roundingSolution;
    12011227  delete [] usedColumn;
    12021228  delete [] lastSolution;
     
    12061232  delete [] firstPerturbedObjective;
    12071233  delete [] firstPerturbedSolution;
    1208   sprintf(pumpPrint,"After %.2f seconds - Feasibility pump exiting - took %.2f seconds",
    1209           model_->getCurrentSeconds(),CoinCpuTime()-time1);
     1234  if (solutionValue==incomingObjective)
     1235    sprintf(pumpPrint,"After %.2f seconds - Feasibility pump exiting - took %.2f seconds",
     1236            model_->getCurrentSeconds(),CoinCpuTime()-time1);
     1237  else
     1238    sprintf(pumpPrint,"After %.2f seconds - Feasibility pump exiting with objective of %g - took %.2f seconds",
     1239            model_->getCurrentSeconds(),solutionValue,CoinCpuTime()-time1);
    12101240  model_->messageHandler()->message(CBC_FPUMP1,model_->messages())
    12111241    << pumpPrint
     
    12511281  int flip_up = 0;
    12521282  int flip_down  = 0;
    1253   double  v = CoinDrand48() * 20;
     1283  double  v = randomNumberGenerator_.randomDouble() * 20.0;
    12541284  int nn = 10 + (int) v;
    12551285  int nnv = 0;
     
    12841314
    12851315  if (nnv > nn) nnv = nn;
    1286   if (iter != 0)
    1287     sprintf(pumpPrint+strlen(pumpPrint),"up = %5d , down = %5d", flip_up, flip_down);
     1316  //if (iter != 0)
     1317  //sprintf(pumpPrint+strlen(pumpPrint),"up = %5d , down = %5d", flip_up, flip_down);
    12881318  *flip = flip_up + flip_down;
    12891319  delete [] tmp;
     
    12921322  const double * columnUpper = solver->getColUpper();
    12931323  if (*flip == 0 && iter != 0) {
    1294     sprintf(pumpPrint+strlen(pumpPrint)," -- rand = %4d (%4d) ", nnv, nn);
     1324    //sprintf(pumpPrint+strlen(pumpPrint)," -- rand = %4d (%4d) ", nnv, nn);
    12951325     for (i = 0; i < nnv; i++) {
    12961326       // was solution[list[i]] = 1. - solution[list[i]]; but does that work for 7>=x>=6
  • trunk/Cbc/src/CbcHeuristicGreedy.cpp

    r759 r838  
    246246            // add to next time
    247247            which[newNumber++]=iColumn;
    248             double ratio = (cost/sum)*(1.0+perturb*CoinDrand48());
     248            double ratio = (cost/sum)*(1.0+perturb*randomNumberGenerator_.randomDouble());
    249249            // If at root choose first
    250250            if (atRoot)
     
    286286            }
    287287            assert (sum>0.0);
    288             double ratio = (cost/sum)*(1.0+perturb*CoinDrand48());
     288            double ratio = (cost/sum)*(1.0+perturb*randomNumberGenerator_.randomDouble());
    289289            if (ratio<bestRatio) {
    290290              bestRatio=ratio;
     
    663663            // add to next time
    664664            which[newNumber++]=iColumn;
    665             double ratio = (cost/sum)*(1.0+perturb*CoinDrand48());
     665            double ratio = (cost/sum)*(1.0+perturb*randomNumberGenerator_.randomDouble());
    666666            // If at root
    667667            if (atRoot) {
     
    695695            // add to next time
    696696            which[newNumber++]=iColumn;
    697             double ratio = (cost/sum)*(1.0+perturb*CoinDrand48());
     697            double ratio = (cost/sum)*(1.0+perturb*randomNumberGenerator_.randomDouble());
    698698            if (ratio<bestRatio) {
    699699              bestRatio=ratio;
  • trunk/Cbc/src/CbcHeuristicRINS.cpp

    r833 r838  
    2525  numberTries_=0;
    2626  howOften_=100;
     27  decayFactor_ = 0.5;
    2728  used_=NULL;
    2829}
     
    3738  numberTries_=0;
    3839  howOften_=100;
     40  decayFactor_ = 0.5;
    3941  assert(model.solver());
    4042  int numberColumns = model.solver()->getNumCols();
     
    6466    numberSolutions_ = rhs.numberSolutions_;
    6567    howOften_ = rhs.howOften_;
     68    decayFactor_ = rhs.decayFactor_;
    6669    numberSuccesses_ = rhs.numberSuccesses_;
    6770    numberTries_ = rhs.numberTries_;
     
    99102  numberSolutions_(rhs.numberSolutions_),
    100103  howOften_(rhs.howOften_),
     104  decayFactor_(rhs.decayFactor_),
    101105  numberSuccesses_(rhs.numberSuccesses_),
    102106  numberTries_(rhs.numberTries_)
     
    137141    return 0; // No solution found yet
    138142  if (numberSolutions_<model_->getSolutionCount()) {
    139     // new solution - just add info
     143    // new solution - add info
    140144    numberSolutions_=model_->getSolutionCount();
    141145
     
    163167      }
    164168    }
    165   } else if ((model_->getNodeCount()%howOften_)==0&&model_->getCurrentPassNumber()==1) {
     169  }
     170  if ((model_->getNodeCount()%howOften_)==0&&model_->getCurrentPassNumber()==1) {
    166171    OsiSolverInterface * solver = model_->solver();
    167172
     
    217222      numberTries_++;
    218223      if ((numberTries_%10)==0&&numberSuccesses_*3<numberTries_)
    219         howOften_ += howOften_/2;
     224        howOften_ += howOften_*decayFactor_;
    220225    }
    221226
  • trunk/Cbc/src/CbcHeuristicRINS.hpp

    r833 r838  
    5656  inline void setHowOften(int value)
    5757  { howOften_=value;}
     58  /// Sets decay factor (for howOften) on failure
     59  inline void setDecayFactor(double value)
     60  { decayFactor_=value;}
    5861  /// Used array so we can set
    5962  inline char * used() const
     
    6770  /// How often to do (code can change)
    6871  int howOften_;
     72  /// How much to increase how often
     73  double decayFactor_;
    6974  /// Number of successes
    7075  int numberSuccesses_;
  • trunk/Cbc/src/CbcModel.cpp

    r837 r838  
    77
    88#include "CbcConfig.h"
     9//static int nXXXXXX=0;
    910
    1011#include <string>
     
    6869#include "CbcCompareActual.hpp"
    6970#include "CbcTree.hpp"
    70 //#define CBC_THREAD
     71//#define CBC_DETERMINISTIC_THREAD
    7172#ifdef CBC_THREAD
     73#ifdef CBC_DETERMINISTIC_THREAD
     74//#define DELETE_OUTSIDE
     75#else
     76#define CBC_NORMAL_THREAD
     77#endif
    7278#include <pthread.h>
    7379#ifndef CLP_FAST_CODE
    74 //#define CBC_THREAD_DEBUG 1
     80#define CBC_THREAD_DEBUG 1
    7581#endif
    7682#ifdef CBC_THREAD_DEBUG
     
    109115#if CBC_THREAD_DEBUG
    110116  int threadNumber;
     117#endif
     118#ifdef CBC_DETERMINISTIC_THREAD
     119  CbcNode ** delNode;
     120  int maxDeleteNode;
     121  int nDeleteNode;
     122  int nodesThisTime;
     123  int iterationsThisTime;
    111124#endif
    112125} threadStruct;
     
    869882  strongInfo_[2]=0;
    870883  numberStrongIterations_ = 0;
    871   // Initialize random seed
    872   CoinSeedRandom(1234567);
     884  CoinThreadRandom randomGenerator(1234567);
     885#ifdef COIN_HAS_CLP
     886 {
     887   OsiClpSolverInterface * clpSolver
     888     = dynamic_cast<OsiClpSolverInterface *> (solver_);
     889   if (clpSolver) {
     890     // Initialise solvers seed
     891     clpSolver->getModelPtr()->setRandomSeed(1234567);
     892   }
     893 }
     894#endif
    873895#ifndef NDEBUG
    874896  {
     
    13951417  delete [] addedCuts_ ;
    13961418  addedCuts_ = NULL ;
     1419  OsiObject ** saveObjects=NULL;
    13971420/*
    13981421  Set up an empty heap and associated data structures to hold the live set
     
    17351758  pthread_cond_t * condition2 = NULL;
    17361759  threadStruct * threadInfo = NULL;
     1760#ifdef CBC_NORMAL_THREAD
    17371761  bool locked=false;
     1762#endif
    17381763  int threadStats[6];
     1764#ifdef CBC_DETERMINISTIC_THREAD
     1765  int defaultParallelIterations=500;
     1766  int defaultParallelNodes=10;
     1767#endif
    17391768  memset(threadStats,0,sizeof(threadStats));
    17401769  double timeWaiting=0.0;
     
    17521781    mutex2 = new pthread_mutex_t [numberThreads_];
    17531782    condition2 = new pthread_cond_t [numberThreads_];
     1783#ifdef CBC_DETERMINISTIC_THREAD
     1784    // May need for deterministic
     1785    saveObjects=new OsiObject * [numberObjects_];
     1786    for (int i=0;i<numberObjects_;i++) {
     1787      saveObjects[i] = object_[i]->clone();
     1788    }
     1789#endif
    17541790    // we don't want a strategy object
    17551791    CbcStrategy * saveStrategy = strategy_;
     
    17901826      threadInfo[i].threadNumber=i+2;
    17911827#endif
     1828#ifdef CBC_DETERMINISTIC_THREAD
     1829      threadInfo[i].delNode = NULL;
     1830      threadInfo[i].maxDeleteNode=0;
     1831      threadInfo[i].nDeleteNode=0;
     1832      threadInfo[i].nodesThisTime=0;
     1833      threadInfo[i].iterationsThisTime=0;
     1834#endif
    17921835      pthread_create(threadId+i,NULL,doNodesThread,threadInfo+i);
    17931836    }
     
    18421885    }
    18431886  }
     1887#ifdef CBC_DETERMINISTIC_THREAD
     1888#define MAX_DEL_NODE 1
     1889  CbcNode * delNode[MAX_DEL_NODE+1];
     1890  int nDeleteNode=0;
     1891  bool goneParallel=false;
     1892#endif
     1893  // For Printing etc when parallel
     1894  int lastEvery1000=0;
     1895  int lastPrintEvery=0;
    18441896  while (true) {
    1845 #ifdef CBC_THREAD
     1897#ifdef CBC_NORMAL_THREAD
    18461898    if (!locked) {
    18471899      lockThread();
     
    18501902#endif
    18511903    if (tree_->empty()) {
    1852 #ifdef CBC_THREAD
     1904#ifdef CBC_NORMAL_THREAD
    18531905      if (numberThreads_) {
    18541906#ifdef COIN_DEVELOP
     
    18671919          printf("waiting for thread %d code 0\n",iThread);
    18681920#endif
     1921#ifndef CBC_DETERMINISTIC_THREAD
    18691922          unlockThread();
     1923#endif
    18701924          locked = false;
    18711925          pthread_cond_signal(threadInfo[iThread].condition2); // unlock in case
     
    19101964          }
    19111965          if (iThread<numberThreads_) {
     1966#ifndef CBC_DETERMINISTIC_THREAD
    19121967            unlockThread();
     1968#endif
    19131969            locked = false;
    19141970            threadModel[iThread]->moveToModel(this,1);
     
    19411997#endif
    19421998      }
     1999#ifndef CBC_DETERMINISTIC_THREAD
    19432000      unlockThread();
     2001#endif
    19442002      locked=false; // not needed as break
    19452003#endif
    19462004      break;
    19472005    }
    1948 #ifdef CBC_THREAD
     2006#ifdef CBC_NORMAL_THREAD
    19492007    unlockThread();
    19502008    locked = false;
     
    19992057        }
    20002058      }
     2059#ifndef CBC_DETERMINISTIC_THREAD
    20012060      lockThread();
     2061#endif
    20022062      // Do from deepest
    20032063      tree_->cleanTree(this, newCutoff,bestPossibleObjective_) ;
     
    20072067      tree_->setComparison(*nodeCompare_) ;
    20082068      if (tree_->empty()) {
     2069#ifndef CBC_DETERMINISTIC_THREAD
    20092070        unlockThread();
     2071#endif
    20102072        // For threads we need to check further
    20112073        //break; // finished
    20122074        continue;
    20132075      }
     2076#ifndef CBC_DETERMINISTIC_THREAD
    20142077      unlockThread();
     2078#endif
    20152079    }
    20162080    cutoff = getCutoff() ;
     
    20212085    + print a summary line to let the user know we're working
    20222086*/
    2023     if ((numberNodes_%1000) == 0) {
     2087    if (numberNodes_>=lastEvery1000) {
     2088#ifndef CBC_DETERMINISTIC_THREAD
    20242089      lockThread();
     2090#endif
     2091      lastEvery1000 = numberNodes_ + 1000;
    20252092      bool redoTree=nodeCompare_->every1000Nodes(this, numberNodes_) ;
    20262093#ifdef CHECK_CUT_SIZE
     
    20302097      if (redoTree)
    20312098        tree_->setComparison(*nodeCompare_) ;
     2099#ifndef CBC_DETERMINISTIC_THREAD
    20322100      unlockThread();
     2101#endif
    20332102    }
    20342103    if (saveCompare&&!hotstartSolution_) {
     
    20382107      saveCompare=NULL;
    20392108      // redo tree
     2109#ifndef CBC_DETERMINISTIC_THREAD
    20402110      lockThread();
     2111#endif
    20412112      tree_->setComparison(*nodeCompare_) ;
     2113#ifndef CBC_DETERMINISTIC_THREAD
    20422114      unlockThread();
    2043     }
    2044     if ((numberNodes_%printFrequency_) == 0) {
     2115#endif
     2116    }
     2117    if (numberNodes_>=lastPrintEvery) {
     2118      lastPrintEvery = numberNodes_ + printFrequency_;
     2119#ifndef CBC_DETERMINISTIC_THREAD
    20452120      lockThread();
     2121#endif
    20462122      int nNodes = tree_->size() ;
    20472123
    20482124      //MODIF PIERRE
    20492125      bestPossibleObjective_ = tree_->getBestPossibleObjective();
     2126#ifndef CBC_DETERMINISTIC_THREAD
    20502127      unlockThread();
     2128#endif
    20512129      if (!intParam_[CbcPrinting]) {
    20522130        messageHandler()->message(CBC_STATUS,messages())
     
    20852163  active subproblem.
    20862164*/
     2165#ifndef CBC_THREAD
    20872166    CbcNode *node = tree_->bestNode(cutoff) ;
    20882167    // Possible one on tree worse than cutoff
    2089     if (!node)
     2168    if (!node||node->objectiveValue()>cutoff)
    20902169      continue;
    2091 #ifndef CBC_THREAD
    20922170    int currentNumberCuts = 0 ;
    20932171    currentNode_=node; // so can be accessed elsewhere
     
    24972575        delete [] delRows ; }
    24982576#else // end of not CBC_THREAD
    2499       if (!numberThreads_) {
     2577#ifndef CBC_DETERMINISTIC_THREAD
     2578      CbcNode *node = tree_->bestNode(cutoff) ;
     2579      // Possible one on tree worse than cutoff
     2580      if (!node||node->objectiveValue()>cutoff)
     2581        continue;
     2582    if (!numberThreads_) {
     2583#else
     2584      if (!numberThreads_||(tree_->size()<5*numberThreads_&&!goneParallel)) {
     2585      CbcNode *node = tree_->bestNode(cutoff) ;
     2586      // Possible one on tree worse than cutoff
     2587      if (!node||node->objectiveValue()>cutoff)
     2588        continue;
     2589#endif
    25002590        doOneNode(this,node,createdNode);
     2591#ifdef CBC_DETERMINISTIC_THREAD
     2592        assert (createdNode);
     2593        if (!createdNode->active()) {
     2594          delete createdNode;
     2595          createdNode=NULL;
     2596        } else {
     2597          // Say one more pointing to this
     2598          node->nodeInfo()->increment() ;
     2599          tree_->push(createdNode) ;
     2600        }
     2601        //if (node) {
     2602        //assert (node->active());
     2603        if (node->active()) {
     2604          assert (node->nodeInfo());
     2605          if (node->nodeInfo()->numberBranchesLeft()) {
     2606            tree_->push(node) ;
     2607          } else {
     2608            node->setActive(false);
     2609          }
     2610        } else {
     2611          if (node->nodeInfo()) {
     2612            if (!node->nodeInfo()->numberBranchesLeft())
     2613              node->nodeInfo()->allBranchesGone(); // can clean up
     2614            // So will delete underlying stuff
     2615            node->setActive(true);
     2616          }
     2617          delNode[nDeleteNode++]=node;
     2618          node=NULL;
     2619        }
     2620        if (nDeleteNode>=MAX_DEL_NODE) {
     2621          for (int i=0;i<nDeleteNode;i++) {
     2622            //printf("trying to del %d %x\n",i,delNode[i]);
     2623            delete delNode[i];
     2624            //printf("done to del %d %x\n",i,delNode[i]);
     2625          }
     2626          nDeleteNode=0;
     2627        }
     2628#endif
    25012629      } else {
     2630#ifdef CBC_NORMAL_THREAD
    25022631        threadStats[0]++;
    25032632        //need to think
     
    25172646          threadCount[iThread]++;
    25182647        }
     2648#ifndef CBC_DETERMINISTIC_THREAD
    25192649        lockThread();
     2650#endif
    25202651        locked=true;
    25212652        // see if any finished
     
    25242655            break;
    25252656        }
     2657#ifndef CBC_DETERMINISTIC_THREAD
    25262658        unlockThread();
     2659#endif
    25272660        locked=false;
    25282661        if (iThread<numberThreads_) {
     
    25402673          }
    25412674          if (iThread<numberThreads_) {
     2675#ifndef CBC_DETERMINISTIC_THREAD
    25422676            lockThread();
     2677#endif
    25432678            locked=true;
    25442679            // If any on tree get
     
    25492684              continue; // ** get another node
    25502685            }
     2686#ifndef CBC_DETERMINISTIC_THREAD
    25512687            unlockThread();
     2688#endif
    25522689            locked=false;
    25532690          }
     
    25882725          threadStats[2]++;
    25892726        }
     2727#else
     2728        // Deterministic parallel
     2729#ifndef CBC_DETERMINISTIC_THREAD
     2730        abort();
     2731#endif
     2732        int saveTreeSize = tree_->size();
     2733        goneParallel=true;
     2734        int nAffected=splitModel(numberThreads_,threadModel,defaultParallelNodes);
     2735        int saveTreeSize2 = tree_->size();
     2736        int iThread;
     2737        // do all until finished
     2738        for (iThread=0;iThread<numberThreads_;iThread++) {
     2739          // obviously tune
     2740          threadInfo[iThread].nDeleteNode=defaultParallelIterations;
     2741        }
     2742        // Save current state
     2743        int iObject;
     2744        for (iObject=0;iObject<numberObjects_;iObject++) {
     2745          saveObjects[iObject]->updateBefore(object_[iObject]);
     2746        }
     2747        for (iThread=0;iThread<numberThreads_;iThread++) {
     2748          threadInfo[iThread].returnCode=0;
     2749          pthread_cond_signal(threadInfo[iThread].condition2); // unlock
     2750#if 0
     2751          //wait!!
     2752          bool finished=false;
     2753          while (!finished) {
     2754            pthread_mutex_lock(&condition_mutex);
     2755            struct timespec absTime;
     2756            clock_gettime(CLOCK_REALTIME,&absTime);
     2757            double time = absTime.tv_sec+1.0e-9*absTime.tv_nsec;
     2758            absTime.tv_nsec += 1000000; // millisecond
     2759            if (absTime.tv_nsec>=1000000000) {
     2760              absTime.tv_nsec -= 1000000000;
     2761              absTime.tv_sec++;
     2762            }
     2763            pthread_cond_timedwait(&condition_main,&condition_mutex,&absTime);
     2764            clock_gettime(CLOCK_REALTIME,&absTime);
     2765            double time2 = absTime.tv_sec+1.0e-9*absTime.tv_nsec;
     2766            timeWaiting += time2-time;
     2767            pthread_mutex_unlock(&condition_mutex);
     2768            finished=true;
     2769            if (threadInfo[iThread].returnCode<=0) {
     2770              finished=false;
     2771            }
     2772          }
     2773#endif
     2774        }
     2775        // wait
     2776        bool finished=false;
     2777        while (!finished) {
     2778          pthread_mutex_lock(&condition_mutex);
     2779          struct timespec absTime;
     2780          clock_gettime(CLOCK_REALTIME,&absTime);
     2781          double time = absTime.tv_sec+1.0e-9*absTime.tv_nsec;
     2782          absTime.tv_nsec += 1000000; // millisecond
     2783          if (absTime.tv_nsec>=1000000000) {
     2784            absTime.tv_nsec -= 1000000000;
     2785            absTime.tv_sec++;
     2786          }
     2787          pthread_cond_timedwait(&condition_main,&condition_mutex,&absTime);
     2788          clock_gettime(CLOCK_REALTIME,&absTime);
     2789          double time2 = absTime.tv_sec+1.0e-9*absTime.tv_nsec;
     2790          timeWaiting += time2-time;
     2791          pthread_mutex_unlock(&condition_mutex);
     2792          finished=true;
     2793          for (iThread=0;iThread<numberThreads_;iThread++) {
     2794            if (threadInfo[iThread].returnCode<=0) {
     2795              finished=false;
     2796            }
     2797          }
     2798        }
     2799        // Unmark marked
     2800        for (int i=0;i<nAffected;i++) {
     2801          walkback_[i]->unmark();
     2802        }
     2803        assert (saveTreeSize2 == tree_->size());
     2804        if (0) {
     2805          // put back cut counts
     2806          for (int i=0;i<nAffected;i++) {
     2807            walkback_[i]->decrementCuts(1000000);
     2808          }
     2809        }
     2810#ifndef NDEBUG
     2811        for (iObject=0;iObject<numberObjects_;iObject++) {
     2812          CbcSimpleIntegerDynamicPseudoCost * obj =
     2813            dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object_[iObject]) ;
     2814          CbcSimpleIntegerDynamicPseudoCost * obj2 =
     2815            dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(saveObjects[iObject]) ;
     2816          assert (obj->same(obj2));
     2817        }
     2818#endif
     2819        int iModel;
     2820        double scaleFactor=1.0;
     2821        for (iModel=0;iModel<numberThreads_;iModel++) {
     2822          //printf("model %d tree size %d\n",iModel,threadModel[iModel]->tree_->size());
     2823          if (saveTreeSize>4*numberThreads_*defaultParallelNodes) {
     2824            if (!threadModel[iModel]->tree_->size()) {
     2825              scaleFactor *= 1.05;
     2826            }
     2827          }
     2828          threadModel[iModel]->moveToModel(this,11);
     2829          // Update base model
     2830          OsiObject ** threadObject = threadModel[iModel]->object_;
     2831          for (iObject=0;iObject<numberObjects_;iObject++) {
     2832            object_[iObject]->updateAfter(threadObject[iObject],saveObjects[iObject]);
     2833          }
     2834        }
     2835        if (scaleFactor!=1.0) {
     2836          int newNumber = (int) (defaultParallelNodes * scaleFactor+0.5001);
     2837          if (newNumber*2<defaultParallelIterations) {
     2838            printf("Changing tree size from %d to %d\n",
     2839                   defaultParallelNodes,newNumber);
     2840            defaultParallelNodes = newNumber;
     2841          }
     2842        }
     2843        printf("Tree sizes %d %d %d - affected %d\n",saveTreeSize,saveTreeSize2,tree_->size(),nAffected);
     2844        // later remember random may not be thread neutral
     2845#endif
    25902846      }
    25912847      //lastDepth=node->depth();
     
    25932849#endif // end of CBC_THREAD
    25942850  }
     2851#ifdef CBC_DETERMINISTIC_THREAD
     2852  if (nDeleteNode) {
     2853    for (int i=0;i<nDeleteNode;i++) {
     2854      delete delNode[i];
     2855    }
     2856    nDeleteNode=0;
     2857  }
     2858#endif
    25952859#ifdef CBC_THREAD
    25962860  if (numberThreads_) {
     
    26272891      pthread_mutex_lock(&condition_mutex); // not sure necessary but have had one hang on interrupt
    26282892      threadModel[i]->numberThreads_=0; // say exit
     2893#ifdef CBC_DETERMINISTIC_THREAD
     2894      delete [] threadInfo[i].delNode;
     2895#endif
    26292896      threadInfo[i].returnCode=0;
    26302897      pthread_mutex_unlock(&condition_mutex);
     
    29603227*/
    29613228  delete lastws ;
     3229  if (saveObjects) {
     3230    for (int i=0;i<numberObjects_;i++)
     3231      delete saveObjects[i];
     3232    delete [] saveObjects;
     3233  }
    29623234  delete [] whichGenerator_ ;
    29633235  whichGenerator_=NULL;
     
    31243396:
    31253397  solver_(NULL),
    3126   ourSolver_(true),
     3398  ownership_(0x80000000),
    31273399  continuousSolver_(NULL),
    31283400  referenceSolver_(NULL),
     
    31693441  numberBeforeTrust_(10),
    31703442  numberPenalties_(20),
     3443  stopNumberIterations_(-1),
    31713444  penaltyScaleFactor_(3.0),
    31723445  numberAnalyzeIterations_(0),
     
    33073580  numberBeforeTrust_(10),
    33083581  numberPenalties_(20),
     3582  stopNumberIterations_(-1),
    33093583  penaltyScaleFactor_(3.0),
    33103584  numberAnalyzeIterations_(0),
     
    33943668  solver_ = rhs.clone();
    33953669  referenceSolver_ = solver_->clone();
    3396   ourSolver_ = true ;
     3670  ownership_ = 0x80000000;
    33973671  cbcColLower_ = NULL;
    33983672  cbcColUpper_ = NULL;
     
    34763750    solver->messageHandler()->setLogLevel(solver_->messageHandler()->logLevel()) ;
    34773751
    3478   if (ourSolver_&&deleteSolver) delete solver_ ;
     3752  if (modelOwnsSolver()&&deleteSolver) delete solver_ ;
    34793753  solver_ = solver;
    34803754  solver = NULL ;
    3481   ourSolver_ = true ;
     3755  setModelOwnsSolver(true) ;
    34823756/*
    34833757  Basis information is solver-specific.
     
    35413815  numberBeforeTrust_(rhs.numberBeforeTrust_),
    35423816  numberPenalties_(rhs.numberPenalties_),
     3817  stopNumberIterations_(rhs.stopNumberIterations_),
    35433818  penaltyScaleFactor_(rhs.penaltyScaleFactor_),
    35443819  numberAnalyzeIterations_(rhs.numberAnalyzeIterations_),
     
    36973972  appData_=rhs.appData_;
    36983973  messages_ = rhs.messages_;
    3699   ourSolver_ = true ;
     3974  ownership_ = 0x80000000;
    37003975  messageHandler()->setLogLevel(rhs.messageHandler()->logLevel());
    37013976  numberIntegers_=rhs.numberIntegers_;
     
    37784053{
    37794054  if (this!=&rhs) {
    3780     if (ourSolver_) {
     4055    if (modelOwnsSolver()) {
    37814056      delete solver_;
    37824057      solver_=NULL;
     
    37984073    else
    37994074    { solver_ = 0 ; }
    3800     ourSolver_ = true ;
     4075    ownership_ = 0x80000000;
    38014076    delete continuousSolver_ ;
    38024077    if (rhs.continuousSolver_)
     
    38504125    numberBeforeTrust_ = rhs.numberBeforeTrust_;
    38514126    numberPenalties_ = rhs.numberPenalties_;
     4127    stopNumberIterations_ = rhs.stopNumberIterations_;
    38524128    penaltyScaleFactor_ = rhs.penaltyScaleFactor_;
    38534129    numberAnalyzeIterations_ = rhs.numberAnalyzeIterations_;
     
    40534329  delete tree_;
    40544330  tree_=NULL;
    4055   if (ourSolver_) {
     4331  if (modelOwnsSolver()) {
    40564332    delete solver_;
    40574333    solver_ = NULL;
     
    41144390  numberObjects_=0;
    41154391  // Below here is whatever consensus is
    4116   ourSolver_=true;
     4392  ownership_ = 0x80000000;
    41174393  delete branchingMethod_;
    41184394  branchingMethod_=NULL;
     
    43414617CbcModel::setNumberBeforeTrust(int number)
    43424618{
    4343   if (number<-1) {
     4619  if (number<-3) {
    43444620    numberBeforeTrust_=0;
    43454621  } else {
     
    44134689  if (name)
    44144690  { heuristic_[numberHeuristics_]->setHeuristicName(name) ; }
     4691  heuristic_[numberHeuristics_]->setSeed(987654321+numberHeuristics_);
    44154692  numberHeuristics_++ ;
    44164693}
     
    45044781*/
    45054782  currentNumberCuts=0;
     4783  //#define CBC_PRINT2
     4784#ifdef CBC_PRINT2
     4785  printf("Starting bounds at node %d\n",numberNodes_);
     4786#endif
    45064787  while (nNode) {
    45074788    --nNode;
    45084789    walkback_[nNode]->applyToModel(this,lastws,addedCuts_,currentNumberCuts);
     4790  }
     4791  if (0) {
     4792    int numberDebugValues=18;
     4793    double * debugValues = new double[numberDebugValues];
     4794    CoinZeroN(debugValues,numberDebugValues);
     4795    debugValues[1]=6.0;
     4796    debugValues[3]=60.0;
     4797    debugValues[4]=6.0;
     4798    debugValues[6]=60.0;
     4799    debugValues[7]=16.0;
     4800    debugValues[9]=70.0;
     4801    debugValues[10]=7.0;
     4802    debugValues[12]=70.0;
     4803    debugValues[13]=12.0;
     4804    debugValues[15]=75.0;
     4805    int nBad=0;
     4806    for (int j=0;j<numberColumns;j++) {
     4807      if (integerInfo_[j]) {
     4808        if(solver_->getColLower()[j]>debugValues[j]||
     4809           solver_->getColUpper()[j]<debugValues[j]) {
     4810          printf("** (%g) ** ",debugValues[j]);
     4811          nBad++;
     4812        }
     4813        printf("%d bounds %g %g\n",j,solver_->getColLower()[j],solver_->getColUpper()[j]);
     4814      }
     4815    }
     4816    if (nBad)
     4817      printf("%d BAD\n",nBad);
     4818    else
     4819      printf("OKAY\n");
     4820    delete [] debugValues;
    45094821  }
    45104822}
     
    46704982  { int i;
    46714983    if (currentNumberCuts) {
     4984#ifndef CBC_DETERMINISTIC_THREAD
    46724985      lockThread();
     4986#endif
    46734987      int numberLeft = nodeInfo->numberBranchesLeft();
    46744988      for (i = 0 ; i < currentNumberCuts ; i++)
     
    46774991            { delete addedCuts_[i];
    46784992            addedCuts_[i] = NULL; } } }
     4993#ifndef CBC_DETERMINISTIC_THREAD
    46794994      unlockThread();
     4995#endif
    46804996    }
    46814997    return 1 ; }
     
    47935109    saveClpOptions = clpSolver->specialOptions();
    47945110# endif
     5111  //solver_->writeMps("saved");
    47955112#ifdef CBC_THREAD
    47965113  CbcModel ** threadModel = NULL;
     
    58906207    { int i ;
    58916208      if (currentNumberCuts_) {
     6209#ifndef CBC_DETERMINISTIC_THREAD
    58926210        lockThread();
     6211#endif
    58936212        for (i = 0;i<currentNumberCuts_;i++) {
    58946213          // take off node
     
    64936812    int oldCutIndex = 0 ;
    64946813    if (numberOldActiveCuts_) {
     6814#ifndef CBC_DETERMINISTIC_THREAD
    64956815      lockThread();
     6816#endif
    64966817      for (i = 0 ; i < numberOldActiveCuts_ ; i++)
    64976818        { status = ws->getArtifStatus(i+firstOldCut) ;
     
    65166837        else
    65176838          { oldCutIndex++ ; } }
     6839#ifndef CBC_DETERMINISTIC_THREAD
    65186840      unlockThread();
     6841#endif
    65196842    }
    65206843/*
     
    71067429    down[iColumn]=downValue;
    71077430    if (solver_->isInteger(iColumn)) {
    7108       if (!numberNodes_)
     7431      if (!numberNodes_&&handler_->logLevel()>1)
    71097432        printf("%d - dj %g up %g down %g cost %g\n",
    71107433               iColumn,dj,upValue,downValue,objective[iColumn]);
     
    71287451        upPseudoCost = CoinMax(upPseudoCost,0.1*down[iColumn]);
    71297452        obj1->setUpDynamicPseudoCost(upPseudoCost);
    7130         if (upPseudoCost>saveUp&&!numberNodes_)
     7453        if (upPseudoCost>saveUp&&!numberNodes_&&handler_->logLevel()>1)
    71317454          printf("For %d up went from %g to %g\n",
    71327455                 iColumn,saveUp,upPseudoCost);
     
    71377460        downPseudoCost = CoinMax(downPseudoCost,0.1*down[iColumn]);
    71387461        obj1->setDownDynamicPseudoCost(downPseudoCost);
    7139         if (downPseudoCost>saveDown&&!numberNodes_)
     7462        if (downPseudoCost>saveDown&&!numberNodes_&&handler_->logLevel()>1)
    71407463          printf("For %d down went from %g to %g\n",
    71417464                 iColumn,saveDown,downPseudoCost);
     
    78268149      double integerTolerance = getIntegerTolerance() ;
    78278150#endif
     8151#ifdef COIN_DEVELOP
     8152      const double * dj = solver_->getReducedCost();
     8153      const double * colLower = saveSolver->getColLower();
     8154      const double * colUpper = saveSolver->getColUpper();
     8155      int nAtLbNatural=0;
     8156      int nAtUbNatural=0;
     8157      int nAtLbNaturalZero=0;
     8158      int nAtUbNaturalZero=0;
     8159      int nAtLbFixed=0;
     8160      int nAtUbFixed=0;
     8161      int nAtOther=0;
     8162      int nAtOtherNatural=0;
     8163      int nNotNeeded=0;
     8164#endif
    78288165      for (iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
    78298166        double value = solution[iColumn] ;
    78308167        value = CoinMax(value, saveLower[iColumn]) ;
    78318168        value = CoinMin(value, saveUpper[iColumn]) ;
    7832         if (solver_->isInteger(iColumn))
     8169        if (solver_->isInteger(iColumn)) {
    78338170          assert(fabs(value-solution[iColumn]) <= integerTolerance) ;
     8171#ifdef COIN_DEVELOP
     8172          double value2 = floor(value+0.5);
     8173          if (dj[iColumn]<-1.0e-6) {
     8174            // negative dj
     8175            //assert (value2==colUpper[iColumn]);
     8176            if (saveUpper[iColumn]==colUpper[iColumn]) {
     8177              nAtUbNatural++;
     8178              if (saveLower[iColumn]!=colLower[iColumn])
     8179                nNotNeeded++;
     8180            } else if (saveLower[iColumn]==colUpper[iColumn]) {
     8181              nAtLbFixed++;
     8182            } else {
     8183              nAtOther++;
     8184              if (saveLower[iColumn]!=colLower[iColumn]&&
     8185                  saveUpper[iColumn]!=colUpper[iColumn])
     8186                nNotNeeded++;
     8187            }
     8188          } else if (dj[iColumn]>1.0e-6) {
     8189            // positive dj
     8190            //assert (value2==colLower[iColumn]);
     8191            if (saveLower[iColumn]==colLower[iColumn]) {
     8192              nAtLbNatural++;
     8193              if (saveUpper[iColumn]!=colUpper[iColumn])
     8194                nNotNeeded++;
     8195            } else if (saveUpper[iColumn]==colLower[iColumn]) {
     8196              nAtUbFixed++;
     8197            } else {
     8198              nAtOther++;
     8199              if (saveLower[iColumn]!=colLower[iColumn]&&
     8200                  saveUpper[iColumn]!=colUpper[iColumn])
     8201                nNotNeeded++;
     8202            }
     8203          } else {
     8204            // zero dj
     8205            if (value2==saveUpper[iColumn]) {
     8206              nAtUbNaturalZero++;
     8207              if (saveLower[iColumn]!=colLower[iColumn])
     8208                nNotNeeded++;
     8209            } else if (value2==saveLower[iColumn]) {
     8210              nAtLbNaturalZero++;
     8211            } else {
     8212              nAtOtherNatural++;
     8213              if (saveLower[iColumn]!=colLower[iColumn]&&
     8214                  saveUpper[iColumn]!=colUpper[iColumn])
     8215                nNotNeeded++;
     8216            }
     8217          }
     8218#endif
     8219        }
    78348220        solution[iColumn] = value ;
    78358221      }
     8222#ifdef COIN_DEVELOP
     8223      printf("nAtLbNat %d,nAtUbNat %d,nAtLbNatZero %d,nAtUbNatZero %d,nAtLbFixed %d,nAtUbFixed %d,nAtOther %d,nAtOtherNat %d, useless %d\n",
     8224             nAtLbNatural,
     8225             nAtUbNatural,
     8226             nAtLbNaturalZero,
     8227             nAtUbNaturalZero,
     8228             nAtLbFixed,
     8229             nAtUbFixed,
     8230             nAtOther,
     8231             nAtOtherNatural,nNotNeeded);
     8232      //if (currentNode_)
     8233      //printf(" SOL at depth %d\n",currentNode_->depth());
     8234      //else
     8235      //printf(" SOL at unknown depth\n");
     8236#endif
    78368237      if ((specialOptions_&16)==0) {
    78378238        const double * rowLower = solver_->getRowLower() ;
     
    1005310454      newNode->initializeInfo() ;
    1005410455      if (cuts.sizeRowCuts()) {
     10456#ifndef CBC_DETERMINISTIC_THREAD
    1005510457        lockThread();
     10458#endif
    1005610459        newNode->nodeInfo()->addCuts(cuts,newNode->numberBranches(),
    1005710460                                     whichGenerator_) ;
     10461#ifndef CBC_DETERMINISTIC_THREAD
    1005810462        unlockThread();
     10463#endif
    1005910464      }
    1006010465    }
     
    1064811053    return 0;
    1064911054  }
    10650 #endif
     11055#endif 
    1065111056#if NEW_UPDATE_OBJECT==0
    1065211057  // Save clone in branching decision
     
    1068511090  double * lowerBefore = new double [numberColumns] ;
    1068611091  double * upperBefore = new double [numberColumns] ;
     11092#ifndef CBC_DETERMINISTIC_THREAD
    1068711093  newNode = NULL ;
     11094#else
     11095  newNode = new CbcNode();
     11096  //printf("CbcNode %x newNode\n",newNode);
     11097#endif
    1068811098  bool feasible=true;
    1068911099  CoinWarmStartBasis *lastws = new CoinWarmStartBasis();
     11100#ifndef CBC_DETERMINISTIC_THREAD
    1069011101  lockThread();
     11102#endif
    1069111103  // point to genuine ones
    1069211104  //int save1 = maximumNumberCuts_;
    10693   int save2 = maximumDepth_;
    1069411105  //maximumNumberCuts_ = baseModel->maximumNumberCuts_;
    1069511106  //addedCuts_ = baseModel->addedCuts_;
     11107#ifndef CBC_DETERMINISTIC_THREAD
    1069611108  maximumDepth_ = baseModel->maximumDepth_;
    1069711109  walkback_ = baseModel->walkback_;
     11110#endif
     11111#ifndef CBC_DETERMINISTIC_THREAD
     11112  int save2 = maximumDepth_;
     11113#endif
    1069811114  int retCode =addCuts(node,lastws,numberFixedNow_>numberFixedAtRoot_);
    1069911115  //if (save1<maximumNumberCuts_) {
     
    1070211118    //baseModel->addedCuts_ = addedCuts_;
    1070311119  //}
     11120#ifndef CBC_DETERMINISTIC_THREAD
    1070411121  if (save2<maximumDepth_) {
    1070511122    // increased
     
    1070711124    baseModel->walkback_ = walkback_;
    1070811125  }
    10709   unlockThread();
     11126#endif
    1071011127  int branchesLeft=0;
    1071111128  if (!retCode) {
     11129#ifndef CBC_DETERMINISTIC_THREAD
     11130    unlockThread();
     11131#endif
    1071211132    int i ;
    1071311133    const double * lower = getColLower() ;
     
    1072111141      solverCharacteristics_->setBeforeUpper(upperBefore);
    1072211142    }
     11143#ifndef CBC_DETERMINISTIC_THREAD
    1072311144    lockThread();
     11145#endif
     11146    assert (node->objectiveValue()<1.0e200);
    1072411147    if (messageHandler()->logLevel()>2)
    1072511148      node->modifiableBranchingObject()->print();
     
    1073311156      branch->setModel(this);
    1073411157      branchesLeft = node->branch(NULL); // old way
     11158#ifndef CBC_DETERMINISTIC_THREAD
    1073511159      branch->setModel(baseModel);
    10736     }
     11160#endif
     11161    }
     11162    assert (branchesLeft==node->nodeInfo()->numberBranchesLeft());
     11163#ifndef CBC_DETERMINISTIC_THREAD
    1073711164    if (mutex_) {
    1073811165      assert (node->nodeInfo());
    1073911166      node->nodeInfo()->increment() ;
    1074011167    }
     11168#endif
     11169#ifndef CBC_DETERMINISTIC_THREAD
    1074111170    unlockThread();
     11171#endif
    1074211172    if ((specialOptions_&1)!=0) {
    1074311173      /*
     
    1084611276    bool checkingNode=false;
    1084711277    if (feasible) {
    10848       newNode = new CbcNode ;
     11278#if 0
     11279      // Far too clever
     11280      if (numberThreads_==-10&&node->numberBranches()==2) {
     11281        // see if any parent branches redundant
     11282        // Look at state of "node"
     11283        CbcNodeInfo * nodeInfo = node->nodeInfo();
     11284        // See if any branched variables off bounds
     11285        const double * dj = solver_->getReducedCost();
     11286        const double * lower = solver_->getColLower();
     11287        const double * upper = solver_->getColUpper();
     11288        const double * solution = solver_->getColSolution();
     11289        double direction = solver_->getObjSense() ;
     11290        if (nodeInfo) {
     11291          bool canDelete = nodeInfo->numberBranchesLeft()>0;
     11292          //int numberBounds = nodeInfo->numberChangedBounds();
     11293          //const int * which = nodeInfo->variables();
     11294          //const double * bounds = nodeInfo->newBounds();
     11295          const OsiBranchingObject * obj = node->branchingObject();
     11296          const CbcIntegerBranchingObject * objectI = dynamic_cast<const CbcIntegerBranchingObject *> (obj);
     11297          if (objectI) {
     11298            const CbcSimpleInteger * object1 = dynamic_cast<const CbcSimpleInteger *> (objectI->object());
     11299            int iColumn1=-1;
     11300            int way1=0;
     11301            const double * bounds1=NULL;
     11302            bool zeroOne1=false;
     11303            if (object1) {
     11304              iColumn1 = object1->columnNumber();
     11305              double originalLower1 = object1->originalLowerBound();
     11306              double originalUpper1 = object1->originalUpperBound();
     11307              zeroOne1=originalLower1==0.0&&originalUpper1==1.0;
     11308              way1 = objectI->way();
     11309              assert (way1==-1||way1==1);
     11310              //way1 = -way1; // what last branch did
     11311              // work out using bounds
     11312              if (objectI->downBounds()[1]>=upper[iColumn1]&&
     11313                  objectI->downBounds()[0]<=lower[iColumn1])
     11314                way1=-1;
     11315              else
     11316                way1=1;
     11317              if (way1<0) {
     11318                // must have been down branch
     11319                bounds1 = objectI->downBounds();
     11320              } else {
     11321                // must have been up branch
     11322                bounds1 = objectI->upBounds();
     11323              }
     11324              // double check bounds
     11325              assert (bounds1[0]<=lower[iColumn1]&&bounds1[1]>=upper[iColumn1]);
     11326            }
     11327            bool inBetween=false;
     11328#ifdef CBC_PRINT2
     11329                printf("%d (way %d) with down bounds %g, %g and up bounds %g, %g current bounds %g, %g solution %g dj %g (bleft %d)\n",
     11330                       iColumn1,way1,objectI->downBounds()[0],objectI->downBounds()[1],
     11331                       objectI->upBounds()[0],objectI->upBounds()[1],
     11332                       lower[iColumn1],upper[iColumn1],solution[iColumn1],
     11333                       dj[iColumn1],nodeInfo->numberBranchesLeft());
     11334#endif
     11335            while (nodeInfo->parent()) {
     11336              nodeInfo = nodeInfo->parent();
     11337              CbcNode * nodeLook = nodeInfo->mutableOwner();
     11338              if (!nodeLook||nodeLook->objectiveValue()==0.5*COIN_DBL_MAX)
     11339                continue;
     11340              OsiBranchingObject * obj = nodeLook->modifiableBranchingObject();
     11341              CbcIntegerBranchingObject * objectI = dynamic_cast<CbcIntegerBranchingObject *> (obj);
     11342              //const OsiObject * object2a = obj->originalObject();
     11343              //assert (object2a);
     11344              const CbcSimpleInteger * object2 = dynamic_cast<const CbcSimpleInteger *> (objectI->object());
     11345              if (nodeInfo->numberBranchesLeft()&&object2) {
     11346                int iColumn2 = object2->columnNumber();
     11347                double originalLower = object2->originalLowerBound();
     11348                double originalUpper = object2->originalUpperBound();
     11349                bool zeroOne2=originalLower==0.0&&originalUpper==1.0;
     11350                zeroOne1=true; // temp
     11351                double newUpper = originalUpper;
     11352                double newLower = originalLower;
     11353                //double value = solution[iColumn2];
     11354                double djValue = dj[iColumn2]*direction;
     11355                int way = objectI->way();
     11356                assert (way==-1||way==1);
     11357                way = -way; // what last branch did
     11358#ifdef CBC_PRINT2
     11359                printf("%d (way %d) with down bounds %g, %g and up bounds %g, %g current bounds %g, %g solution %g dj %g (bleft %d)\n",
     11360                       iColumn2,way,objectI->downBounds()[0],objectI->downBounds()[1],
     11361                       objectI->upBounds()[0],objectI->upBounds()[1],
     11362                       lower[iColumn2],upper[iColumn2],solution[iColumn2],
     11363                       djValue,nodeInfo->numberBranchesLeft());
     11364#endif
     11365                /*if (objectI->downBounds()[0]==0&&objectI->downBounds()[1]==1&&
     11366                    objectI->upBounds()[0]==0&&objectI->upBounds()[1]==1)
     11367                    assert(lower[iColumn2]<upper[iColumn2]);*/
     11368                if (way<0) {
     11369                  // must have been down branch
     11370                  const double * bounds = objectI->downBounds();
     11371                  if (djValue>1.0e-3||solution[iColumn2]<upper[iColumn2]-1.0e-5) {
     11372                    if (canDelete) {
     11373                      //nRedundantDown++;
     11374#if 1
     11375                      printf("%d redundant branch down with bounds %g, %g current upper %g solution %g dj %g\n",
     11376                             iColumn2,bounds[0],bounds[1],upper[iColumn2],solution[iColumn2],djValue);
     11377#endif
     11378                      if (bounds[0]==bounds[1]||zeroOne2||(bounds[0]==lower[iColumn2]&&false)) {
     11379                      {
     11380                        // get rid of node as far as branching
     11381                        nodeLook->setObjectiveValue(0.5*COIN_DBL_MAX);
     11382                        objectI->deactivate();
     11383                      }
     11384                      previousBounds(node,nodeInfo,iColumn2,newLower,newUpper,2);
     11385                      solver_->setColUpper(iColumn2,newUpper);
     11386                      } else {
     11387                        printf("SKipping\n");
     11388                      }
     11389                    } else if (iColumn1>=0&&iColumn1!=iColumn2&&(!inBetween||true)&&zeroOne1&&zeroOne2) {
     11390#if 1
     11391                      if (true) {
     11392                        // add in bounds
     11393                        newLower=bounds1[0];
     11394                        newUpper=bounds1[1];
     11395                        printf("setting bounds of %g and %g (column %d) on other branch for column %d\n",
     11396                               newLower,newUpper,iColumn1,iColumn2);
     11397                        int infeasible = objectI->applyExtraBounds(iColumn1,newLower,newUpper,objectI->way());
     11398                        if (infeasible) {
     11399                          printf("infeasa!\n");;
     11400                          // get rid of node as far as branching
     11401                          nodeLook->setObjectiveValue(0.5*COIN_DBL_MAX);
     11402                        }
     11403                      }
     11404#endif
     11405                    }
     11406                    //break;
     11407                  } else {
     11408                    inBetween=true;
     11409                  }             
     11410                } else {
     11411                  // must have been up branch
     11412                  const double * bounds = objectI->upBounds();
     11413                  if (djValue<-1.0e-3||solution[iColumn2]>lower[iColumn2]+1.0e-5) {
     11414                    if (canDelete) {
     11415                      //nRedundantUp++;
     11416#if 1
     11417                      printf("%d redundant branch up with bounds %g, %g current lower %g solution %g dj %g\n",
     11418                             iColumn2,bounds[0],bounds[1],lower[iColumn2],solution[iColumn2],djValue);
     11419#endif
     11420                      if (bounds[0]==bounds[1]||zeroOne2||(bounds[1]==upper[iColumn2]&&false)) {
     11421                      {
     11422                        // get rid of node as far as branching
     11423                        nodeLook->setObjectiveValue(0.5*COIN_DBL_MAX);
     11424                        objectI->deactivate();
     11425                      }
     11426                      previousBounds(node,nodeInfo,iColumn2,newLower,newUpper,1);
     11427                      solver_->setColLower(iColumn2,newLower);
     11428                      } else {
     11429                        printf("SKipping\n");
     11430                      }
     11431                    } else if (iColumn1>=0&&iColumn1!=iColumn2&&(!inBetween||true)&&zeroOne1&&zeroOne2) {
     11432#if 1
     11433                      // add in bounds
     11434                      newLower=bounds1[0];
     11435                      newUpper=bounds1[1];
     11436                      printf("setting bounds of %g and %g (column %d) on other branch for column %d\n",
     11437                             newLower,newUpper,iColumn1,iColumn2);
     11438                      int infeasible = objectI->applyExtraBounds(iColumn1,newLower,newUpper,objectI->way());
     11439                      if (infeasible) {
     11440                        printf("infeasb!\n");;
     11441                        // get rid of node as far as branching
     11442                        nodeLook->setObjectiveValue(0.5*COIN_DBL_MAX);
     11443                      }
     11444#endif
     11445                    }
     11446                    // break;
     11447                  } else {
     11448                    inBetween=true;
     11449                  }
     11450                }
     11451              } else {
     11452                // odd
     11453                break;
     11454              }
     11455            }
     11456          }
     11457        }
     11458      }
     11459#endif
     11460#ifndef CBC_DETERMINISTIC_THREAD
     11461      newNode = new CbcNode() ;
     11462#endif
    1084911463      // Set objective value (not so obvious if NLP etc)
    1085011464      setObjectiveValue(newNode,node);
    1085111465      int anyAction =-1 ;
    1085211466      bool resolved = false ;
    10853       if (newNode->objectiveValue() >= getCutoff())
     11467      if (newNode->objectiveValue() >= getCutoff()) {
    1085411468        anyAction=-2;
    10855       // only allow at most a few passes
    10856       int numberPassesLeft=5;
    10857       checkingNode=true;
    10858       OsiSolverBranch * branches=NULL;
    10859       // point to useful information
    10860       anyAction = chooseBranch(newNode, numberPassesLeft,node, cuts,resolved,
    10861                                lastws, lowerBefore, upperBefore, branches);
     11469      } else {// only allow at most a few passes
     11470        int numberPassesLeft=5;
     11471        checkingNode=true;
     11472        OsiSolverBranch * branches=NULL;
     11473        // point to useful information
     11474        anyAction = chooseBranch(newNode, numberPassesLeft,node, cuts,resolved,
     11475                                 lastws, lowerBefore, upperBefore, branches);
     11476      }
    1086211477      /*
    1086311478        If we end up infeasible, we can delete the new node immediately. Since this
     
    1086611481        increment the reference count in the current (parent) nodeInfo.
    1086711482      */
     11483#ifndef CBC_DETERMINISTIC_THREAD
    1086811484      lockThread();
     11485#endif
    1086911486      if (anyAction == -2) {
     11487#ifndef CBC_DETERMINISTIC_THREAD
    1087011488        if (mutex_) {
    1087111489          assert (node->nodeInfo());
     
    1087811496        }
    1087911497        newNode = NULL ;
     11498#else
     11499        //assert (newNode->active());
     11500        newNode->setActive(false);
     11501#endif
    1088011502        // say strong doing well
    1088111503        if (checkingNode)
     
    1089211514      } else {
    1089311515        assert (node->nodeInfo());
     11516#ifndef CBC_DETERMINISTIC_THREAD
    1089411517        node->nodeInfo()->increment() ;
     11518#endif
    1089511519        if ((numberNodes_%20)==0) {
    1089611520          // say strong not doing as well
     
    1089811522        }
    1089911523      }
     11524#ifndef CBC_DETERMINISTIC_THREAD
    1090011525      unlockThread();
     11526#endif
    1090111527    }
    1090211528    /*
     
    1091611542      eventHappened_=true; // exit
    1091711543    }
     11544#ifndef CBC_DETERMINISTIC_THREAD
    1091811545    assert (!newNode || newNode->objectiveValue() <= getCutoff()) ;
     11546#else
     11547    assert (!newNode->active() || newNode->objectiveValue() <= getCutoff()) ;
     11548#endif
    1091911549    if (statistics_) {
    1092011550      assert (numberNodes2_);
    1092111551      assert (statistics_[numberNodes2_-1]);
    1092211552      assert (statistics_[numberNodes2_-1]->node()==numberNodes2_-1);
    10923       if (newNode)
     11553      if (newNode&&newNode->active())
    1092411554        statistics_[numberNodes2_-1]->updateInfeasibility(newNode->numberUnsatisfied());
    1092511555      else
    1092611556        statistics_[numberNodes2_-1]->sayInfeasible();
    1092711557    }
     11558#ifndef CBC_DETERMINISTIC_THREAD
    1092811559    lockThread();
     11560#endif
    1092911561#if NEW_UPDATE_OBJECT>1
    10930       if (numberUpdateItems_&&!numberThreads_) {
     11562#ifndef CBC_DETERMINISTIC_THREAD
     11563    if (!numberThreads_) {
     11564#endif
     11565      if (numberUpdateItems_) {
    1093111566        for (i=0;i<numberUpdateItems_;i++) {
    1093211567          CbcObjectUpdateData * update = updateItems_+i;
    1093311568          CbcObject * object = dynamic_cast<CbcObject *> (update->object_);
     11569#ifndef NDEBUG
     11570          bool found=false;
     11571          for (int j=0;j<numberObjects_;j++) {
     11572            if (update->object_== object_[j]) {
     11573              found=true;
     11574              break;
     11575            }
     11576          }
     11577          assert (found);
     11578#endif
     11579          //if (object)
     11580          //assert (object==object_[update->objectNumber_]);
    1093411581          if (object)
    1093511582            object->updateInformation(*update);
     
    1093711584        numberUpdateItems_=0;
    1093811585      }
    10939 #endif
    10940     if (newNode) {
    10941       if (newNode->branchingObject() == NULL&&solverCharacteristics_->solverType()==4) {
    10942         // need to check if any cuts would do anything
    10943         OsiCuts theseCuts;
    10944         // reset probing info
    10945         //if (probingInfo_)
    10946         //probingInfo_->initializeFixing(solver_);
    10947         for (int i = 0;i<numberCutGenerators_;i++) {
    10948           bool generate = generator_[i]->normal();
    10949           // skip if not optimal and should be (maybe a cut generator has fixed variables)
    10950           if (generator_[i]->needsOptimalBasis()&&!solver_->basisIsAvailable())
    10951             generate=false;
    10952           if (!generator_[i]->mustCallAgain())
    10953             generate=false; // only special cuts
    10954           if (generate) {
    10955             generator_[i]->generateCuts(theseCuts,true,solver_,NULL) ;
    10956             int numberRowCutsAfter = theseCuts.sizeRowCuts() ;
    10957             if (numberRowCutsAfter) {
    10958               // need dummy branch
    10959               newNode->setBranchingObject(new CbcDummyBranchingObject(this));
    10960               newNode->nodeInfo()->initializeInfo(1);
    10961               break;
     11586#ifndef CBC_DETERMINISTIC_THREAD
     11587    }
     11588#endif
     11589#endif
     11590      if (newNode&&newNode->active()) {
     11591        if (newNode->branchingObject() == NULL&&solverCharacteristics_->solverType()==4) {
     11592          // need to check if any cuts would do anything
     11593          OsiCuts theseCuts;
     11594          // reset probing info
     11595          //if (probingInfo_)
     11596          //probingInfo_->initializeFixing(solver_);
     11597          for (int i = 0;i<numberCutGenerators_;i++) {
     11598            bool generate = generator_[i]->normal();
     11599            // skip if not optimal and should be (maybe a cut generator has fixed variables)
     11600            if (generator_[i]->needsOptimalBasis()&&!solver_->basisIsAvailable())
     11601              generate=false;
     11602            if (!generator_[i]->mustCallAgain())
     11603              generate=false; // only special cuts
     11604            if (generate) {
     11605              generator_[i]->generateCuts(theseCuts,true,solver_,NULL) ;
     11606              int numberRowCutsAfter = theseCuts.sizeRowCuts() ;
     11607              if (numberRowCutsAfter) {
     11608                // need dummy branch
     11609                newNode->setBranchingObject(new CbcDummyBranchingObject(this));
     11610                newNode->nodeInfo()->initializeInfo(1);
     11611                break;
     11612              }
    1096211613            }
    1096311614          }
    1096411615        }
    10965       }
    10966       if (newNode->branchingObject()) {
    10967         handler_->message(CBC_BRANCH,messages_)
    10968           << numberNodes_<< newNode->objectiveValue()
    10969           << newNode->numberUnsatisfied()<< newNode->depth()
    10970           << CoinMessageEol ;
    10971         // Increment cut counts (taking off current)
    10972         int numberLeft = newNode->numberBranches() ;
    10973         for (i = 0;i < currentNumberCuts_;i++) {
    10974           if (addedCuts_[i]) {
     11616        if (newNode->branchingObject()) {
     11617          handler_->message(CBC_BRANCH,messages_)
     11618            << numberNodes_<< newNode->objectiveValue()
     11619            << newNode->numberUnsatisfied()<< newNode->depth()
     11620            << CoinMessageEol ;
     11621          // Increment cut counts (taking off current)
     11622          int numberLeft = newNode->numberBranches() ;
     11623          for (i = 0;i < currentNumberCuts_;i++) {
     11624            if (addedCuts_[i]) {
    1097511625#               ifdef CHECK_CUT_COUNTS
    10976             printf("Count on cut %x increased by %d\n",addedCuts_[i],
    10977                    numberLeft-1) ;
     11626              printf("Count on cut %x increased by %d\n",addedCuts_[i],
     11627                     numberLeft-1) ;
    1097811628#               endif
    10979             addedCuts_[i]->increment(numberLeft-1) ;
     11629              addedCuts_[i]->increment(numberLeft-1) ;
     11630            }
    1098011631          }
    10981         }
    10982         unlockThread();
    10983 
    10984         double estValue = newNode->guessedObjectiveValue() ;
    10985         int found = -1 ;
    10986         double * newSolution = new double [numberColumns] ;
    10987         double heurValue = getCutoff() ;
    10988         int iHeur ;
    10989         for (iHeur = 0 ; iHeur < numberHeuristics_ ; iHeur++) {
    10990           double saveValue = heurValue ;
    10991           int ifSol = heuristic_[iHeur]->solution(heurValue,newSolution) ;
    10992           if (ifSol > 0) {
    10993             // new solution found
    10994             found = iHeur ;
    10995             lockThread();
    10996             baseModel->incrementUsed(newSolution);
    10997             unlockThread();
    10998           } else if (ifSol < 0) { // just returning an estimate
    10999             estValue = CoinMin(heurValue,estValue) ;
    11000             heurValue = saveValue ;
     11632#ifndef CBC_DETERMINISTIC_THREAD
     11633          unlockThread();
     11634#endif
     11635         
     11636          double estValue = newNode->guessedObjectiveValue() ;
     11637          int found = -1 ;
     11638          double * newSolution = new double [numberColumns] ;
     11639          double heurValue = getCutoff() ;
     11640          int iHeur ;
     11641          for (iHeur = 0 ; iHeur < numberHeuristics_ ; iHeur++) {
     11642            double saveValue = heurValue ;
     11643            int ifSol = heuristic_[iHeur]->solution(heurValue,newSolution) ;
     11644            if (ifSol > 0) {
     11645              // new solution found
     11646              found = iHeur ;
     11647#ifndef CBC_DETERMINISTIC_THREAD
     11648              lockThread();
     11649              baseModel->incrementUsed(newSolution);
     11650              unlockThread();
     11651#endif
     11652            } else if (ifSol < 0)       { // just returning an estimate
     11653              estValue = CoinMin(heurValue,estValue) ;
     11654              heurValue = saveValue ;
     11655            }
    1100111656          }
    11002         }
    11003         if (found >= 0) {
    11004           lastHeuristic_ = heuristic_[found];
    11005           setBestSolution(CBC_ROUNDING,heurValue,newSolution) ;
    11006           foundSolution=1;
    11007         }
    11008         delete [] newSolution ;
    11009         newNode->setGuessedObjectiveValue(estValue) ;
    11010         lockThread();
     11657          if (found >= 0) {
     11658            lastHeuristic_ = heuristic_[found];
     11659            setBestSolution(CBC_ROUNDING,heurValue,newSolution) ;
     11660            foundSolution=1;
     11661          }
     11662          delete [] newSolution ;
     11663          newNode->setGuessedObjectiveValue(estValue) ;
     11664#ifndef CBC_DETERMINISTIC_THREAD
     11665          lockThread();
     11666#endif
     11667#ifndef CBC_DETERMINISTIC_THREAD
    1101111668#define PUSH_LATER
    1101211669#ifdef PUSH_LATER
     11670          if (!mutex_) // only if serial
     11671#endif
     11672            tree_->push(newNode) ;
     11673#endif
     11674          if (statistics_) {
     11675            if (numberNodes2_==maximumStatistics_) {
     11676              maximumStatistics_ = 2*maximumStatistics_;
     11677              CbcStatistics ** temp = new CbcStatistics * [maximumStatistics_];
     11678              memset(temp,0,maximumStatistics_*sizeof(CbcStatistics *));
     11679              memcpy(temp,statistics_,numberNodes2_*sizeof(CbcStatistics *));
     11680              delete [] statistics_;
     11681              statistics_=temp;
     11682            }
     11683            assert (!statistics_[numberNodes2_]);
     11684            statistics_[numberNodes2_]=new CbcStatistics(newNode);
     11685          }
     11686          numberNodes2_++;
     11687#           ifdef CHECK_NODE
     11688          printf("Node %x pushed on tree c\n",newNode) ;
     11689#           endif
     11690        } else {
     11691          if(solverCharacteristics_ && //we may be in a non standard bab
     11692             solverCharacteristics_->solutionAddsCuts()// we are in some kind of OA based bab.
     11693             ) {
     11694           
     11695            std::cerr<<"You should never get here"<<std::endl;
     11696            throw CoinError("Nodes should not be fathomed on integer infeasibility in this setting",
     11697                            "branchAndBound","CbcModel") ;
     11698          }
     11699          for (i = 0 ; i < currentNumberCuts_ ; i++) {
     11700            if (addedCuts_[i]) {
     11701              if (!addedCuts_[i]->decrement(1)) {
     11702                delete addedCuts_[i] ;
     11703                addedCuts_[i]=NULL;
     11704              }
     11705            }
     11706          }
     11707          double objectiveValue = newNode->objectiveValue();
     11708          lastHeuristic_ = NULL;
     11709          // Just possible solver did not know about a solution from another thread!
     11710          if (objectiveValue<getCutoff()) {
     11711            incrementUsed(solver_->getColSolution());
     11712            setBestSolution(CBC_SOLUTION,objectiveValue,
     11713                            solver_->getColSolution()) ;
     11714            foundSolution=1;
     11715          }
     11716          //assert(nodeInfo->numberPointingToThis() <= 2) ;
     11717#ifndef CBC_DETERMINISTIC_THREAD
     11718          // avoid accidental pruning, if newNode was final branch arm
     11719          node->nodeInfo()->increment();
     11720          delete newNode ;
     11721          newNode=NULL;
     11722          node->nodeInfo()->decrement() ;
     11723#else
     11724          newNode->setActive(false);
     11725          printf("at 11370\n");
     11726#endif
     11727        }
     11728      }
     11729      if (branchesLeft) {
     11730        // set nodenumber correctly
     11731        if (node->nodeInfo())
     11732          node->nodeInfo()->setNodeNumber(numberNodes2_);
     11733#ifndef CBC_DETERMINISTIC_THREAD
     11734#ifdef PUSH_LATER
    1101311735        if (!mutex_) // only if serial
    1101411736#endif
    11015         tree_->push(newNode) ;
     11737          tree_->push(node) ;
     11738#endif
    1101611739        if (statistics_) {
    1101711740          if (numberNodes2_==maximumStatistics_) {
     
    1102411747          }
    1102511748          assert (!statistics_[numberNodes2_]);
    11026           statistics_[numberNodes2_]=new CbcStatistics(newNode);
     11749          statistics_[numberNodes2_]=new CbcStatistics(node);
    1102711750        }
    1102811751        numberNodes2_++;
    11029 #           ifdef CHECK_NODE
    11030         printf("Node %x pushed on tree c\n",newNode) ;
    11031 #           endif
    11032       } else {
    11033         if(solverCharacteristics_ && //we may be in a non standard bab
    11034            solverCharacteristics_->solutionAddsCuts()// we are in some kind of OA based bab.
    11035            ) {
    11036          
    11037           std::cerr<<"You should never get here"<<std::endl;
    11038           throw CoinError("Nodes should not be fathomed on integer infeasibility in this setting",
    11039                           "branchAndBound","CbcModel") ;
     11752        //nodeOnTree=true; // back on tree
     11753        //deleteNode = false ;
     11754#       ifdef CHECK_NODE
     11755        printf("Node %x pushed back on tree - %d left, %d count\n",node,
     11756               node->nodeInfo()->numberBranchesLeft(),
     11757               node->nodeInfo()->numberPointingToThis()) ;
     11758#       endif
     11759#ifndef CBC_DETERMINISTIC_THREAD
     11760        if (mutex_) {
     11761          assert (node->nodeInfo());
     11762          node->nodeInfo()->decrement() ;
    1104011763        }
    11041         for (i = 0 ; i < currentNumberCuts_ ; i++) {
    11042           if (addedCuts_[i]) {
    11043             if (!addedCuts_[i]->decrement(1)) {
    11044               delete addedCuts_[i] ;
    11045               addedCuts_[i]=NULL;
    11046             }
    11047           }
     11764#endif
     11765      } else {
     11766        /*
     11767          This node has been completely expanded and can be removed from the live
     11768          set.
     11769        */
     11770#ifndef CBC_DETERMINISTIC_THREAD
     11771        if (mutex_) {
     11772          assert (node->nodeInfo());
     11773          node->nodeInfo()->decrement() ;
    1104811774        }
    11049         double objectiveValue = newNode->objectiveValue();
    11050         lastHeuristic_ = NULL;
    11051         // Just possible solver did not know about a solution from another thread!
    11052         if (objectiveValue<getCutoff()) {
    11053           incrementUsed(solver_->getColSolution());
    11054           setBestSolution(CBC_SOLUTION,objectiveValue,
    11055                           solver_->getColSolution()) ;
    11056           foundSolution=1;
    11057         }
    11058         //assert(nodeInfo->numberPointingToThis() <= 2) ;
    11059         // avoid accidental pruning, if newNode was final branch arm
    11060         node->nodeInfo()->increment();
    11061         delete newNode ;
    11062         newNode=NULL;
    11063         node->nodeInfo()->decrement() ;
    11064       }
    11065     }
    11066     if (branchesLeft) {
    11067       // set nodenumber correctly
    11068       if (node->nodeInfo())
    11069         node->nodeInfo()->setNodeNumber(numberNodes2_);
    11070 #ifdef PUSH_LATER
    11071         if (!mutex_) // only if serial
    11072 #endif
    11073       tree_->push(node) ;
    11074       if (statistics_) {
    11075         if (numberNodes2_==maximumStatistics_) {
    11076           maximumStatistics_ = 2*maximumStatistics_;
    11077           CbcStatistics ** temp = new CbcStatistics * [maximumStatistics_];
    11078           memset(temp,0,maximumStatistics_*sizeof(CbcStatistics *));
    11079           memcpy(temp,statistics_,numberNodes2_*sizeof(CbcStatistics *));
    11080           delete [] statistics_;
    11081           statistics_=temp;
    11082         }
    11083         assert (!statistics_[numberNodes2_]);
    11084         statistics_[numberNodes2_]=new CbcStatistics(node);
    11085       }
    11086       numberNodes2_++;
    11087       //nodeOnTree=true; // back on tree
    11088       //deleteNode = false ;
    11089 #       ifdef CHECK_NODE
    11090       printf("Node %x pushed back on tree - %d left, %d count\n",node,
    11091              node->nodeInfo()->numberBranchesLeft(),
    11092              node->nodeInfo()->numberPointingToThis()) ;
    11093 #       endif
    11094       if (mutex_) {
     11775#endif
    1109511776        assert (node->nodeInfo());
    11096         node->nodeInfo()->decrement() ;
    11097       }
    11098     } else {
    11099     /*
    11100       This node has been completely expanded and can be removed from the live
    11101       set.
    11102     */
    11103       if (mutex_) {
    11104         assert (node->nodeInfo());
    11105         node->nodeInfo()->decrement() ;
    11106       }
    11107       assert (node->nodeInfo());
    11108       if (!node->nodeInfo()->numberBranchesLeft())
    11109         node->nodeInfo()->allBranchesGone(); // can clean up
    11110       delete node ;
    11111       node=NULL;
    11112     }
    11113     unlockThread();
     11777#ifndef CBC_DETERMINISTIC_THREAD
     11778        if (!node->nodeInfo()->numberBranchesLeft())
     11779          node->nodeInfo()->allBranchesGone(); // can clean up
     11780        delete node ;
     11781        node=NULL;
     11782#else
     11783        node->setActive(false);
     11784#endif
     11785      }
     11786#ifndef CBC_DETERMINISTIC_THREAD
     11787      unlockThread();
     11788#endif
    1111411789  } else {
    1111511790    // add cuts found to be infeasible (on bound)!
    11116     printf("found to be infeas! - branches left %d\n",node->nodeInfo()->numberBranchesLeft());
     11791    printf("found to be infeas! - branches left %d - cutoff %g\n",node->nodeInfo()->numberBranchesLeft(),
     11792           getCutoff());
     11793    node->print();
    1111711794    //abort();
    1111811795    assert (node->nodeInfo());
     11796#ifndef CBC_DETERMINISTIC_THREAD
    1111911797    if (!node->nodeInfo()->numberBranchesLeft())
    1112011798      node->nodeInfo()->allBranchesGone(); // can clean up
    1112111799    delete node;
    1112211800    node=NULL;
     11801#else
     11802    node->setActive(false);
     11803#endif
    1112311804  }
    1112411805  /*
     
    1114211823  if (bestObjective > bestObjective_)
    1114311824    foundSolution=2;
     11825#ifndef CBC_DETERMINISTIC_THREAD
    1114411826  if (foundSolution) {
    1114511827    lockThread();
     
    1116111843    unlockThread();
    1116211844  }
     11845#endif
    1116311846  return foundSolution;
    1116411847}
     
    1116811851CbcModel::addUpdateInformation(const CbcObjectUpdateData & data)
    1116911852{
     11853  CbcObject * object = dynamic_cast<CbcObject *> (data.object_);
     11854#if 0
     11855  bool found=false;
     11856  for (int j=0;j<numberObjects_;j++) {
     11857    if (object== object_[j]) {
     11858      found=true;
     11859      if (j!=data.objectNumber_) {
     11860        printf("bad number\n");
     11861      }
     11862      break;
     11863    }
     11864  }
     11865  assert (found);
     11866#endif
    1117011867  if (numberUpdateItems_==maximumNumberUpdateItems_) {
    1117111868    maximumNumberUpdateItems_ += 10;
     
    1117911876}
    1118011877#endif
     11878// Split up nodes - returns number of CbcNodeInfo's affected
     11879int
     11880CbcModel::splitModel(int numberModels, CbcModel ** model,
     11881                     int numberNodes)
     11882{
     11883  int iModel;
     11884  int i;
     11885  for (iModel=0;iModel<numberModels;iModel++) {
     11886    CbcModel * otherModel = model[iModel];
     11887    otherModel->moveToModel(this,10);
     11888    assert (!otherModel->tree()->size());
     11889    otherModel->tree()->resetNodeNumbers();
     11890    otherModel->bestPossibleObjective_ = bestPossibleObjective_;
     11891    otherModel->sumChangeObjective1_ = sumChangeObjective1_;
     11892    otherModel->sumChangeObjective2_ = sumChangeObjective2_;
     11893    int numberColumns = solver_->getNumCols();
     11894    if (otherModel->bestSolution_) {
     11895      assert (bestSolution_);
     11896      memcpy(otherModel->bestSolution_,bestSolution_,numberColumns*sizeof(double));
     11897    } else if (bestSolution_) {
     11898      otherModel->bestSolution_ = CoinCopyOfArray(bestSolution_,numberColumns);
     11899    }
     11900    otherModel->globalCuts_=globalCuts_;
     11901    otherModel->numberSolutions_ = numberSolutions_;
     11902    otherModel->numberHeuristicSolutions_ = numberHeuristicSolutions_;
     11903    otherModel->numberNodes_ = numberNodes_;
     11904    otherModel->numberIterations_ = numberIterations_;
     11905#if 0
     11906    if (maximumNumberCuts_>otherModel->maximumNumberCuts_) {
     11907      otherModel->maximumNumberCuts_ = maximumNumberCuts_;
     11908      delete [] otherModel->addedCuts_;
     11909      otherModel->addedCuts_ = new CbcCountRowCut * [maximumNumberCuts_];
     11910    }
     11911    if (maximumDepth_>otherModel->maximumDepth_) {
     11912      otherModel->maximumDepth_ = maximumDepth_;
     11913      delete [] otherModel->walkback_;
     11914      otherModel->walkback_ = new CbcNodeInfo * [maximumDepth_];
     11915    }
     11916#endif
     11917    otherModel->currentNumberCuts_ = currentNumberCuts_;
     11918    if (otherModel->usedInSolution_) {
     11919      assert (usedInSolution_);
     11920      memcpy(otherModel->usedInSolution_,usedInSolution_,numberColumns*sizeof(int));
     11921    } else if (usedInSolution_) {
     11922      otherModel->usedInSolution_ = CoinCopyOfArray(usedInSolution_,numberColumns);
     11923    }
     11924    /// ??? tree_;
     11925    // Need flag (stopNumberIterations_>0?) which says don't update cut etc counts
     11926    for (i=0;i<numberObjects_;i++) {
     11927      otherModel->object_[i]->updateBefore(object_[i]);
     11928    }
     11929    otherModel->maximumDepthActual_ = maximumDepthActual_;
     11930    // Real cuts are in node info
     11931    otherModel->numberOldActiveCuts_ = numberOldActiveCuts_;
     11932    otherModel->numberNewCuts_ = numberNewCuts_;
     11933    otherModel->numberStrongIterations_ = numberStrongIterations_;
     11934  }
     11935  double cutoff = getCutoff();
     11936  int nAffected=0;
     11937  // Pointers back to objects
     11938  int numberColumns = solver_->getNumCols();
     11939  int * back = new int[numberColumns];
     11940  for (i=0;i<numberColumns;i++)
     11941    back[i]=-1;
     11942  for (i=0;i<numberObjects_;i++) {
     11943    int iColumn = object_[i]->columnNumber();
     11944    assert (iColumn>=0);
     11945    back[iColumn]=i;
     11946  }
     11947  while (!tree_->empty()) {
     11948    for (iModel=0;iModel<numberModels;iModel++) {
     11949      if (tree_->empty())
     11950        break;
     11951      CbcModel * otherModel = model[iModel];
     11952      CbcNode * node = tree_->bestNode(cutoff) ;
     11953      CbcNodeInfo * nodeInfo = node->nodeInfo();
     11954      assert (nodeInfo);
     11955      if (!nodeInfo->marked()) {
     11956        //while (nodeInfo&&!nodeInfo->marked()) {
     11957          if (nAffected==maximumDepth_) {
     11958            maximumDepth_ *= 2;
     11959            CbcNodeInfo ** temp = new CbcNodeInfo * [maximumDepth_];
     11960            for (i=0;i<nAffected;i++)
     11961              temp[i] = walkback_[i];
     11962            delete [] walkback_;
     11963            walkback_ = temp;
     11964          }
     11965          nodeInfo->mark();
     11966          //nodeInfo->incrementCuts(1000000);
     11967          walkback_[nAffected++]=nodeInfo;
     11968          //nodeInfo = nodeInfo->parent() ;
     11969          //}
     11970      }
     11971      // Make node join otherModel
     11972      OsiBranchingObject * bobj = node->modifiableBranchingObject();
     11973      CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (bobj);
     11974      //assert (cbcobj);
     11975      if (cbcobj) {
     11976        CbcObject * object = cbcobj->object();
     11977        assert (object);
     11978        // could use variable_??
     11979        int columnNumber = object->columnNumber();
     11980        assert (columnNumber>=0);
     11981        columnNumber = back[columnNumber];
     11982        assert (columnNumber>=0);
     11983        CbcObject * objectNew = dynamic_cast<CbcObject *> (otherModel->object_[columnNumber]);
     11984        cbcobj->setOriginalObject(objectNew);
     11985      }
     11986      otherModel->tree_->push(node);
     11987    }
     11988    numberNodes--;
     11989    if (!numberNodes)
     11990      break;
     11991  }
     11992  delete [] back;
     11993  return nAffected;
     11994}
     11995// Start threads
     11996void
     11997CbcModel::startSplitModel(int numberIterations)
     11998{
     11999  abort();
     12000}
     12001// Merge models
     12002void
     12003CbcModel::mergeModels(int numberModel, CbcModel ** model,
     12004                      int numberNodes)
     12005{
     12006  abort();
     12007}
    1118112008/* Move/copy information from one model to another
    1118212009   -1 - initial setup
     
    1118412011   1 - to base model (and reset)
    1118512012   2 - add in final statistics etc (and reset so can do clean destruction)
     12013   10 - from base model (deterministic)
     12014   11 - to base model (deterministic)
    1118612015*/
    1118712016void
     
    1128412113      generator->incrementTimeInCutGenerator(generator2->timeInCutGenerator());
    1128512114    }
     12115#ifndef CBC_DETERMINISTIC_THREAD
    1128612116    nodeCompare_ = NULL;
     12117#endif
    1128712118    baseModel->maximumDepthActual_ = CoinMax(baseModel->maximumDepthActual_,maximumDepthActual_);
    1128812119    baseModel->numberDJFixed_ += numberDJFixed_;
     
    1129112122    for (i=0;i<3;i++)
    1129212123      baseModel->strongInfo_[i] += strongInfo_[i];
     12124#ifndef CBC_DETERMINISTIC_THREAD
    1129312125    walkback_ = NULL;
    1129412126    //addedCuts_ = NULL;
    1129512127    tree_ = NULL;
     12128#else
     12129    //threadStruct * stuff = (threadStruct *) mutex_;
     12130    //assert (stuff);
     12131    //delete [] stuff->nodeCount;
     12132#endif
    1129612133    eventHandler_=NULL;
    1129712134    delete solverCharacteristics_;
    1129812135    solverCharacteristics_ = NULL;
     12136    //#ifndef CBC_DETERMINISTIC_THREAD
    1129912137    bool newMethod = (baseModel->branchingMethod_&&baseModel->branchingMethod_->chooseMethod());
    1130012138    if (newMethod) {
     
    1130312141      object_=NULL;
    1130412142    }
    11305   } else {
     12143    //#endif
     12144  } else if (mode==-1) {
    1130612145    delete eventHandler_;
    1130712146    eventHandler_ = baseModel->eventHandler_;
    1130812147    assert (!statistics_);
     12148    assert(baseModel->solverCharacteristics_);
     12149    solverCharacteristics_ = new OsiBabSolver (*baseModel->solverCharacteristics_);
     12150    solverCharacteristics_->setSolver(solver_);
     12151    setMaximumNodes(INT_MAX);
     12152#ifndef CBC_DETERMINISTIC_THREAD
    1130912153    delete [] walkback_;
    1131012154    //delete [] addedCuts_;
    1131112155    walkback_ = NULL;
    1131212156    //addedCuts_ = NULL;
    11313     assert(baseModel->solverCharacteristics_);
    11314     solverCharacteristics_ = new OsiBabSolver (*baseModel->solverCharacteristics_);
    11315     solverCharacteristics_->setSolver(solver_);
    1131612157    delete tree_;
    1131712158    tree_ = NULL;
    1131812159    delete nodeCompare_;
    1131912160    nodeCompare_ = NULL;
     12161#else
     12162    delete tree_;
     12163    tree_ = new CbcTree();
     12164    tree_->setComparison(*nodeCompare_) ;
     12165#endif
    1132012166    continuousSolver_ = baseModel->continuousSolver_->clone();
    1132112167    bool newMethod = (baseModel->branchingMethod_&&baseModel->branchingMethod_->chooseMethod());
     
    1132412170      // We may update an object in wrong order - shouldn't matter?
    1132512171      numberObjects_=baseModel->numberObjects_;
     12172#ifndef CBC_DETERMINISTIC_THREAD
    1132612173      object_=baseModel->object_;
     12174#else
     12175      printf("*****WARNING - fix testosi option\n");
     12176      object_=baseModel->object_;
     12177#endif
    1132712178    }
    1132812179    mutex_ = baseModel->mutex_;
     
    1133912190      generator_[i]->setModel(this);
    1134012191    }
     12192  } else if (mode==10) {
     12193    setCutoff(baseModel->getCutoff());
     12194    bestObjective_ = baseModel->bestObjective_;
     12195    assert (!baseModel->globalCuts_.sizeRowCuts());
     12196    numberSolutions_ = baseModel->numberSolutions_;
     12197    assert (usedInSolution_);
     12198    assert (baseModel->usedInSolution_);
     12199    memcpy(usedInSolution_,baseModel->usedInSolution_,solver_->getNumCols()*sizeof(int));
     12200    stateOfSearch_ = baseModel->stateOfSearch_;
     12201    //numberNodes_ = baseModel->numberNodes_;
     12202    //numberIterations_ = baseModel->numberIterations_;
     12203    //numberFixedAtRoot_ = numberIterations_; // for statistics
     12204    phase_ = baseModel->phase_;
     12205    assert (!nextRowCut_);
     12206    delete nodeCompare_;
     12207    nodeCompare_ = baseModel->nodeCompare_->clone();
     12208    tree_->setComparison(*nodeCompare_) ;
     12209    assert (!subTreeModel_);
     12210    //branchingMethod_ = NULL; // need something but what
     12211    numberOldActiveCuts_ = baseModel->numberOldActiveCuts_;
     12212    cutModifier_ = NULL;
     12213    assert (!analyzeResults_);
     12214    threadStruct * stuff = (threadStruct *) mutex_;
     12215    assert (stuff);
     12216    //if (stuff)
     12217    stuff->createdNode=NULL;
     12218    // ?? searchStrategy_;
     12219    searchStrategy_=baseModel->searchStrategy_;
     12220    stuff->saveStuff[0]=searchStrategy_;
     12221    stateOfSearch_=baseModel->stateOfSearch_;
     12222    stuff->saveStuff[1]=stateOfSearch_;
     12223    OsiObject ** baseObject = baseModel->object_;
     12224    for (int iObject = 0 ; iObject < numberObjects_ ; iObject++) {
     12225      object_[iObject]->updateBefore(baseObject[iObject]);
     12226    }
     12227    //delete [] stuff->nodeCount;
     12228    //stuff->nodeCount = new int [baseModel->maximumDepth_+1];
     12229  } else if (mode==11) {
     12230#ifdef CBC_DETERMINISTIC_THREAD
     12231    // from deterministic
     12232    threadStruct * stuff = (threadStruct *) mutex_;
     12233    assert (stuff);
     12234    // Move solution etc
     12235    // might as well mark all including continuous
     12236    int numberColumns = solver_->getNumCols();
     12237    for (int i=0;i<numberColumns;i++) {
     12238      baseModel->usedInSolution_[i] += usedInSolution_[i];
     12239      //usedInSolution_[i]=0;
     12240    }
     12241    baseModel->numberSolutions_ += numberSolutions_;
     12242    if (bestObjective_ < baseModel->bestObjective_&&bestObjective_<baseModel->getCutoff()) {
     12243      baseModel->bestObjective_ = bestObjective_ ;
     12244      int numberColumns = solver_->getNumCols();
     12245      if (!baseModel->bestSolution_)
     12246        baseModel->bestSolution_ = new double[numberColumns];
     12247      CoinCopyN(bestSolution_,numberColumns,baseModel->bestSolution_);
     12248      baseModel->setCutoff(getCutoff());
     12249    }
     12250    //stateOfSearch_
     12251#if 1
     12252    if(stuff->saveStuff[0]!=searchStrategy_) {
     12253#ifdef COIN_DEVELOP
     12254      printf("changing searchStrategy from %d to %d\n",
     12255             baseModel->searchStrategy_,searchStrategy_);
     12256#endif
     12257      baseModel->searchStrategy_=searchStrategy_;
     12258    }
     12259    if(stuff->saveStuff[1]!=stateOfSearch_) {
     12260#ifdef COIN_DEVELOP
     12261      printf("changing stateOfSearch from %d to %d\n",
     12262             baseModel->stateOfSearch_,stateOfSearch_);
     12263#endif
     12264      baseModel->stateOfSearch_=stateOfSearch_;
     12265    }
     12266#endif
     12267    int i;
     12268    if (eventHappened_)
     12269      baseModel->eventHappened_=true;
     12270    baseModel->numberNodes_ += stuff->nodesThisTime;
     12271    baseModel->numberIterations_ += stuff->iterationsThisTime;
     12272    double cutoff = baseModel->getCutoff();
     12273    while (!tree_->empty()) {
     12274      CbcNode * node = tree_->bestNode(COIN_DBL_MAX) ;
     12275      if (node->objectiveValue()<cutoff)
     12276        baseModel->tree_->push(node);
     12277      else
     12278        delete node;
     12279    }
     12280    for (i=0;i<stuff->nDeleteNode;i++) {
     12281      //printf("CbcNode %x stuff delete\n",stuff->delNode[i]);
     12282      delete stuff->delNode[i];
     12283    }
     12284#endif
     12285  } else {
     12286    abort();
    1134112287  }
    1134212288}
     
    1136912315      double time2 = CoinCpuTime();
    1137012316      assert (stuff->returnCode==0);
     12317#ifndef CBC_DETERMINISTIC_THREAD
    1137112318      assert (stuff->node->nodeInfo());
    1137212319      thisModel->doOneNode(baseModel,stuff->node,stuff->createdNode);
    1137312320      stuff->returnCode=1;
     12321#else
     12322      assert (!stuff->node);
     12323      assert (!stuff->createdNode);
     12324      int numberIterations = stuff->nDeleteNode;
     12325      int nDeleteNode = 0;
     12326      int maxDeleteNode = stuff->maxDeleteNode;
     12327      CbcNode ** delNode = stuff->delNode;
     12328      int returnCode=1;
     12329      // this should be updated by heuristics strong branching etc etc
     12330      assert (numberIterations>0);
     12331      thisModel->setNumberThreads(0);
     12332      int nodesThisTime=thisModel->getNodeCount();
     12333      int iterationsThisTime=thisModel->getIterationCount();
     12334      thisModel->setStopNumberIterations(thisModel->getIterationCount()+numberIterations);
     12335      int numberColumns = thisModel->getNumCols();
     12336      int * used = CoinCopyOfArray(thisModel->usedInSolution(),numberColumns);
     12337      int numberSolutions = thisModel->getSolutionCount();
     12338      while (true) {
     12339        if (thisModel->tree()->empty()) {
     12340          returnCode=1+1;
     12341          break;
     12342        }
     12343        if (thisModel->getIterationCount()>thisModel->getStopNumberIterations()) {
     12344          // out of loop
     12345          //printf("out of loop\n");
     12346          break;
     12347        }
     12348        double cutoff = thisModel->getCutoff() ;
     12349        CbcNode *node = thisModel->tree()->bestNode(cutoff) ;
     12350        // Possible one on tree worse than cutoff
     12351        if (!node)
     12352          continue;
     12353        CbcNode * createdNode=NULL;
     12354#if 0
     12355        nXXXXXX++;
     12356        if (nXXXXXX==66)
     12357          printf("next one %d\n",nXXXXXX);
     12358        else
     12359          printf("xxxx %d\n",nXXXXXX);
     12360#endif
     12361        thisModel->doOneNode(NULL,node,createdNode);
     12362#if CBC_THREAD_DEBUG
     12363        //printf("SThread %d node %d\n",stuff->threadNumber,thisModel->getNodeCount());
     12364        //node->print();
     12365        //createdNode->print();
     12366        //printf("EThread %d node %d\n",stuff->threadNumber,thisModel->getNodeCount());
     12367#endif
     12368        assert (createdNode);
     12369        if (!createdNode->active()) {
     12370          delete createdNode;
     12371        } else {
     12372          // Say one more pointing to this **** postpone if marked
     12373          node->nodeInfo()->increment() ;
     12374          thisModel->tree()->push(createdNode) ;
     12375        }
     12376        if (node->active()) {
     12377          assert (node->nodeInfo());
     12378          if (node->nodeInfo()->numberBranchesLeft()) {
     12379            thisModel->tree()->push(node) ;
     12380          } else {
     12381            node->setActive(false);
     12382          }
     12383        } else {
     12384          if (node->nodeInfo()) {
     12385            if (!node->nodeInfo()->numberBranchesLeft())
     12386              node->nodeInfo()->allBranchesGone(); // can clean up
     12387            // So will delete underlying stuff
     12388            node->setActive(true);
     12389          }
     12390          if (nDeleteNode==maxDeleteNode) {
     12391            maxDeleteNode = (3*maxDeleteNode)/2+10;
     12392            stuff->maxDeleteNode=maxDeleteNode;
     12393            stuff->delNode = new CbcNode * [maxDeleteNode];
     12394            for (int i=0;i<nDeleteNode;i++)
     12395              stuff->delNode[i] = delNode[i];
     12396            delete [] delNode;
     12397            delNode = stuff->delNode;
     12398          }
     12399          delNode[nDeleteNode++]=node;
     12400        }
     12401      }
     12402      int * usedA = thisModel->usedInSolution();
     12403      for (int i=0;i<numberColumns;i++) {
     12404        usedA[i] -= used[i];
     12405      }
     12406      delete [] used;
     12407      thisModel->setSolutionCount(thisModel->getSolutionCount()-numberSolutions);
     12408      stuff->nodesThisTime=thisModel->getNodeCount()-nodesThisTime;
     12409      stuff->iterationsThisTime=thisModel->getIterationCount()-iterationsThisTime;
     12410      stuff->nDeleteNode=nDeleteNode;
     12411      stuff->returnCode=returnCode;
     12412      thisModel->setNumberThreads(mode);
     12413#endif
    1137412414      //printf("end node %x\n",stuff->node);
    1137512415      threadStruct * stuffMain = (threadStruct *) baseModel->mutex();
     
    1144612486/*
    1144712487  Locks a thread if parallel so that stuff like cut pool
    11448   can be updated and/or used.y
     12488  can be updated and/or used.
    1144912489*/
    1145012490void
     
    1156612606#endif
    1156712607}
     12608// Main loop
     12609int
     12610CbcModel::whileIterating(int numberIterations)
     12611{
     12612  abort();
     12613  // this should be updated by heuristics strong branching etc etc
     12614  if (numberIterations>0)
     12615   stopNumberIterations_ = numberIterations_+numberIterations;
     12616  else
     12617    stopNumberIterations_=-1;
     12618  int returnCode=0;
     12619  while (true) {
     12620    if (tree_->empty()) {
     12621      returnCode=1;
     12622      break;
     12623    }
     12624    if (stopNumberIterations_>0&&numberIterations_>stopNumberIterations_) {
     12625      // out of loop
     12626      break;
     12627    }
     12628    /*
     12629      Periodic activities: Opportunities to
     12630      + tweak the nodeCompare criteria,
     12631    */
     12632    if ((numberNodes_%1000) == 0) {
     12633      bool redoTree=nodeCompare_->every1000Nodes(this, numberNodes_) ;
     12634      // redo tree if wanted
     12635      if (redoTree)
     12636        tree_->setComparison(*nodeCompare_) ;
     12637    }
     12638   
     12639    /*
     12640      Now we come to the meat of the loop. To create the active subproblem, we'll
     12641      pop the most promising node in the live set, rebuild the subproblem it
     12642      represents, and then execute the current arm of the branch to create the
     12643      active subproblem.
     12644    */
     12645    double cutoff = getCutoff() ;
     12646    CbcNode *node = tree_->bestNode(cutoff) ;
     12647    // Possible one on tree worse than cutoff
     12648    if (!node)
     12649      continue;
     12650    CbcNode * createdNode=NULL;
     12651    doOneNode(this,node,createdNode);
     12652  }
     12653  stopNumberIterations_=-1;
     12654  return returnCode;
     12655}
     12656// Returns bounds just before where - initially original bounds - also sets bounds
     12657void CbcModel::previousBounds (CbcNode * node, CbcNodeInfo * where,int iColumn,
     12658                               double & lower, double & upper,int force)
     12659{ int i;
     12660  int nNode=0;
     12661  CbcNodeInfo * nodeInfo = node->nodeInfo();
     12662  int nWhere=-1;
     12663
     12664/*
     12665  Accumulate the path from node to the root in walkback_
     12666*/
     12667  while (nodeInfo) {
     12668    //printf("nNode = %d, nodeInfo = %x\n",nNode,nodeInfo);
     12669    walkback_[nNode++]=nodeInfo;
     12670    nodeInfo = nodeInfo->parent() ;
     12671    if (nNode==maximumDepth_) {
     12672      maximumDepth_ *= 2;
     12673      CbcNodeInfo ** temp = new CbcNodeInfo * [maximumDepth_];
     12674      for (i=0;i<nNode;i++)
     12675        temp[i] = walkback_[i];
     12676      delete [] walkback_;
     12677      walkback_ = temp;
     12678    }
     12679    if (nodeInfo==where)
     12680      nWhere = nNode;
     12681  }
     12682  assert (nWhere>=0);
     12683  nWhere = nNode-nWhere;
     12684  for (i=0;i<nWhere;i++) {
     12685    --nNode;
     12686    walkback_[nNode]->applyBounds(iColumn,lower,upper,0);
     12687  }
     12688  // correct bounds
     12689  walkback_[nNode]->applyBounds(iColumn,lower,upper,3);
     12690  CbcNode * nodeLook = walkback_[nNode]->mutableOwner();
     12691  if (nodeLook) {
     12692    OsiBranchingObject * obj = nodeLook->modifiableBranchingObject();
     12693    CbcIntegerBranchingObject * objectI = dynamic_cast<CbcIntegerBranchingObject *> (obj);
     12694    //const OsiObject * object2 = obj->orig
     12695    const CbcSimpleInteger * object2 = dynamic_cast<const CbcSimpleInteger *> (objectI->object());
     12696    assert (object2);
     12697    assert (iColumn == object2->columnNumber());
     12698    double bounds[2];
     12699    bounds[0]=lower;
     12700    bounds[1]=upper;
     12701    objectI->setDownBounds(bounds);
     12702    objectI->setUpBounds(bounds);
     12703  }
     12704  while (nNode) {
     12705    --nNode;
     12706    walkback_[nNode]->applyBounds(iColumn,lower,upper,force);
     12707    CbcNode * nodeLook = walkback_[nNode]->mutableOwner();
     12708    if (nodeLook&&0) {
     12709      const OsiBranchingObject * obj = nodeLook->branchingObject();
     12710      const CbcIntegerBranchingObject * objectI = dynamic_cast<const CbcIntegerBranchingObject *> (obj);
     12711      //const OsiObject * object2 = obj->orig
     12712      const CbcSimpleInteger * object2 = dynamic_cast<const CbcSimpleInteger *> (objectI->object());
     12713      assert (object2);
     12714      int iColumn2 = object2->columnNumber();
     12715      assert (iColumn!=iColumn2);
     12716    }
     12717  }
     12718}
  • trunk/Cbc/src/CbcModel.hpp

    r789 r838  
    282282  /// Returns true if locked
    283283  bool isLocked() const;
     284  /// Main loop (without threads but when subtrees) 1 if finished, 0 if stopped
     285#if 0
     286  int whileIterating(bool & locked, threadId, threadInfo,condition_mutex,condition_main,
     287                     timeWaiting,threadModel,threadStats,totalTime,cutoff,
     288                     eventHandler,saveCompare,lastDepth,lastUnsatisfied,createdNode);
     289#else
     290  int whileIterating(int numberIterations);
     291#endif
    284292#ifdef CBC_THREAD
    285293  /**
     
    11571165  inline void setThreadMode(int value)
    11581166  { threadMode_=value;}
     1167  /// Get number of "iterations" to stop after
     1168  inline int getStopNumberIterations() const
     1169  { return stopNumberIterations_;}
     1170  /// Set number of "iterations" to stop after
     1171  inline void setStopNumberIterations(int value)
     1172  { stopNumberIterations_=value;}
    11591173  //@}
    11601174
     
    14481462  inline void * mutex()
    14491463  { return mutex_;}
     1464  /// Split up nodes
     1465  int splitModel(int numberModels, CbcModel ** model,
     1466                  int numberNodes);
     1467  /// Start threads
     1468  void startSplitModel(int numberIterations);
     1469  /// Merge models
     1470  void mergeModels(int numberModel, CbcModel ** model,
     1471                   int numberNodes);
    14501472  //@}
    14511473  //---------------------------------------------------------------------------
     
    14811503    */
    14821504    inline void setModelOwnsSolver (bool ourSolver)
    1483     { ourSolver_ = ourSolver ; }
     1505  { ownership_ = ourSolver ? (ownership_ |0x80000000) : (ownership_ & (~0x80000000)) ; }
    14841506
    14851507    /*! \brief Get ownership of solver
     
    14881510      take responsibility for deleting it when that becomes necessary.
    14891511    */
    1490     inline bool modelOwnsSolver () { return (ourSolver_) ; }
     1512  inline bool modelOwnsSolver () { return ((ownership_&0x80000000)!=0) ; }
    14911513 
    14921514    /** Copy constructor .
     
    15041526    inline OsiSolverInterface * solver() const
    15051527    { return solver_;}
     1528
     1529    /// Returns current solver - sets new one
     1530    inline OsiSolverInterface * swapSolver(OsiSolverInterface * solver)
     1531    { OsiSolverInterface * returnSolver = solver_; solver_ = solver; return returnSolver;}
    15061532
    15071533    /// Returns solver with continuous state
     
    16181644  */
    16191645  void addCuts1(CbcNode * node, CoinWarmStartBasis *&lastws);
     1646  /** Returns bounds just before where - initially original bounds.
     1647      Also sets downstream nodes (lower if force 1, upper if 2)
     1648  */
     1649  void previousBounds (CbcNode * node, CbcNodeInfo * where,int iColumn,
     1650                       double & lower, double & upper,int force);
    16201651  /** Set objective value in a node.  This is separated out so that
    16211652     odd solvers can use.  It may look at extra information in
     
    16961727  OsiSolverInterface * solver_;
    16971728
    1698   /** Ownership of the solver object
    1699 
    1700     The convention is that CbcModel owns the null solver. Currently there
    1701     is no public method to give CbcModel a solver without giving ownership,
    1702     but the hook is here.
    1703   */
    1704   bool ourSolver_ ;
     1729  /** Ownership of objects
     1730
     1731      0x80000000 model owns solver
     1732  */
     1733  unsigned int ownership_ ;
    17051734
    17061735  /// A copy of the solver, taken at the continuous (root) node.
     
    19301959  */
    19311960  int numberPenalties_;
     1961  /// For threads - stop after this many "iterations"
     1962  int stopNumberIterations_;
    19321963  /** Scale factor to make penalties match strong.
    19331964      Should/will be computed */
  • trunk/Cbc/src/CbcNode.cpp

    r833 r838  
    5151  cuts_(NULL),
    5252  numberRows_(0),
    53   numberBranchesLeft_(0)
     53  numberBranchesLeft_(0),
     54  active_(7)
    5455{
    5556#ifdef CHECK_NODE
     
    6768  cuts_(NULL),
    6869  numberRows_(0),
    69   numberBranchesLeft_(2)
     70  numberBranchesLeft_(2),
     71  active_(7)
    7072{
    7173#ifdef CHECK_NODE
     
    8789  cuts_(NULL),
    8890  numberRows_(rhs.numberRows_),
    89   numberBranchesLeft_(rhs.numberBranchesLeft_)
     91  numberBranchesLeft_(rhs.numberBranchesLeft_),
     92  active_(rhs.active_)
    9093{
    9194#ifdef CHECK_NODE
     
    117120  cuts_(NULL),
    118121  numberRows_(0),
    119   numberBranchesLeft_(2)
     122  numberBranchesLeft_(2),
     123  active_(7)
    120124{
    121125#ifdef CHECK_NODE
     
    139143
    140144  assert(!numberPointingToThis_);
    141   // But they may be some left (max nodes?)
     145  // But there may be some left (max nodes?)
    142146  for (int i=0;i<numberCuts_;i++) {
     147    if (cuts_[i]) {
    143148#ifndef GLOBAL_CUTS_JUST_POINTERS
    144     delete cuts_[i];
     149      delete cuts_[i];
    145150#else
    146     if (cuts_[i]->globallyValidAsInteger()!=2)
    147       delete cuts_[i];
    148 #endif
     151      if (cuts_[i]->globallyValidAsInteger()!=2)
     152        delete cuts_[i];
     153#endif
     154    }
    149155  }
    150156  delete [] cuts_;
     
    184190      }
    185191    }
     192  }
     193}
     194void
     195CbcNodeInfo::incrementCuts(int change)
     196{
     197  int i;
     198  assert (change>0);
     199  // increment cut counts
     200  for (i=0;i<numberCuts_;i++) {
     201    if (cuts_[i])
     202      cuts_[i]->increment(change);
    186203  }
    187204}
     
    441458  cuts_[whichOne]=NULL;
    442459}
     460/* Deactivate node information.
     461   1 - bounds
     462   2 - cuts
     463   4 - basis!
     464*/
     465void
     466CbcNodeInfo::deactivate(int mode)
     467{
     468  active_ &= (~mode);
     469}
    443470
    444471CbcFullNodeInfo::CbcFullNodeInfo() :
     
    527554
    528555  // branch - do bounds
     556  assert (active_==7||active_==15);
    529557  int i;
    530558  solver->setColLower(lower_);
     
    547575  assert(!parent_);
    548576  return ;
     577}
     578// Just apply bounds to one variable (1=>infeasible)
     579int
     580CbcFullNodeInfo::applyBounds(int iColumn, double & lower, double & upper,int force)
     581{
     582  if ((force&&1)==0) {
     583    if (lower>lower_[iColumn])
     584      printf("%d odd lower going from %g to %g\n",iColumn,lower,lower_[iColumn]);
     585    lower = lower_[iColumn];
     586  } else {
     587    lower_[iColumn]=lower;
     588  }
     589  if ((force&&2)==0) {
     590    if (upper<upper_[iColumn])
     591      printf("%d odd upper going from %g to %g\n",iColumn,upper,upper_[iColumn]);
     592    upper = upper_[iColumn];
     593  } else {
     594    upper_[iColumn]=upper;
     595  }
     596  return (upper_[iColumn]>=lower_[iColumn]) ? 0 : 1;
    549597}
    550598
     
    649697
    650698{ OsiSolverInterface *solver = model->solver();
    651   basis->applyDiff(basisDiff_) ;
     699  if ((active_&4)!=0) {
     700    basis->applyDiff(basisDiff_) ;
     701  }
    652702
    653703  // branch - do bounds
    654704  int i;
     705  if ((active_&1)!=0) {
     706    for (i=0;i<numberChangedBounds_;i++) {
     707      int variable = variables_[i];
     708      int k = variable&0x3fffffff;
     709      if ((variable&0x80000000)==0) {
     710        // lower bound changing
     711        //#define CBC_PRINT2
     712#ifdef CBC_PRINT2
     713        if(solver->getColLower()[k]!=newBounds_[i])
     714          printf("lower change for column %d - from %g to %g\n",k,solver->getColLower()[k],newBounds_[i]);
     715#endif
     716#ifndef NDEBUG
     717        if ((variable&0x40000000)==0&&false) {
     718          double oldValue = solver->getColLower()[k];
     719          assert (newBounds_[i]>oldValue-1.0e-8);
     720          if (newBounds_[i]<oldValue+1.0e-8)
     721            printf("bad null lower change for column %d - bound %g\n",k,oldValue);
     722        }
     723#endif
     724        solver->setColLower(k,newBounds_[i]);
     725      } else {
     726        // upper bound changing
     727#ifdef CBC_PRINT2
     728        if(solver->getColUpper()[k]!=newBounds_[i])
     729          printf("upper change for column %d - from %g to %g\n",k,solver->getColUpper()[k],newBounds_[i]);
     730#endif
     731#ifndef NDEBUG
     732        if ((variable&0x40000000)==0&&false) {
     733          double oldValue = solver->getColUpper()[k];
     734          assert (newBounds_[i]<oldValue+1.0e-8);
     735          if (newBounds_[i]>oldValue-1.0e-8)
     736            printf("bad null upper change for column %d - bound %g\n",k,oldValue);
     737        }
     738#endif
     739        solver->setColUpper(k,newBounds_[i]);
     740      }
     741    }
     742  }
     743  if ((active_&2)!=0) {
     744    for (i=0;i<numberCuts_;i++) {
     745      addCuts[currentNumberCuts+i]= cuts_[i];
     746      if (cuts_[i]&&model->messageHandler()->logLevel()>4) {
     747        cuts_[i]->print();
     748      }
     749    }
     750   
     751    currentNumberCuts += numberCuts_;
     752  }
     753  return ;
     754}
     755// Just apply bounds to one variable (1=>infeasible)
     756int
     757CbcPartialNodeInfo::applyBounds(int iColumn, double & lower, double & upper,int force)
     758{
     759  // branch - do bounds
     760  int i;
     761  int found=0;
     762  double newLower = -COIN_DBL_MAX;
     763  double newUpper = COIN_DBL_MAX;
    655764  for (i=0;i<numberChangedBounds_;i++) {
    656765    int variable = variables_[i];
    657     int k = variable&0x7fffffff;
    658     if ((variable&0x80000000)==0) {
    659       // lower bound changing
    660 #ifndef NDEBUG
    661       double oldValue = solver->getColLower()[k];
    662       assert (newBounds_[i]>oldValue-1.0e-8);
    663       if (newBounds_[i]<oldValue+1.0e-8)
    664         printf("bad null lower change for column %d - bound %g\n",k,oldValue);
    665 #endif
    666       solver->setColLower(k,newBounds_[i]);
    667     } else {
    668       // upper bound changing
    669 #ifndef NDEBUG
    670       double oldValue = solver->getColUpper()[k];
    671       assert (newBounds_[i]<oldValue+1.0e-8);
    672       if (newBounds_[i]>oldValue-1.0e-8)
    673         printf("bad null upper change for column %d - bound %g\n",k,oldValue);
    674 #endif
    675       solver->setColUpper(k,newBounds_[i]);
    676     }
    677   }
    678   for (i=0;i<numberCuts_;i++) {
    679     addCuts[currentNumberCuts+i]= cuts_[i];
    680     if (cuts_[i]&&model->messageHandler()->logLevel()>4) {
    681       cuts_[i]->print();
    682     }
    683   }
    684    
    685   currentNumberCuts += numberCuts_;
    686   return ;
     766    int k = variable&0x3fffffff;
     767    if (k==iColumn) {
     768      if ((variable&0x80000000)==0) {
     769        // lower bound changing
     770        found |= 1;
     771        newLower = CoinMax(newLower,newBounds_[i]);
     772        if ((force&1)==0) {
     773          if (lower>newBounds_[i])
     774            printf("%d odd lower going from %g to %g\n",iColumn,lower,newBounds_[i]);
     775          lower = newBounds_[i];
     776        } else {
     777          newBounds_[i]=lower;
     778          variables_[i] |= 0x40000000; // say can go odd way
     779        }
     780      } else {
     781        // upper bound changing
     782        found |= 2;
     783        newUpper = CoinMin(newUpper,newBounds_[i]);
     784        if ((force&2)==0) {
     785          if (upper<newBounds_[i])
     786            printf("%d odd upper going from %g to %g\n",iColumn,upper,newBounds_[i]);
     787          upper = newBounds_[i];
     788        } else {
     789          newBounds_[i]=upper;
     790          variables_[i] |= 0x40000000; // say can go odd way
     791        }
     792      }
     793    }
     794  }
     795  newLower = CoinMax(newLower,lower);
     796  newUpper = CoinMin(newUpper,upper);
     797  int nAdd=0;
     798  if ((force&2)!=0&&(found&2)==0) {
     799    // need to add new upper
     800    nAdd++;
     801  }
     802  if ((force&1)!=0&&(found&1)==0) {
     803    // need to add new lower
     804    nAdd++;
     805  }
     806  if (nAdd) {
     807    int size = (numberChangedBounds_+nAdd)*(sizeof(double)+sizeof(int));
     808    char * temp = new char [size];
     809    double * newBounds = (double *) temp;
     810    int * variables = (int *) (newBounds+numberChangedBounds_+nAdd);
     811
     812    int i ;
     813    for (i=0;i<numberChangedBounds_;i++) {
     814      variables[i]=variables_[i];
     815      newBounds[i]=newBounds_[i];
     816    }
     817    delete [] newBounds_;
     818    newBounds_ = newBounds;
     819    variables_ = variables;
     820    if ((force&2)!=0&&(found&2)==0) {
     821      // need to add new upper
     822      int variable = iColumn | 0x80000000;
     823      variables_[numberChangedBounds_]=variable;
     824      newBounds_[numberChangedBounds_++]=newUpper;
     825    }
     826    if ((force&1)!=0&&(found&1)==0) {
     827      // need to add new lower
     828      int variable = iColumn;
     829      variables_[numberChangedBounds_]=variable;
     830      newBounds_[numberChangedBounds_++]=newLower;
     831    }
     832  }
     833 
     834  return (newUpper>=newLower) ? 0 : 1;
    687835}
    688836
     
    706854  branch_(NULL),
    707855  depth_(-1),
    708   numberUnsatisfied_(0)
     856  numberUnsatisfied_(0),
     857  nodeNumber_(-1),
     858  state_(0)
    709859{
    710860#ifdef CHECK_NODE
     
    712862#endif
    713863}
    714 
     864// Print
     865void
     866CbcNode::print() const
     867{
     868  printf("number %d obj %g depth %d sumun %g nunsat %d state %d\n",
     869         nodeNumber_,objectiveValue_,depth_,sumInfeasibilities_,numberUnsatisfied_,state_);
     870}
    715871CbcNode::CbcNode(CbcModel * model,
    716872                 CbcNode * lastNode) :
     
    721877  branch_(NULL),
    722878  depth_(-1),
    723   numberUnsatisfied_(0)
     879  numberUnsatisfied_(0),
     880  nodeNumber_(-1),
     881  state_(0)
    724882{
    725883#ifdef CHECK_NODE
     
    728886  model->setObjectiveValue(this,lastNode);
    729887
    730   if (lastNode)
    731     if (lastNode->nodeInfo_)
    732     lastNode->nodeInfo_->increment();
     888  if (lastNode) {
     889    if (lastNode->nodeInfo_) {
     890       lastNode->nodeInfo_->increment();
     891    }
     892  }
     893  nodeNumber_= model->getNodeCount();
    733894}
    734895
     
    9341095  // Set node number
    9351096  nodeInfo_->setNodeNumber(model->getNodeCount2());
     1097  state_ |= 2; // say active
    9361098}
    9371099
     
    11131275  // Set node number
    11141276  nodeInfo_->setNodeNumber(model->getNodeCount2());
     1277  state_ |= 2; // say active
    11151278}
    11161279
     
    22922455    numberPenalties=0;
    22932456  } else if (numberBeforeTrust<0) {
    2294     numberPenalties=numberColumns;
     2457    if (numberBeforeTrust==-1)
     2458      numberPenalties=numberColumns;
     2459    else if (numberBeforeTrust==-2)
     2460      numberPenalties=0;
    22952461    numberBeforeTrust=0;
    22962462  }
     
    25562722            }
    25572723          }
     2724          if (model->messageHandler()->logLevel()>3) {
     2725            int iColumn = dynamicObject->columnNumber();
     2726            printf("%d (%d) down %d %g up %d %g - infeas %g - sort %g solution %g\n",
     2727                   i,iColumn,numberThisDown,object->downEstimate(),numberThisUp,object->upEstimate(),
     2728                   infeasibility,sort[numberToDo],saveSolution[iColumn]);
     2729          }
    25582730          whichObject[numberToDo++]=i;
    25592731        } else {
     
    28793051      int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
    28803052      int numberTest2 = 2*numberStrong;
    2881       double distanceToCutoff2 = model->getCutoff()-objectiveValue_;
     3053      //double distanceToCutoff2 = model->getCutoff()-objectiveValue_;
    28823054      if (!newWay) {
    28833055      if (searchStrategy==3) {
     
    36793851                   iDo,whichChoice,numberToDo);
    36803852        } else {
    3681           printf("choosing %d  iDo %d iChosenWhen %d numberToDo %d\n",bestChoice,
    3682                  iDo,whichChoice,numberToDo);
     3853          int iObject = whichObject[whichChoice];
     3854          OsiObject * object = model->modifiableObject(iObject);
     3855          CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     3856            dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     3857          int iColumn = dynamicObject->columnNumber();
     3858          printf("choosing %d (column %d) iChosenWhen %d numberToDo %d\n",bestChoice,
     3859                 iColumn,whichChoice,numberToDo);
    36833860        }
    36843861      }
     
    37853962    if (numberNodes)
    37863963      strategy=1;  // should only happen after hot start
    3787     model->setSearchStrategy(strategy);
     3964    if (model->searchStrategy()<999)
     3965      model->setSearchStrategy(strategy);
    37883966  }
    37893967  }
     
    42594437  depth_ = rhs.depth_;
    42604438  numberUnsatisfied_ = rhs.numberUnsatisfied_;
     4439  nodeNumber_ = rhs.nodeNumber_;
     4440  state_ = rhs.state_;
     4441  if (nodeInfo_)
     4442    assert ((state_&2)!=0);
     4443  else
     4444    assert ((state_&2)==0);
    42614445}
    42624446
     
    42794463    depth_ = rhs.depth_;
    42804464    numberUnsatisfied_ = rhs.numberUnsatisfied_;
     4465    nodeNumber_ = rhs.nodeNumber_;
     4466    state_ = rhs.state_;
     4467    if (nodeInfo_)
     4468      assert ((state_&2)!=0);
     4469    else
     4470      assert ((state_&2)==0);
    42814471  }
    42824472  return *this;
     
    42854475{
    42864476#ifdef CHECK_NODE
    4287   if (nodeInfo_)
     4477  if (nodeInfo_) {
    42884478    printf("CbcNode %x Destructor nodeInfo %x (%d)\n",
    42894479         this,nodeInfo_,nodeInfo_->numberPointingToThis());
    4290   else
     4480    //assert(nodeInfo_->numberPointingToThis()>=0);
     4481  } else {
    42914482    printf("CbcNode %x Destructor nodeInfo %x (?)\n",
    42924483         this,nodeInfo_);
    4293 #endif
    4294   if (nodeInfo_) {
     4484  }
     4485#endif
     4486  if (nodeInfo_&&(state_&2)!=0) {
    42954487    nodeInfo_->nullOwner();
    42964488    int numberToDelete=nodeInfo_->numberBranchesLeft();
     
    43124504CbcNode::decrementCuts(int change)
    43134505{
     4506  if (nodeInfo_)
     4507    assert ((state_&2)!=0);
     4508  else
     4509    assert ((state_&2)==0);
    43144510  if(nodeInfo_) {
    43154511    nodeInfo_->decrementCuts(change);
     
    43194515CbcNode::decrementParentCuts(int change)
    43204516{
     4517  if (nodeInfo_)
     4518    assert ((state_&2)!=0);
     4519  else
     4520    assert ((state_&2)==0);
    43214521  if(nodeInfo_) {
    43224522    nodeInfo_->decrementParentCuts(change);
     
    43334533  assert(nodeInfo_ && branch_) ;
    43344534  nodeInfo_->initializeInfo(branch_->numberBranches());
     4535  assert ((state_&2)!=0);
    43354536}
    43364537// Nulls out node info
     
    43394540{
    43404541  nodeInfo_=NULL;
     4542  // say not active
     4543  state_ &= ~2;
    43414544}
    43424545
  • trunk/Cbc/src/CbcNode.hpp

    r819 r838  
    105105                             CbcCountRowCut **addCuts,
    106106                             int &currentNumberCuts) const = 0 ;
     107  /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible)
     108  virtual int applyBounds(int iColumn, double & lower, double & upper,int force) = 0;
    107109
    108110  /** Builds up row basis backwards (until original model).
     
    115117  /// Called when number branches left down to zero
    116118  virtual void allBranchesGone() {}
    117 
     119#if 1
    118120  /// Increment number of references
    119121  inline void increment(int amount=1)
     
    123125  inline int decrement(int amount=1)
    124126  {numberPointingToThis_-=amount;/*printf("CbcNodeInfo %x decremented by %d to %d\n",this,amount,numberPointingToThis_);*/return numberPointingToThis_;}
    125 
     127#else
     128  /// Increment number of references
     129  void increment(int amount=1);
     130  /// Decrement number of references and return number left
     131  int decrement(int amount=1);
     132#endif
    126133  /** Initialize reference counts
    127134
     
    139146  inline int numberPointingToThis() const
    140147  {return numberPointingToThis_;}
     148
     149  /// Set number of objects pointing to this
     150  inline void setNumberPointingToThis(int number)
     151  {numberPointingToThis_=number;}
    141152
    142153  /// Say one branch taken
     
    169180  void decrementCuts(int change=1);
    170181
     182  /// Increment active cut counts
     183  void incrementCuts(int change=1);
     184
    171185  /// Decrement all active cut counts in chain starting at parent
    172186  void decrementParentCuts(int change=1);
     
    189203  { owner_=NULL;}
    190204  const inline CbcNode * owner() const
     205  { return owner_;}
     206  inline CbcNode * mutableOwner() const
    191207  { return owner_;}
    192208  /// The node number
     
    195211  inline void setNodeNumber(int node)
    196212  { nodeNumber_=node;}
     213  /** Deactivate node information.
     214      1 - bounds
     215      2 - cuts
     216      4 - basis!
     217  */
     218  void deactivate(int mode=3);
     219  /// Say if normal
     220  inline bool allActivated() const
     221  { return (active_==7);}
     222  /// Say if marked
     223  inline bool marked() const
     224  { return ((active_&8)!=0);}
     225  /// Mark
     226  inline void mark()
     227  { active_ |= 8;}
     228  /// Unmark
     229  inline void unmark()
     230  { active_ &= ~8;}
    197231protected:
    198232
     
    232266  */
    233267  int numberBranchesLeft_;
     268  /** Active node information.
     269      1 - bounds
     270      2 - cuts
     271      4 - basis!
     272  */
     273  int active_;
    234274     
    235275private:
     
    267307                             CbcCountRowCut **addCuts,
    268308                             int &currentNumberCuts) const ;
     309
     310  /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible)
     311  virtual int applyBounds(int iColumn, double & lower, double & upper,int force) ;
    269312
    270313  /** Builds up row basis backwards (until original model).
     
    329372                             int &currentNumberCuts) const ;
    330373
     374  /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible)
     375  virtual int applyBounds(int iColumn, double & lower, double & upper,int force) ;
    331376  /** Builds up row basis backwards (until original model).
    332377      Returns NULL or previous one to apply .
     
    590635  inline void setBranchingObject(OsiBranchingObject * branchingObject)
    591636  { branch_ = branchingObject;}
     637  /// The node number
     638  inline int nodeNumber() const
     639  { return nodeNumber_;}
     640  inline void setNodeNumber(int node)
     641  { nodeNumber_=node;}
     642  /// Returns true if on tree
     643  inline bool onTree() const
     644  { return (state_&1)!=0;}
     645  /// Sets true if on tree
     646  inline void setOnTree(bool yesNo)
     647  { if(yesNo) state_ |= 1; else state_ &= ~1; }
     648  /// Returns true if active
     649  inline bool active() const
     650  { return (state_&2)!=0;}
     651  /// Sets true if active
     652  inline void setActive(bool yesNo)
     653  { if(yesNo) state_ |= 2; else state_ &= ~2; }
     654  /// Print
     655  void print() const;
    592656
    593657private:
     
    607671  /// The number of objects unsatisfied at this node.
    608672  int numberUnsatisfied_;
     673  /// The node number
     674  int nodeNumber_;
     675  /** State
     676      1 - on tree
     677      2 - active
     678  */
     679  int state_;
    609680};
    610681
  • trunk/Cbc/src/CbcSolver.cpp

    r833 r838  
    4242//#define USER_HAS_FAKE_CLP
    4343//#define USER_HAS_FAKE_CBC
    44 //#define CLP_MALLOC_STATISTICS
     44#define CLP_MALLOC_STATISTICS
    4545#ifdef CLP_MALLOC_STATISTICS
    4646#include <malloc.h>
     
    448448#endif
    449449  // Set up likely cut generators and defaults
    450   parameters_[whichParam(PREPROCESS,numberParameters_,parameters_)].setCurrentOption("sos");
     450  parameters_[whichParam(PREPROCESS,numberParameters_,parameters_)].setCurrentOption("on");
    451451  parameters_[whichParam(MIPOPTIONS,numberParameters_,parameters_)].setIntValue(128|64|1);
    452452  parameters_[whichParam(MIPOPTIONS,numberParameters_,parameters_)].setIntValue(1);
     
    31303130#endif
    31313131  // Set up likely cut generators and defaults
    3132   parameters[whichParam(PREPROCESS,numberParameters,parameters)].setCurrentOption("sos");
     3132  parameters[whichParam(PREPROCESS,numberParameters,parameters)].setCurrentOption("on");
    31333133  parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].setIntValue(128|64|1);
    31343134  parameters[whichParam(MIPOPTIONS,numberParameters,parameters)].setIntValue(1);
     
    33043304    anyToDo=true;
    33053305  }
    3306   if (useRINS>=kType) {
    3307     CbcHeuristicRINS heuristic5(*model);
    3308     heuristic5.setHeuristicName("RINS");
    3309     heuristic5.setFractionSmall(0.6);
    3310     model->addHeuristic(&heuristic5) ;
    3311     anyToDo=true;
    3312   }
    33133306  if (useRENS>=kType) {
    33143307    CbcHeuristicRENS heuristic6(*model);
     
    33193312    heuristic6.setNumberNodes(nodes[useRENS]);
    33203313    model->addHeuristic(&heuristic6) ;
     3314    anyToDo=true;
     3315  }
     3316  if (useRINS>=kType) {
     3317    CbcHeuristicRINS heuristic5(*model);
     3318    heuristic5.setHeuristicName("RINS");
     3319    heuristic5.setFractionSmall(0.6);
     3320    if (useRINS==1)
     3321      heuristic5.setDecayFactor(5.0);
     3322    else
     3323      heuristic5.setDecayFactor(1.5);
     3324    model->addHeuristic(&heuristic5) ;
    33213325    anyToDo=true;
    33223326  }
     
    37883792    // set reasonable defaults
    37893793    int preSolve=5;
    3790     int preProcess=4;
     3794    int preProcess=1;
    37913795    bool useStrategy=false;
    37923796    bool preSolveFile=false;
     
    38403844    CglGomory gomoryGen;
    38413845    // try larger limit
    3842     gomoryGen.setLimitAtRoot(512);
     3846    gomoryGen.setLimitAtRoot(1000);
    38433847    gomoryGen.setLimit(50);
    38443848    // set default action (0=off,1=on,2=root)
     
    38583862    // Only look at rows with fewer than this number of elements
    38593863    probingGen.setMaxElements(200);
     3864    probingGen.setMaxElementsRoot(300);
    38603865    probingGen.setRowCuts(3);
    38613866    // set default action (0=off,1=on,2=root)
     
    53315336                }
    53325337#endif
     5338                if (logLevel<=1)
     5339                  si->setHintParam(OsiDoReducePrint,true,OsiHintTry);
    53335340                si->setSpecialOptions(0x40000000);
    53345341              }
     
    53905397                    <<CoinMessageEol;
    53915398                }
    5392                 if (!complicatedInteger&&preProcess==0&&clpSolver->tightenPrimalBounds()!=0) {
     5399                if (!complicatedInteger&&preProcess==0&&clpSolver->tightenPrimalBounds(0.0,0,true)!=0) {
    53935400#ifndef DISALLOW_PRINTING
    53945401                  std::cout<<"Problem is infeasible - tightenPrimalBounds!"<<std::endl;
     
    55825589                  generator1.setMaxPass(1);
    55835590                  generator1.setMaxPassRoot(1);
    5584                   generator1.setMaxProbeRoot(saveSolver->getNumCols());
     5591                  generator1.setMaxProbeRoot(CoinMin(3000,saveSolver->getNumCols()));
    55855592                  generator1.setMaxElements(100);
     5593                  generator1.setMaxElementsRoot(200);
    55865594                  generator1.setMaxLookRoot(50);
    55875595                  generator1.setRowCuts(3);
     
    55905598                    generator1.setMaxPassRoot(2);
    55915599                    generator1.setMaxElements(300);
     5600                    generator1.setMaxProbeRoot(saveSolver->getNumCols());
    55925601                  }
    55935602                  // Add in generators
     
    57875796                si->resolve();
    57885797              }
    5789 #if 0
    5790               numberDebugValues=599;
    5791               debugValues = new double[numberDebugValues];
    5792               CoinZeroN(debugValues,numberDebugValues);
    5793               debugValues[3]=1.0;
    5794               debugValues[6]=25.0;
    5795               debugValues[9]=4.0;
    5796               debugValues[26]=4.0;
    5797               debugValues[27]=6.0;
    5798               debugValues[35]=8.0;
    5799               debugValues[53]=21.0;
    5800               debugValues[56]=4.0;
    5801 #endif
    58025798              if (debugValues) {
    58035799                // for debug
     
    59285924              int translate[]={-100,-1,-99,-98,1,1,1,1,-1};
    59295925              if (probingAction) {
     5926                probingGen.setMaxProbeRoot(CoinMin(2000,babModel_->solver()->getNumCols()));
    59305927                if (probingAction==5||probingAction==7)
    59315928                  probingGen.setRowCuts(-3); // strengthening etc just at root
     
    59415938                  probingGen.setMaxPassRoot(2);
    59425939                  probingGen.setMaxProbeRoot(babModel_->solver()->getNumCols());
    5943                   probingGen.setMaxLookRoot(50);
     5940                  probingGen.setMaxLookRoot(100);
    59445941                }
    59455942                babModel_->addCutGenerator(&probingGen,translate[probingAction],"Probing");
     
    61396136                    pseudoUp=info.pseudoUp_;
    61406137                    solutionIn=info.primalSolution_;
    6141                     int numberColumns = originalCoinModel_ ? originalCoinModel_->numberColumns() :
    6142                       lpSolver->getNumCols();
    6143                     prioritiesIn = (int *) malloc(numberColumns*sizeof(int));
    6144                     memcpy(prioritiesIn,info.priorities_,numberColumns*sizeof(int));
     6138                    if (info.priorities_) {
     6139                      int numberColumns = originalCoinModel_ ? originalCoinModel_->numberColumns() :
     6140                        lpSolver->getNumCols();
     6141                      prioritiesIn = (int *) malloc(numberColumns*sizeof(int));
     6142                      memcpy(prioritiesIn,info.priorities_,numberColumns*sizeof(int));
     6143                    }
    61456144                    sosPriority = info.sosPriority_;
    61466145                  }
     
    67016700                  }
    67026701                }
    6703                 if (!babModel_->numberStrong())
     6702                if (!babModel_->numberStrong()&&babModel_->numberBeforeTrust()>0)
    67046703                  babModel_->setNumberBeforeTrust(0);
    67056704                if (useStrategy) {
     
    70767075                }
    70777076#endif
     7077                if (logLevel<=1)
     7078                  babModel_->solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
    70787079                babModel_->branchAndBound(statistics);
    70797080#ifdef COIN_DEVELOP
  • trunk/Cbc/src/CbcStrategy.cpp

    r819 r838  
    373373    generator1.setMaxPass(1);
    374374    generator1.setMaxPassRoot(1);
    375     generator1.setMaxProbeRoot(solver->getNumCols());
     375    generator1.setMaxProbeRoot(CoinMin(3000,solver->getNumCols()));
    376376    generator1.setMaxElements(100);
    377377    generator1.setMaxLookRoot(50);
  • trunk/Cbc/src/CbcTree.cpp

    r782 r838  
    1010CbcTree::CbcTree()
    1111{
     12  maximumNodeNumber_=0;
    1213}
    1314CbcTree::~CbcTree()
     
    1819{
    1920  nodes_=rhs.nodes_;
     21  maximumNodeNumber_=rhs.maximumNodeNumber_;
    2022}
    2123// Assignment operator
     
    2527  if (this != &rhs) {
    2628    nodes_=rhs.nodes_;
     29    maximumNodeNumber_=rhs.maximumNodeNumber_;
    2730  }
    2831  return *this;
     
    5457void
    5558CbcTree::push(CbcNode * x) {
     59  x->setNodeNumber(maximumNodeNumber_);
     60  maximumNodeNumber_++;
    5661  /*printf("push obj %g, refcount %d, left %d, pointing to %d\n",
    5762         x->objectiveValue(),x->nodeInfo()->decrement(0),
    5863         x->nodeInfo()->numberBranchesLeft(),x->nodeInfo()->numberPointingToThis());*/
    5964  assert(x->objectiveValue()!=COIN_DBL_MAX&&x->nodeInfo());
     65  x->setOnTree(true);
    6066  nodes_.push_back(x);
    6167  std::push_heap(nodes_.begin(), nodes_.end(), comparison_);
     
    6571void
    6672CbcTree::pop() {
     73  nodes_.front()->setOnTree(false);
    6774  std::pop_heap(nodes_.begin(), nodes_.end(), comparison_);
    6875  nodes_.pop_back();
     
    176183  }
    177184#endif
     185  if (best)
     186    best->setOnTree(false);
    178187  return best;
    179188}
     
    215224    double value = node ? node->objectiveValue() : COIN_DBL_MAX;
    216225    bestPossibleObjective = CoinMin(bestPossibleObjective,value);
    217     if (value >= cutoff) {
     226    if (value >= cutoff||!node->active()) {
    218227      if (node) {
    219228        nodeArray[--kDelete] = node;
     
    324333void
    325334CbcTree::push(CbcNode * x) {
     335  x->setNodeNumber(maximumNodeNumber_);
     336  maximumNodeNumber_++;
    326337  /*printf("push obj %g, refcount %d, left %d, pointing to %d\n",
    327338         x->objectiveValue(),x->nodeInfo()->decrement(0),
     
    463474  }
    464475#endif
     476  if (best)
     477    best->setOnTree(false);
    465478  return best;
    466479}
     
    614627void
    615628CbcTree::realpush(CbcNode * node) {
     629  node->setOnTree(true);
    616630  nodes_.push_back(node);
    617631  CbcNode** candidates = &nodes_[0];
  • trunk/Cbc/src/CbcTree.hpp

    r777 r838  
    9191  /// Get best possible objective function in the tree
    9292  virtual double getBestPossibleObjective();
     93  /// Reset maximum node number
     94  inline void resetNodeNumbers()
     95  { maximumNodeNumber_=0;}
    9396//@}
    9497protected:
    9598  std::vector <CbcNode *> nodes_;
    9699  CbcCompare comparison_;       ///> Sort function for heap ordering.
    97 
    98 
     100  /// Maximum "node" number so far to split ties
     101  int maximumNodeNumber_;
    99102};
    100103
     
    269272  /// We may have got an intelligent tree so give it one more chance
    270273  virtual void endSearch() {}
     274  /// Reset maximum node number
     275  inline void resetNodeNumbers()
     276  { maximumNodeNumber_=0;}
    271277//@}
    272278protected:
    273279  std::vector <CbcNode *> nodes_;
    274280  CbcCompare comparison_;       ///> Sort function for heap ordering.
     281  /// Maximum "node" number so far to split ties
     282  int maximumNodeNumber_;
    275283
    276284
  • trunk/Cbc/src/ClpAmplStuff.cpp

    r811 r838  
    3737               1 - errors
    3838  */
    39   virtual int importData(CbcSolver * model, int & argc, char * argv[]);
     39  virtual int importData(CbcSolver * model, int & argc, char ** & argv);
    4040  /// Export 1 OsiClpSolver, 2 CbcModel - add 10 if infeasible from odd situation
    4141  virtual void exportSolution(CbcSolver * model, int mode,const char * message=NULL) ;
     
    130130*/
    131131int
    132 CbcAmpl::importData(CbcSolver * control, int &argc, char * argv[])
     132CbcAmpl::importData(CbcSolver * control, int &argc, char ** & argv)
    133133{
    134134  CbcModel * babModel = control->model();
  • trunk/Cbc/src/unitTestClp.cpp

    r824 r838  
    1010#include "CbcCutGenerator.hpp"
    1111#include "OsiClpSolverInterface.hpp"
     12#include "OsiRowCutDebugger.hpp"
    1213
    1314//#############################################################################
     
    126127#if HOWMANY
    127128#if HOWMANY>1
     129    PUSH_MPS("gen",780,870,112313,112130.0,7);
     130    //PUSH_MPS("blend2",274,353,7.598985,6.9156751140,7);
    128131    PUSH_MPS("10teams",230,2025,924,917,7);
    129132#endif
     
    338341      }
    339342    }
     343    if (model->getNumCols()==-353) {
     344      // blend2
     345      std::string problemName ;
     346      model->solver()->getStrParam(OsiProbName,problemName) ;
     347      model->solver()->activateRowCutDebugger(problemName.c_str()) ;
     348    }
    340349    model->branchAndBound();
    341350     
     
    368377                  << "; error=" << fabs(objValue[m] - soln);
    369378        numberFailures++;
     379        abort();
    370380      }
    371381    } else {
    372382      std::cout << "error; too many nodes" ;
    373383    }
    374     std::cout<<" - took " <<timeOfSolution<<" seconds.\n";
     384    std::cout<<" - took " <<timeOfSolution<<" seconds.("<<
     385      model->getNodeCount()<<" / "<<model->getIterationCount()<<
     386      " )"<<std::endl;
    375387    timeTaken += timeOfSolution;
    376388    delete model;
Note: See TracChangeset for help on using the changeset viewer.