Changeset 662 for branches/devel/Cbc/src


Ignore:
Timestamp:
Jul 2, 2007 10:54:01 AM (12 years ago)
Author:
forrest
Message:

faster parallel?

Location:
branches/devel/Cbc/src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • branches/devel/Cbc/src/CbcBranchBase.cpp

    r445 r662  
    179179{
    180180  return NULL;
     181}
     182/* Pass in information on branch just done and create CbcObjectUpdateData instance.
     183   If object does not need data then backward pointer will be NULL.
     184   Assumes can get information from solver */
     185CbcObjectUpdateData
     186CbcObject::createUpdateInformation(const OsiSolverInterface * solver,
     187                                                        const CbcNode * node,
     188                                                        const CbcBranchingObject * branchingObject)
     189{
     190  return CbcObjectUpdateData();
    181191}
    182192 
     
    318328  return *this;
    319329}
    320 
    321  
     330// Default constructor
     331CbcObjectUpdateData::CbcObjectUpdateData()
     332  : object_(NULL),
     333    way_(0),
     334    objectNumber_(-1),
     335    change_(0.0),
     336    status_(0),
     337    intDecrease_(0),
     338    branchingValue_(0.0)
     339{
     340}
     341
     342// Useful constructor
     343CbcObjectUpdateData::CbcObjectUpdateData (CbcObject * object,
     344                                          int way,
     345                                          double change,
     346                                          int status,
     347                                          int intDecrease,
     348                                          double branchingValue)
     349  : object_(object),
     350    way_(way),
     351    objectNumber_(-1),
     352    change_(change),
     353    status_(status),
     354    intDecrease_(intDecrease),
     355    branchingValue_(branchingValue)
     356{
     357}
     358
     359// Destructor
     360CbcObjectUpdateData::~CbcObjectUpdateData ()
     361{
     362}
     363
     364// Copy constructor
     365CbcObjectUpdateData::CbcObjectUpdateData ( const CbcObjectUpdateData & rhs)
     366  : object_(rhs.object_),
     367    way_(rhs.way_),
     368    objectNumber_(rhs.objectNumber_),
     369    change_(rhs.change_),
     370    status_(rhs.status_),
     371    intDecrease_(rhs.intDecrease_),
     372    branchingValue_(rhs.branchingValue_)
     373{
     374}
     375
     376// Assignment operator
     377CbcObjectUpdateData &
     378CbcObjectUpdateData::operator=( const CbcObjectUpdateData& rhs)
     379{
     380  if (this!=&rhs) {
     381    object_ = rhs.object_;
     382    way_ = rhs.way_;
     383    objectNumber_ = rhs.objectNumber_;
     384    change_ = rhs.change_;
     385    status_ = rhs.status_;
     386    intDecrease_ = rhs.intDecrease_;
     387    branchingValue_ = rhs.branchingValue_;
     388  }
     389  return *this;
     390}
     391
     392 
  • branches/devel/Cbc/src/CbcBranchBase.hpp

    r642 r662  
    1515class CbcBranchingObject;
    1616class OsiChooseVariable;
     17class CbcObjectUpdateData;
    1718
    1819//#############################################################################
     
    190191                            double tolerance) const;
    191192
     193  /** Pass in information on branch just done and create CbcObjectUpdateData instance.
     194      If object does not need data then backward pointer will be NULL.
     195      Assumes can get information from solver */
     196  virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver,
     197                                                        const CbcNode * node,
     198                                                        const CbcBranchingObject * branchingObject);
     199
     200  /// Update object by CbcObjectUpdateData
     201  virtual void updateInformation(const CbcObjectUpdateData & data) {};
     202
    192203  /// Identifier (normally column number in matrix)
    193204  inline int id() const
     
    492503protected:
    493504};
     505/*  This stores data so an object can be updated
     506 */
     507class CbcObjectUpdateData {
     508
     509public:
     510
     511  /// Default Constructor
     512  CbcObjectUpdateData ();
     513
     514  /// Useful constructor
     515  CbcObjectUpdateData (CbcObject * object,
     516                       int way,
     517                       double change,
     518                       int status,
     519                       int intDecrease_,
     520                       double branchingValue);
     521 
     522  /// Copy constructor
     523  CbcObjectUpdateData ( const CbcObjectUpdateData &);
     524   
     525  /// Assignment operator
     526  CbcObjectUpdateData & operator=( const CbcObjectUpdateData& rhs);
     527
     528  /// Destructor
     529  virtual ~CbcObjectUpdateData ();
     530
     531 
     532public:
     533  /// data
     534
     535  /// Object
     536  CbcObject * object_;
     537  /// Branch as defined by instance of CbcObject
     538  int way_;
     539  /// Object number
     540  int objectNumber_;
     541  /// Change in objective
     542  double change_;
     543  /// Status 0 Optimal, 1 infeasible, 2 unknown
     544  int status_;
     545  /// Decrease in number unsatisfied
     546  int intDecrease_;
     547  /// Branching value
     548  double branchingValue_;
     549
     550};
    494551
    495552#endif
  • branches/devel/Cbc/src/CbcBranchDynamic.cpp

    r439 r662  
    267267{
    268268}
     269// Copy some information i.e. just variable stuff
     270void
     271CbcSimpleIntegerDynamicPseudoCost::copySome(CbcSimpleIntegerDynamicPseudoCost * otherObject)
     272{
     273  downDynamicPseudoCost_=otherObject->downDynamicPseudoCost_;
     274  upDynamicPseudoCost_=otherObject->upDynamicPseudoCost_;
     275  sumDownCost_ = otherObject->sumDownCost_;
     276  sumUpCost_ = otherObject->sumUpCost_;
     277  sumDownChange_ = otherObject->sumDownChange_;
     278  sumUpChange_ = otherObject->sumUpChange_;
     279  sumDownCostSquared_ = otherObject->sumDownCostSquared_;
     280  sumUpCostSquared_ = otherObject->sumUpCostSquared_;
     281  sumDownDecrease_ = otherObject->sumDownDecrease_;
     282  sumUpDecrease_ = otherObject->sumUpDecrease_;
     283  lastDownCost_ = otherObject->lastDownCost_;
     284  lastUpCost_ = otherObject->lastUpCost_;
     285  lastDownDecrease_ = otherObject->lastDownDecrease_;
     286  lastUpDecrease_ = otherObject->lastUpDecrease_;
     287  numberTimesDown_ = otherObject->numberTimesDown_;
     288  numberTimesUp_ = otherObject->numberTimesUp_;
     289  numberTimesDownInfeasible_ = otherObject->numberTimesDownInfeasible_;
     290  numberTimesUpInfeasible_ = otherObject->numberTimesUpInfeasible_;
     291  numberTimesDownLocalFixed_ = otherObject->numberTimesDownLocalFixed_;
     292  numberTimesUpLocalFixed_ = otherObject->numberTimesUpLocalFixed_;
     293  numberTimesDownTotalFixed_ = otherObject->numberTimesDownTotalFixed_;
     294  numberTimesUpTotalFixed_ = otherObject->numberTimesUpTotalFixed_;
     295  numberTimesProbingTotal_ = otherObject->numberTimesProbingTotal_;
     296}
    269297// Creates a branching object
    270298CbcBranchingObject *
     
    646674  double downCost = CoinMax((value-below)*downDynamicPseudoCost_,0.0);
    647675  return downCost;
     676}
     677/* Pass in information on branch just done and create CbcObjectUpdateData instance.
     678   If object does not need data then backward pointer will be NULL.
     679   Assumes can get information from solver */
     680CbcObjectUpdateData
     681CbcSimpleIntegerDynamicPseudoCost::createUpdateInformation(const OsiSolverInterface * solver,
     682                                                           const CbcNode * node,
     683                                                           const CbcBranchingObject * branchingObject)
     684{
     685  double originalValue=node->objectiveValue();
     686  int originalUnsatisfied = node->numberUnsatisfied();
     687  double objectiveValue = solver->getObjValue()*solver->getObjSense();
     688  int unsatisfied=0;
     689  int i;
     690  //might be base model - doesn't matter
     691  int numberIntegers = model_->numberIntegers();;
     692  const double * solution = solver->getColSolution();
     693  //const double * lower = solver->getColLower();
     694  //const double * upper = solver->getColUpper();
     695  double change = CoinMax(0.0,objectiveValue-originalValue);
     696  int iStatus;
     697  if (solver->isProvenOptimal())
     698    iStatus=0; // optimal
     699  else if (solver->isIterationLimitReached()
     700           &&!solver->isDualObjectiveLimitReached())
     701    iStatus=2; // unknown
     702  else
     703    iStatus=1; // infeasible
     704
     705  bool feasible = iStatus!=1;
     706  if (feasible) {
     707    double integerTolerance =
     708      model_->getDblParam(CbcModel::CbcIntegerTolerance);
     709    const int * integerVariable = model_->integerVariable();
     710    for (i=0;i<numberIntegers;i++) {
     711      int j=integerVariable[i];
     712      double value = solution[j];
     713      double nearest = floor(value+0.5);
     714      if (fabs(value-nearest)>integerTolerance)
     715        unsatisfied++;
     716    }
     717  }
     718  int way = branchingObject->way();
     719  way = - way; // because after branch so moved on
     720  double value = branchingObject->value();
     721  return CbcObjectUpdateData (this, way,
     722                                  change, iStatus,
     723                                  originalUnsatisfied-unsatisfied,value);
     724}
     725// Update object by CbcObjectUpdateData
     726void
     727CbcSimpleIntegerDynamicPseudoCost::updateInformation(const CbcObjectUpdateData & data)
     728{
     729  bool feasible = data.status_!=1;
     730  int way = data.way_;
     731  double value = data.branchingValue_;
     732  double change = data.change_;
     733#define TYPE2 1
     734#define TYPERATIO 0.9
     735  if (way<0) {
     736    // down
     737    if (feasible) {
     738      //printf("(down change %g value down %g ",change,value-floor(value));
     739      incrementNumberTimesDown();
     740      addToSumDownChange(1.0e-30+value-floor(value));
     741      addToSumDownDecrease(data.intDecrease_);
     742#if TYPE2==0
     743      addToSumDownCost(change/(1.0e-30+(value-floor(value))));
     744      setDownDynamicPseudoCost(sumDownCost()/(double) numberTimesDown());
     745#elif TYPE2==1
     746      addToSumDownCost(change);
     747      setDownDynamicPseudoCost(sumDownCost()/sumDownChange());
     748#elif TYPE2==2
     749      addToSumDownCost(change*TYPERATIO+(1.0-TYPERATIO)*change/(1.0e-30+(value-floor(value))));
     750      setDownDynamicPseudoCost(sumDownCost()*(TYPERATIO/sumDownChange()+(1.0-TYPERATIO)/(double) numberTimesDown()));
     751#endif
     752    } else {
     753      //printf("(down infeasible value down %g ",change,value-floor(value));
     754      incrementNumberTimesDownInfeasible();
     755#if INFEAS==2
     756      double distanceToCutoff=0.0;
     757      double objectiveValue = model->getCurrentMinimizationObjValue();
     758      distanceToCutoff =  model->getCutoff()  - originalValue;
     759      if (distanceToCutoff<1.0e20)
     760        change = distanceToCutoff*2.0;
     761      else
     762        change = downDynamicPseudoCost()*(value-floor(value))*10.0;
     763      change = CoinMax(1.0e-12*(1.0+fabs(originalValue)),change);
     764      incrementNumberTimesDown();
     765      addToSumDownChange(1.0e-30+value-floor(value));
     766      addToSumDownDecrease(data.intDecrease_);
     767#if TYPE2==0
     768      addToSumDownCost(change/(1.0e-30+(value-floor(value))));
     769      setDownDynamicPseudoCost(sumDownCost()/(double) numberTimesDown());
     770#elif TYPE2==1
     771      addToSumDownCost(change);
     772      setDownDynamicPseudoCost(sumDownCost()/sumDownChange());
     773#elif TYPE2==2
     774      addToSumDownCost(change*TYPERATIO+(1.0-TYPERATIO)*change/(1.0e-30+(value-floor(value))));
     775      setDownDynamicPseudoCost(sumDownCost()*(TYPERATIO/sumDownChange()+(1.0-TYPERATIO)/(double) numberTimesDown()));
     776#endif
     777#endif
     778    }
     779  } else {
     780    // up
     781    if (feasible) {
     782      //printf("(up change %g value down %g ",change,ceil(value)-value);
     783      incrementNumberTimesUp();
     784      addToSumUpChange(1.0e-30+ceil(value)-value);
     785      addToSumUpDecrease(data.intDecrease_);
     786#if TYPE2==0
     787      addToSumUpCost(change/(1.0e-30+(ceil(value)-value)));
     788      setUpDynamicPseudoCost(sumUpCost()/(double) numberTimesUp());
     789#elif TYPE2==1
     790      addToSumUpCost(change);
     791      setUpDynamicPseudoCost(sumUpCost()/sumUpChange());
     792#elif TYPE2==2
     793      addToSumUpCost(change*TYPERATIO+(1.0-TYPERATIO)*change/(1.0e-30+(ceil(value)-value)));
     794      setUpDynamicPseudoCost(sumUpCost()*(TYPERATIO/sumUpChange()+(1.0-TYPERATIO)/(double) numberTimesUp()));
     795#endif
     796    } else {
     797      //printf("(up infeasible value down %g ",change,ceil(value)-value);
     798      incrementNumberTimesUpInfeasible();
     799#if INFEAS==2
     800      double distanceToCutoff=0.0;
     801      double objectiveValue = model->getCurrentMinimizationObjValue();
     802      distanceToCutoff =  model->getCutoff()  - originalValue;
     803      if (distanceToCutoff<1.0e20)
     804        change = distanceToCutoff*2.0;
     805      else
     806        change = upDynamicPseudoCost()*(ceil(value)-value)*10.0;
     807      change = CoinMax(1.0e-12*(1.0+fabs(originalValue)),change);
     808      incrementNumberTimesUp();
     809      addToSumUpChange(1.0e-30+ceil(value)-value);
     810      addToSumUpDecrease(data.intDecrease_);
     811#if TYPE2==0
     812      addToSumUpCost(change/(1.0e-30+(ceil(value)-value)));
     813      setUpDynamicPseudoCost(sumUpCost()/(double) numberTimesUp());
     814#elif TYPE2==1
     815      addToSumUpCost(change);
     816      setUpDynamicPseudoCost(sumUpCost()/sumUpChange());
     817#elif TYPE2==2
     818      addToSumUpCost(change*TYPERATIO+(1.0-TYPERATIO)*change/(1.0e-30+(ceil(value)-value)));
     819      setUpDynamicPseudoCost(sumUpCost()*(TYPERATIO/sumUpChange()+(1.0-TYPERATIO)/(double) numberTimesUp()));
     820#endif
     821#endif
     822    }
     823  }
     824  //print(1,0.5);
    648825}
    649826// Pass in probing information
     
    9521129  int way = object_->way();
    9531130  double value = object_->value();
    954 #define TYPE2 1
    955 #define TYPERATIO 0.9
     1131  //#define TYPE2 1
     1132  //#define TYPERATIO 0.9
    9561133  if (way<0) {
    9571134    // down
     
    10431220    }
    10441221  }
    1045   //object->print();
     1222  //object->print(1,0.5);
    10461223  delete object_;
    10471224  object_=NULL;
     
    10611238                            double changeDown, int numInfDown)
    10621239{
    1063   int stateOfSearch = thisOne->model()->stateOfSearch();
     1240  CbcModel * model = thisOne->model();
     1241  int stateOfSearch = model->stateOfSearch();
    10641242  int betterWay=0;
    10651243  double value=0.0;
     1244  if (!bestObject_) {
     1245    bestCriterion_=-1.0;
     1246    bestNumberUp_=INT_MAX;
     1247    bestNumberDown_=INT_MAX;
     1248  }
    10661249  if (stateOfSearch<=1&&thisOne->model()->currentNode()->depth()>10) {
    1067 #if 0
    1068     if (!bestObject_) {
    1069       bestNumberUp_=INT_MAX;
    1070       bestNumberDown_=INT_MAX;
    1071     }
     1250#define TRY_STUFF 1
     1251#ifdef TRY_STUFF
    10721252    // before solution - choose smallest number
    10731253    // could add in depth as well
     
    11081288    }
    11091289#else
    1110     if (!bestObject_) {
    1111       bestCriterion_=-1.0;
    1112     }
    11131290    // got a solution
    11141291    double minValue = CoinMin(changeDown,changeUp);
     
    11241301#endif
    11251302  } else {
    1126     if (!bestObject_) {
    1127       bestCriterion_=-1.0;
    1128     }
     1303#if TRY_STUFF > 1
     1304    // Get current number of infeasibilities, cutoff and current objective
     1305    CbcNode * node = model->currentNode();
     1306    int numberUnsatisfied = node->numberUnsatisfied();
     1307    double cutoff = model->getCutoff();
     1308    double objectiveValue = node->objectiveValue();
     1309#endif
    11291310    // got a solution
    11301311    double minValue = CoinMin(changeDown,changeUp);
    11311312    double maxValue = CoinMax(changeDown,changeUp);
    11321313    // Reduce
     1314#ifdef TRY_STUFF
     1315    //maxValue = CoinMin(maxValue,minValue*4.0);
     1316#else
    11331317    maxValue = CoinMin(maxValue,minValue*2.0);
     1318#endif
    11341319    value = WEIGHT_AFTER*minValue + (1.0-WEIGHT_AFTER)*maxValue;
    1135     if (value>bestCriterion_+1.0e-8) {
     1320    double useValue = value;
     1321    double useBest = bestCriterion_;
     1322#if TRY_STUFF>1
     1323    int thisNumber = CoinMin(numInfUp,numInfDown);
     1324    int bestNumber = CoinMin(bestNumberUp_,bestNumberDown_);
     1325    double distance = cutoff-objectiveValue;
     1326    assert (distance>=0.0);
     1327    if (useValue+0.1*distance>useBest&&useValue*1.1>useBest&&
     1328        useBest+0.1*distance>useValue&&useBest*1.1>useValue) {
     1329      // not much in it - look at unsatisfied
     1330      if (thisNumber<numberUnsatisfied||bestNumber<numberUnsatisfied) {
     1331        double perInteger = distance/ ((double) numberUnsatisfied);
     1332        useValue += thisNumber*perInteger;
     1333        useBest += bestNumber*perInteger;
     1334      }
     1335    }
     1336#endif
     1337    if (useValue>useBest+1.0e-8) {
    11361338      if (changeUp<=changeDown) {
    11371339        betterWay=1;
  • branches/devel/Cbc/src/CbcBranchDynamic.hpp

    r439 r662  
    6464  virtual CbcBranchingObject * createBranch(OsiSolverInterface * solver,
    6565                                            const OsiBranchingInformation * info, int way) ;
     66
     67  /** Pass in information on branch just done and create CbcObjectUpdateData instance.
     68      If object does not need data then backward pointer will be NULL.
     69      Assumes can get information from solver */
     70  virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver,
     71                                                        const CbcNode * node,
     72                                                        const CbcBranchingObject * branchingObject);
     73  /// Update object by CbcObjectUpdateData
     74  virtual void updateInformation(const CbcObjectUpdateData & data) ;
     75  /// Copy some information i.e. just variable stuff
     76  void copySome(CbcSimpleIntegerDynamicPseudoCost * otherObject);
    6677
    6778  /** Create an OsiSolverBranch object
  • branches/devel/Cbc/src/CbcModel.cpp

    r649 r662  
    1414//#define NODE_LOG
    1515//#define GLOBAL_CUTS_JUST_POINTERS
     16#ifndef CLP_FAST_CODE
     17#ifdef NDEBUG
     18#undef NDEBUG
     19#endif
     20#endif
    1621#include <cassert>
    1722#include <cmath>
     
    6570#ifdef CBC_THREAD
    6671#include <pthread.h>
     72#ifndef CLP_FAST_CODE
    6773#define CBC_THREAD_DEBUG 1
     74#endif
    6875#ifdef CBC_THREAD_DEBUG
    6976#ifdef NDEBUG
     
    533540  std::string problemName ;
    534541  solver_->getStrParam(OsiProbName,problemName) ;
    535   if (!strcmp(problemName.c_str(),"P0282")) solver_->activateRowCutDebugger(problemName.c_str()) ;
     542  if (!strcmp(problemName.c_str(),"PP08A")) solver_->activateRowCutDebugger(problemName.c_str()) ;
    536543#endif
    537544  if (strategy_) {
     
    14621469    if (tree_->empty()) {
    14631470#ifdef CBC_THREAD
     1471      if (numberThreads_) {
    14641472#ifdef COIN_DEVELOP
    1465       printf("empty\n");
    1466 #endif
    1467       if (numberThreads_) {
     1473        printf("empty\n");
     1474#endif
    14681475        // may still be outstanding nodes
    14691476        int iThread;
     
    17211728           node->guessedObjectiveValue());
    17221729#endif
     1730#if NEW_UPDATE_OBJECT==0
    17231731    // Save clone in branching decision
    17241732    if(branchingMethod_)
    17251733      branchingMethod_->saveBranchingObject(node->modifiableBranchingObject());
     1734#endif
    17261735    // Say not on optimal path
    17271736    bool onOptimalPath=false;
     
    28122821  numberStrongIterations_(0),
    28132822  resolveAfterTakeOffCuts_(true),
     2823#if NEW_UPDATE_OBJECT>1
     2824  numberUpdateItems_(0),
     2825  maximumNumberUpdateItems_(0),
     2826  updateItems_(NULL),
     2827#endif
    28142828  numberThreads_(0),
    28152829  threadMode_(0)
     
    29452959  numberStrongIterations_(0),
    29462960  resolveAfterTakeOffCuts_(true),
     2961#if NEW_UPDATE_OBJECT>1
     2962  numberUpdateItems_(0),
     2963  maximumNumberUpdateItems_(0),
     2964  updateItems_(NULL),
     2965#endif
    29472966  numberThreads_(0),
    29482967  threadMode_(0)
     
    31623181  numberStrongIterations_(rhs.numberStrongIterations_),
    31633182  resolveAfterTakeOffCuts_(rhs.resolveAfterTakeOffCuts_),
     3183#if NEW_UPDATE_OBJECT>1
     3184  numberUpdateItems_(rhs.numberUpdateItems_),
     3185  maximumNumberUpdateItems_(rhs.maximumNumberUpdateItems_),
     3186  updateItems_(NULL),
     3187#endif
    31643188  numberThreads_(rhs.numberThreads_),
    31653189  threadMode_(rhs.threadMode_)
     
    32183242        object_[i]=(rhs.object_[i])->clone();
    32193243        CbcObject * obj = dynamic_cast <CbcObject *>(object_[i]) ;
    3220         assert (obj);
    3221         obj->setModel(this);
     3244        // Could be OsiObjects
     3245        if (obj)
     3246          obj->setModel(this);
    32223247      }
    32233248    } else {
     
    32443269    originalColumns_=NULL;
    32453270  }
     3271#if NEW_UPDATE_OBJECT>1
     3272  if (maximumNumberUpdateItems_) {
     3273    updateItems_ = new CbcObjectUpdateData [maximumNumberUpdateItems_];
     3274    for (int i=0;i<maximumNumberUpdateItems_;i++)
     3275      updateItems_[i] = rhs.updateItems_[i];
     3276  }
     3277#endif
    32463278  if (maximumWhich_&&rhs.whichGenerator_)
    32473279    whichGenerator_ = CoinCopyOfArray(rhs.whichGenerator_,maximumWhich_);
     
    34693501    numberNewCuts_ = rhs.numberNewCuts_;
    34703502    resolveAfterTakeOffCuts_=rhs.resolveAfterTakeOffCuts_;
     3503#if NEW_UPDATE_OBJECT>1
     3504    numberUpdateItems_ = rhs.numberUpdateItems_;
     3505    maximumNumberUpdateItems_ = rhs.maximumNumberUpdateItems_;
     3506    delete [] updateItems_;
     3507    if (maximumNumberUpdateItems_) {
     3508      updateItems_ = new CbcObjectUpdateData [maximumNumberUpdateItems_];
     3509      for (i=0;i<maximumNumberUpdateItems_;i++)
     3510        updateItems_[i] = rhs.updateItems_[i];
     3511    } else {
     3512      updateItems_ = NULL;
     3513    }
     3514#endif
    34713515    numberThreads_ = rhs.numberThreads_;
    34723516    threadMode_ = rhs.threadMode_;
     
    36443688  originalColumns_=NULL;
    36453689  delete strategy_;
     3690#if NEW_UPDATE_OBJECT>1
     3691  delete [] updateItems_;
     3692  updateItems_=NULL;
     3693  numberUpdateItems_=0;
     3694  maximumNumberUpdateItems_=0;
     3695#endif
    36463696  gutsOfDestructor2();
    36473697}
     
    43974447  }
    43984448 
     4449#if NEW_UPDATE_OBJECT==0
    43994450  // Update branching information if wanted
    44004451  if(node &&branchingMethod_)
    44014452    branchingMethod_->updateInformation(solver_,node);
     4453#elif NEW_UPDATE_OBJECT<2
     4454  // Update branching information if wanted
     4455  if(node &&branchingMethod_) {
     4456    OsiBranchingObject * bobj = node->modifiableBranchingObject();
     4457    CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (bobj);
     4458    if (cbcobj) {
     4459      CbcObject * object = cbcobj->object();
     4460      CbcObjectUpdateData update = object->createUpdateInformation(solver_,node,cbcobj);
     4461      object->updateInformation(update);
     4462    } else {
     4463      branchingMethod_->updateInformation(solver_,node);
     4464    }
     4465  }
     4466#else
     4467  // Update branching information if wanted
     4468  if(node &&branchingMethod_) {
     4469    OsiBranchingObject * bobj = node->modifiableBranchingObject();
     4470    CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (bobj);
     4471    if (cbcobj) {
     4472      CbcObject * object = cbcobj->object();
     4473      CbcObjectUpdateData update = object->createUpdateInformation(solver_,node,cbcobj);
     4474      // have to compute object number as not saved
     4475      CbcSimpleInteger * simpleObject =
     4476          dynamic_cast <CbcSimpleInteger *>(object) ;
     4477      int iObject;
     4478      int iColumn = simpleObject->columnNumber();
     4479      for (iObject = 0 ; iObject < numberObjects_ ; iObject++) {
     4480        simpleObject =
     4481          dynamic_cast <CbcSimpleInteger *>(object_[iObject]) ;
     4482        if (simpleObject->columnNumber()==iColumn)
     4483          break;
     4484      }
     4485      assert (iObject<numberObjects_);
     4486      update.objectNumber_ = iObject;
     4487      addUpdateInformation(update);
     4488    } else {
     4489      branchingMethod_->updateInformation(solver_,node);
     4490    }
     4491  }
     4492#endif
    44024493
    44034494#ifdef CBC_DEBUG
     
    74187509        handler_->message(CBC_NOTFEAS2, messages_)
    74197510          << objectiveValue << cutoff << CoinMessageEol ;
    7420     } else {
     7511    } else if (objectiveValue<bestObjective_) {
    74217512      /*
    74227513        We have a winner. Install it as the new incumbent.
     
    92889379  bool feasible=true;
    92899380  int branchingState=-1;
     9381  currentNode_=newNode; // so can be used elsewhere
    92909382  while (anyAction == -1) {
    92919383    // Set objective value (not so obvious if NLP etc)
     
    98859977  }
    98869978#endif
     9979#if NEW_UPDATE_OBJECT==0
    98879980  // Save clone in branching decision
    98889981  if(branchingMethod_)
    98899982    branchingMethod_->saveBranchingObject(node->modifiableBranchingObject());
     9983#elif NEW_UPDATE_OBJECT>1
     9984  numberUpdateItems_=0;
     9985#endif
    98909986  // Say not on optimal path
    98919987  bool onOptimalPath=false;
     
    1003310129    }
    1003410130    if ((specialOptions_&1)!=0&&onOptimalPath) {
    10035       if (!solver_->getRowCutDebugger()) {
     10131      if (!solver_->getRowCutDebugger()||!feasible) {
    1003610132        // dj fix did something???
    1003710133        solver_->writeMps("infeas2");
    1003810134        assert (solver_->getRowCutDebugger()) ;
     10135        assert (feasible);
    1003910136      }
    1004010137    }
     
    1015810255    }
    1015910256    lockThread();
     10257#if NEW_UPDATE_OBJECT>1
     10258      if (numberUpdateItems_&&!numberThreads_) {
     10259        for (i=0;i<numberUpdateItems_;i++) {
     10260          CbcObjectUpdateData * update = updateItems_+i;
     10261          CbcObject * object = dynamic_cast<CbcObject *> (update->object_);
     10262          if (object)
     10263            object->updateInformation(*update);
     10264        }
     10265        numberUpdateItems_=0;
     10266      }
     10267#endif
    1016010268    if (newNode) {
    1016110269      if (newNode->branchingObject() == NULL&&solverCharacteristics_->solverType()==4) {
     
    1038310491  return foundSolution;
    1038410492}
     10493#if NEW_UPDATE_OBJECT>1
     10494// Adds an update information object
     10495void
     10496CbcModel::addUpdateInformation(const CbcObjectUpdateData & data)
     10497{
     10498  if (numberUpdateItems_==maximumNumberUpdateItems_) {
     10499    maximumNumberUpdateItems_ += 10;
     10500    CbcObjectUpdateData * temp = new CbcObjectUpdateData [maximumNumberUpdateItems_];
     10501    for (int i=0;i<maximumNumberUpdateItems_-10;i++)
     10502      temp[i] = updateItems_[i];
     10503    delete [] updateItems_;
     10504    updateItems_ = temp;
     10505  }
     10506  updateItems_[numberUpdateItems_++]=data;
     10507}
     10508#endif
    1038510509/* Move/copy information from one model to another
    1038610510   -1 - initial setup
     
    1041910543    stateOfSearch_=baseModel->stateOfSearch_;
    1042010544    stuff->saveStuff[1]=stateOfSearch_;
     10545#if NEW_UPDATE_OBJECT>1
     10546    for (int iObject = 0 ; iObject < numberObjects_ ; iObject++) {
     10547      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     10548        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object_[iObject]) ;
     10549      if (dynamicObject) {
     10550        CbcSimpleIntegerDynamicPseudoCost * baseObject =
     10551        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(baseModel->object_[iObject]) ;
     10552        assert (baseObject);
     10553        dynamicObject->copySome(baseObject);
     10554      }
     10555    }
     10556#endif
    1042110557 } else if (mode==1) {
    1042210558    lockThread();
     
    1043810574#endif
    1043910575      baseModel->stateOfSearch_=stateOfSearch_;
     10576    }
     10577#endif
     10578#if NEW_UPDATE_OBJECT>1
     10579    if (numberUpdateItems_) {
     10580      for (int i=0;i<numberUpdateItems_;i++) {
     10581        CbcObjectUpdateData * update = updateItems_+i;
     10582        int objectNumber = update->objectNumber_;
     10583        CbcObject * object = dynamic_cast<CbcObject *> (baseModel->object_[objectNumber]);
     10584        if (object)
     10585          object->updateInformation(*update);
     10586      }
     10587      numberUpdateItems_=0;
    1044010588    }
    1044110589#endif
     
    1047710625    delete solverCharacteristics_;
    1047810626    solverCharacteristics_ = NULL;
    10479     if (baseModel->branchingMethod_&&baseModel->branchingMethod_->chooseMethod()) {
     10627    bool newMethod = (baseModel->branchingMethod_&&baseModel->branchingMethod_->chooseMethod());
     10628    if (newMethod) {
    1048010629      // new method - we were using base models
    1048110630      numberObjects_=0;
     
    1049810647    nodeCompare_ = NULL;
    1049910648    continuousSolver_ = baseModel->continuousSolver_->clone();
    10500     if (baseModel->branchingMethod_&&baseModel->branchingMethod_->chooseMethod()) {
     10649    bool newMethod = (baseModel->branchingMethod_&&baseModel->branchingMethod_->chooseMethod());
     10650    if (newMethod) {
    1050110651      // new method uses solver - but point to base model
     10652      // We may update an object in wrong order - shouldn't matter?
    1050210653      numberObjects_=baseModel->numberObjects_;
    1050310654      object_=baseModel->object_;
  • branches/devel/Cbc/src/CbcModel.hpp

    r642 r662  
    263263  void resizeWhichGenerator(int numberNow, int numberAfter);
    264264public:
     265#ifndef CBC_THREAD
     266#define NEW_UPDATE_OBJECT 0
     267#else
     268#define NEW_UPDATE_OBJECT 2
     269#endif
     270#if NEW_UPDATE_OBJECT>1
     271  /// Adds an update information object
     272  void addUpdateInformation(const CbcObjectUpdateData & data);
     273#endif
    265274  /** Do one node - broken out for clarity?
    266275      also for parallel (when baseModel!=this)
     
    20062015  /// Whether to force a resolve after takeOffCuts
    20072016  bool resolveAfterTakeOffCuts_;
     2017#if NEW_UPDATE_OBJECT>1
     2018  /// Number of outstanding update information items
     2019  int numberUpdateItems_;
     2020  /// Maximum number of outstanding update information items
     2021  int maximumNumberUpdateItems_;
     2022  /// Update items
     2023  CbcObjectUpdateData * updateItems_;
     2024#endif
    20082025  /**
    20092026     Parallel
  • branches/devel/Cbc/src/CbcNode.cpp

    r642 r662  
    20822082        osiclp->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
    20832083      }
    2084 #     endif
     2084#     endif 
    20852085    }
    20862086    /*
     
    26162616      break;
    26172617    //bool skipAll = (numberBeforeTrust>20&&numberNodes>20000&&numberNotTrusted==0);
    2618     bool skipAll = numberNotTrusted==0;
     2618    bool skipAll = numberNotTrusted==0||numberToDo==1;
    26192619    bool doneHotStart=false;
    26202620    int searchStrategy = saveSearchStrategy>=0 ? (saveSearchStrategy%10) : -1;
     
    31143114          // status is 0 finished, 1 infeasible and other
    31153115          int iStatus;
     3116          if (0) {
     3117            CbcDynamicPseudoCostBranchingObject * cbcobj = dynamic_cast<CbcDynamicPseudoCostBranchingObject *> (choice.possibleBranch);
     3118            if (cbcobj) {
     3119              CbcSimpleIntegerDynamicPseudoCost * object = cbcobj->object();
     3120              printf("strong %d ",iDo);
     3121              object->print(1,0.5);
     3122            }
     3123          }
    31163124          /*
    31173125            Try the down direction first. (Specify the initial branching alternative as
     
    31213129          */
    31223130          choice.possibleBranch->way(-1) ;
     3131#if NEW_UPDATE_OBJECT==0
    31233132          decision->saveBranchingObject( choice.possibleBranch);
     3133#endif
    31243134          choice.possibleBranch->branch() ;
    31253135          solver->solveFromHotStart() ;
     
    31443154          choice.numItersDown = solver->getIterationCount();
    31453155          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
     3156          // Update branching information if wanted
     3157#if NEW_UPDATE_OBJECT==0
    31463158          decision->updateInformation( solver,this);
     3159#elif NEW_UPDATE_OBJECT<2
     3160          CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
     3161          if (cbcobj) {
     3162            CbcObject * object = cbcobj->object();
     3163            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
     3164            object->updateInformation(update);
     3165          } else {
     3166            decision->updateInformation( solver,this);
     3167          }
     3168#else
     3169          CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
     3170          if (cbcobj) {
     3171            CbcObject * object = cbcobj->object();
     3172            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
     3173            update.objectNumber_ = choice.objectNumber;
     3174            model->addUpdateInformation(update);
     3175          } else {
     3176            decision->updateInformation( solver,this);
     3177          }
     3178#endif
    31473179          if (!iStatus) {
    31483180            choice.finishedDown = true ;
     
    32263258         
    32273259          // repeat the whole exercise, forcing the variable up
     3260#if NEW_UPDATE_OBJECT==0
    32283261          decision->saveBranchingObject( choice.possibleBranch);
     3262#endif
    32293263          choice.possibleBranch->branch();
    32303264          solver->solveFromHotStart() ;
     
    32483282          choice.numItersUp = solver->getIterationCount();
    32493283          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
     3284          // Update branching information if wanted
     3285#if NEW_UPDATE_OBJECT==0
    32503286          decision->updateInformation( solver,this);
     3287#elif NEW_UPDATE_OBJECT<2
     3288          cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
     3289          if (cbcobj) {
     3290            CbcObject * object = cbcobj->object();
     3291            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
     3292            object->updateInformation(update);
     3293          } else {
     3294            decision->updateInformation( solver,this);
     3295          }
     3296#else
     3297          cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
     3298          if (cbcobj) {
     3299            CbcObject * object = cbcobj->object();
     3300            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
     3301            update.objectNumber_ = choice.objectNumber;
     3302            model->addUpdateInformation(update);
     3303          } else {
     3304            decision->updateInformation( solver,this);
     3305          }
     3306#endif
    32513307          if (!iStatus) {
    32523308            choice.finishedUp = true ;
  • branches/devel/Cbc/src/CbcSolver.cpp

    r648 r662  
    15061506    bool useStrategy=false;
    15071507    bool preSolveFile=false;
     1508    bool strongChanged=false;
    15081509   
    15091510    double djFix=1.0e100;
     
    19851986              else if (parameters[iParam].type()==FPUMPITS)
    19861987                { useFpump = true;parameters[iParam].setIntValue(value);}
     1988              else if (parameters[iParam].type()==STRONGBRANCHING||
     1989                       parameters[iParam].type()==NUMBERBEFORE)
     1990                strongChanged=true;
    19871991              parameters[iParam].setIntParameter(model,value);
    19881992            }
     
    43804384                }
    43814385#endif
     4386                // If defaults then increase trust for small models
     4387                if (!strongChanged) {
     4388                  int numberColumns = babModel->getNumCols();
     4389                  if (numberColumns<=50)
     4390                    babModel->setNumberBeforeTrust(1000);
     4391                  else if (numberColumns<=100)
     4392                    babModel->setNumberBeforeTrust(100);
     4393                  else if (numberColumns<=300)
     4394                    babModel->setNumberBeforeTrust(50);
     4395                }
    43824396#ifdef CBC_THREAD
    43834397                int numberThreads =parameters[whichParam(THREADS,numberParameters,parameters)].intValue();
  • branches/devel/Cbc/src/unitTestClp.cpp

    r452 r662  
    20162016    else
    20172017      model->setMaximumCutPassesAtRoot(20);
     2018    // If defaults then increase trust for small models
     2019    if (model->numberStrong()==5&&model->numberBeforeTrust()==10) {
     2020      int numberColumns = model->getNumCols();
     2021      if (numberColumns<=50)
     2022        model->setNumberBeforeTrust(1000);
     2023      else if (numberColumns<=100)
     2024        model->setNumberBeforeTrust(100);
     2025      else if (numberColumns<=300)
     2026        model->setNumberBeforeTrust(50);
     2027    }
    20182028    model->branchAndBound();
    20192029     
Note: See TracChangeset for help on using the changeset viewer.