Changeset 1165


Ignore:
Timestamp:
May 16, 2009 4:24:19 AM (11 years ago)
Author:
forrest
Message:

try and improve Cbc

Location:
trunk/Cbc/src
Files:
8 edited

Legend:

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

    r1132 r1165  
    133133    method_(0)
    134134{
    135 #ifdef CBC_INSTRUMENT
    136   numberTimesInfeasible_=0;
    137 #endif
    138135}
    139136
     
    170167    method_(0)
    171168{
    172 #ifdef CBC_INSTRUMENT
    173   numberTimesInfeasible_=0;
    174 #endif
    175169  const double * cost = model->getObjCoefficients();
    176170  double costValue = CoinMax(1.0e-5,fabs(cost[iColumn]));
     
    238232    method_(0)
    239233{
    240 #ifdef CBC_INSTRUMENT
    241   numberTimesInfeasible_=0;
    242 #endif
    243234  downDynamicPseudoCost_ = downDynamicPseudoCost;
    244235  upDynamicPseudoCost_ = upDynamicPseudoCost;
     
    312303
    313304{
    314 #ifdef CBC_INSTRUMENT
    315   numberTimesInfeasible_=rhs.numberTimesInfeasible_;
    316 #endif
    317305}
    318306
     
    355343    numberTimesUpTotalFixed_ = rhs.numberTimesUpTotalFixed_;
    356344    numberTimesProbingTotal_ = rhs.numberTimesProbingTotal_;
    357 #ifdef CBC_INSTRUMENT
    358     numberTimesInfeasible_=rhs.numberTimesInfeasible_;
    359 #endif
    360345    method_=rhs.method_;
    361346  }
     
    730715      return 1.0e-13;
    731716  } else {
    732 #ifdef CBC_INSTRUMENT
    733     numberTimesInfeasible_++;
    734 #endif
    735717    int stateOfSearch = model_->stateOfSearch()%10;
    736718    double returnValue=0.0;
     
    799781      returnValue *= 1.0e-3;
    800782    }
    801 #if 0 //def CBC_INSTRUMENT
    802     int nn = numberTimesInfeasible_  - CoinMax(numberTimesUp_,numberTimesDown_);
    803     if (nn<0) {
    804       // Something to do with parallel synchronization
    805       numberTimesInfeasible_  = CoinMax(numberTimesUp_,numberTimesDown_);
    806     } else if (nn) {
    807       returnValue *= sqrt(static_cast<double> (nn));
    808     }
    809 #endif
    810783#ifdef COIN_DEVELOP
    811784    History hist;
     
    12921265                                                   int numberUpInfeasible,double sumUp)
    12931266{
    1294 #ifdef CBC_INSTRUMENT
    1295   int difference = numberDown-numberTimesDown_;
    1296   difference += numberUp-numberTimesUp_;
    1297   numberTimesInfeasible_ += 2*difference;
    1298 #endif
    12991267  numberTimesDown_ = numberDown;
    13001268  numberTimesDownInfeasible_ = numberDownInfeasible;
     
    13461314        devUp = sqrt(devUp);
    13471315    }
    1348 #if 0
    13491316    printf("%d down %d times (%d inf) mean %g (dev %g) up %d times (%d inf) mean %g (dev %g)\n",
    13501317           columnNumber_,
    13511318           numberTimesDown_,numberTimesDownInfeasible_,meanDown,devDown,
    13521319           numberTimesUp_,numberTimesUpInfeasible_,meanUp,devUp);
    1353 #else
    1354     int n=0;
    1355 #ifdef CBC_INSTRUMENT
    1356     n=numberTimesInfeasible_;
    1357 #endif
    1358     printf("%d down %d times (%d inf) mean %g  up %d times (%d inf) mean %g - pseudocosts %g %g - inftimes %d\n",
    1359            columnNumber_,
    1360            numberTimesDown_,numberTimesDownInfeasible_,meanDown,
    1361            numberTimesUp_,numberTimesUpInfeasible_,meanUp,downDynamicPseudoCost_,upDynamicPseudoCost_,n);
    1362 #endif
    13631320  } else {
    13641321    const double * upper = model_->getCbcColUpper();
  • trunk/Cbc/src/CbcBranchDynamic.hpp

    r1121 r1165  
    305305  int numberTimesProbingTotal_;
    306306  /// Number of times infeasible when tested
    307 #define CBC_INSTRUMENT
    308 #ifdef CBC_INSTRUMENT
    309   mutable int numberTimesInfeasible_;
    310 #endif
    311307  /** Method -
    312308      0 - pseudo costs
  • trunk/Cbc/src/CbcCutGenerator.cpp

    r1132 r1165  
    180180CbcCutGenerator::generateCuts( OsiCuts & cs , int fullScan, OsiSolverInterface * solver, CbcNode * node)
    181181{
    182 #define PROBE1 1
    183 #define PROBE2 0
    184 #define PROBE3 1
    185182  int depth;
    186183  if (node)
     
    189186    depth=0;
    190187  int howOften = whenCutGenerator_;
    191   if (dynamic_cast<CglProbing*>(generator_)&&PROBE1) {
     188  if (dynamic_cast<CglProbing*>(generator_)) {
    192189    if (howOften==-100&&model_->doCutsNow(3)) {
    193190      howOften=1; // do anyway
     
    206203  int pass=model_->getCurrentPassNumber()-1;
    207204  bool doThis=(model_->getNodeCount()%howOften)==0;
    208   CoinThreadRandom * randomNumberGenerator=NULL;
    209 #ifdef COIN_HAS_CLP
    210   {
    211     OsiClpSolverInterface * clpSolver
    212       = dynamic_cast<OsiClpSolverInterface *> (solver);
    213     if (clpSolver)
    214       randomNumberGenerator = clpSolver->getModelPtr()->randomNumberGenerator();
    215   }
    216 #endif
    217205  if (depthCutGenerator_>0) {
    218206    doThis = (depth % depthCutGenerator_) ==0;
     
    229217  }
    230218  if (fullScan||doThis) {
     219    CoinThreadRandom * randomNumberGenerator=NULL;
     220#ifdef COIN_HAS_CLP
     221    {
     222      OsiClpSolverInterface * clpSolver
     223        = dynamic_cast<OsiClpSolverInterface *> (solver);
     224      if (clpSolver)
     225        randomNumberGenerator =
     226          clpSolver->getModelPtr()->randomNumberGenerator();
     227    }
     228#endif
    231229    double time1=0.0;
    232230    if (timing_)
     
    267265        generator->generateCutsAndModify(*solver,cs,info2);
    268266        doCuts=true;
    269       } else if (depth||PROBE2) {
    270 #if PROBE3
     267      } else if (depth) {
     268        /* The idea behind this is that probing may work in a different
     269           way deep in tree.  So every now and then try various
     270           combinations to see what works.
     271        */
     272#define TRY_NOW_AND_THEN
     273#ifdef TRY_NOW_AND_THEN
    271274        if ((numberTimes_==200||(numberTimes_>200&&(numberTimes_%2000)==0))
    272              &&!model_->parentModel()&&info.formulation_rows>500) {
    273           // in tree, maxStack, maxProbe
     275             &&!model_->parentModel()&&info.formulation_rows>200) {
     276          /* In tree, every now and then try various combinations
     277             maxStack, maxProbe (last 5 digits)
     278             123 is special and means CglProbing will try and
     279             be intelligent.
     280          */
    274281          int test[]= {
    275282            100123,
     
    286293          int saveStack = generator->getMaxLook();
    287294          int saveNumber = generator->getMaxProbe();
    288 #undef CLP_INVESTIGATE
    289 #ifdef CLP_INVESTIGATE
    290295          int kr1=0;
    291296          int kc1=0;
    292 #endif
    293297          int bestStackTree=-1;
    294298          int bestNumberTree=-1;
    295299          for (int i=0;i<n;i++) {
    296             OsiCuts cs2 = cs;
     300            //OsiCuts cs2 = cs;
    297301            int stack = test[i]/100000;
    298302            int number = test[i] - 100000*stack;
    299303            generator->setMaxLook(stack);
    300304            generator->setMaxProbe(number);
    301             generator_->generateCuts(*solver,cs2,info);
     305            int numberRowCutsBefore = cs.sizeRowCuts() ;
     306            int numberColumnCutsBefore = cs.sizeColCuts() ;
     307            generator_->generateCuts(*solver,cs,info);
     308            int numberRowCuts = cs.sizeRowCuts()-numberRowCutsBefore ;
     309            int numberColumnCuts= cs.sizeColCuts()-numberColumnCutsBefore ;
    302310#ifdef CLP_INVESTIGATE
    303             int numberRowCuts = cs2.sizeRowCuts()-numberRowCutsBefore ;
    304             int numberColumnCuts= cs2.sizeColCuts()-numberColumnCutsBefore ;
    305311            if (numberRowCuts<kr1||numberColumnCuts<kc1)
    306312              printf("Odd ");
     313#endif
    307314            if (numberRowCuts>kr1||numberColumnCuts>kc1) {
     315#ifdef CLP_INVESTIGATE
    308316              printf("*** ");
     317#endif
    309318              kr1=numberRowCuts;
    310319              kc1=numberColumnCuts;
    311320              bestStackTree=stack;
    312321              bestNumberTree=number;
     322              doCuts=true;
    313323            }
     324#ifdef CLP_INVESTIGATE
    314325            printf("maxStack %d number %d gives %d row cuts and %d column cuts\n",
    315326                   stack,number,numberRowCuts,numberColumnCuts);
     
    330341#ifdef CLP_INVESTIGATE
    331342            printf("RRSwitching off number %d -> %d, stack %d -> %d\n",
    332                    saveNumber,saveNumber,saveStack,0);
    333 #endif
    334           }
    335         }
    336 #endif
    337         if (generator->getMaxLook()>0) {
     343                   saveNumber,saveNumber,saveStack,1);
     344#endif
     345          }
     346        }
     347#endif
     348        if (generator->getMaxLook()>0&&!doCuts) {
    338349          generator->generateCutsAndModify(*solver,cs,&info);
    339350          doCuts=true;
     
    341352      } else {
    342353        // at root - don't always do
    343         if (!PROBE3||pass<15||(pass&1)==0) {
     354        if (pass<15||(pass&1)==0) {
    344355          generator->generateCutsAndModify(*solver,cs,&info);
    345356          doCuts=true;
     
    347358      }
    348359      if (doCuts) {
     360        // probing may have tightened bounds - check
    349361        const double * tightLower = generator->tightLower();
    350362        const double * lower = solver->getColLower();
     
    763775        delete [] which;
    764776        numberRowCutsAfter = cs.sizeRowCuts() ;
    765 #if 0 //def CLP_INVESTIGATE
    766         nEls=0;
    767         int nCuts2= numberRowCutsAfter-numberRowCutsBefore;
    768         for (k = numberRowCutsBefore;k<numberRowCutsAfter;k++) {
    769           const OsiRowCut * thisCut = cs.rowCutPtr(k) ;
    770           int n=thisCut->row().getNumElements();
    771           nEls+= n;
    772         }
    773         if (!model_->parentModel()&&nCuts!=nCuts2)
    774           printf("%s NOW has %d cuts and %d elements( down from %d cuts and %d els) - %d parallel\n",
    775                  generatorName_,
    776                  nCuts2,nEls,nCuts,nElsNow,nParallel);
    777 #endif
    778777      }
    779778    }
  • trunk/Cbc/src/CbcModel.cpp

    r1163 r1165  
    55#  pragma warning(disable:4786)
    66#endif
    7 #define MODEL1 0
    87#define MODEL2 0
    9 #define MODEL3 1
    108#define MODEL4 0
    11 #define MODEL5 1
    12 #define MODEL6 0
    13 #define MODEL7 0
    14 #define MODEL8 0
    15 #define MODEL10 1
    16 #define MODEL11 0
    17 #define MODEL12 1
    189#define MODEL13 1
    1910
    2011#include "CbcConfig.h"
    21 //static int nXXXXXX=0;
    2212
    2313#include <string>
     
    9282}
    9383#else
    94 //struct timespec {
    95 //      time_t tv_sec;
    96 //      long tv_nsec;
    97 //};
    9884inline int my_gettime(struct timespec* tp) {
    9985        struct timeval tv;
     
    10490}
    10591#endif
    106 //#include "clocktime.hpp"
    107 //#undef small
    10892
    10993struct Coin_pthread_t {
     
    11296};
    11397
    114 #ifndef CLP_FAST_CODE
    115 #define CBC_THREAD_DEBUG 1
    116 #endif
    117 #ifdef CBC_THREAD_DEBUG
    118 #ifdef NDEBUG
    119 #undef NDEBUG
    120 #undef assert
    121 #         define assert(expression) {                              \
    122              if (!(expression)) {                                          \
    123                 throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \
    124                                 "", __FILE__, __LINE__);                   \
    125              }                                                             \
    126           }
    127 #endif
    128 #endif
    12998// To Pass across to doOneNode
    13099typedef struct {
     
    149118  struct timespec absTime;
    150119  bool locked;
    151 #if CBC_THREAD_DEBUG
    152   int threadNumber;
    153 #endif
    154120  int nDeleteNode;
    155121  CbcNode ** delNode;
     
    379345
    380346
    381 //#define CHECK_CUT_SIZE
    382347#ifdef CHECK_CUT_SIZE
    383348
     
    511476             solver_->getNumRows()>100&&cost!=-COIN_DBL_MAX)
    512477      iType=8;
    513     //else if (!numberContinuousObj&&
    514     //numberIntegerObj*20<numberObjects_&&!parentModel_&&
    515     //     solver_->getNumRows()>100)
    516     //iType=8;
    517478    int iTest =getMaximumNodes();
    518 #if 0
    519     // Give priority to costed in probing if few
    520     if (!numberContinuousObj&&numberIntegerObj<=100&&
    521         numberIntegerObj*5<numberObjects_)
    522         specialOptions_ |= xxxx;
    523 #endif
    524479    if (iTest>=987654320&&iTest<987654330&&numberObjects_&&!parentModel_) {
    525480      iType = iTest-987654320;
     
    10511006  system held by the solver.
    10521007*/
    1053 //#define CHECK_PATH
    1054 #ifdef CHECK_PATH
    1055 extern const double * debuggerSolution_Z;
    1056 extern int numberColumns_Z;
    1057 #endif
    10581008#ifdef COIN_HAS_CPX
    10591009#include "OsiCpxSolverInterface.hpp"
     
    10941044     // Initialise solvers seed
    10951045     clpSolver->getModelPtr()->setRandomSeed(1234567);
    1096 #if MODEL1
     1046#if 0
    10971047     // reduce factorization frequency
    10981048     int frequency = clpSolver->getModelPtr()->factorizationFrequency();
     
    11011051   }
    11021052 }
    1103 #endif
    1104 #ifndef NDEBUG
    1105   {
    1106 #if COIN_DEVELOP>1
    1107     double big = 1.0e12;
    1108 #else
    1109     double big = 1.0e20;
    1110 #endif
    1111     int i;
    1112     int n = solver_->getNumCols();
    1113     const double *lower = solver_->getColLower() ;
    1114     const double *upper = solver_->getColUpper() ;
    1115     for (i=0;i<n;i++) {
    1116       assert (lower[i]<big);
    1117       assert (upper[i]>-big);
    1118     }
    1119     n = solver_->getNumRows();
    1120     lower = solver_->getRowLower() ;
    1121     upper = solver_->getRowUpper() ;
    1122     for (i=0;i<n;i++) {
    1123       assert (lower[i]<big);
    1124       assert (upper[i]>-big);
    1125     }
    1126   }
    11271053#endif
    11281054  // original solver (only set if pre-processing)
     
    12961222  if (eventHandler)
    12971223    eventHandler->setModel(this);
    1298 #if MODEL12
    12991224#define CLIQUE_ANALYSIS
    1300 #endif
    13011225#ifdef CLIQUE_ANALYSIS
    13021226  // set up for probing
     
    14281352      = dynamic_cast<OsiClpSolverInterface *> (solver_);
    14291353    if (clpSolver) {
    1430       //#define CLP_QUICK_OPTIONS
    1431 #ifdef CLP_QUICK_OPTIONS
    1432       // Try and re-use regions   
    1433       ClpSimplex * simplex = clpSolver->getModelPtr();
    1434       simplex->setPersistenceFlag(1);
    1435 #if 0
    1436       clpSolver->deleteScaleFactors();
    1437       int value=131072;
    1438       clpSolver->setSpecialOptions(clpSolver->specialOptions()|value);
    1439       if ((clpSolver->specialOptions()&value)!=0)
    1440         simplex->setSpecialOptions(simplex->specialOptions()|value);
    1441 #else
    1442 #undef CLP_QUICK_OPTIONS
    1443       //if (simplex->numberRows()<50)
    1444       //simplex->setAlphaAccuracy(1.0);
    1445       //clpSolver->setSpecialOptions((clpSolver->specialOptions()&~128)|65536);
    1446       //simplex->setMoreSpecialOptions(simplex->moreSpecialOptions()|4);
    1447       //simplex->setSpecialOptions(simplex->specialOptions()|65536);
    1448       //simplex->startPermanentArrays();
    1449 #endif
    1450 #endif
    14511354      ClpSimplex * clpSimplex = clpSolver->getModelPtr();
    14521355      if ((specialOptions_&32)==0) {
     
    16171520  // If debugger exists set specialOptions_ bit
    16181521  if (solver_->getRowCutDebuggerAlways()) {
    1619 #ifdef CHECK_PATH
    1620     if (numberColumns_Z==-1) {
    1621       // If not -1 then in nested B&B
    1622       OsiRowCutDebugger * debugger =
    1623         const_cast<OsiRowCutDebugger *> (solver_->getRowCutDebuggerAlways());
    1624       debuggerSolution_Z = debugger->optimalSolution();
    1625       numberColumns_Z = getNumCols();
    1626     }
    1627   } else {
    1628     debuggerSolution_Z = NULL;
    1629     numberColumns_Z = -1;
    1630 #else
    16311522    specialOptions_ |= 1;
    1632 #endif
    16331523  }
    16341524
     
    17401630  delete [] walkback_ ;
    17411631  walkback_ = new CbcNodeInfo * [maximumDepth_] ;
    1742 #ifdef NODE_LAST
    17431632  lastDepth_=0;
    17441633  delete [] lastNodeInfo_ ;
     
    17501639  delete [] lastCut_;
    17511640  lastCut_ = new const OsiRowCut * [maximumCuts_];
    1752 #endif
    17531641/*
    17541642  Used to generate bound edits for CbcPartialNodeInfo.
     
    20931981   if (tryNewSearch) {
    20941982     // back to solver without cuts?
    2095 #if 1
    20961983     OsiSolverInterface * solver2 = continuousSolver_->clone();
    2097 #else
    2098      OsiSolverInterface * solver2 = saveSolver->clone();
    2099 #endif
    21001984     const double *lower = saveSolver->getColLower() ;
    21011985     const double *upper = saveSolver->getColUpper() ;
     
    26012485      threadInfo[i].dantzigState=0; // 0 unset, -1 waiting to be set, 1 set
    26022486      threadInfo[i].locked=false;
    2603 #if CBC_THREAD_DEBUG
    2604       threadInfo[i].threadNumber=i+2;
    2605 #endif
    26062487      threadInfo[i].delNode = NULL;
    26072488      threadInfo[i].maxDeleteNode=0;
     
    26262507    threadInfo[numberThreads_].numberTimesUnlocked=0;
    26272508    threadInfo[numberThreads_].locked=false;
    2628 #if CBC_THREAD_DEBUG
    2629     threadInfo[numberThreads_].threadNumber=1;
    2630 #endif
    26312509  }
    26322510#endif
     
    29062784      if (tryNewSearch) {
    29072785        // back to solver without cuts?
    2908 #if 0
    2909         int numberCuts = solver_->getNumRows()-continuousSolver_->getNumRows();
    2910         OsiSolverInterface * solver2;
    2911         if (numberCuts>50&&numberCuts*10>solver_->getNumRows())
    2912           solver2 = continuousSolver_->clone();
    2913         else
    2914           solver2 = saveSolver->clone();
    2915 #else
    29162786        OsiSolverInterface * solver2 = saveSolver->clone();
    2917 #endif
    29182787        const double *lower = saveSolver->getColLower() ;
    29192788        const double *upper = saveSolver->getColUpper() ;
     
    30872956      if (searchStrategy_==2) {
    30882957        // may be time to tweak numberBeforeTrust
    3089         if (numberStrongIterations_*5<numberIterations_&&numberNodes_<-10000) {
     2958        if (numberStrongIterations_*5<numberIterations_&&numberNodes_<10000) {
    30902959          int numberDone = strongInfo_[0]-strongInfo_[3];
    30912960          int numberFixed = strongInfo_[1]-strongInfo_[4];
     
    31252994    if (numberNodes_>=lastPrintEvery) {
    31262995      lastPrintEvery = numberNodes_ + printFrequency_;
    3127 #ifdef CBC_INSTRUMENT
    3128       if (0) {
    3129         printf("==Start instrument\n");
    3130         for (int iObject=0;iObject<numberObjects_;iObject++) {
    3131           CbcSimpleIntegerDynamicPseudoCost * obj =
    3132             dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object_[iObject]) ;
    3133           if (obj)
    3134             obj->print();
    3135         }
    3136         printf("==End instrument\n");
    3137       }
    3138 #endif
    31392996      if (parallelMode()>0)
    31402997        lockThread();
     
    33473204        goneParallel=true;
    33483205        int nAffected=splitModel(numberThreads_,threadModel,defaultParallelNodes);
    3349 #ifndef NDEBUG
    3350         int saveTreeSize2 = tree_->size();
    3351 #endif
    33523206        int iThread;
    33533207        // do all until finished
     
    33933247          walkback_[i]->unmark();
    33943248        }
    3395         assert (saveTreeSize2 == tree_->size());
    3396         if (0) {
    3397           // put back cut counts
    3398           for (int i=0;i<nAffected;i++) {
    3399             walkback_[i]->decrementCuts(1000000);
    3400           }
    3401         }
    3402 #if 0 //ndef NDEBUG
    3403         for (iObject=0;iObject<numberObjects_;iObject++) {
    3404           CbcSimpleIntegerDynamicPseudoCost * obj =
    3405             dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object_[iObject]) ;
    3406           CbcSimpleIntegerDynamicPseudoCost * obj2 =
    3407             dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(saveObjects[iObject]) ;
    3408           if (obj)
    3409             assert (obj->same(obj2));
    3410         }
    3411 #endif
    34123249        int iModel;
    34133250        double scaleFactor=1.0;
     
    34553292#ifdef CBC_THREAD
    34563293  if (numberThreads_) {
    3457     //printf("stats ");
    3458     //for (unsigned int j=0;j<sizeof(threadStats)/sizeof(int);j++)
    3459     //printf("%d ",threadStats[j]);
    3460     //printf("\n");
    34613294    int i;
    34623295    // Seems to be bug in CoinCpu on Linux - does threads as well despite documentation
     
    34653298      time += threadInfo[i].timeInThread;
    34663299    bool goodTimer = time<(getCurrentSeconds());
    3467     //bool stopped = (!(numberNodes_ < intParam_[CbcMaxNumNode] &&
    3468     //        numberSolutions_ < intParam_[CbcMaxNumSol] &&
    3469     //        totalTime < dblParam_[CbcMaximumSeconds] &&
    3470     //        !stoppedOnGap_&&!eventHappened_));
    34713300    for (i=0;i<numberThreads_;i++) {
    34723301      while (threadInfo[i].returnCode==0) {
     
    38523681  delete [] walkback_ ;
    38533682  walkback_ = NULL ;
    3854 #ifdef NODE_LAST
    38553683  delete [] lastNodeInfo_ ;
    38563684  lastNodeInfo_ = NULL;
     
    38593687  delete [] lastCut_;
    38603688  lastCut_ = NULL;
    3861 #endif
    38623689  delete [] addedCuts_ ;
    38633690  addedCuts_ = NULL ;
     
    39053732  }
    39063733  delete saveSolver;
    3907 #if COIN_DEVELOP>1
    3908   void print_fac_stats();
    3909   //if (!parentModel_)
    3910   //  print_fac_stats();
    3911 #endif
    39123734  if (strategy_&&strategy_->preProcessState()>0) {
    39133735    // undo preprocessing
     
    39553777    if (clpSolver)
    39563778      clpSolver->setFakeObjective(reinterpret_cast<double *> (NULL));
    3957   }
    3958 #endif
    3959 #ifdef CLP_QUICK_OPTIONS
    3960   {
    3961     OsiClpSolverInterface * clpSolver
    3962       = dynamic_cast<OsiClpSolverInterface *> (solver_);
    3963     if (clpSolver) {
    3964       // Try and re-use regions   
    3965       ClpSimplex * simplex = clpSolver->getModelPtr();
    3966       simplex->setPersistenceFlag(0);
    3967       clpSolver->deleteScaleFactors();
    3968       clpSolver->setSpecialOptions(clpSolver->specialOptions()&(~131072));
    3969       simplex->setSpecialOptions(simplex->specialOptions()&(~131072));
    3970       simplex->setAlphaAccuracy(-1.0);
    3971       //clpSolver->setSpecialOptions((clpSolver->specialOptions()&~128)|65536);
    3972     }
    39733779  }
    39743780#endif
     
    40853891  maximumDepth_(0),
    40863892  walkback_(NULL),
    4087 #ifdef NODE_LAST
    40883893  lastNodeInfo_(NULL),
    40893894  lastCut_(NULL),
     
    40923897  maximumCuts_(0),
    40933898  lastNumberCuts_(NULL),
    4094 #endif
    40953899  addedCuts_(NULL),
    40963900  nextRowCut_(NULL),
     
    41603964  resolveAfterTakeOffCuts_(true),
    41613965  maximumNumberIterations_(-1),
    4162 #if NEW_UPDATE_OBJECT>1
    41633966  numberUpdateItems_(0),
    41643967  maximumNumberUpdateItems_(0),
    41653968  updateItems_(NULL),
    4166 #endif
    41673969  numberThreads_(0),
    41683970  threadMode_(0)
     
    42504052  maximumDepth_(0),
    42514053  walkback_(NULL),
    4252 #ifdef NODE_LAST
    42534054  lastNodeInfo_(NULL),
    42544055  lastCut_(NULL),
     
    42574058  maximumCuts_(0),
    42584059  lastNumberCuts_(NULL),
    4259 #endif
    42604060  addedCuts_(NULL),
    42614061  nextRowCut_(NULL),
     
    43224122  resolveAfterTakeOffCuts_(true),
    43234123  maximumNumberIterations_(-1),
    4324 #if NEW_UPDATE_OBJECT>1
    43254124  numberUpdateItems_(0),
    43264125  maximumNumberUpdateItems_(0),
    43274126  updateItems_(NULL),
    4328 #endif
    43294127  numberThreads_(0),
    43304128  threadMode_(0)
     
    45624360  resolveAfterTakeOffCuts_(rhs.resolveAfterTakeOffCuts_),
    45634361  maximumNumberIterations_(rhs.maximumNumberIterations_),
    4564 #if NEW_UPDATE_OBJECT>1
    45654362  numberUpdateItems_(rhs.numberUpdateItems_),
    45664363  maximumNumberUpdateItems_(rhs.maximumNumberUpdateItems_),
    45674364  updateItems_(NULL),
    4568 #endif
    45694365  numberThreads_(rhs.numberThreads_),
    45704366  threadMode_(rhs.threadMode_)
     
    46504446    originalColumns_=NULL;
    46514447  }
    4652 #if NEW_UPDATE_OBJECT>1
    46534448  if (maximumNumberUpdateItems_) {
    46544449    updateItems_ = new CbcObjectUpdateData [maximumNumberUpdateItems_];
     
    46564451      updateItems_[i] = rhs.updateItems_[i];
    46574452  }
    4658 #endif
    46594453  if (maximumWhich_&&rhs.whichGenerator_)
    46604454    whichGenerator_ = CoinCopyOfArray(rhs.whichGenerator_,maximumWhich_);
     
    47354529  if (maximumDepth_) {
    47364530    walkback_ = new CbcNodeInfo * [maximumDepth_];
    4737 #ifdef NODE_LAST
    47384531    lastNodeInfo_ = new CbcNodeInfo * [maximumDepth_] ;
    47394532    lastNumberCuts_ = new int [maximumDepth_] ;
    4740 #endif
    47414533  } else {
    47424534    walkback_ = NULL;
    4743 #ifdef NODE_LAST
    47444535    lastNodeInfo_ = NULL;
    47454536    lastNumberCuts_ = NULL;
    4746 #endif
    4747   }
    4748 #ifdef NODE_LAST
     4537  }
    47494538  maximumCuts_ = rhs.maximumCuts_;
    47504539  if (maximumCuts_) {
     
    47534542    lastCut_ = NULL;
    47544543  }
    4755 #endif
    47564544  synchronizeModel();
    47574545  if (cloneHandler&&!defaultHandler_) {
     
    49044692    resolveAfterTakeOffCuts_=rhs.resolveAfterTakeOffCuts_;
    49054693    maximumNumberIterations_ = rhs.maximumNumberIterations_;
    4906 #if NEW_UPDATE_OBJECT>1
    49074694    numberUpdateItems_ = rhs.numberUpdateItems_;
    49084695    maximumNumberUpdateItems_ = rhs.maximumNumberUpdateItems_;
     
    49154702      updateItems_ = NULL;
    49164703    }
    4917 #endif
    49184704    numberThreads_ = rhs.numberThreads_;
    49194705    threadMode_ = rhs.threadMode_;
     
    50384824      addedCuts_ = NULL;
    50394825    }
    5040 #ifdef NODE_LAST
    50414826    delete [] lastNodeInfo_ ;
    50424827    delete [] lastNumberCuts_ ;
    50434828    delete [] lastCut_;
    5044 #endif
    50454829    bestSolutionBasis_ = rhs.bestSolutionBasis_;
    50464830    nextRowCut_ = NULL;
     
    50484832    if (maximumDepth_) {
    50494833      walkback_ = new CbcNodeInfo * [maximumDepth_];
    5050 #ifdef NODE_LAST
    50514834      lastNodeInfo_ = new CbcNodeInfo * [maximumDepth_] ;
    50524835      lastNumberCuts_ = new int [maximumDepth_] ;
    5053 #endif
    50544836    } else {
    50554837      walkback_ = NULL;
    5056 #ifdef NODE_LAST
    50574838      lastNodeInfo_ = NULL;
    50584839      lastNumberCuts_ = NULL;
    5059 #endif
    5060     }
    5061 #ifdef NODE_LAST
     4840    }
    50624841    maximumCuts_ = rhs.maximumCuts_;
    50634842    if (maximumCuts_) {
     
    50664845      lastCut_ = NULL;
    50674846    }
    5068 #endif
    50694847    synchronizeModel();
    50704848    cbcColLower_ = NULL;
     
    51224900  originalColumns_=NULL;
    51234901  delete strategy_;
    5124 #if NEW_UPDATE_OBJECT>1
    51254902  delete [] updateItems_;
    51264903  updateItems_=NULL;
    51274904  numberUpdateItems_=0;
    51284905  maximumNumberUpdateItems_=0;
    5129 #endif
    51304906  gutsOfDestructor2();
    51314907}
     
    51814957  delete [] walkback_;
    51824958  walkback_=NULL;
    5183 #ifdef NODE_LAST
    51844959  delete [] lastNodeInfo_ ;
    51854960  lastNodeInfo_ = NULL;
     
    51884963  delete [] lastCut_;
    51894964  lastCut_ = NULL;
    5190 #endif
    51914965  delete [] whichGenerator_;
    51924966  whichGenerator_ = NULL;
     
    56165390  applyToModel does all the heavy lifting.
    56175391*/
    5618   //#define CBC_PRINT2
    5619 #ifdef CBC_PRINT2
    5620   printf("Starting bounds at node %d\n",numberNodes_);
    5621 #endif
    56225392  bool sameProblem=false;
    5623 #ifdef NODE_LAST
    56245393  if ((specialOptions_&4096)==0) {
    56255394    {
     
    56785447    lastDepth_=nNode;
    56795448  }
    5680 #endif
    56815449  currentDepth_=nNode;
    56825450/*
     
    57185486        lastws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
    57195487    }
    5720 #if 0
    5721   } else {
    5722     // OPTION - take off slack cuts
    5723     // First see if any cuts are slack
    5724     int numberAdded = currentNumberCuts;
    5725     if (saveNode<2&&false) {
    5726       printf("nNode %d cuts %d\n",saveNode,currentNumberCuts);
    5727       for (int i=0;i<currentNumberCuts;i++)
    5728         addedCuts_[i]->print();
    5729     }
    5730     if (numberAdded&&saveNode<5&&!parentModel_) {
    5731 #if 0
    5732       currentNumberCuts=0;
    5733       for (int j=numberRowsAtContinuous_;
    5734            j<numberAdded+numberRowsAtContinuous_;j++) {
    5735         CoinWarmStartBasis::Status status = lastws->getArtifStatus(j);
    5736         if (status!=CoinWarmStartBasis::basic) {
    5737           lastws->setArtifStatus(currentNumberCuts+numberRowsAtContinuous_,
    5738                                  status);
    5739           addedCuts_[currentNumberCuts++]=addedCuts_[j-numberRowsAtContinuous_];
    5740         }
    5741       }
    5742       if (currentNumberCuts<numberAdded) {
    5743         printf("deleting %d rows\n",numberAdded-currentNumberCuts);
    5744         lastws->resize(currentNumberCuts+numberRowsAtContinuous_,
    5745                        lastws->getNumStructural());
    5746         currentNumberCuts_=currentNumberCuts;
    5747       }
    5748 #else
    5749       int nDelete=0;
    5750       for (int j=numberRowsAtContinuous_;
    5751            j<numberAdded+numberRowsAtContinuous_;j++) {
    5752         CoinWarmStartBasis::Status status = lastws->getArtifStatus(j);
    5753         if (status==CoinWarmStartBasis::basic)
    5754           nDelete++;
    5755       }
    5756       if (nDelete)
    5757         printf("depth %d can delete %d\n",saveNode-1,nDelete);
    5758 #endif
    5759     }
    5760 #endif
    5761   }
    5762 #endif
    5763   if (0) {
    5764     int numberDebugValues=18;
    5765     double * debugValues = new double[numberDebugValues];
    5766     CoinZeroN(debugValues,numberDebugValues);
    5767     debugValues[1]=6.0;
    5768     debugValues[3]=60.0;
    5769     debugValues[4]=6.0;
    5770     debugValues[6]=60.0;
    5771     debugValues[7]=16.0;
    5772     debugValues[9]=70.0;
    5773     debugValues[10]=7.0;
    5774     debugValues[12]=70.0;
    5775     debugValues[13]=12.0;
    5776     debugValues[15]=75.0;
    5777     int nBad=0;
    5778     for (int j=0;j<numberColumns;j++) {
    5779       if (integerInfo_[j]) {
    5780         if(solver_->getColLower()[j]>debugValues[j]||
    5781            solver_->getColUpper()[j]<debugValues[j]) {
    5782           printf("** (%g) ** ",debugValues[j]);
    5783           nBad++;
    5784         }
    5785         printf("%d bounds %g %g\n",j,solver_->getColLower()[j],solver_->getColUpper()[j]);
    5786       }
    5787     }
    5788     if (nBad)
    5789       printf("%d BAD\n",nBad);
    5790     else
    5791       printf("OKAY\n");
    5792     delete [] debugValues;
    5793   }
     5488  }
     5489#endif
    57945490  return sameProblem;
    57955491}
     
    58085504  comments there.
    58095505*/
    5810 #ifdef NODE_LAST
    58115506  bool sameProblem=
    5812 #endif
    58135507    addCuts1(node,lastws);
    58145508  int i;
     
    59295623      lastws->resize(numberRowsNow,numberColumns);
    59305624      // Take out as local search can give bad basisassert (lastws->fullBasis());
    5931 #ifdef NODE_LAST
    59325625      bool canMissStuff=false;
    59335626      if ((specialOptions_&4096)==0) {
     
    59885681            nDiff += nDiff2;
    59895682          }
    5990 #ifdef COIN_DEVELOP_z
    5991           printf("add now %d add last %d - same %d, diff %d %s\n",
    5992                  numberToAdd,lastNumberCuts2_,nSame,nDiff,
    5993                  !nDiff ? "YES" : "NO1");
    5994 #endif
    59955683          canMissStuff=!nDiff&&sameProblem;
    59965684          // But only if number of rows looks OK
     
    60135701        }
    60145702      }
    6015 #endif
    6016 #ifdef NODE_LAST
    60175703      if (!canMissStuff) {
    60185704        //if (canMissStuff)
     
    60205706        //printf("Not Skipped\n");
    60215707        //int n1=solver_->getNumRows();
    6022 #endif
    60235708        if ((specialOptions_&4096)==0) {
    60245709          solver_->restoreBaseModel(numberRowsAtContinuous_);
     
    60385723        //int n3=solver_->getNumRows();
    60395724        //printf("NBefore %d, after del %d, now %d\n",n1,n2,n3);
    6040 #ifdef NODE_LAST
    6041       } else {
    6042 #ifdef COIN_HAS_CLP
    6043 #if 0 //def COIN_DEVELOP
    6044         OsiClpSolverInterface * clpSolver
    6045           = dynamic_cast<OsiClpSolverInterface *> (solver_);
    6046         if (clpSolver) {
    6047           printf("Skipped - whatschanged %d\n",clpSolver->getModelPtr()->whatsChanged());
    6048         }
    6049 #endif
    6050 #endif
    6051       }
    6052 #endif
     5725      }
    60535726#     ifdef CBC_CHECK_BASIS
    60545727      printf("addCuts: stripped basis; rows %d + %d\n",
     
    60655738*/
    60665739    solver_->setWarmStart(lastws);
    6067 #if 0
    6068     if ((numberNodes_%printFrequency_)==0) {
    6069       printf("Objective %g, depth %d, unsatisfied %d\n",
    6070              node->objectiveValue(),
    6071              node->depth(),node->numberUnsatisfied());
    6072     }
    6073 #endif
    60745740/*
    60755741  Clean up and we're out of here.
     
    61335799  down the current situation.
    61345800*/
    6135 #if 0
    6136 int CbcModel::reducedCostFix ()
    6137 
    6138 {
    6139   if(!solverCharacteristics_->reducedCostsAccurate())
    6140     return 0; //NLP
    6141   double cutoff = getCutoff() ;
    6142   double direction = solver_->getObjSense() ;
    6143   double gap = cutoff - solver_->getObjValue()*direction ;
    6144   double tolerance;
    6145   solver_->getDblParam(OsiDualTolerance,tolerance) ;
    6146   if (gap<=0.0)
    6147     gap = tolerance; //return 0;
    6148   gap += 100.0*tolerance;
    6149   double integerTolerance = getDblParam(CbcIntegerTolerance) ;
    6150 
    6151   const double *lower = solver_->getColLower() ;
    6152   const double *upper = solver_->getColUpper() ;
    6153   const double *solution = solver_->getColSolution() ;
    6154   const double *reducedCost = solver_->getReducedCost() ;
    6155 
    6156   int numberFixed = 0 ;
    6157 
    6158 # ifdef COIN_HAS_CLP
    6159   OsiClpSolverInterface * clpSolver
    6160     = dynamic_cast<OsiClpSolverInterface *> (solver_);
    6161   ClpSimplex * clpSimplex=NULL;
    6162   if (clpSolver)
    6163     clpSimplex = clpSolver->getModelPtr();
    6164 # endif
    6165   for (int i = 0 ; i < numberIntegers_ ; i++) {
    6166     int iColumn = integerVariable_[i] ;
    6167     double djValue = direction*reducedCost[iColumn] ;
    6168     if (upper[iColumn]-lower[iColumn] > integerTolerance) {
    6169       if (solution[iColumn] < lower[iColumn]+integerTolerance && djValue > gap) {
    6170 #ifdef COIN_HAS_CLP
    6171         // may just have been fixed before
    6172         if (clpSimplex) {
    6173           if (clpSimplex->getColumnStatus(iColumn)==ClpSimplex::basic) {
    6174 #ifdef COIN_DEVELOP
    6175             printf("DJfix %d has status of %d, dj of %g gap %g, bounds %g %g\n",
    6176                    iColumn,clpSimplex->getColumnStatus(iColumn),
    6177                    djValue,gap,lower[iColumn],upper[iColumn]);
    6178 #endif
    6179           } else {         
    6180             assert(clpSimplex->getColumnStatus(iColumn)==ClpSimplex::atLowerBound||
    6181                    clpSimplex->getColumnStatus(iColumn)==ClpSimplex::isFixed);
    6182           }
    6183         }
    6184 #endif
    6185         solver_->setColUpper(iColumn,lower[iColumn]) ;
    6186         numberFixed++ ;
    6187       } else if (solution[iColumn] > upper[iColumn]-integerTolerance && -djValue > gap) {
    6188 #ifdef COIN_HAS_CLP
    6189         // may just have been fixed before
    6190         if (clpSimplex) {
    6191           if (clpSimplex->getColumnStatus(iColumn)==ClpSimplex::basic) {
    6192 #ifdef COIN_DEVELOP
    6193             printf("DJfix %d has status of %d, dj of %g gap %g, bounds %g %g\n",
    6194                    iColumn,clpSimplex->getColumnStatus(iColumn),
    6195                    djValue,gap,lower[iColumn],upper[iColumn]);
    6196 #endif
    6197           } else {         
    6198             assert(clpSimplex->getColumnStatus(iColumn)==ClpSimplex::atUpperBound||
    6199                    clpSimplex->getColumnStatus(iColumn)==ClpSimplex::isFixed);
    6200           }
    6201         }
    6202 #endif
    6203         solver_->setColLower(iColumn,upper[iColumn]) ;
    6204         numberFixed++ ;
    6205       }
    6206     }
    6207   }
    6208   numberDJFixed_ += numberFixed;
    6209   return numberFixed; }
    6210 #else
    62115801int CbcModel::reducedCostFix ()
    62125802
     
    63035893  }
    63045894  numberDJFixed_ += numberFixed-numberTightened;
    6305 #ifdef COIN_DEVELOP
    6306   //if (numberTightened)
    6307   //printf("%d tightened, %d others fixed\n",numberTightened,
    6308   //   numberFixed-numberTightened);
    6309 #endif
    63105895  return numberFixed; }
    6311 #endif
    63125896// Collect coding to replace whichGenerator
    63135897void
     
    64676051  }
    64686052 
    6469 #if NEW_UPDATE_OBJECT==0
    6470   // Update branching information if wanted
    6471   if(node &&branchingMethod_)
    6472     branchingMethod_->updateInformation(solver_,node);
    6473 #elif NEW_UPDATE_OBJECT<2
    6474   // Update branching information if wanted
    6475   if(node &&branchingMethod_) {
    6476     OsiBranchingObject * bobj = node->modifiableBranchingObject();
    6477     CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (bobj);
    6478     if (cbcobj) {
    6479       CbcObject * object = cbcobj->object();
    6480       CbcObjectUpdateData update = object->createUpdateInformation(solver_,node,cbcobj);
    6481       object->updateInformation(update);
    6482     } else {
    6483       branchingMethod_->updateInformation(solver_,node);
    6484     }
    6485   }
    6486 #else
    64876053  // Update branching information if wanted
    64886054  if(node &&branchingMethod_) {
     
    65326098        else
    65336099          movement = value -floor(value);
    6534 #if 0
    6535         // OUT as much too complicated - we are not at a natural hotstart place
    6536         OsiBranchingInformation usefulInfo=usefulInformation();
    6537         // hotInfo is meant for BEFORE a branch so we need to fool
    6538         // was much simpler with alternate method
    6539         double save[3];
    6540         save[0]=usefulInfo.lower_[iColumn];
    6541         save[1]=usefulInfo.solution_[iColumn];
    6542         save[2]=usefulInfo.upper_[iColumn];
    6543         usefulInfo.lower_[iColumn]=floor(value);
    6544         usefulInfo.solution_[iColumn]=value;
    6545         usefulInfo.upper_[iColumn]=ceil(value);
    6546         OsiHotInfo hotInfo(solver_,&usefulInfo,&object,0);
    6547         usefulInfo.lower_[iColumn]=save[0];
    6548         usefulInfo.solution_[iColumn]=save[1];
    6549         usefulInfo.upper_[iColumn]=save[2];
    6550         if (branch) {
    6551           hotInfo.setUpStatus(iStatus);
    6552           hotInfo.setUpChange(changeInObjective);
    6553           //object->setUpEstimate(movement);
    6554         } else {
    6555           hotInfo.setDownStatus(iStatus);
    6556           hotInfo.setDownChange(changeInObjective);
    6557           //object->setDownEstimate(movement);
    6558         }
    6559         branchingMethod_->chooseMethod()->updateInformation(&usefulInfo,branch,&hotInfo);
    6560 #else
    65616100        branchingMethod_->chooseMethod()->updateInformation(iObject,branch,changeInObjective,
    65626101                                                            movement,iStatus);
    6563 #endif
    6564       }
    6565     }
    6566   }
    6567 #endif
     6102      }
     6103    }
     6104  }
    65686105
    65696106#ifdef CBC_DEBUG
     
    68036340      }
    68046341# endif
     6342      int switchOff = (!doCutsNow(1)&&!fullScan) ? 1 : 0;
     6343      //if (2*solver_->getNumRows()+solver_->getNumCols()>1000)
     6344      //switchOff *= 2;
    68056345      for (i = 0;i<numberCutGenerators_;i++) {
    68066346        int numberRowCutsBefore = theseCuts.sizeRowCuts() ;
     
    68096349        int numberColumnCutsAfter = numberColumnCutsBefore;
    68106350        bool generate = generator_[i]->normal();
    6811         //if (i!=1)
    6812         //continue;
    68136351        // skip if not optimal and should be (maybe a cut generator has fixed variables)
    6814         if (generator_[i]->needsOptimalBasis()&&!solver_->basisIsAvailable())
     6352        if (generator_[i]->howOften()==-100||
     6353            (generator_[i]->needsOptimalBasis()&&!solver_->basisIsAvailable())
     6354            ||generator_[i]->switchedOff())
    68156355          generate=false;
    6816         if (generator_[i]->switchedOff())
    6817           generate=false;
    6818 #if MODEL5
    6819         if (generator_[i]->howOften()==1000000||
    6820             generator_[i]->howOften()==-100||
    6821             generator_[i]->howOften()==0)
    6822           generate=false;
    6823 #endif
    6824         if (!doCutsNow(1)&&!fullScan) {
     6356        if (switchOff) {
    68256357          // switch off if default
    6826 #if MODEL6
    6827           if (generator_[i]->whatDepth()<0)
     6358          if (generator_[i]->howOften()==1&&generator_[i]->whatDepth()<0) {
     6359            /*if (generate)
     6360              printf("Gg %d %d %d\n",i,
     6361              generator_[i]->howOften(),generator_[i]->whatDepth());*/
    68286362            generate=false;
    6829 #else
    6830           if (generator_[i]->howOften()==1&&generator_[i]->whatDepth()<0)
     6363          } else if (currentDepth_>-10&&switchOff==2) {
    68316364            generate=false;
    6832 #endif
     6365          }
    68336366        }
    68346367        if (generate) {
     
    69076440                solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
    69086441                solver_->writeMpsNative("badCut.mps",NULL,NULL,2);
    6909 #if 1 //#ifdef NDEBUG
    69106442                printf("Cut generator %d (%s) produced invalid cut (%dth in this go)\n",
    69116443                       i,generator_[i]->cutGeneratorName(),k-numberRowCutsBefore);
     
    69186450                }
    69196451                abort();
    6920 #endif
    69216452              }
    69226453              assert(!debugger->invalidCut(thisCut)) ;
     
    72576788      int found = -1; // no solution found
    72586789      for (i = 0;i<numberHeuristics_;i++) {
    7259 #if MODEL3
    72606790        // skip if can't run here
    72616791        if (!heuristic_[i]->shouldHeurRun())
    72626792          continue;
    7263 #endif
    72646793        // see if heuristic will do anything
    72656794        double saveValue = heuristicValue ;
     
    75017030    { int cutIterations = solver_->getIterationCount() ;
    75027031      if (numberOldActiveCuts_+numberNewCuts_
    7503 #ifdef NODE_LAST
    75047032          &&(numberNewCuts_||doCutsNow(1))
    7505 #endif
    75067033          ) {
    75077034        OsiCuts * saveCuts = node ? NULL : &slackCuts;
    7508 #ifdef NODE_LAST
    75097035        int nDel=takeOffCuts(cuts,resolveAfterTakeOffCuts_,saveCuts,numberToAdd,addCuts) ;
    75107036        if (nDel)
    75117037          lastNumberCuts2_=0;
    7512 #else
    7513         takeOffCuts(cuts,resolveAfterTakeOffCuts_,saveCuts,numberToAdd,addCuts) ;
    7514 #endif
    75157038        if (solver_->isDualObjectiveLimitReached()&&resolveAfterTakeOffCuts_)
    75167039          { feasible = false ;
     
    77017224    if (feasible) {
    77027225      for (int i = 0;i<numberHeuristics_;i++) {
    7703 #if MODEL3
    77047226        // skip if can't run here
    77057227        if (!heuristic_[i]->shouldHeurRun())
    77067228          continue;
    7707 #endif
    77087229        // see if heuristic will do anything
    77097230        double saveValue = heuristicValue ;
     
    79437464      double value = generator_[i]->numberCutsInTotal() ;
    79447465#endif
    7945 #if MODEL7
    7946       // But cap
    7947       totalCuts += CoinMin(value,2.0*currentPassNumber_+10);
    7948 #else
    79497466      totalCuts += value;
    7950 #endif
    79517467    }
    79527468    int iProbing=-1;
     
    79937509          }
    79947510          if (!thisCuts||howOften == -99) {
    7995 #if MODEL8
    7996             howOften = -100 ;
    7997 #else
    7998             if (howOften == -99||howOften == -98)
     7511            if (howOften == -99||howOften == -98) {
    79997512              howOften = -100 ;
    8000             else
     7513            } else {
    80017514              howOften = 1000000+SCANCUTS; // wait until next time
    8002 #endif
     7515              if (probing) {
     7516                // not quite so drastic
     7517                howOften=1000000+1;
     7518                probing->setMaxLook(1);
     7519                probing->setMaxProbe(123);
     7520              }
     7521            }
    80037522          } else if (thisCuts+generator_[i]->numberColumnCuts()<smallProblem) {
    80047523            if (howOften!=1&&!probingWasOnBut) {
     
    84717990    }
    84727991  }
    8473 #if 0
    8474   {
    8475     int iColumn;
    8476     int numberColumns = solver_->getNumCols();
    8477     const double * columnLower = solver_->getColLower();
    8478     const double * columnUpper = solver_->getColUpper();
    8479     const double * sol = solver_->getColSolution();
    8480     bool feasible=true;
    8481     double xx[37];
    8482     memset(xx,0,sizeof(xx));
    8483     xx[6]=xx[7]=xx[9]=xx[18]=xx[26]=xx[36]=1.0;
    8484     for (iColumn= 0;iColumn<numberColumns;iColumn++) {
    8485       if (solver_->isInteger(iColumn)) {
    8486         //printf("yy %d at %g (bounds %g, %g)\n",iColumn,
    8487         //     sol[iColumn],columnLower[iColumn],columnUpper[iColumn]);
    8488         if (columnLower[iColumn]>xx[iColumn]||
    8489             columnUpper[iColumn]<xx[iColumn])
    8490           feasible=false;
    8491         //solver_->setColLower(iColumn,CoinMin(xx[iColumn],columnUpper[iColumn]));
    8492         //solver_->setColUpper(iColumn,CoinMax(xx[iColumn],columnLower[iColumn]));
    8493       }
    8494     }
    8495     if (feasible)
    8496       printf("On Feasible path\n");
    8497   }
    8498 #endif
    84997992/*
    85007993  Reoptimize. Consider the possibility that we should fathom on bounds. But be
     
    1119210685        double heuristicValue=getCutoff();
    1119310686        for (iHeuristic=0;iHeuristic<numberHeuristics_;iHeuristic++) {
    11194 #if MODEL3
    1119510687          // skip if can't run here
    1119610688          if (!heuristic_[iHeuristic]->shouldHeurRun())
    1119710689            continue;
    11198 #endif
    1119910690          double saveValue=heuristicValue;
    1120010691          int ifSol = heuristic_[iHeuristic]->solution(heuristicValue,
     
    1123810729        delete [] walkback_;
    1123910730        walkback_ = new CbcNodeInfo * [maximumDepth_];
    11240 #ifdef NODE_LAST
    1124110731        lastDepth_=0;
    1124210732        delete [] lastNodeInfo_ ;
     
    1124710737        delete [] lastCut_;
    1124810738        lastCut_ = new const OsiRowCut * [maximumCuts_];
    11249 #endif
    1125010739       
    1125110740        OsiCuts cuts;
     
    1148110970    int iColumn=integerVariable[i];
    1148210971    const OsiObject * object = object_[i];
    11483 #if NDEBUG
     10972#ifndef NDEBUG
    1148410973    const CbcSimpleInteger * integerObject =
    1148510974      dynamic_cast<const  CbcSimpleInteger *> (object);
     
    1161711106    int iColumn=integerVariable[i];
    1161811107    const OsiObject * object = object_[i];
    11619 #if NDEBUG
     11108#ifndef NDEBUG
    1162011109    const CbcSimpleInteger * integerObject =
    1162111110      dynamic_cast<const  CbcSimpleInteger *> (object);
     
    1187011359  delete [] walkback_ ;
    1187111360  walkback_ = NULL ;
    11872 #ifdef NODE_LAST
    1187311361  delete [] lastNodeInfo_ ;
    1187411362  lastNodeInfo_ = NULL;
     
    1187711365  delete [] lastCut_;
    1187811366  lastCut_ = NULL;
    11879 #endif
    1188011367  delete [] addedCuts_ ;
    1188111368  addedCuts_ = NULL ;
     
    1233111818      //branchingState=0;
    1233211819    }
    12333 #if MODEL10
    12334 #if NEW_UPDATE_OBJECT>1
    1233511820    if (!oldNode) {
    1233611821      if (numberUpdateItems_) {
     
    1235611841      }
    1235711842    }
    12358 #endif
    12359 #endif
    1236011843    if (solverCharacteristics_ &&
    1236111844        solverCharacteristics_->solutionAddsCuts() && // we are in some OA based bab
     
    1296512448            parameters[i].model=NULL;
    1296612449          for (int i=iChunk;i<CoinMin(numberHeuristics_,iChunk+chunk);i++) {
    12967 #if MODEL3
    1296812450            // skip if can't run here
    1296912451            if (!heuristic_[i]->shouldHeurRun())
    1297012452              continue;
    12971 #endif
    1297212453            parameters[i-iChunk].solutionValue=heuristicValue;
    1297312454            CbcModel * newModel = new CbcModel(*this);
     
    1303412515#endif
    1303512516        for (i = 0;i<numberHeuristics_;i++) {
    13036 #if MODEL3
    1303712517          // skip if can't run here
    1303812518          if (!heuristic_[i]->shouldHeurRun())
    1303912519            continue;
    13040 #endif
    1304112520          // see if heuristic will do anything
    1304212521          double saveValue = heuristicValue ;
     
    1332312802  currentNode_=node; // so can be accessed elsewhere
    1332412803  double bestObjective = bestObjective_;
    13325 #ifdef CBC_DEBUG
    13326   printf("%d unsat, way %d, obj %g est %g\n",
    13327          node->numberUnsatisfied(),node->way(),node->objectiveValue(),
    13328          node->guessedObjectiveValue());
    13329 #endif
    13330 #if 0
    13331   if (node->objectiveValue()>getCutoff()) {
    13332     printf("cutoff\n");
    13333     assert (node->nodeInfo());
    13334     node->nodeInfo()->decrement(node->nodeInfo()->numberBranchesLeft()) ;
    13335     delete node;
    13336     node=NULL;
    13337     newNode=NULL;
    13338     return 0;
    13339   }
    13340 #endif
    13341 #if NEW_UPDATE_OBJECT==0
    13342   // Save clone in branching decision
    13343   if(branchingMethod_)
    13344     branchingMethod_->saveBranchingObject(node->modifiableBranchingObject());
    13345 #elif NEW_UPDATE_OBJECT>1
    1334612804  numberUpdateItems_=0;
    13347 #endif
    1334812805  // Say not on optimal path
    1334912806  bool onOptimalPath=false;
     
    1339012847    maximumDepth_ = baseModel->maximumDepth_;
    1339112848    walkback_ = baseModel->walkback_;
    13392 #ifdef NODE_LAST
    1339312849    lastNodeInfo_ = baseModel->lastNodeInfo_;
    1339412850    lastNumberCuts_ = baseModel->lastNumberCuts_;
    1339512851    lastCut_ = baseModel->lastCut_;
    1339612852    lastNumberCuts2_ = baseModel->lastNumberCuts2_;
    13397 #endif
    1339812853  }
    1339912854  int save2 = maximumDepth_;
     
    1340812863    baseModel->maximumDepth_ = maximumDepth_;
    1340912864    baseModel->walkback_ = walkback_;
    13410 #ifdef NODE_LAST
    1341112865    baseModel->lastNodeInfo_ = lastNodeInfo_;
    1341212866    baseModel->lastNumberCuts_ = lastNumberCuts_;
    1341312867    baseModel->lastCut_ = lastCut_;
    1341412868    baseModel->lastNumberCuts2_ = lastNumberCuts2_;
    13415 #endif
    1341612869  }
    1341712870  int branchesLeft=0;
     
    1353112984          &&!parentModel_) {
    1353212985#define FATHOM_BIAS -2
    13533         //#ifdef COIN_DEVELOP
    1353412986        if (numberNodes_==1) {
    1353512987          int numberNodesBeforeFathom = 500;
     
    1355313005        //double * upperBefore = NULL;
    1355413006        int fastNodeDepth1 = -fastNodeDepth_ % 1000000;
    13555 #if MODEL11
    13556         int numberNodesBeforeFathom = 1000;
    13557 #else
    1355813007        int numberNodesBeforeFathom = 500;
    13559 #endif
    1356013008        if (fastNodeDepth_<-1000001) {
    1356113009          numberNodesBeforeFathom = (-fastNodeDepth_)/1000000;
    13562           numberNodesBeforeFathom = 250*numberNodesBeforeFathom;
     13010          numberNodesBeforeFathom = 100*numberNodesBeforeFathom;
    1356313011        }
    1356413012        int go_fathom = FATHOM_BIAS+fastNodeDepth1;
     
    1409513543    if (parallelMode()>0)
    1409613544      lockThread();
    14097 #if NEW_UPDATE_OBJECT>1
    1409813545    if (parallelMode()<=0) {
    1409913546      if (numberUpdateItems_) {
     
    1411913566      }
    1412013567    }
    14121 #endif
    1412213568    if (newNode)
    1412313569      if (newNode&&newNode->active()) {
     
    1417213618          int iHeur ;
    1417313619          for (iHeur = 0 ; iHeur < numberHeuristics_ ; iHeur++) {
    14174 #if MODEL3
    1417513620            // skip if can't run here
    1417613621            if (!heuristic_[iHeur]->shouldHeurRun())
    1417713622              continue;
    14178 #endif
    1417913623            double saveValue = heurValue ;
    1418013624            int ifSol = heuristic_[iHeur]->solution(heurValue,newSolution) ;
     
    1420313647            lockThread();
    1420413648          if (parallelMode()>=0) {
    14205 #define PUSH_LATER
    14206 #ifdef PUSH_LATER
    1420713649            if (!mutex_) // only if serial
    14208 #endif
    1420913650              tree_->push(newNode) ;
    1421013651          }
     
    1426813709          node->nodeInfo()->setNodeNumber(numberNodes2_);
    1426913710        if (parallelMode()>=0) {
    14270 #ifdef PUSH_LATER
    1427113711          if (!mutex_) // only if serial
    14272 #endif
    1427313712            tree_->push(node) ;
    1427413713        }
     
    1438113820  return foundSolution;
    1438213821}
    14383 #if NEW_UPDATE_OBJECT>1
    1438413822// Adds an update information object
    1438513823void
    1438613824CbcModel::addUpdateInformation(const CbcObjectUpdateData & data)
    1438713825{
    14388 #if 0
    14389   CbcObject * object = dynamic_cast<CbcObject *> (data.object_);
    14390   bool found=false;
    14391   for (int j=0;j<numberObjects_;j++) {
    14392     if (object== object_[j]) {
    14393       found=true;
    14394       if (j!=data.objectNumber_) {
    14395         printf("bad number\n");
    14396       }
    14397       break;
    14398     }
    14399   }
    14400   assert (found);
    14401 #endif
    1440213826  if (numberUpdateItems_==maximumNumberUpdateItems_) {
    1440313827    maximumNumberUpdateItems_ += 10;
     
    1441013834  updateItems_[numberUpdateItems_++]=data;
    1441113835}
    14412 #endif
    1441313836#ifdef CBC_THREAD
    1441413837// Split up nodes - returns number of CbcNodeInfo's affected
     
    1456413987    stateOfSearch_=baseModel->stateOfSearch_;
    1456513988    stuff->saveStuff[1]=stateOfSearch_;
    14566 #if NEW_UPDATE_OBJECT>1
    1456713989    for (int iObject = 0 ; iObject < numberObjects_ ; iObject++) {
    1456813990      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     
    1457513997      }
    1457613998    }
    14577 #endif
    1457813999 } else if (mode==1) {
    1457914000    lockThread();
     
    1458114002    assert (stuff);
    1458214003    //stateOfSearch_
    14583 #if 1
    1458414004    if(stuff->saveStuff[0]!=searchStrategy_) {
    1458514005#ifdef COIN_DEVELOP
     
    1459614016      baseModel->stateOfSearch_=stateOfSearch_;
    1459714017    }
    14598 #endif
    14599 #if NEW_UPDATE_OBJECT>1
    1460014018    if (numberUpdateItems_) {
    1460114019      for (int i=0;i<numberUpdateItems_;i++) {
     
    1460814026      numberUpdateItems_=0;
    1460914027    }
    14610 #endif
    1461114028    if (eventHappened_)
    1461214029      baseModel->eventHappened_=true;
     
    1461514032      numberIterations_ - numberFixedAtRoot_;
    1461614033    baseModel->numberSolves_ += numberSolves_;
    14617 #ifdef PUSH_LATER
    1461814034    if (stuff->node)
    1461914035      baseModel->tree_->push(stuff->node);
    1462014036    if (stuff->createdNode)
    1462114037      baseModel->tree_->push(stuff->createdNode);
    14622 #endif
    1462314038    unlockThread();
    1462414039  } else if (mode==2) {
     
    1464414059    if (parallelMode()>=0) {
    1464514060      walkback_ = NULL;
    14646 #ifdef NODE_LAST
    1464714061      lastNodeInfo_ = NULL;
    1464814062      lastNumberCuts_ = NULL;
    1464914063      lastCut_ = NULL;
    14650 #endif
    1465114064      //addedCuts_ = NULL;
    1465214065      tree_ = NULL;
     
    1467414087      walkback_ = NULL;
    1467514088      //addedCuts_ = NULL;
    14676 #ifdef NODE_LAST
    1467714089      delete [] lastNodeInfo_ ;
    1467814090      lastNodeInfo_ = NULL;
     
    1468114093      delete [] lastCut_ ;
    1468214094      lastCut_ = NULL;
    14683 #endif
    1468414095      delete tree_;
    1468514096      tree_ = NULL;
     
    1477614187      }
    1477714188      //stateOfSearch_
    14778 #if 1
    1477914189      if(stuff->saveStuff[0]!=searchStrategy_) {
    1478014190#ifdef COIN_DEVELOP
     
    1479114201        baseModel->stateOfSearch_=stateOfSearch_;
    1479214202      }
    14793 #endif
    1479414203      int i;
    1479514204      if (eventHappened_)
     
    1491214321            continue;
    1491314322          CbcNode * createdNode=NULL;
    14914 #if 0
    14915           nXXXXXX++;
    14916           if (nXXXXXX==66)
    14917             printf("next one %d\n",nXXXXXX);
    14918           else
    14919             printf("xxxx %d\n",nXXXXXX);
    14920 #endif
    1492114323          // Do real work of node
    1492214324          thisModel->doOneNode(NULL,node,createdNode);
    14923 #if CBC_THREAD_DEBUG
    14924           //printf("SThread %d node %d\n",stuff->threadNumber,thisModel->getNodeCount());
    14925           //node->print();
    14926           //createdNode->print();
    14927           //printf("EThread %d node %d\n",stuff->threadNumber,thisModel->getNodeCount());
    14928 #endif
    1492914325          assert (createdNode);
    1493014326          if (!createdNode->active()) {
     
    1504514441#endif
    1504614442#endif
    15047 #if CBC_THREAD_DEBUG
    15048 static int threadFlag=0;
    15049 /*
    15050   -1000 all quiet
    15051   k locked
    15052   k+n*1000 locked for n'th time
    15053   -k unlocked when already unlocked
    15054 */
    15055 static int lastAction=-1000;
    15056 #if CBC_THREAD_DEBUG>1
    15057 #define MAX_DEBUG 10000000
    15058 static int numberActions=0;
    15059 static int action[MAX_DEBUG];
    15060 #endif
    15061 #endif
    1506214443#ifdef CBC_THREAD
    1506314444/*
     
    1508014461      stuff->timeWaitingToLock+=time-time2;;
    1508114462      stuff->numberTimesLocked++;
    15082 #if CBC_THREAD_DEBUG
    15083       if (lastAction==-1000) {
    15084         lastAction = stuff->threadNumber;
    15085       } else if (lastAction<=0) {
    15086         printf ("thread %d was over unlocked - now locked by %d\n",
    15087                 lastAction,stuff->threadNumber);
    15088         lastAction = stuff->threadNumber;
    15089       } else if ((lastAction%1000)==stuff->threadNumber) {
    15090         printf ("thread %d was already locked at level %d\n",
    15091                 stuff->threadNumber,lastAction);
    15092         lastAction += 1000;
    15093       } else {
    15094         printf ("thread %d was locked - now lock wanted by %d\n",
    15095                 lastAction,stuff->threadNumber);
    15096         abort();
    15097       }
    15098 #if CBC_THREAD_DEBUG>1
    15099       assert (numberActions<MAX_DEBUG);
    15100       action[numberActions++] = lastAction;
    15101 #endif
    15102       assert (threadFlag==0);
    15103       threadFlag=1;
    15104     } else {
    15105       if (lastAction>0&&(lastAction%1000)==stuff->threadNumber) {
    15106         //printf ("OKish - thread %d was already locked at level %d\n",
    15107         //stuff->threadNumber,lastAction);
    15108         lastAction += 1000;
    15109       } else {
    15110         printf ("lastAction %d - now second lock wanted by %d\n",
    15111                 lastAction,stuff->threadNumber);
    15112         abort();
    15113       }
    15114 #if CBC_THREAD_DEBUG>1
    15115       assert (numberActions<MAX_DEBUG);
    15116       action[numberActions++] = lastAction;
    15117 #endif
    15118       assert (threadFlag==1);
    15119 #endif
    1512014463    }
    1512114464  }
     
    1513014473  if (stuff) {
    1513114474    if(stuff->locked) {
    15132 #if CBC_THREAD_DEBUG
    15133       if (lastAction>0&&(lastAction%1000)==stuff->threadNumber) {
    15134         lastAction = -1000;
    15135       } else {
    15136         printf ("lastAction %d - %d trying to unlock\n",
    15137                 lastAction,stuff->threadNumber);
    15138         abort();
    15139       }
    15140 #if CBC_THREAD_DEBUG>1
    15141       assert (numberActions<MAX_DEBUG);
    15142       action[numberActions++] = lastAction;
    15143 #endif
    15144       assert (threadFlag==1);
    15145       threadFlag=0;
    15146 #endif
    1514714475      stuff->locked=false;
    1514814476      pthread_mutex_unlock (stuff->mutex);
     
    1515314481      stuff->timeLocked+=time2-time;
    1515414482      stuff->numberTimesUnlocked++;
    15155 #if CBC_THREAD_DEBUG
    15156     } else {
    15157       printf ("lastAction %d - %d trying to unlock when flag says unlocked!\n",
    15158               lastAction,stuff->threadNumber);
    15159       lastAction = -1000;
    15160 #if CBC_THREAD_DEBUG>1
    15161       assert (numberActions<MAX_DEBUG);
    15162       action[numberActions++] = lastAction;
    15163 #endif
    15164       assert (threadFlag==0);
    15165 #endif
    1516614483    }
    1516714484  }
     
    1518214499  return true;
    1518314500#endif
    15184 }
    15185 // Main loop
    15186 int
    15187 CbcModel::whileIterating(int numberIterations)
    15188 {
    15189   abort();
    15190   int returnCode=0;
    15191 #if 0
    15192   // this should be updated by heuristics strong branching etc etc
    15193   if (numberIterations>0)
    15194    stopNumberIterations_ = numberIterations_+numberIterations;
    15195   else
    15196     stopNumberIterations_=-1;
    15197   while (true) {
    15198     if (tree_->empty()) {
    15199       returnCode=1;
    15200       break;
    15201     }
    15202     if (stopNumberIterations_>0&&numberIterations_>stopNumberIterations_) {
    15203       // out of loop
    15204       break;
    15205     }
    15206     /*
    15207       Periodic activities: Opportunities to
    15208       + tweak the nodeCompare criteria,
    15209     */
    15210     if ((numberNodes_%1000) == 0) {
    15211       bool redoTree=nodeCompare_->every1000Nodes(this, numberNodes_) ;
    15212       // redo tree if wanted
    15213       if (redoTree)
    15214         tree_->setComparison(*nodeCompare_) ;
    15215     }
    15216    
    15217     /*
    15218       Now we come to the meat of the loop. To create the active subproblem, we'll
    15219       pop the most promising node in the live set, rebuild the subproblem it
    15220       represents, and then execute the current arm of the branch to create the
    15221       active subproblem.
    15222     */
    15223     double cutoff = getCutoff() ;
    15224     CbcNode *node = tree_->bestNode(cutoff) ;
    15225     // Possible one on tree worse than cutoff
    15226     if (!node)
    15227       continue;
    15228     CbcNode * createdNode=NULL;
    15229     doOneNode(this,node,createdNode);
    15230   }
    15231   stopNumberIterations_=-1;
    15232 #endif
    15233   return returnCode;
    1523414501}
    1523514502// Returns bounds just before where - initially original bounds - also sets bounds
     
    1535214619  maximumDepth_ *= 2;
    1535314620  CbcNodeInfo ** temp = new CbcNodeInfo * [maximumDepth_];
    15354 #ifdef NODE_LAST
    1535514621  CbcNodeInfo ** temp2 = new CbcNodeInfo * [maximumDepth_];
    1535614622  int * temp3 = new int [maximumDepth_];
    15357 #endif
    1535814623  for (int i=0;i<nNode;i++) {
    1535914624    temp[i] = walkback_[i];
    15360 #ifdef NODE_LAST
    1536114625    temp2[i] = lastNodeInfo_[i];
    1536214626    temp3[i] = lastNumberCuts_[i];
    15363 #endif
    1536414627  }
    1536514628  delete [] walkback_;
    1536614629  walkback_ = temp;
    15367 #ifdef NODE_LAST
    1536814630  delete [] lastNodeInfo_ ;
    1536914631  lastNodeInfo_ = temp2;
    1537014632  delete [] lastNumberCuts_ ;
    1537114633  lastNumberCuts_ = temp3;
    15372 #endif
    1537314634}
    1537414635/* Return true if we want to do cuts
  • trunk/Cbc/src/CbcModel.hpp

    r1160 r1165  
    281281  void resizeWhichGenerator(int numberNow, int numberAfter);
    282282public:
    283 #ifndef CBC_THREAD
    284 #define NEW_UPDATE_OBJECT 2
    285 #else
    286 #define NEW_UPDATE_OBJECT 2
    287 #endif
    288 #if NEW_UPDATE_OBJECT>1
    289283  /// Adds an update information object
    290284  void addUpdateInformation(const CbcObjectUpdateData & data);
    291 #endif
    292285  /** Do one node - broken out for clarity?
    293286      also for parallel (when baseModel!=this)
     
    300293  /// Returns true if locked
    301294  bool isLocked() const;
    302   /// Main loop (without threads but when subtrees) 1 if finished, 0 if stopped
    303 #if 0
    304   int whileIterating(bool & locked, threadId, threadInfo,condition_mutex,condition_main,
    305                      timeWaiting,threadModel,threadStats,totalTime,cutoff,
    306                      eventHandler,saveCompare,lastDepth,lastUnsatisfied,createdNode);
    307 #else
    308   int whileIterating(int numberIterations);
    309 #endif
    310295#ifdef CBC_THREAD
    311296  /**
     
    20422027  */
    20432028  CbcNodeInfo ** walkback_;
    2044 #define NODE_LAST
    2045 #ifdef NODE_LAST
    20462029  CbcNodeInfo ** lastNodeInfo_;
    20472030  const OsiRowCut ** lastCut_;
     
    20502033  int maximumCuts_;
    20512034  int * lastNumberCuts_;
    2052 #endif
    20532035
    20542036  /** The list of cuts initially collected for this subproblem
     
    22852267  /// Maximum number of iterations (designed to be used in heuristics)
    22862268  int maximumNumberIterations_;
    2287 #if NEW_UPDATE_OBJECT>1
    22882269  /// Number of outstanding update information items
    22892270  int numberUpdateItems_;
     
    22922273  /// Update items
    22932274  CbcObjectUpdateData * updateItems_;
    2294 #endif
    22952275  /**
    22962276     Parallel
  • trunk/Cbc/src/CbcNode.cpp

    r1158 r1165  
    1313//#define CHECK_NODE
    1414//#define CBC_CHECK_BASIS
    15 #define CBC_WEAK_STRONG
    1615#include <cassert>
    1716#include <cfloat>
     
    164163
    165164/**
    166   Take care to detach from the owning CbcNode and decrement the reference
    167   count in the parent.  If this is the last nodeInfo object pointing to the
    168   parent, make a recursive call to delete the parent.
     165   Take care to detach from the owning CbcNode and decrement the reference
     166   count in the parent.  If this is the last nodeInfo object pointing to the
     167   parent, make a recursive call to delete the parent.
    169168*/
    170169CbcNodeInfo::~CbcNodeInfo()
     
    173172  printf("CbcNodeInfo %x Destructor parent %x\n",this,parent_);
    174173#endif
    175 
     174 
    176175  assert(!numberPointingToThis_);
    177176  // But there may be some left (max nodes?)
     
    208207  else
    209208    changeThis = change;
    210  // decrement cut counts
     209  // decrement cut counts
    211210  for (i=0;i<numberCuts_;i++) {
    212211    if (cuts_[i]) {
     
    524523  const double * upper = solver->getColUpper();
    525524  int i;
    526 
     525 
    527526  for (i=0;i<numberColumns;i++) {
    528527    lower_[i]=lower[i];
    529528    upper_[i]=upper[i];
    530529  }
    531 
     530 
    532531  basis_ =  dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
    533532}
     
    564563
    565564/*
    566    The basis supplied as a parameter is deleted and replaced with a new basis
    567    appropriate for the node, and lower and upper bounds on variables are
    568    reset according to the stored bounds arrays. Any cuts associated with this
    569    node are added to the list in addCuts, but not actually added to the
    570    constraint system in the model.
    571 
    572    Why pass in a basis at all? The short answer is ``We need the parameter to
    573    pass out a basis, so might as well use it to pass in the size.''
    574    
    575    A longer answer is that in practice we take a memory allocation hit up in
    576    addCuts1 (the only place applyToModel is called) when we setSize() the
    577    basis that's passed in. It's immediately tossed here in favour of a clone
    578    of the basis attached to this nodeInfo. This can probably be fixed, given
    579    a bit of thought.
     565  The basis supplied as a parameter is deleted and replaced with a new basis
     566  appropriate for the node, and lower and upper bounds on variables are
     567  reset according to the stored bounds arrays. Any cuts associated with this
     568  node are added to the list in addCuts, but not actually added to the
     569  constraint system in the model.
     570 
     571  Why pass in a basis at all? The short answer is ``We need the parameter to
     572  pass out a basis, so might as well use it to pass in the size.''
     573 
     574  A longer answer is that in practice we take a memory allocation hit up in
     575  addCuts1 (the only place applyToModel is called) when we setSize() the
     576  basis that's passed in. It's immediately tossed here in favour of a clone
     577  of the basis attached to this nodeInfo. This can probably be fixed, given
     578  a bit of thought.
    580579*/
    581580
     
    584583                                    CbcCountRowCut **addCuts,
    585584                                    int &currentNumberCuts) const
    586 
     585 
    587586{ OsiSolverInterface *solver = model->solver() ;
    588 
     587 
    589588  // branch - do bounds
    590589  assert (active_==7||active_==15);
     
    658657// Default constructor
    659658CbcPartialNodeInfo::CbcPartialNodeInfo()
    660 
     659 
    661660  : CbcNodeInfo(),
    662661    basisDiff_(NULL),
     
    664663    newBounds_(NULL),
    665664    numberChangedBounds_(0)
    666 
     665   
    667666{ /* this space intentionally left blank */ }
    668667
     
    673672                                        const double *boundChanges,
    674673                                        const CoinWarmStartDiff *basisDiff)
    675  : CbcNodeInfo(parent,owner)
     674  : CbcNodeInfo(parent,owner)
    676675{
    677676  basisDiff_ = basisDiff->clone() ;
    678677#ifdef CBC_CHECK_BASIS
    679     std::cout << "Constructor (" <<this<<") "<< std::endl ;
     678  std::cout << "Constructor (" <<this<<") "<< std::endl ;
    680679#endif   
    681 
     680 
    682681  numberChangedBounds_ = numberChangedBounds;
    683682  int size = numberChangedBounds_*(sizeof(double)+sizeof(int));
     
    685684  newBounds_ = reinterpret_cast<double *> (temp);
    686685  variables_ = reinterpret_cast<int *> (newBounds_+numberChangedBounds_);
    687 
     686 
    688687  int i ;
    689688  for (i=0;i<numberChangedBounds_;i++) {
     
    694693
    695694CbcPartialNodeInfo::CbcPartialNodeInfo (const CbcPartialNodeInfo & rhs)
    696 
     695 
    697696  : CbcNodeInfo(rhs)
    698 
     697   
    699698{ basisDiff_ = rhs.basisDiff_->clone() ;
    700 
     699 
    701700#ifdef CBC_CHECK_BASIS
    702701  std::cout << "Copy constructor (" <<this<<") from "<<this<< std::endl ;
     
    707706  newBounds_ = reinterpret_cast<double *> (temp);
    708707  variables_ = reinterpret_cast<int *> (newBounds_+numberChangedBounds_);
    709 
     708 
    710709  int i ;
    711710  for (i=0;i<numberChangedBounds_;i++) {
     
    739738                                       CbcCountRowCut **addCuts,
    740739                                       int &currentNumberCuts) const
    741 
     740 
    742741{ OsiSolverInterface *solver = model->solver();
    743742  if ((active_&4)!=0) {
     
    748747#endif   
    749748  }
    750 
     749 
    751750  // branch - do bounds
    752751  int i;
     
    857856    double * newBounds = reinterpret_cast<double *> (temp);
    858857    int * variables = reinterpret_cast<int *> (newBounds+numberChangedBounds_+nAdd);
    859 
     858   
    860859    int i ;
    861860    for (i=0;i<numberChangedBounds_;i++) {
     
    890889CbcNodeInfo *
    891890CbcPartialNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const
    892 
     891 
    893892{ basis.applyDiff(basisDiff_) ;
    894 
     893 
    895894  return parent_ ; }
    896895CbcNode::CbcNode() :
     
    932931#endif
    933932  model->setObjectiveValue(this,lastNode);
    934 
     933 
    935934  if (lastNode) {
    936935    if (lastNode->nodeInfo_) {
    937        lastNode->nodeInfo_->increment();
     936      lastNode->nodeInfo_->increment();
    938937    }
    939938  }
     
    956955                     const double *lastLower, const double *lastUpper,
    957956                     int numberOldActiveCuts, int numberNewCuts)
    958 
     957 
    959958{ OsiSolverInterface *solver = model->solver();
    960959  CbcStrategy *strategy = model->strategy();
    961 /*
    962   The root --- no parent. Create full basis and bounds information.
    963 */
     960  /*
     961    The root --- no parent. Create full basis and bounds information.
     962  */
    964963  if (!lastNode)
    965   {
    966     if (!strategy)
    967       nodeInfo_=new CbcFullNodeInfo(model,solver->getNumRows());
    968     else
    969       nodeInfo_ = strategy->fullNodeInfo(model,solver->getNumRows());
    970   } else {
    971 /*
    972   Not the root. Create an edit from the parent's basis & bound information.
    973   This is not quite as straightforward as it seems. We need to reintroduce
    974   cuts we may have dropped out of the basis, in the correct position, because
    975   this whole process is strictly positional. Start by grabbing the current
    976   basis.
    977 */
     964    {
     965      if (!strategy)
     966        nodeInfo_=new CbcFullNodeInfo(model,solver->getNumRows());
     967      else
     968        nodeInfo_ = strategy->fullNodeInfo(model,solver->getNumRows());
     969    } else {
     970    /*
     971      Not the root. Create an edit from the parent's basis & bound information.
     972      This is not quite as straightforward as it seems. We need to reintroduce
     973      cuts we may have dropped out of the basis, in the correct position, because
     974      this whole process is strictly positional. Start by grabbing the current
     975      basis.
     976    */
    978977    bool mustDeleteBasis;
    979978    const CoinWarmStartBasis *ws =
     
    992991    ws->print();
    993992#   endif
    994 /*
    995   Clone the basis and resize it to hold the structural constraints, plus
    996   all the cuts: old cuts, both active and inactive (currentNumberCuts),
    997   and new cuts (numberNewCuts). This will become the expanded basis.
    998 */
     993    /*
     994      Clone the basis and resize it to hold the structural constraints, plus
     995      all the cuts: old cuts, both active and inactive (currentNumberCuts),
     996      and new cuts (numberNewCuts). This will become the expanded basis.
     997    */
    999998    CoinWarmStartBasis *expanded =
    1000999      dynamic_cast<CoinWarmStartBasis *>(ws->clone()) ;
     
    10111010      << iCompact << " rows." << std::endl ;
    10121011#   endif
    1013 /*
    1014   Now flesh out the expanded basis. The clone already has the
    1015   correct status information for the variables and for the structural
    1016   (numberRowsAtContinuous) constraints. Any indices beyond nPartial must be
    1017   cuts created while processing this node --- they can be copied en bloc
    1018   into the correct position in the expanded basis. The space reserved for
    1019   xferRows is a gross overestimate.
    1020 */
     1012    /*
     1013      Now flesh out the expanded basis. The clone already has the
     1014      correct status information for the variables and for the structural
     1015      (numberRowsAtContinuous) constraints. Any indices beyond nPartial must be
     1016      cuts created while processing this node --- they can be copied en bloc
     1017      into the correct position in the expanded basis. The space reserved for
     1018      xferRows is a gross overestimate.
     1019    */
    10211020    CoinWarmStartBasis::XferVec xferRows ;
    10221021    xferRows.reserve(iFull-numberRowsAtContinuous+1) ;
    10231022    if (numberNewCuts) {
    10241023      xferRows.push_back(
    1025           CoinWarmStartBasis::XferEntry(iCompact-numberNewCuts,
    1026                                         iFull-numberNewCuts,numberNewCuts)) ;
    1027     }
    1028 /*
    1029   From nPartial down, record the entries we want to copy from the current
    1030   basis (the entries for the active cuts; non-zero in the list returned
    1031   by addedCuts). Fill the expanded basis with entries showing a status of
    1032   basic for the deactivated (loose) cuts.
    1033 */
     1024                        CoinWarmStartBasis::XferEntry(iCompact-numberNewCuts,
     1025                                                       iFull-numberNewCuts,numberNewCuts)) ;
     1026    }
     1027    /*
     1028      From nPartial down, record the entries we want to copy from the current
     1029      basis (the entries for the active cuts; non-zero in the list returned
     1030      by addedCuts). Fill the expanded basis with entries showing a status of
     1031      basic for the deactivated (loose) cuts.
     1032    */
    10341033    CbcCountRowCut **cut = model->addedCuts();
    10351034    iFull -= (numberNewCuts+1) ;
     
    10531052        expanded->setArtifStatus(iFull,CoinWarmStartBasis::basic);
    10541053    }
    1055 /*
    1056   Finally, call mergeBasis to copy over entries from the current basis to
    1057   the expanded basis. Since we cloned the expanded basis from the active basis
    1058   and haven't changed the number of variables, only row status entries need
    1059   to be copied.
    1060 */
     1054    /*
     1055      Finally, call mergeBasis to copy over entries from the current basis to
     1056      the expanded basis. Since we cloned the expanded basis from the active basis
     1057      and haven't changed the number of variables, only row status entries need
     1058      to be copied.
     1059    */
    10611060    expanded->mergeBasis(ws,&xferRows,0) ;
    1062 
     1061   
    10631062#ifdef CBC_CHECK_BASIS
    10641063    std::cout << "Expanded basis:" << std::endl ;
     
    10761075    }
    10771076#endif
    1078 
    1079 /*
    1080   Now that we have two bases in proper positional correspondence, creating
    1081   the actual diff is dead easy.
    1082 
    1083   Note that we're going to compare the expanded basis here to the stripped
    1084   basis (lastws) produced by addCuts. It doesn't affect the correctness (the
    1085   diff process has no knowledge of the meaning of an entry) but it does
    1086   mean that we'll always generate a whack of diff entries because the expanded
    1087   basis is considerably larger than the stripped basis.
    1088 */
     1077   
     1078    /*
     1079      Now that we have two bases in proper positional correspondence, creating
     1080      the actual diff is dead easy.
     1081     
     1082      Note that we're going to compare the expanded basis here to the stripped
     1083      basis (lastws) produced by addCuts. It doesn't affect the correctness (the
     1084      diff process has no knowledge of the meaning of an entry) but it does
     1085      mean that we'll always generate a whack of diff entries because the expanded
     1086      basis is considerably larger than the stripped basis.
     1087    */
    10891088    CoinWarmStartDiff *basisDiff = expanded->generateDiff(lastws) ;
    1090 
    1091 /*
    1092   Diff the bound vectors. It's assumed the number of structural variables
    1093   is not changing. For branching objects that change bounds on integer
    1094   variables, we should see at least one bound change as a consequence
    1095   of applying the branch that generated this subproblem from its parent.
    1096   This need not hold for other types of branching objects (hyperplane
    1097   branches, for example).
    1098 */
     1089   
     1090    /*
     1091      Diff the bound vectors. It's assumed the number of structural variables
     1092      is not changing. For branching objects that change bounds on integer
     1093      variables, we should see at least one bound change as a consequence
     1094      of applying the branch that generated this subproblem from its parent.
     1095      This need not hold for other types of branching objects (hyperplane
     1096      branches, for example).
     1097    */
    10991098    const double * lower = solver->getColLower();
    11001099    const double * upper = solver->getColUpper();
    1101 
     1100   
    11021101    double *boundChanges = new double [2*numberColumns] ;
    11031102    int *variables = new int [2*numberColumns] ;
     
    11321131    //if (lastNode->branchingObject()->boundBranch())
    11331132    //assert (numberChangedBounds);
    1134 /*
    1135   Hand the lot over to the CbcPartialNodeInfo constructor, then clean up and
    1136   return.
    1137 */
     1133    /*
     1134      Hand the lot over to the CbcPartialNodeInfo constructor, then clean up and
     1135      return.
     1136    */
    11381137    if (!strategy)
    11391138      nodeInfo_ =
     
    11711170                     int numberOldActiveCuts,int numberNewCuts)
    11721171{ OsiSolverInterface * solver = model->solver();
    1173  CbcStrategy * strategy = model->strategy();
    1174 /*
    1175   The root --- no parent. Create full basis and bounds information.
    1176 */
     1172  CbcStrategy * strategy = model->strategy();
     1173  /*
     1174    The root --- no parent. Create full basis and bounds information.
     1175  */
    11771176  if (!lastNode)
    1178   {
    1179     if (!strategy)
    1180       nodeInfo_=new CbcFullNodeInfo(model,solver->getNumRows());
    1181     else
    1182       nodeInfo_ = strategy->fullNodeInfo(model,solver->getNumRows());
    1183   }
    1184 /*
    1185   Not the root. Create an edit from the parent's basis & bound information.
    1186   This is not quite as straightforward as it seems. We need to reintroduce
    1187   cuts we may have dropped out of the basis, in the correct position, because
    1188   this whole process is strictly positional. Start by grabbing the current
    1189   basis.
    1190 */
     1177    {
     1178      if (!strategy)
     1179        nodeInfo_=new CbcFullNodeInfo(model,solver->getNumRows());
     1180      else
     1181        nodeInfo_ = strategy->fullNodeInfo(model,solver->getNumRows());
     1182    }
     1183  /*
     1184    Not the root. Create an edit from the parent's basis & bound information.
     1185    This is not quite as straightforward as it seems. We need to reintroduce
     1186    cuts we may have dropped out of the basis, in the correct position, because
     1187    this whole process is strictly positional. Start by grabbing the current
     1188    basis.
     1189  */
    11911190  else
    1192   {
    1193     bool mustDeleteBasis;
    1194     const CoinWarmStartBasis* ws =
    1195       dynamic_cast<const CoinWarmStartBasis*>(solver->getPointerToWarmStart(mustDeleteBasis));
    1196     assert(ws!=NULL); // make sure not volume
    1197     //int numberArtificials = lastws->getNumArtificial();
    1198     int numberColumns = solver->getNumCols();
    1199    
    1200     const double * lower = solver->getColLower();
    1201     const double * upper = solver->getColUpper();
    1202 
    1203     int i;
    1204 /*
    1205   Create a clone and resize it to hold all the structural constraints, plus
    1206   all the cuts: old cuts, both active and inactive (currentNumberCuts), and
    1207   new cuts (numberNewCuts).
    1208 
    1209   TODO: You'd think that the set of constraints (logicals) in the expanded
     1191    {
     1192      bool mustDeleteBasis;
     1193      const CoinWarmStartBasis* ws =
     1194        dynamic_cast<const CoinWarmStartBasis*>(solver->getPointerToWarmStart(mustDeleteBasis));
     1195      assert(ws!=NULL); // make sure not volume
     1196      //int numberArtificials = lastws->getNumArtificial();
     1197      int numberColumns = solver->getNumCols();
     1198     
     1199      const double * lower = solver->getColLower();
     1200      const double * upper = solver->getColUpper();
     1201     
     1202      int i;
     1203      /*
     1204        Create a clone and resize it to hold all the structural constraints, plus
     1205        all the cuts: old cuts, both active and inactive (currentNumberCuts), and
     1206        new cuts (numberNewCuts).
     1207       
     1208        TODO: You'd think that the set of constraints (logicals) in the expanded
    12101209        basis should match the set represented in lastws. At least, that's
    12111210        what I thought. But at the point I first looked hard at this bit of
     
    12161215        bug'' and went back to John's code to see where I'd gone wrong.
    12171216        And discovered the same `error' in his code.
    1218 
     1217       
    12191218        After a bit of thought, my conclusion is that correctness is not
    12201219        affected by whether lastws is the stripped or raw basis. The diffs
     
    12241223        the stripped basis). But I need to give this more thought. There
    12251224        may well be some subtle error cases.
    1226 
     1225       
    12271226        In the mean time, I've twiddled addCuts() to set lastws to the raw
    12281227        basis. Makes me (Lou) less nervous to compare apples to apples.
    1229 */
    1230     CoinWarmStartBasis *expanded =
    1231       dynamic_cast<CoinWarmStartBasis *>(ws->clone()) ;
    1232     int numberRowsAtContinuous = model->numberRowsAtContinuous();
    1233     int iFull = numberRowsAtContinuous+model->currentNumberCuts()+
    1234       numberNewCuts;
    1235     //int numberArtificialsNow = iFull;
    1236     //int maxBasisLength = ((iFull+15)>>4)+((numberColumns+15)>>4);
    1237     //printf("l %d full %d\n",maxBasisLength,iFull);
    1238     if (expanded)
    1239       expanded->resize(iFull,numberColumns);
     1228      */
     1229      CoinWarmStartBasis *expanded =
     1230        dynamic_cast<CoinWarmStartBasis *>(ws->clone()) ;
     1231      int numberRowsAtContinuous = model->numberRowsAtContinuous();
     1232      int iFull = numberRowsAtContinuous+model->currentNumberCuts()+
     1233        numberNewCuts;
     1234      //int numberArtificialsNow = iFull;
     1235      //int maxBasisLength = ((iFull+15)>>4)+((numberColumns+15)>>4);
     1236      //printf("l %d full %d\n",maxBasisLength,iFull);
     1237      if (expanded)
     1238        expanded->resize(iFull,numberColumns);
    12401239#ifdef CBC_CHECK_BASIS
    1241     printf("Before expansion: orig %d, old %d, new %d, current %d\n",
    1242            numberRowsAtContinuous,numberOldActiveCuts,numberNewCuts,
    1243            model->currentNumberCuts()) ;
    1244     ws->print();
    1245 #endif
    1246 /*
    1247   Now fill in the expanded basis. Any indices beyond nPartial must
    1248   be cuts created while processing this node --- they can be copied directly
    1249   into the expanded basis. From nPartial down, pull the status of active cuts
    1250   from ws, interleaving with a B entry for the deactivated (loose) cuts.
    1251 */
    1252     int numberDropped = model->currentNumberCuts()-numberOldActiveCuts;
    1253     int iCompact=iFull-numberDropped;
    1254     CbcCountRowCut ** cut = model->addedCuts();
    1255     int nPartial = model->currentNumberCuts()+numberRowsAtContinuous;
    1256     iFull--;
    1257     for (;iFull>=nPartial;iFull--) {
    1258       CoinWarmStartBasis::Status status = ws->getArtifStatus(--iCompact);
    1259       //assert (status != CoinWarmStartBasis::basic); // may be permanent cut
    1260       expanded->setArtifStatus(iFull,status);
    1261     }
    1262     for (;iFull>=numberRowsAtContinuous;iFull--) {
    1263       if (cut[iFull-numberRowsAtContinuous]) {
     1240      printf("Before expansion: orig %d, old %d, new %d, current %d\n",
     1241             numberRowsAtContinuous,numberOldActiveCuts,numberNewCuts,
     1242             model->currentNumberCuts()) ;
     1243      ws->print();
     1244#endif
     1245      /*
     1246        Now fill in the expanded basis. Any indices beyond nPartial must
     1247        be cuts created while processing this node --- they can be copied directly
     1248        into the expanded basis. From nPartial down, pull the status of active cuts
     1249        from ws, interleaving with a B entry for the deactivated (loose) cuts.
     1250      */
     1251      int numberDropped = model->currentNumberCuts()-numberOldActiveCuts;
     1252      int iCompact=iFull-numberDropped;
     1253      CbcCountRowCut ** cut = model->addedCuts();
     1254      int nPartial = model->currentNumberCuts()+numberRowsAtContinuous;
     1255      iFull--;
     1256      for (;iFull>=nPartial;iFull--) {
    12641257        CoinWarmStartBasis::Status status = ws->getArtifStatus(--iCompact);
    1265         // If no cut generator being used then we may have basic variables
    1266         //if (model->getMaximumCutPasses()&&
    1267         //  status == CoinWarmStartBasis::basic)
    1268         //printf("cut basic\n");
     1258        //assert (status != CoinWarmStartBasis::basic); // may be permanent cut
    12691259        expanded->setArtifStatus(iFull,status);
    1270       } else {
    1271         expanded->setArtifStatus(iFull,CoinWarmStartBasis::basic);
    1272       }
    1273     }
     1260      }
     1261      for (;iFull>=numberRowsAtContinuous;iFull--) {
     1262        if (cut[iFull-numberRowsAtContinuous]) {
     1263          CoinWarmStartBasis::Status status = ws->getArtifStatus(--iCompact);
     1264          // If no cut generator being used then we may have basic variables
     1265          //if (model->getMaximumCutPasses()&&
     1266          //  status == CoinWarmStartBasis::basic)
     1267          //printf("cut basic\n");
     1268          expanded->setArtifStatus(iFull,status);
     1269        } else {
     1270          expanded->setArtifStatus(iFull,CoinWarmStartBasis::basic);
     1271        }
     1272      }
    12741273#ifdef CBC_CHECK_BASIS
    1275     printf("Expanded basis\n");
    1276     expanded->print() ;
    1277     printf("Diffing against\n") ;
    1278     lastws->print() ;
     1274      printf("Expanded basis\n");
     1275      expanded->print() ;
     1276      printf("Diffing against\n") ;
     1277      lastws->print() ;
    12791278#endif   
    1280 /*
    1281   Now that we have two bases in proper positional correspondence, creating
    1282   the actual diff is dead easy.
    1283 */
    1284 
    1285     CoinWarmStartDiff *basisDiff = expanded->generateDiff(lastws) ;
    1286 /*
    1287   Diff the bound vectors. It's assumed the number of structural variables is
    1288   not changing. Assuming that branching objects all involve integer variables,
    1289   we should see at least one bound change as a consequence of processing this
    1290   subproblem. Different types of branching objects could break this assertion.
    1291   Not true at all - we have not applied current branch - JJF.
    1292 */
    1293     double *boundChanges = new double [2*numberColumns] ;
    1294     int *variables = new int [2*numberColumns] ;
    1295     int numberChangedBounds=0;
    1296     for (i=0;i<numberColumns;i++) {
    1297       if (lower[i]!=lastLower[i]) {
    1298         variables[numberChangedBounds]=i;
    1299         boundChanges[numberChangedBounds++]=lower[i];
    1300       }
    1301       if (upper[i]!=lastUpper[i]) {
    1302         variables[numberChangedBounds]=i|0x80000000;
    1303         boundChanges[numberChangedBounds++]=upper[i];
    1304       }
     1279      /*
     1280        Now that we have two bases in proper positional correspondence, creating
     1281        the actual diff is dead easy.
     1282      */
     1283     
     1284      CoinWarmStartDiff *basisDiff = expanded->generateDiff(lastws) ;
     1285      /*
     1286        Diff the bound vectors. It's assumed the number of structural variables is
     1287        not changing. Assuming that branching objects all involve integer variables,
     1288        we should see at least one bound change as a consequence of processing this
     1289        subproblem. Different types of branching objects could break this assertion.
     1290        Not true at all - we have not applied current branch - JJF.
     1291      */
     1292      double *boundChanges = new double [2*numberColumns] ;
     1293      int *variables = new int [2*numberColumns] ;
     1294      int numberChangedBounds=0;
     1295      for (i=0;i<numberColumns;i++) {
     1296        if (lower[i]!=lastLower[i]) {
     1297          variables[numberChangedBounds]=i;
     1298          boundChanges[numberChangedBounds++]=lower[i];
     1299        }
     1300        if (upper[i]!=lastUpper[i]) {
     1301          variables[numberChangedBounds]=i|0x80000000;
     1302          boundChanges[numberChangedBounds++]=upper[i];
     1303        }
    13051304#ifdef CBC_DEBUG
    1306       if (lower[i]!=lastLower[i])
    1307         printf("lower on %d changed from %g to %g\n",
    1308               i,lastLower[i],lower[i]);
    1309       if (upper[i]!=lastUpper[i])
    1310         printf("upper on %d changed from %g to %g\n",
    1311               i,lastUpper[i],upper[i]);
    1312 #endif
    1313     }
     1305        if (lower[i]!=lastLower[i])
     1306          printf("lower on %d changed from %g to %g\n",
     1307                i,lastLower[i],lower[i]);
     1308        if (upper[i]!=lastUpper[i])
     1309          printf("upper on %d changed from %g to %g\n",
     1310                i,lastUpper[i],upper[i]);
     1311#endif
     1312      }
    13141313#ifdef CBC_DEBUG
    1315     printf("%d changed bounds\n",numberChangedBounds) ;
    1316 #endif
    1317     //if (lastNode->branchingObject()->boundBranch())
    1318     //assert (numberChangedBounds);
    1319 /*
    1320   Hand the lot over to the CbcPartialNodeInfo constructor, then clean up and
    1321   return.
    1322 */
    1323     if (!strategy)
    1324       nodeInfo_ =
    1325         new CbcPartialNodeInfo(lastNode->nodeInfo_,this,numberChangedBounds,
    1326                               variables,boundChanges,basisDiff) ;
    1327     else
    1328       nodeInfo_ = strategy->partialNodeInfo(model, lastNode->nodeInfo_,this,numberChangedBounds,
    1329                                variables,boundChanges,basisDiff) ;
    1330     delete basisDiff ;
    1331     delete [] boundChanges;
    1332     delete [] variables;
    1333     delete expanded ;
    1334     if  (mustDeleteBasis)
    1335       delete ws;
    1336   }
     1314      printf("%d changed bounds\n",numberChangedBounds) ;
     1315#endif
     1316      //if (lastNode->branchingObject()->boundBranch())
     1317      //assert (numberChangedBounds);
     1318      /*
     1319        Hand the lot over to the CbcPartialNodeInfo constructor, then clean up and
     1320        return.
     1321      */
     1322      if (!strategy)
     1323        nodeInfo_ =
     1324          new CbcPartialNodeInfo(lastNode->nodeInfo_,this,numberChangedBounds,
     1325                                variables,boundChanges,basisDiff) ;
     1326      else
     1327        nodeInfo_ = strategy->partialNodeInfo(model, lastNode->nodeInfo_,this,numberChangedBounds,
     1328                                              variables,boundChanges,basisDiff) ;
     1329      delete basisDiff ;
     1330      delete [] boundChanges;
     1331      delete [] variables;
     1332      delete expanded ;
     1333      if  (mustDeleteBasis)
     1334        delete ws;
     1335    }
    13371336  // Set node number
    13381337  nodeInfo_->setNodeNumber(model->getNodeCount2());
     
    13461345  and selects the one with the least objective degradation.  A corresponding
    13471346  branching object is left attached to lastNode.
    1348 
     1347 
    13491348  If strong branching is disabled, a candidate object is chosen essentially
    13501349  at random (whatever object ends up in pos'n 0 of the candidate array).
    1351 
     1350 
    13521351  If a branching candidate is found to be monotone, bounds are set to fix the
    13531352  variable and the routine immediately returns (the caller is expected to
    13541353  reoptimize).
    1355 
     1354 
    13561355  If a branching candidate is found to result in infeasibility in both
    13571356  directions, the routine immediately returns an indication of infeasibility.
    1358 
     1357 
    13591358  Returns:  0   both branch directions are feasible
    1360            -1   branching variable is monotone
    1361            -2   infeasible
    1362 
     1359  -1    branching variable is monotone
     1360  -2    infeasible
     1361 
    13631362  Original comments:
    1364     Here could go cuts etc etc
    1365     For now just fix on objective from strong branching.
     1363  Here could go cuts etc etc
     1364  For now just fix on objective from strong branching.
    13661365*/
    13671366
    13681367int CbcNode::chooseBranch (CbcModel *model, CbcNode *lastNode,int numberPassesLeft)
    1369 
     1368 
    13701369{ if (lastNode)
    13711370    depth_ = lastNode->depth_+1;
     
    14191418  double * saveUpper = new double[numberColumns];
    14201419  double * saveLower = new double[numberColumns];
    1421 
     1420 
    14221421  // Save solution in case heuristics need good solution later
    14231422 
     
    17111710         outputStuff[2*i+1] is status (0 - finished, 1 infeas, other unknown
    17121711         outputStuff[2*i+1+numberStrong] is number iterations
    1713       On entry newLower[i] is new lower bound, on exit obj change
     1712        On entry newLower[i] is new lower bound, on exit obj change
    17141713      */
    17151714      ClpSimplex * clp=NULL;
     
    18041803        //clp->writeMps("bad");
    18051804        returnCode=clp->strongBranching(numberStrong,which,
    1806                                             newLower, newUpper,outputSolution,
    1807                                             outputStuff,outputStuff+2*numberStrong,!solveAll,false,
    1808                                             startFinishOptions);
     1805                                        newLower, newUpper,outputSolution,
     1806                                        outputStuff,outputStuff+2*numberStrong,!solveAll,false,
     1807                                        startFinishOptions);
    18091808#ifndef CRUNCH
    18101809        clp->setSpecialOptions(clpOptions); // restore
     
    18571856      }
    18581857#     else      /* COIN_HAS_CLP */
    1859 
     1858     
    18601859      OsiSolverInterface *clp = NULL ;
    18611860      double **outputSolution = NULL ;
     
    18631862      double * newLower = NULL ;
    18641863      double * newUpper = NULL ;
    1865 
     1864     
    18661865      solver->markHotStart();
    1867 
     1866     
    18681867#     endif     /* COIN_HAS_CLP */
    18691868      /*
     
    18771876        unbranch() method. Branching objects more exotic than simple integers
    18781877        or cliques might not restrict themselves to variable bounds.
    1879 
     1878       
    18801879        TODO: Virtuous solvers invalidate the current solution (or give bogus
    18811880        results :-) when the bounds are changed out from under them. So we
     
    18851884      for (i = 0 ; i < numberStrong ; i++)
    18861885        { double objectiveChange ;
    1887         double newObjectiveValue=1.0e100;
    1888         // status is 0 finished, 1 infeasible and other
    1889         int iStatus;
    1890         /*
    1891           Try the down direction first. (Specify the initial branching alternative as
    1892           down with a call to way(-1). Each subsequent call to branch() performs the
    1893           specified branch and advances the branch object state to the next branch
    1894           alternative.)
    1895         */
    1896         if (!clp) {
    1897           choice[i].possibleBranch->way(-1) ;
    1898           choice[i].possibleBranch->branch() ;
    1899           bool feasible=true;
    1900           if (checkFeasibility) {
    1901             // check branching did not make infeasible
    1902             int iColumn;
    1903             int numberColumns = solver->getNumCols();
    1904             const double * columnLower = solver->getColLower();
    1905             const double * columnUpper = solver->getColUpper();
    1906             for (iColumn= 0;iColumn<numberColumns;iColumn++) {
    1907               if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
    1908                 feasible=false;
    1909             }
    1910           }
    1911           if (feasible) {
    1912             solver->solveFromHotStart() ;
    1913             numberStrongDone++;
    1914             numberStrongIterations += solver->getIterationCount();
    1915             /*
    1916               We now have an estimate of objective degradation that we can use for strong
    1917               branching. If we're over the cutoff, the variable is monotone up.
    1918               If we actually made it to optimality, check for a solution, and if we have
    1919               a good one, call setBestSolution to process it. Note that this may reduce the
    1920               cutoff, so we check again to see if we can declare this variable monotone.
    1921             */
    1922             if (solver->isProvenOptimal())
    1923               iStatus=0; // optimal
    1924             else if (solver->isIterationLimitReached()
    1925                      &&!solver->isDualObjectiveLimitReached())
    1926               iStatus=2; // unknown
    1927             else
    1928               iStatus=1; // infeasible
    1929             newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    1930             choice[i].numItersDown = solver->getIterationCount();
    1931           } else {
    1932             iStatus=1; // infeasible
    1933             newObjectiveValue = 1.0e100;
    1934             choice[i].numItersDown = 0;
    1935           }
    1936         } else {
    1937           iStatus = outputStuff[2*i];
    1938           choice[i].numItersDown = outputStuff[2*numberStrong+2*i];
    1939           numberStrongDone++;
    1940           numberStrongIterations += choice[i].numItersDown;
    1941           newObjectiveValue = objectiveValue+newUpper[i];
    1942           solver->setColSolution(outputSolution[2*i]);
    1943         }
    1944         objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
    1945         if (!iStatus) {
    1946           choice[i].finishedDown = true ;
    1947           if (newObjectiveValue>=model->getCutoff()) {
    1948             objectiveChange = 1.0e100; // say infeasible
    1949             numberStrongInfeasible++;
    1950           } else {
    1951             // See if integer solution
    1952             if (model->feasibleSolution(choice[i].numIntInfeasDown,
    1953                                         choice[i].numObjInfeasDown)
    1954                 &&model->problemFeasibility()->feasible(model,-1)>=0) {
    1955               model->setBestSolution(CBC_STRONGSOL,
    1956                                      newObjectiveValue,
    1957                                      solver->getColSolution()) ;
    1958               // only needed for odd solvers
    1959               newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    1960               objectiveChange = CoinMax(newObjectiveValue-objectiveValue_,0.0) ;
    1961               model->setLastHeuristic(NULL);
    1962               model->incrementUsed(solver->getColSolution());
    1963               if (newObjectiveValue >= model->getCutoff()) {    //  *new* cutoff
    1964                 objectiveChange = 1.0e100 ;
    1965                 numberStrongInfeasible++;
    1966               }
    1967             }
    1968           }
    1969         } else if (iStatus==1) {
    1970           objectiveChange = 1.0e100 ;
    1971           numberStrongInfeasible++;
    1972         } else {
    1973           // Can't say much as we did not finish
    1974           choice[i].finishedDown = false ;
    1975           numberUnfinished++;
    1976         }
    1977         choice[i].downMovement = objectiveChange ;
    1978        
    1979         // restore bounds
    1980         if (!clp)
    1981           { for (int j=0;j<numberColumns;j++) {
    1982             if (saveLower[j] != lower[j])
    1983               solver->setColLower(j,saveLower[j]);
    1984             if (saveUpper[j] != upper[j])
    1985               solver->setColUpper(j,saveUpper[j]);
    1986           }
    1987           }
    1988         //printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    1989         //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersDown,
    1990         //     choice[i].downMovement,choice[i].finishedDown,choice[i].numIntInfeasDown,
    1991         //     choice[i].numObjInfeasDown);
    1992        
    1993         // repeat the whole exercise, forcing the variable up
    1994         if (!clp) {
    1995           bool feasible=true;
    1996           // If odd branching then maybe just one possibility
    1997           if(choice[i].possibleBranch->numberBranchesLeft()>0) {
    1998             choice[i].possibleBranch->branch();
    1999             if (checkFeasibility) {
    2000               // check branching did not make infeasible
    2001               int iColumn;
    2002               int numberColumns = solver->getNumCols();
    2003               const double * columnLower = solver->getColLower();
    2004               const double * columnUpper = solver->getColUpper();
    2005               for (iColumn= 0;iColumn<numberColumns;iColumn++) {
    2006                 if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
    2007                   feasible=false;
    2008               }
    2009             }
    2010           } else {
    2011             // second branch infeasible
    2012             feasible=false;
    2013           }
    2014           if (feasible) {
    2015             solver->solveFromHotStart() ;
    2016             numberStrongDone++;
    2017             numberStrongIterations += solver->getIterationCount();
    2018             /*
    2019               We now have an estimate of objective degradation that we can use for strong
    2020               branching. If we're over the cutoff, the variable is monotone up.
    2021               If we actually made it to optimality, check for a solution, and if we have
    2022               a good one, call setBestSolution to process it. Note that this may reduce the
    2023               cutoff, so we check again to see if we can declare this variable monotone.
    2024             */
    2025             if (solver->isProvenOptimal())
    2026               iStatus=0; // optimal
    2027             else if (solver->isIterationLimitReached()
    2028                      &&!solver->isDualObjectiveLimitReached())
    2029               iStatus=2; // unknown
    2030             else
    2031               iStatus=1; // infeasible
    2032             newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    2033             choice[i].numItersUp = solver->getIterationCount();
    2034           } else {
    2035             iStatus=1; // infeasible
    2036             newObjectiveValue = 1.0e100;
    2037             choice[i].numItersDown = 0;
    2038           }
    2039         } else {
    2040           iStatus = outputStuff[2*i+1];
    2041           choice[i].numItersUp = outputStuff[2*numberStrong+2*i+1];
    2042           numberStrongDone++;
    2043           numberStrongIterations += choice[i].numItersUp;
    2044           newObjectiveValue = objectiveValue+newLower[i];
    2045           solver->setColSolution(outputSolution[2*i+1]);
    2046         }
    2047         objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
    2048         if (!iStatus) {
    2049           choice[i].finishedUp = true ;
    2050           if (newObjectiveValue>=model->getCutoff()) {
    2051             objectiveChange = 1.0e100; // say infeasible
    2052             numberStrongInfeasible++;
    2053           } else {
    2054             // See if integer solution
    2055             if (model->feasibleSolution(choice[i].numIntInfeasUp,
    2056                                         choice[i].numObjInfeasUp)
    2057                 &&model->problemFeasibility()->feasible(model,-1)>=0) {
    2058               model->setBestSolution(CBC_STRONGSOL,
    2059                                      newObjectiveValue,
    2060                                      solver->getColSolution()) ;
    2061               // only needed for odd solvers
    2062               newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    2063               objectiveChange = CoinMax(newObjectiveValue-objectiveValue_,0.0) ;
    2064               model->setLastHeuristic(NULL);
    2065               model->incrementUsed(solver->getColSolution());
    2066               if (newObjectiveValue >= model->getCutoff()) {    //  *new* cutoff
    2067                 objectiveChange = 1.0e100 ;
    2068                 numberStrongInfeasible++;
    2069               }
    2070             }
    2071           }
    2072         } else if (iStatus==1) {
    2073           objectiveChange = 1.0e100 ;
    2074           numberStrongInfeasible++;
    2075         } else {
    2076           // Can't say much as we did not finish
    2077           choice[i].finishedUp = false ;
    2078           numberUnfinished++;
    2079         }
    2080         choice[i].upMovement = objectiveChange ;
    2081        
    2082         // restore bounds
    2083         if (!clp)
    2084           { for (int j=0;j<numberColumns;j++) {
    2085             if (saveLower[j] != lower[j])
    2086               solver->setColLower(j,saveLower[j]);
    2087             if (saveUpper[j] != upper[j])
    2088               solver->setColUpper(j,saveUpper[j]);
    2089           }
    2090           }
    2091        
    2092         //printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    2093         //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersUp,
    2094         //     choice[i].upMovement,choice[i].finishedUp,choice[i].numIntInfeasUp,
    2095         //     choice[i].numObjInfeasUp);
    2096        
    2097         /*
    2098           End of evaluation for this candidate variable. Possibilities are:
    2099           * Both sides below cutoff; this variable is a candidate for branching.
    2100           * Both sides infeasible or above the objective cutoff: no further action
    2101           here. Break from the evaluation loop and assume the node will be purged
    2102           by the caller.
    2103           * One side below cutoff: Install the branch (i.e., fix the variable). Break
    2104           from the evaluation loop and assume the node will be reoptimised by the
    2105           caller.
    2106         */
    2107         // reset
    2108         choice[i].possibleBranch->resetNumberBranchesLeft();
    2109         if (choice[i].upMovement<1.0e100) {
    2110           if(choice[i].downMovement<1.0e100) {
    2111             // feasible - no action
    2112           } else {
    2113             // up feasible, down infeasible
    2114             anyAction=-1;
    2115             //printf("Down infeasible for choice %d sequence %d\n",i,
    2116             // model->object(choice[i].objectNumber)->columnNumber());
    2117             if (!solveAll) {
    2118               choice[i].possibleBranch->way(1);
    2119               choice[i].possibleBranch->branch();
    2120               break;
    2121             } else {
    2122               choice[i].fix=1;
    2123             }
    2124           }
    2125         } else {
    2126           if(choice[i].downMovement<1.0e100) {
    2127             // down feasible, up infeasible
    2128             anyAction=-1;
    2129             //printf("Up infeasible for choice %d sequence %d\n",i,
    2130             // model->object(choice[i].objectNumber)->columnNumber());
    2131             if (!solveAll) {
    2132               choice[i].possibleBranch->way(-1);
    2133               choice[i].possibleBranch->branch();
    2134               break;
    2135             } else {
    2136               choice[i].fix=-1;
    2137             }
    2138           } else {
    2139             // neither side feasible
    2140             anyAction=-2;
    2141             //printf("Both infeasible for choice %d sequence %d\n",i,
    2142             // model->object(choice[i].objectNumber)->columnNumber());
    2143             break;
    2144           }
    2145         }
    2146         bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) >
    2147                             model->getDblParam(CbcModel::CbcMaximumSeconds));
    2148         if (hitMaxTime) {
    2149           numberStrong=i+1;
    2150           break;
    2151         }
     1886          double newObjectiveValue=1.0e100;
     1887          // status is 0 finished, 1 infeasible and other
     1888          int iStatus;
     1889          /*
     1890            Try the down direction first. (Specify the initial branching alternative as
     1891            down with a call to way(-1). Each subsequent call to branch() performs the
     1892            specified branch and advances the branch object state to the next branch
     1893            alternative.)
     1894          */
     1895          if (!clp) {
     1896            choice[i].possibleBranch->way(-1) ;
     1897            choice[i].possibleBranch->branch() ;
     1898            bool feasible=true;
     1899            if (checkFeasibility) {
     1900              // check branching did not make infeasible
     1901              int iColumn;
     1902              int numberColumns = solver->getNumCols();
     1903              const double * columnLower = solver->getColLower();
     1904              const double * columnUpper = solver->getColUpper();
     1905              for (iColumn= 0;iColumn<numberColumns;iColumn++) {
     1906                if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
     1907                  feasible=false;
     1908              }
     1909            }
     1910            if (feasible) {
     1911              solver->solveFromHotStart() ;
     1912              numberStrongDone++;
     1913              numberStrongIterations += solver->getIterationCount();
     1914              /*
     1915                We now have an estimate of objective degradation that we can use for strong
     1916                branching. If we're over the cutoff, the variable is monotone up.
     1917                If we actually made it to optimality, check for a solution, and if we have
     1918                a good one, call setBestSolution to process it. Note that this may reduce the
     1919                cutoff, so we check again to see if we can declare this variable monotone.
     1920              */
     1921              if (solver->isProvenOptimal())
     1922                iStatus=0; // optimal
     1923              else if (solver->isIterationLimitReached()
     1924                       &&!solver->isDualObjectiveLimitReached())
     1925                iStatus=2; // unknown
     1926              else
     1927                iStatus=1; // infeasible
     1928              newObjectiveValue = solver->getObjSense()*solver->getObjValue();
     1929              choice[i].numItersDown = solver->getIterationCount();
     1930            } else {
     1931              iStatus=1; // infeasible
     1932              newObjectiveValue = 1.0e100;
     1933              choice[i].numItersDown = 0;
     1934            }
     1935          } else {
     1936            iStatus = outputStuff[2*i];
     1937            choice[i].numItersDown = outputStuff[2*numberStrong+2*i];
     1938            numberStrongDone++;
     1939            numberStrongIterations += choice[i].numItersDown;
     1940            newObjectiveValue = objectiveValue+newUpper[i];
     1941            solver->setColSolution(outputSolution[2*i]);
     1942          }
     1943          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
     1944          if (!iStatus) {
     1945            choice[i].finishedDown = true ;
     1946            if (newObjectiveValue>=model->getCutoff()) {
     1947              objectiveChange = 1.0e100; // say infeasible
     1948              numberStrongInfeasible++;
     1949            } else {
     1950              // See if integer solution
     1951              if (model->feasibleSolution(choice[i].numIntInfeasDown,
     1952                                          choice[i].numObjInfeasDown)
     1953                  &&model->problemFeasibility()->feasible(model,-1)>=0) {
     1954                model->setBestSolution(CBC_STRONGSOL,
     1955                                       newObjectiveValue,
     1956                                       solver->getColSolution()) ;
     1957                // only needed for odd solvers
     1958                newObjectiveValue = solver->getObjSense()*solver->getObjValue();
     1959                objectiveChange = CoinMax(newObjectiveValue-objectiveValue_,0.0) ;
     1960                model->setLastHeuristic(NULL);
     1961                model->incrementUsed(solver->getColSolution());
     1962                if (newObjectiveValue >= model->getCutoff()) {  //  *new* cutoff
     1963                  objectiveChange = 1.0e100 ;
     1964                  numberStrongInfeasible++;
     1965                }
     1966              }
     1967            }
     1968          } else if (iStatus==1) {
     1969            objectiveChange = 1.0e100 ;
     1970            numberStrongInfeasible++;
     1971          } else {
     1972            // Can't say much as we did not finish
     1973            choice[i].finishedDown = false ;
     1974            numberUnfinished++;
     1975          }
     1976          choice[i].downMovement = objectiveChange ;
     1977         
     1978          // restore bounds
     1979          if (!clp)
     1980            { for (int j=0;j<numberColumns;j++) {
     1981                if (saveLower[j] != lower[j])
     1982                  solver->setColLower(j,saveLower[j]);
     1983                if (saveUpper[j] != upper[j])
     1984                  solver->setColUpper(j,saveUpper[j]);
     1985              }
     1986            }
     1987          //printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
     1988          //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersDown,
     1989          //     choice[i].downMovement,choice[i].finishedDown,choice[i].numIntInfeasDown,
     1990          //     choice[i].numObjInfeasDown);
     1991         
     1992          // repeat the whole exercise, forcing the variable up
     1993          if (!clp) {
     1994            bool feasible=true;
     1995            // If odd branching then maybe just one possibility
     1996            if(choice[i].possibleBranch->numberBranchesLeft()>0) {
     1997              choice[i].possibleBranch->branch();
     1998              if (checkFeasibility) {
     1999                // check branching did not make infeasible
     2000                int iColumn;
     2001                int numberColumns = solver->getNumCols();
     2002                const double * columnLower = solver->getColLower();
     2003                const double * columnUpper = solver->getColUpper();
     2004                for (iColumn= 0;iColumn<numberColumns;iColumn++) {
     2005                  if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
     2006                    feasible=false;
     2007                }
     2008              }
     2009            } else {
     2010              // second branch infeasible
     2011              feasible=false;
     2012            }
     2013            if (feasible) {
     2014              solver->solveFromHotStart() ;
     2015              numberStrongDone++;
     2016              numberStrongIterations += solver->getIterationCount();
     2017              /*
     2018                We now have an estimate of objective degradation that we can use for strong
     2019                branching. If we're over the cutoff, the variable is monotone up.
     2020                If we actually made it to optimality, check for a solution, and if we have
     2021                a good one, call setBestSolution to process it. Note that this may reduce the
     2022                cutoff, so we check again to see if we can declare this variable monotone.
     2023              */
     2024              if (solver->isProvenOptimal())
     2025                iStatus=0; // optimal
     2026              else if (solver->isIterationLimitReached()
     2027                       &&!solver->isDualObjectiveLimitReached())
     2028                iStatus=2; // unknown
     2029              else
     2030                iStatus=1; // infeasible
     2031              newObjectiveValue = solver->getObjSense()*solver->getObjValue();
     2032              choice[i].numItersUp = solver->getIterationCount();
     2033            } else {
     2034              iStatus=1; // infeasible
     2035              newObjectiveValue = 1.0e100;
     2036              choice[i].numItersDown = 0;
     2037            }
     2038          } else {
     2039            iStatus = outputStuff[2*i+1];
     2040            choice[i].numItersUp = outputStuff[2*numberStrong+2*i+1];
     2041            numberStrongDone++;
     2042            numberStrongIterations += choice[i].numItersUp;
     2043            newObjectiveValue = objectiveValue+newLower[i];
     2044            solver->setColSolution(outputSolution[2*i+1]);
     2045          }
     2046          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
     2047          if (!iStatus) {
     2048            choice[i].finishedUp = true ;
     2049            if (newObjectiveValue>=model->getCutoff()) {
     2050              objectiveChange = 1.0e100; // say infeasible
     2051              numberStrongInfeasible++;
     2052            } else {
     2053              // See if integer solution
     2054              if (model->feasibleSolution(choice[i].numIntInfeasUp,
     2055                                          choice[i].numObjInfeasUp)
     2056                  &&model->problemFeasibility()->feasible(model,-1)>=0) {
     2057                model->setBestSolution(CBC_STRONGSOL,
     2058                                       newObjectiveValue,
     2059                                       solver->getColSolution()) ;
     2060                // only needed for odd solvers
     2061                newObjectiveValue = solver->getObjSense()*solver->getObjValue();
     2062                objectiveChange = CoinMax(newObjectiveValue-objectiveValue_,0.0) ;
     2063                model->setLastHeuristic(NULL);
     2064                model->incrementUsed(solver->getColSolution());
     2065                if (newObjectiveValue >= model->getCutoff()) {  //  *new* cutoff
     2066                  objectiveChange = 1.0e100 ;
     2067                  numberStrongInfeasible++;
     2068                }
     2069              }
     2070            }
     2071          } else if (iStatus==1) {
     2072            objectiveChange = 1.0e100 ;
     2073            numberStrongInfeasible++;
     2074          } else {
     2075            // Can't say much as we did not finish
     2076            choice[i].finishedUp = false ;
     2077            numberUnfinished++;
     2078          }
     2079          choice[i].upMovement = objectiveChange ;
     2080         
     2081          // restore bounds
     2082          if (!clp)
     2083            { for (int j=0;j<numberColumns;j++) {
     2084                if (saveLower[j] != lower[j])
     2085                  solver->setColLower(j,saveLower[j]);
     2086                if (saveUpper[j] != upper[j])
     2087                  solver->setColUpper(j,saveUpper[j]);
     2088              }
     2089            }
     2090         
     2091          //printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
     2092          //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersUp,
     2093          //     choice[i].upMovement,choice[i].finishedUp,choice[i].numIntInfeasUp,
     2094          //     choice[i].numObjInfeasUp);
     2095         
     2096          /*
     2097            End of evaluation for this candidate variable. Possibilities are:
     2098            * Both sides below cutoff; this variable is a candidate for branching.
     2099            * Both sides infeasible or above the objective cutoff: no further action
     2100            here. Break from the evaluation loop and assume the node will be purged
     2101            by the caller.
     2102            * One side below cutoff: Install the branch (i.e., fix the variable). Break
     2103            from the evaluation loop and assume the node will be reoptimised by the
     2104            caller.
     2105          */
     2106          // reset
     2107          choice[i].possibleBranch->resetNumberBranchesLeft();
     2108          if (choice[i].upMovement<1.0e100) {
     2109            if(choice[i].downMovement<1.0e100) {
     2110              // feasible - no action
     2111            } else {
     2112              // up feasible, down infeasible
     2113              anyAction=-1;
     2114              //printf("Down infeasible for choice %d sequence %d\n",i,
     2115              // model->object(choice[i].objectNumber)->columnNumber());
     2116              if (!solveAll) {
     2117                choice[i].possibleBranch->way(1);
     2118                choice[i].possibleBranch->branch();
     2119                break;
     2120              } else {
     2121                choice[i].fix=1;
     2122              }
     2123            }
     2124          } else {
     2125            if(choice[i].downMovement<1.0e100) {
     2126              // down feasible, up infeasible
     2127              anyAction=-1;
     2128              //printf("Up infeasible for choice %d sequence %d\n",i,
     2129              // model->object(choice[i].objectNumber)->columnNumber());
     2130              if (!solveAll) {
     2131                choice[i].possibleBranch->way(-1);
     2132                choice[i].possibleBranch->branch();
     2133                break;
     2134              } else {
     2135                choice[i].fix=-1;
     2136              }
     2137            } else {
     2138              // neither side feasible
     2139              anyAction=-2;
     2140              //printf("Both infeasible for choice %d sequence %d\n",i,
     2141              // model->object(choice[i].objectNumber)->columnNumber());
     2142              break;
     2143            }
     2144          }
     2145          bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) >
     2146                              model->getDblParam(CbcModel::CbcMaximumSeconds));
     2147          if (hitMaxTime) {
     2148            numberStrong=i+1;
     2149            break;
     2150          }
    21522151        }
    21532152      if (!clp) {
     
    23342333  // Set guessed solution value
    23352334  guessedObjectiveValue_ = objectiveValue_+estimatedDegradation;
    2336 /*
    2337   Cleanup, then we're outta here.
    2338 */
     2335  /*
     2336    Cleanup, then we're outta here.
     2337  */
    23392338  if (!model->branchingMethod()||dynamicBranchingObject)
    23402339    delete decision;
    2341    
     2340 
    23422341  for (i=0;i<maximumStrong;i++)
    23432342    delete choice[i].possibleBranch;
     
    23582357/*
    23592358  Version for dynamic pseudo costs.
    2360 
     2359 
    23612360  **** For now just return if anything odd
    23622361  later allow even if odd
    2363 
     2362 
    23642363  The routine scans through the object list of the model looking for objects
    23652364  that indicate infeasibility. It tests each object using strong branching
     
    23702369  to say give up if last few tries have not changed incumbent.
    23712370  See Achterberg, Koch and Martin.
    2372 
     2371 
    23732372  If strong branching is disabled, a candidate object is chosen essentially
    23742373  at random (whatever object ends up in pos'n 0 of the candidate array).
    2375 
     2374 
    23762375  If a branching candidate is found to be monotone, bounds are set to fix the
    23772376  variable and the routine immediately returns (the caller is expected to
    23782377  reoptimize).
    2379 
     2378 
    23802379  If a branching candidate is found to result in infeasibility in both
    23812380  directions, the routine immediately returns an indication of infeasibility.
    2382 
     2381 
    23832382  Returns:  0   both branch directions are feasible
    2384            -1   branching variable is monotone
    2385            -2   infeasible
    2386            -3   Use another method
    2387 
    2388            For now just fix on objective from strong branching.
     2383  -1    branching variable is monotone
     2384  -2    infeasible
     2385  -3   Use another method
     2386 
     2387  For now just fix on objective from strong branching.
    23892388*/
    23902389
    23912390int CbcNode::chooseDynamicBranch (CbcModel *model, CbcNode *lastNode,
    23922391                                  OsiSolverBranch * & branches,int numberPassesLeft)
    2393 
     2392 
    23942393{ if (lastNode)
    23952394    depth_ = lastNode->depth_+1;
     
    24102409  }
    24112410  int numberObjects = model->numberObjects();
    2412   bool checkFeasibility = false;
     2411  // If very odd set of objects then use older chooseBranch
     2412  bool useOldWay = false;
    24132413  if (numberObjects>model->numberIntegers()) {
    24142414    for (int i=model->numberIntegers();i<numberObjects;i++) {
     
    24162416      CbcObject * obj = dynamic_cast <CbcObject *>(object) ;
    24172417      if (!obj || !obj->optionalObject()) {
    2418         checkFeasibility=true;
     2418        useOldWay=true;
    24192419        break;
    24202420      }
     
    24222422  }
    24232423  if ((model->specialOptions()&128)!=0)
    2424     checkFeasibility=false; // allow
     2424    useOldWay=false; // allow
    24252425  // For now return if not simple
    2426   if (checkFeasibility)
     2426  if (useOldWay)
    24272427    return -3;
    24282428  // point to useful information
     
    24502450  }
    24512451  assert (auxiliaryInfo);
    2452   //assert(objectiveValue_ == solver->getObjSense()*solver->getObjValue());
    24532452  double cutoff =model->getCutoff();
    2454   double distanceToCutoff=cutoff-objectiveValue_;
    24552453  const double * lower = solver->getColLower();
    24562454  const double * upper = solver->getColUpper();
    2457   //const double * objective = solver->getObjCoefficients();
    2458   // See what user thinks
     2455  // See if user thinks infeasible
    24592456  int anyAction=model->problemFeasibility()->feasible(model,0);
    24602457  if (anyAction) {
     
    24652462  int saveStateOfSearch = model->stateOfSearch()%10;
    24662463  int numberStrong=model->numberStrong();
    2467   //if (!auxiliaryInfo->warmStart())
    2468   //numberStrong=0;
    2469   // But make more likely to get out after some times
    2470   int changeStrategy=numberStrong;
    2471   double changeFactor=1.0;
    2472   // Use minimum of this and one stored in objects
    2473   //int numberBeforeTrust = model->numberBeforeTrust();
    2474   // Return if doing hot start (in BAB sense)
    2475   if (model->hotstartSolution())
    2476     return -3;
     2464  /* Ranging is switched off.
     2465     The idea is that you can find out the effect of one iteration
     2466     on each unsatisfied variable cheaply.  Then use this
     2467     if you have not got much else to go on.
     2468  */
    24772469  //#define RANGING
    24782470#ifdef RANGING
     2471  // must have clp
     2472#ifndef COIN_HAS_CLP
     2473#  warning("Ranging switched off as not Clp");
     2474#undef RANGING
     2475#endif
    24792476  // Pass number
    24802477  int kPass=0;
     
    24842481  double * saveUpper = new double[numberColumns];
    24852482  double * saveLower = new double[numberColumns];
    2486 
     2483  for (i=0;i<numberColumns;i++) {
     2484    saveLower[i] = lower[i];
     2485    saveUpper[i] = upper[i];
     2486  }
     2487 
    24872488  // Save solution in case heuristics need good solution later
    24882489 
     
    24902491  memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
    24912492  model->reserveCurrentSolution(saveSolution);
    2492   if (false) {
    2493         OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
    2494         const double * sol = osiclp->getColSolution();
    2495         int n = osiclp->getNumCols();
    2496         for (int i=0;i<n;i++) {
    2497           double sC = sol[i];
    2498           double sS = saveSolution[i];
    2499           double sU = usefulInfo.solution_[i];
    2500           if (fabs(sC-sS)>1.0e-5||fabs(sC-sU)>1.0e-5)
    2501             printf("DiffA %d clp %g saved %g useful %g\n",
    2502                    i,sC,sS,sU);
    2503         }
    2504   }
    25052493  /*
    25062494    Get a branching decision object. Use the default dynamic decision criteria unless
     
    25102498  if (!decision)
    25112499    decision = new CbcBranchDynamicDecision();
    2512   int xPen=0;
    25132500  int xMark=0;
    2514   for (i=0;i<numberColumns;i++) {
    2515     saveLower[i] = lower[i];
    2516     saveUpper[i] = upper[i];
    2517   }
    25182501  // Get arrays to sort
    25192502  double * sort = new double[numberObjects];
    25202503  int * whichObject = new int[numberObjects];
     2504#ifdef RANGING
     2505  int xPen=0;
    25212506  int * objectMark = new int[2*numberObjects+1];
     2507#endif
    25222508  // Arrays with movements
    25232509  double * upEstimate = new double[numberObjects];
    25242510  double * downEstimate = new double[numberObjects];
    2525   CbcStrongInfo * fixObject = new CbcStrongInfo[numberObjects];
    25262511  double estimatedDegradation=0.0;
    25272512  int numberNodes=model->getNodeCount();
    25282513  int saveLogLevel = model->logLevel();
    2529   if ((numberNodes%500)==0&&false) {
     2514#if 0
     2515  if ((numberNodes%500)==0) {
    25302516    model->setLogLevel(6);
    25312517    // Get average up and down costs
     
    25372523    for ( i=0;i<numberObjects;i++) {
    25382524      OsiObject * object = model->modifiableObject(i);
    2539 #ifndef NDEBUG
    25402525      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    25412526        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    25422527      assert(dynamicObject);
    2543 #else
    2544       CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    2545         static_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2546 #endif
    25472528      int  numberUp2=0;
    25482529      int numberDown2=0;
     
    25762557           numberUp,averageUp,numberDown,averageDown);
    25772558  }
     2559#endif
    25782560  int numberBeforeTrust = model->numberBeforeTrust();
    2579   int numberPenalties = model->numberPenalties();
    2580   if (numberBeforeTrust>=1000000) {
    2581     numberBeforeTrust = numberBeforeTrust % 1000000;
    2582     numberPenalties=0;
    2583   } else if (numberBeforeTrust<0) {
    2584     if (numberBeforeTrust==-1)
    2585       numberPenalties=numberColumns;
    2586     else if (numberBeforeTrust==-2)
    2587       numberPenalties=0;
    2588     numberBeforeTrust=0;
    2589   }
    25902561  // May go round twice if strong branching fixes all local candidates
    25912562  bool finished=false;
     
    26032574# endif
    26042575  const CglTreeProbingInfo * probingInfo = NULL; //model->probingInfo();
     2576  // Old code left in with DEPRECATED_STRATEGY
     2577  assert (model->searchStrategy()==-1||
     2578          model->searchStrategy()==1||
     2579          model->searchStrategy()==2);
     2580#ifdef DEPRECATED_STRATEGY
    26052581  int saveSearchStrategy2 = model->searchStrategy();
    2606 #define NODE_NEW  2
    2607 #ifdef RANGING
    2608   bool useRanging;
    2609 #if NODE_NEW !=3
    2610   useRanging = false;
    2611 #else
    2612   useRanging = true;
    2613 #endif
    2614   if (saveSearchStrategy2!=2)
    2615     useRanging=false;
    2616 #endif
    2617   if (saveSearchStrategy2<999) {
    2618 #if NODE_NEW ==4
    2619     if (saveSearchStrategy2!=2) {
    2620 #endif
    2621     // Get average up and down costs
    2622     double averageUp=0.0;
    2623     double averageDown=0.0;
    2624     {
    2625       int numberUp=0;
    2626       int numberDown=0;
    2627       int i;
    2628       for ( i=0;i<numberObjects;i++) {
    2629         OsiObject * object = model->modifiableObject(i);
    2630         CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    2631           dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2632         if (dynamicObject) {
    2633           if (dynamicObject->numberTimesUp()) {
    2634             numberUp++;
    2635             averageUp += dynamicObject->upDynamicPseudoCost();
    2636           }
    2637           if (dynamicObject->numberTimesDown()) {
    2638             numberDown++;
    2639             averageDown += dynamicObject->downDynamicPseudoCost();
    2640           }
     2582#endif
     2583  // Get average up and down costs
     2584  double averageUp=0.0;
     2585  double averageDown=0.0;
     2586  {
     2587    int numberUp=0;
     2588    int numberDown=0;
     2589    int i;
     2590    for ( i=0;i<numberObjects;i++) {
     2591      OsiObject * object = model->modifiableObject(i);
     2592      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     2593        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     2594      if (dynamicObject) {
     2595        if (dynamicObject->numberTimesUp()) {
     2596          numberUp++;
     2597          averageUp += dynamicObject->upDynamicPseudoCost();
    26412598        }
    2642       }
    2643       if (numberUp)
    2644         averageUp /= static_cast<double> (numberUp);
    2645       else
    2646         averageUp=1.0;
    2647       if (numberDown)
    2648         averageDown /= static_cast<double> (numberDown);
    2649       else
    2650         averageDown=1.0;
    2651       for ( i=0;i<numberObjects;i++) {
    2652         OsiObject * object = model->modifiableObject(i);
    2653         CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    2654           dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2655         if (dynamicObject) {
    2656           if (!dynamicObject->numberTimesUp())
    2657             dynamicObject->setUpDynamicPseudoCost(averageUp);
    2658           if (!dynamicObject->numberTimesDown())
    2659             dynamicObject->setDownDynamicPseudoCost(averageDown);
     2599        if (dynamicObject->numberTimesDown()) {
     2600          numberDown++;
     2601          averageDown += dynamicObject->downDynamicPseudoCost();
    26602602        }
    26612603      }
    26622604    }
    2663 #if NODE_NEW ==4
    2664     } else {
    2665     // pseudo shadow prices
    2666     model->pseudoShadow(NULL,NULL);
    2667     }
    2668 #endif
     2605    if (numberUp)
     2606      averageUp /= static_cast<double> (numberUp);
     2607    else
     2608      averageUp=1.0;
     2609    if (numberDown)
     2610      averageDown /= static_cast<double> (numberDown);
     2611    else
     2612      averageDown=1.0;
     2613    for ( i=0;i<numberObjects;i++) {
     2614      OsiObject * object = model->modifiableObject(i);
     2615      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     2616        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     2617      if (dynamicObject) {
     2618        if (!dynamicObject->numberTimesUp())
     2619          dynamicObject->setUpDynamicPseudoCost(averageUp);
     2620        if (!dynamicObject->numberTimesDown())
     2621          dynamicObject->setDownDynamicPseudoCost(averageDown);
     2622      }
     2623    }
     2624  }
     2625#ifdef DEPRECATED_STRATEGY
     2626  { // in for tabbing
    26692627  } else if (saveSearchStrategy2<1999) {
    26702628    // pseudo shadow prices
     
    26832641  if (saveSearchStrategy2==999)
    26842642    saveSearchStrategy2=-1;
    2685   int px[4]={-1,-1,-1,-1};
    26862643  int saveSearchStrategy = saveSearchStrategy2<99 ? saveSearchStrategy2 : saveSearchStrategy2-100;
    2687   bool newWay = saveSearchStrategy2>98;
     2644#endif //DEPRECATED_STRATEGY
    26882645  int numberNotTrusted=0;
    26892646  int numberStrongDone=0;
     
    26912648  int numberStrongInfeasible=0;
    26922649  int numberStrongIterations=0;
    2693   // so we can save lots of news
     2650  // so we can save lots of stuff
    26942651  CbcStrongInfo choice;
    26952652  CbcDynamicPseudoCostBranchingObject * choiceObject = NULL;
     
    27002657  choice.possibleBranch=choiceObject;
    27012658  int kkPass=0;
    2702   //#define CBC_NODE7 1
    2703 #ifdef CBC_NODE7
    2704   double * weightModifier = new double [2*numberColumns];
    2705   CoinZeroN(weightModifier,2*numberColumns);
    2706   if (usefulInfo.columnLength_) {
    2707 #if CBC_NODE7>1
    2708     double tolerance=1.0e-6;
    2709     int numberRows = solver->getNumRows();
    2710     double * activeWeight = new double [numberRows];
    2711     for (int iRow = 0;iRow<numberRows;iRow++) {
    2712       // could use pi to see if active or activity
    2713 #if 1
    2714       if (usefulInfo.rowActivity_[iRow]>usefulInfo.rowUpper_[iRow]-tolerance
    2715           ||usefulInfo.rowActivity_[iRow]<usefulInfo.rowLower_[iRow]+tolerance) {
    2716         activeWeight[iRow]=0.0;
    2717       } else {
    2718         activeWeight[iRow]=-1.0;
    2719       }
    2720 #else
    2721       if (fabs(usefulInfo.pi_[iRow])>1.0e-6) {
    2722         activeWeight[iRow]=0.0;
    2723       } else {
    2724         activeWeight[iRow]=-1.0;
    2725       }
    2726 #endif
    2727     }
    2728     for (int iColumn=0;iColumn<numberColumns;iColumn++) {
    2729       if (solver->isInteger(iColumn)) {
    2730         double solValue = usefulInfo.solution_[iColumn];
    2731         if (fabs(solValue-floor(solValue+0.5))>1.0e-6) {
    2732           CoinBigIndex start = usefulInfo.columnStart_[iColumn];
    2733           CoinBigIndex end = start + usefulInfo.columnLength_[iColumn];
    2734 #ifndef NDEBUG
    2735           double value = usefulInfo.direction_*usefulInfo.objective_[iColumn];
    2736 #endif
    2737           for (CoinBigIndex j=start;j<end;j++) {
    2738             int iRow = usefulInfo.row_[j];
    2739 #ifndef NDEBUG
    2740             value -= usefulInfo.pi_[iRow] * usefulInfo.elementByColumn_[j];
    2741 #endif
    2742             if (activeWeight[iRow]>=0.0)
    2743               activeWeight[iRow] += 1.0;
    2744           }
    2745           assert (fabs(value)<1.0e-4);
    2746         }
    2747       }
    2748     }
    2749     for (int iRow = 0;iRow<numberRows;iRow++) {
    2750       if (activeWeight[iRow]>0.0) {
    2751         // could use pi
    2752         activeWeight[iRow] = 1.0/activeWeight[iRow];
    2753 #if 0
    2754         activeWeight[iRow] *= fabs(usefulInfo.pi_[iRow]);
    2755 #endif
    2756       } else {
    2757         activeWeight[iRow]=0.0;
    2758       }
    2759     }
    2760     for (int iColumn=0;iColumn<numberColumns;iColumn++) {
    2761       if (solver->isInteger(iColumn)) {
    2762         double solValue = usefulInfo.solution_[iColumn];
    2763         if (fabs(solValue-floor(solValue+0.5))>1.0e-6) {
    2764           CoinBigIndex start = usefulInfo.columnStart_[iColumn];
    2765           CoinBigIndex end = start + usefulInfo.columnLength_[iColumn];
    2766           solValue -= floor(solValue);
    2767 #if CBC_NODE7>=3
    2768           double upValue = 0.0;
    2769           double downValue = 0.0;
    2770           double value = usefulInfo.direction_*usefulInfo.objective_[iColumn];
    2771           // Bias cost
    2772           if (value>0.0)
    2773             upValue += 1.5*value;
    2774           else
    2775             downValue -= 1.5*value;
    2776           for (CoinBigIndex j=start;j<end;j++) {
    2777             int iRow = usefulInfo.row_[j];
    2778 #if CBC_NODE7<=3
    2779             value = -usefulInfo.pi_[iRow];
    2780             if (value) {
    2781               value *= usefulInfo.elementByColumn_[j];
    2782 #if CBC_NODE7==3
    2783               value *= activeWeight[iRow];
    2784 #endif
    2785               if (value>0.0)
    2786                 upValue += value;
    2787               else
    2788                 downValue -= value;
    2789             }
    2790 #else
    2791             value = usefulInfo.elementByColumn_[j];
    2792             double downMove = -solValue*value;
    2793             double upMove = (1.0-solValue)*value;
    2794             if (usefulInfo.rowActivity_[iRow]+downMove>usefulInfo.rowUpper_[iRow]-tolerance
    2795                 ||usefulInfo.rowActivity_[iRow]+downMove<usefulInfo.rowLower_[iRow]+tolerance)
    2796               downMove = fabs(value);
    2797             else
    2798               downMove = 0.0;
    2799             if (usefulInfo.rowActivity_[iRow]+upMove>usefulInfo.rowUpper_[iRow]-tolerance
    2800                 ||usefulInfo.rowActivity_[iRow]+upMove<usefulInfo.rowLower_[iRow]+tolerance)
    2801               upMove = fabs(value);
    2802             else
    2803               upMove = 0.0;
    2804 #if CBC_NODE7==5
    2805             downMove *= activeWeight[iRow];
    2806             upMove *= activeWeight[iRow];
    2807 #endif
    2808             upValue += upMove;
    2809             downValue += downMove;
    2810 #endif
    2811           }
    2812           downValue = CoinMax(downValue,1.0e-8);
    2813           upValue = CoinMax(upValue,1.0e-8);
    2814           int put = 2*iColumn;
    2815           weightModifier[put]=downValue;
    2816           weightModifier[put+1]=upValue;
    2817 #elif CBC_NODE7==2
    2818           double value=1.0e-8;
    2819           for (CoinBigIndex j=start;j<end;j++) {
    2820             int iRow = usefulInfo.row_[j];
    2821             if (activeWeight[iRow])
    2822               value += fabs(usefulInfo.elementByColumn_[j])*activeWeight[iRow];
    2823           }
    2824           //downValue = value*solValue;
    2825           //upValue = value*(1.0-solValue);
    2826           int put = 2*iColumn;
    2827           weightModifier[put]=value;
    2828           weightModifier[put+1]=value;
    2829 #endif
    2830         }
    2831       }
    2832     }
    2833 #if CBC_NODE7>1
    2834     delete [] activeWeight;
    2835 #endif
    2836 #else
    2837     for (int iColumn=0;iColumn<numberColumns;iColumn++) {
    2838       if (solver->isInteger(iColumn)) {
    2839         CoinBigIndex start = usefulInfo.columnStart_[iColumn];
    2840         CoinBigIndex end = start + usefulInfo.columnLength_[iColumn];
    2841         double upValue = 0.0;
    2842         double downValue = 0.0;
    2843         double solValue = usefulInfo.solution_[iColumn];
    2844         if (fabs(solValue-floor(solValue+0.5))>1.0e-6) {
    2845           solValue -= floor(solValue);
    2846           double value = usefulInfo.direction_*usefulInfo.objective_[iColumn];
    2847           // Bias cost
    2848           if (value>0.0)
    2849             upValue += 1.5*value;
    2850           else
    2851             downValue -= 1.5*value;
    2852           for (CoinBigIndex j=start;j<end;j++) {
    2853             int iRow = usefulInfo.row_[j];
    2854             value = -usefulInfo.pi_[iRow];
    2855             if (value) {
    2856               value *= usefulInfo.elementByColumn_[j];
    2857               if (value>0.0)
    2858                 upValue += value;
    2859               else
    2860                 downValue -= value;
    2861             }
    2862           }
    2863           downValue = CoinMax(downValue,1.0e-8);
    2864           upValue = CoinMax(upValue,1.0e-8);
    2865           int put = 2*iColumn;
    2866           weightModifier[put]=downValue;
    2867           weightModifier[put+1]=upValue;
    2868         }
    2869       }
    2870     }
    2871 #endif
    2872   } else {
    2873     kkPass=-1000000;
    2874   }
    2875 #endif
    28762659  while(!finished) {
    28772660    kkPass++;
     
    28812664    estimatedDegradation=0.0;
    28822665    numberToFix=0;
    2883     int numberIntegerInfeasibilities=0; // without odd ones
    28842666    int numberToDo=0;
    28852667    int iBestNot=-1;
     
    28912673    numberStrongInfeasible=0;
    28922674    numberStrongIterations=0;
     2675#ifdef RANGING
    28932676    int * which = objectMark+numberObjects+1;
    28942677    int neededPenalties;
    2895     int branchingMethod=-1;
     2678    int optionalPenalties;
     2679#endif
    28962680    // We may go round this loop three times (only if we think we have solution)
    28972681    for (int iPass=0;iPass<3;iPass++) {
    2898 
    2899       if (false) {
    2900         const double * sol = osiclp->getColSolution();
    2901         int n = osiclp->getNumCols();
    2902         for (int i=0;i<n;i++) {
    2903           double sC = sol[i];
    2904           double sS = saveSolution[i];
    2905           double sU = usefulInfo.solution_[i];
    2906           if (fabs(sC-sS)>1.0e-5||fabs(sC-sU)>1.0e-5)
    2907             printf("Diff %d clp %g saved %g useful %g\n",
    2908                    i,sC,sS,sU);
    2909         }
    2910       }
    2911       // compute current state
    2912       int numberObjectInfeasibilities; // just odd ones
    2913       model->feasibleSolution(
    2914                               numberIntegerInfeasibilities,
    2915                               numberObjectInfeasibilities);
    29162682     
    29172683      // Some objects may compute an estimate of best solution from here
     
    29502716      */
    29512717      numberToDo=0;
     2718#ifdef RANGING
    29522719      neededPenalties=0;
     2720      optionalPenalties=numberObjects;
     2721#endif
    29532722      iBestNot=-1;
    29542723      double bestNot=0.0;
     
    29632732      */
    29642733      int problemType = model->problemType();
    2965 #define PRINT_STUFF -1
    29662734      for (i=0;i<numberObjects;i++) {
    29672735        OsiObject * object = model->modifiableObject(i);
     
    29902758          double downGuess=object->downEstimate();
    29912759          double upGuess=object->upEstimate();
    2992           // check branching method
    29932760          if (dynamicObject) {
    2994             if (branchingMethod!=dynamicObject->method()) {
    2995               if (branchingMethod==-1)
    2996                 branchingMethod = dynamicObject->method();
    2997               else
    2998                 branchingMethod = 100;
    2999             }
     2761            // Use this object's numberBeforeTrust
     2762            int numberBeforeTrust = dynamicObject->numberBeforeTrust();
    30002763            iColumn = dynamicObject->columnNumber();
    30012764            gotDown=false;
     
    30072770            if (numberThisUp>=numberBeforeTrust)
    30082771              gotUp=true;
    3009             //infeasibility += 10000.0*fabs(objective[iColumn]);
    3010 #ifdef CBC_NODE7
    3011             /*
    3012               Could do for kkPass>=1
    3013               Could do max just if not fully trusted
    3014             */
    3015             if (weightModifier&&kkPass==1) {
    3016               double solValue = usefulInfo.solution_[iColumn];
    3017               solValue -= floor(solValue);
    3018               int get = 2*iColumn;
    3019               double downValue = weightModifier[get];
    3020               double upValue = weightModifier[get+1];
    3021               assert (downValue>0.0&&upValue>0.0);
    3022               downGuess = downValue * solValue;
    3023               upGuess = upValue * (1.0-solValue);
    3024 #if 0
    3025               printf("%d inf %g ord %g %g shadow %g %g\n",
    3026                      iColumn,infeasibility,
    3027                      object->downEstimate(),object->upEstimate(),
    3028                      downGuess,upGuess);
    3029 #endif
    3030               double useInfeasibility = 0.9*CoinMin(downGuess,upGuess)
    3031                 + 0.1*CoinMax(downGuess,upGuess);
    3032 #if CBC_NODE7>=3
    3033 #if 1
    3034               if (numberThisUp<10||numberThisDown<10)
    3035                 //if (!gotUp||!gotDown)
    3036                 infeasibility = CoinMax(useInfeasibility,infeasibility);
    3037               else
    3038                 infeasibility = CoinMax(0.1*useInfeasibility,infeasibility);
    3039 #else
    3040               if (!numberThisUp&&!numberThisDown)
    3041                 infeasibility = CoinMax(useInfeasibility,infeasibility);
    3042               else
    3043                 infeasibility += 0.1*useInfeasibility;
    3044 #endif
    3045 #else
    3046 
    3047 #if 1
    3048               infeasibility = useInfeasibility;
    3049 #else
    3050 #if 1
    3051               if (numberThisUp<10||numberThisDown<10)
    3052                 infeasibility = CoinMax(useInfeasibility,infeasibility);
    3053               else
    3054                 infeasibility = CoinMax(0.1*useInfeasibility,infeasibility);
    3055 #else
    3056               infeasibility *= weightModifier[2*iColumn];
    3057 #endif
    3058 #endif
    3059 #endif
    3060             }
    3061 #endif
    3062             //double gap = saveUpper[iColumn]-saveLower[iColumn];
    3063             // Give precedence to ones with gap of 1.0
    3064             //assert(gap>0.0);
    3065             //infeasibility /= CoinMin(gap,100.0);
    30662772            if (!depth_&&false) {
    30672773              // try closest to 0.5
     
    30852791              }
    30862792            }
    3087             if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
    3088               printf("%d down %d %g up %d %g - infeas %g\n",
    3089                      i,numberThisDown,object->downEstimate(),numberThisUp,object->upEstimate(),
    3090                      infeasibility);
    30912793          } else {
    30922794            // see if SOS
     
    31252827            best=0.0;
    31262828            numberNotTrusted=0;
     2829#ifdef RANGING
     2830            neededPenalties=0;
     2831            optionalPenalties=numberObjects;
     2832#endif
    31272833          } else if (priorityLevel>bestPriority) {
    31282834            continue;
     
    31372843              iBestGot=numberToDo;
    31382844            }
     2845#ifdef RANGING
     2846            if (dynamicObject) {
     2847              objectMark[--optionalPenalties]=numberToDo;
     2848              which[optionalPenalties]=iColumn;
     2849            }
     2850#endif
    31392851          } else {
    3140             objectMark[neededPenalties]=numberToDo;
    3141             which[neededPenalties++]=iColumn;
     2852#ifdef RANGING
     2853            if (dynamicObject) {
     2854              objectMark[neededPenalties]=numberToDo;
     2855              which[neededPenalties++]=iColumn;
     2856            }
     2857#endif
    31422858            sort[numberToDo]=-10.0*infeasibility;
    31432859            if (!(numberThisUp+numberThisDown))
     
    32292945      break;
    32302946    }
    3231     bool solveAll=false; // set true to say look at all even if some fixed (experiment)
    3232     solveAll=true;
    32332947    // skip if solution
    32342948    if (!numberUnsatisfied_)
    32352949      break;
    3236     //bool skipAll = (numberBeforeTrust>20&&numberNodes>20000&&numberNotTrusted==0);
    32372950    int skipAll = (numberNotTrusted==0||numberToDo==1) ? 1 : 0;
    32382951    bool doneHotStart=false;
    3239     int searchStrategy = saveSearchStrategy>=0 ? (saveSearchStrategy%10) : -1;
    3240     if (0) {
    3241       int numberIterations = model->getIterationCount();
    3242       int numberStrongIterations = model->numberStrongIterations();
    3243       printf("node %d saveSearch %d search %d - its %d strong %d\n",
    3244              numberNodes,saveSearchStrategy,searchStrategy,
    3245              numberIterations,numberStrongIterations);
    3246     }
    3247 #ifndef CBC_WEAK_STRONG
    3248     if (((numberNodes%20)==0&&searchStrategy!=2)||(model->specialOptions()&8)!=0)
    3249       skipAll=0;
    3250 #endif
    3251     if (!newWay) {
    3252     // 10 up always use %10, 20 up as 10 and allow penalties
     2952    //DEPRECATED_STRATEGYint searchStrategy = saveSearchStrategy>=0 ? (saveSearchStrategy%10) : -1;
     2953    int searchStrategy = model->searchStrategy();
    32532954    // But adjust depending on ratio of iterations
    3254     if (searchStrategy>0&&saveSearchStrategy<10) {
     2955    if (searchStrategy>0) {
    32552956      if (numberBeforeTrust>=5&&numberBeforeTrust<=10) {
    3256         if (searchStrategy!=2) {
     2957        if (searchStrategy!=2) {
     2958          assert (searchStrategy==1);
    32572959          if (depth_>5) {
    32582960            int numberIterations = model->getIterationCount();
     
    32602962            if (numberStrongIterations>numberIterations+10000) {
    32612963              searchStrategy=2;
    3262               //skipAll=1;
    3263             } else if (numberStrongIterations*4+1000<numberIterations||depth_<5) {
     2964              skipAll=1;
     2965            } else if (numberStrongIterations*4+1000<numberIterations) {
    32642966              searchStrategy=3;
    32652967              skipAll=0;
     
    32692971            skipAll=0;
    32702972          }
    3271         } else {
    3272           //skipAll=1;
    3273         }
    3274       }
    3275     }
    3276     } else {
    3277     // But adjust depending on ratio of iterations
    3278     if (saveSearchStrategy<0) {
    3279       // unset
    3280       if ((numberNodes%20)==0||(model->specialOptions()&8)!=0) {
    3281         // Do numberStrong
    3282         searchStrategy=3;
    3283       } else if (depth_<5) {
    3284         // Do numberStrong
    3285         searchStrategy=2;
    3286       } else {
    3287         int numberIterations = model->getIterationCount();
    3288         int numberStrongIterations = model->numberStrongIterations();
    3289         int numberRows = solver->getNumRows();
    3290         if (numberStrongIterations>numberIterations+CoinMin(10000,10*numberRows)) {
    3291           // off
    3292           searchStrategy=0;
    3293         } else if (numberStrongIterations*4+1000<numberIterations) {
    3294           // Do numberStrong if not trusted
    3295           searchStrategy=2;
    3296         } else {
    3297           searchStrategy=1;
    3298         }
    3299       }
    3300     }
    3301     if (searchStrategy<3&&(!numberNotTrusted||!searchStrategy))
    3302       skipAll=1;
    3303     else
    3304       skipAll=0;
     2973        }
     2974      }
    33052975    }
    33062976    // worth trying if too many times
     
    33152985      ws = solver->getWarmStart();
    33162986      int limit=100;
    3317 #if 0
    3318       int averageBranchIterations = model->getIterationCount()/(model->getNodeCount()+1);
    3319       if (numberNodes)
    3320         limit = CoinMin(CoinMax(limit,2*averageBranchIterations),500);
    3321       else
    3322         limit = 500;
    3323 #endif
    3324       if ((!saveStateOfSearch||searchStrategy>3)&&saveLimit<limit&&saveLimit==100)
     2987      if (!saveStateOfSearch&&saveLimit<limit&&saveLimit==100)
    33252988        solver->setIntParam(OsiMaxNumIterationHotStart,limit);
    33262989    }
     
    33373000                        model->getDblParam(CbcModel::CbcMaximumSeconds));
    33383001    // also give up if we are looping round too much
    3339     if (hitMaxTime||numberPassesLeft<=0||(!numberNotTrusted&&false)||branchingMethod==11) {
     3002    if (hitMaxTime||numberPassesLeft<=0) {
    33403003      int iObject = whichObject[bestChoice];
    33413004      OsiObject * object = model->modifiableObject(iObject);
     
    33683031      int iDo;
    33693032#ifdef RANGING
     3033      bool useRanging = model->allDynamic()&&!skipAll;
    33703034      if (useRanging) {
    3371       if ((skipAll&&numberBeforeTrust&&saveSearchStrategy<20)||saveSearchStrategy<10)
    3372         numberPenalties=0;
     3035        double currentObjective = solver->getObjValue()*solver->getObjSense();
     3036        double gap = cutoff-currentObjective;
     3037        // relax a bit
     3038        gap *= 1.0000001;
     3039        gap = CoinMax(1.0e-5,gap);
     3040        // off penalties if too much
     3041        double needed = neededPenalties;
     3042        needed *= numberRows;
     3043        if (numberNodes) {
     3044          if (needed>1.0e6) {
     3045            neededPenalties=0;
     3046          } else if (gap<1.0e5) {
     3047            // maybe allow some not needed
     3048            int extra = static_cast<int> ((1.0e6-needed)/numberRows);
     3049            int nStored = numberObjects-optionalPenalties;
     3050            extra = CoinMin(extra,nStored);
     3051            for (int i=0;i<extra;i++) {
     3052              objectMark[neededPenalties]=objectMark[optionalPenalties+i];
     3053                which[neededPenalties++]=which[optionalPenalties+i];;
     3054            }
     3055          }
     3056        }
     3057        if (osiclp&&neededPenalties) {
     3058          assert (!doneHotStart);
     3059          xPen += neededPenalties;
     3060          which--;
     3061          which[0]=neededPenalties;
     3062          osiclp->passInRanges(which);
     3063          // Mark hot start and get ranges
     3064          if (kPass) {
     3065            // until can work out why solution can go funny
     3066            int save = osiclp->specialOptions();
     3067            osiclp->setSpecialOptions(save|256);
     3068            solver->markHotStart();
     3069            osiclp->setSpecialOptions(save);
     3070          } else {
     3071            solver->markHotStart();
     3072          }
     3073          doneHotStart=true;
     3074          xMark++;
     3075          kPass++;
     3076          osiclp->passInRanges(NULL);
     3077          const double * downCost=osiclp->upRange();
     3078          const double * upCost=osiclp->downRange();
     3079          bool problemFeasible=true;
     3080          int numberFixed=0;
     3081          for (int i=0;i<neededPenalties;i++) {
     3082            int j = objectMark[i];
     3083            int iObject = whichObject[j];
     3084            OsiObject * object = model->modifiableObject(iObject);
     3085            CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     3086              static_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     3087            // Use this object's numberBeforeTrust
     3088            int numberBeforeTrust = dynamicObject->numberBeforeTrust();
     3089            int iSequence=dynamicObject->columnNumber();
     3090            double value = saveSolution[iSequence];
     3091            value -= floor(value);
     3092            double upPenalty = CoinMin(upCost[i],1.0e110)*(1.0-value);
     3093            double downPenalty = CoinMin(downCost[i],1.0e110)*value;
     3094            int numberThisDown = dynamicObject->numberTimesDown();
     3095            int numberThisUp = dynamicObject->numberTimesUp();
     3096            if (!numberBeforeTrust) {
     3097              // override
     3098              downEstimate[iObject]=downPenalty;
     3099              upEstimate[iObject]=upPenalty;
     3100              double min1 = CoinMin(downEstimate[iObject],
     3101                                    upEstimate[iObject]);
     3102              double max1 = CoinMax(downEstimate[iObject],
     3103                                    upEstimate[iObject]);
     3104              min1 = 0.8*min1+0.2*max1;
     3105              sort[j] = - min1;
     3106            } else if (numberThisDown<numberBeforeTrust||
     3107                       numberThisUp<numberBeforeTrust) {
     3108              double invTrust = 1.0/static_cast<double> (numberBeforeTrust);
     3109              if (numberThisDown<numberBeforeTrust) {
     3110                double fraction = numberThisDown*invTrust;
     3111                downEstimate[iObject] = fraction*downEstimate[iObject]+(1.0-fraction)*downPenalty;
     3112              }
     3113              if (numberThisUp<numberBeforeTrust) {
     3114                double fraction = numberThisUp*invTrust;
     3115                upEstimate[iObject] = fraction*upEstimate[iObject]+(1.0-fraction)*upPenalty;
     3116              }
     3117              double min1 = CoinMin(downEstimate[iObject],
     3118                                    upEstimate[iObject]);
     3119              double max1 = CoinMax(downEstimate[iObject],
     3120                                    upEstimate[iObject]);
     3121              min1 = 0.8*min1+0.2*max1;
     3122              min1 *= 10.0;
     3123              if (!(numberThisDown+numberThisUp))
     3124                min1 *= 100.0;
     3125              sort[j] = - min1;
     3126            }
     3127            if (CoinMax(downPenalty,upPenalty)>gap) {
     3128              printf("gap %g object %d has down range %g, up %g\n",
     3129                     gap,i,downPenalty,upPenalty);
     3130              //sort[j] -= 1.0e50; // make more likely to be chosen
     3131              int number;
     3132              if (downPenalty>gap) {
     3133                number = dynamicObject->numberTimesDown();
     3134                if (upPenalty>gap)
     3135                  problemFeasible=false;
     3136                CbcBranchingObject * branch = dynamicObject->createBranch(1);
     3137                //branch->fix(solver,saveLower,saveUpper,1);
     3138                delete branch;
     3139              } else {
     3140                number = dynamicObject->numberTimesUp();
     3141                CbcBranchingObject * branch = dynamicObject->createBranch(1);
     3142                //branch->fix(solver,saveLower,saveUpper,-1);
     3143                delete branch;
     3144              }
     3145              if(number>=numberBeforeTrust)
     3146                dynamicObject->setNumberBeforeTrust(number+1);
     3147              numberFixed++;
     3148            }
     3149            if (!numberNodes)
     3150              printf("%d pen down ps %g -> %g up ps %g -> %g\n",
     3151                     iObject,downPenalty,downPenalty,upPenalty,upPenalty);
     3152          }
     3153          if(numberFixed&&problemFeasible) {
     3154            assert(doneHotStart);
     3155            solver->unmarkHotStart();
     3156            model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
     3157            solver->markHotStart();
     3158            problemFeasible = solver->isProvenOptimal();
     3159          }
     3160          if(!problemFeasible) {
     3161            fprintf(stdout,"both ways infeas on ranging - code needed\n");
     3162            anyAction=-2;
     3163            if (!choiceObject) {
     3164              delete choice.possibleBranch;
     3165              choice.possibleBranch=NULL;
     3166            }
     3167            //printf("Both infeasible for choice %d sequence %d\n",i,
     3168            // model->object(choice.objectNumber)->columnNumber());
     3169            // Delete the snapshot
     3170            solver->unmarkHotStart();
     3171            // back to normal
     3172            solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
     3173            // restore basis
     3174            solver->setWarmStart(ws);
     3175            doneHotStart=false;
     3176            delete ws;
     3177            ws=NULL;
     3178            break;
     3179          }
     3180        }
     3181      }
     3182#endif          /* RANGING */
    33733183      {
    3374         // off penalties if too much
    3375         double needed = neededPenalties;
    3376         needed *= numberRows;
    3377         if (needed>1.0e6&&numberNodes&&saveSearchStrategy<20) {
    3378           numberPenalties=0;
    3379           neededPenalties=0;
    3380         }
    3381       }
    3382 #     ifdef COIN_HAS_CLP
    3383       if (osiclp&&numberPenalties&&neededPenalties) {
    3384         xPen += neededPenalties;
    3385         which--;
    3386         which[0]=neededPenalties;
    3387         osiclp->passInRanges(which);
    3388         // Mark hot start and get ranges
    3389         if (kPass) {
    3390           // until can work out why solution can go funny
    3391           int save = osiclp->specialOptions();
    3392           osiclp->setSpecialOptions(save|256);
    3393           solver->markHotStart();
    3394           osiclp->setSpecialOptions(save);
    3395         } else {
    3396           solver->markHotStart();
    3397         }
    3398         doneHotStart=true;
    3399         xMark++;
    3400         kPass++;
    3401         osiclp->passInRanges(NULL);
    3402         const double * downCost=osiclp->upRange();
    3403         const double * upCost=osiclp->downRange();
    3404         //printf("numberTodo %d needed %d numberpenalties %d\n",numberToDo,neededPenalties,numberPenalties);
    3405         double invTrust = 1.0/((double) numberBeforeTrust);
    3406         for (int i=0;i<neededPenalties;i++) {
    3407           int j = objectMark[i];
    3408           int iObject = whichObject[j];
    3409           OsiObject * object = model->modifiableObject(iObject);
    3410           CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    3411             static_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    3412           int iSequence=dynamicObject->columnNumber();
    3413           double value = saveSolution[iSequence];
    3414           value -= floor(value);
    3415           double upPenalty = CoinMin(upCost[i],1.0e110)*(1.0-value);
    3416           double downPenalty = CoinMin(downCost[i],1.0e110)*value;
    3417           if (!numberBeforeTrust) {
    3418             // override
    3419             downEstimate[iObject]=downPenalty;
    3420             upEstimate[iObject]=upPenalty;
    3421           } else {
    3422             int numberThisDown = dynamicObject->numberTimesDown();
    3423             if (numberThisDown<numberBeforeTrust) {
    3424               double fraction = ((double) numberThisDown)*invTrust;
    3425               downEstimate[iObject] = fraction*downEstimate[iObject]+(1.0-fraction)*downPenalty;
    3426             }
    3427             int numberThisUp = dynamicObject->numberTimesUp();
    3428             if (numberThisUp<numberBeforeTrust) {
    3429               double fraction = ((double) numberThisUp)*invTrust;
    3430               upEstimate[iObject] = fraction*upEstimate[iObject]+(1.0-fraction)*upPenalty;
    3431             }
    3432           }
    3433           sort[j] = - CoinMin(downEstimate[iObject],upEstimate[iObject]);
    3434 #ifdef CBC_WEAK_STRONG
    3435           sort[j] -= 1.0e10; // make more likely to be chosen
    3436 #endif
    3437           //if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
    3438           if (!numberNodes)
    3439             printf("%d pen down ps %g -> %g up ps %g -> %g\n",
    3440                    iObject,downCost[i],downPenalty,upCost[i],upPenalty);
    3441         }
    3442       } else
    3443 #     endif     /* COIN_HAS_CLP */
    3444       {
    3445         if (!skipAll) {
    3446           // Mark hot start
    3447           solver->markHotStart();
    3448           doneHotStart=true;
    3449           xMark++;
    3450           //if (solver->isProvenPrimalInfeasible())
    3451           //printf("**** Hot start says node infeasible\n");
    3452         }
    3453         // make sure best will be first
    3454         if (iBestGot>=0)
    3455           sort[iBestGot]=-1.0e120;
    3456       }
    3457       } else {
    3458 #endif          /* RANGING */
    3459 #define SKIPM1
    3460 #ifdef SKIPM1
    3461         {
    3462           int numberIterations = model->getIterationCount();
    3463           //numberIterations += (model->numberExtraIterations()>>2);
    3464           const int * strongInfo = model->strongInfo();
    3465           //int numberDone = strongInfo[0]-strongInfo[3];
    3466           int numberFixed = strongInfo[1]-strongInfo[4];
    3467           int numberInfeasible = strongInfo[2]-strongInfo[5];
    3468           assert (!strongInfo[3]);
    3469           assert (!strongInfo[4]);
    3470           assert (!strongInfo[5]);
    3471           int numberStrongIterations = model->numberStrongIterations();
    3472           int numberRows = solver->getNumRows();
    3473           if (numberStrongIterations>numberIterations+CoinMin(100,10*numberRows)&&depth_>=4&&numberNodes>100) {
    3474             if (20*numberInfeasible+4*numberFixed<numberNodes) {
    3475               // Say never do
    3476               skipAll=-1;
    3477             }
    3478           }
    3479           //if (model->parentModel()&&depth_>=4)
    3480           //skipAll=-1;
    3481         }
    3482 #endif
    3483       if (!skipAll) {
    3484         // Mark hot start
    3485         doneHotStart=true;
    3486         solver->markHotStart();
    3487         xMark++;
    3488 #ifdef CLP_INVESTIGATE
    3489         if (kkPass==1&&!solver->isProvenOptimal()) {
    3490           printf("Solver says infeasible on markHotStart?\n");
    3491         }
    3492 #endif
     3184        int numberIterations = model->getIterationCount();
     3185        //numberIterations += (model->numberExtraIterations()>>2);
     3186        const int * strongInfo = model->strongInfo();
     3187        //int numberDone = strongInfo[0]-strongInfo[3];
     3188        int numberFixed = strongInfo[1]-strongInfo[4];
     3189        int numberInfeasible = strongInfo[2]-strongInfo[5];
     3190        assert (!strongInfo[3]);
     3191        assert (!strongInfo[4]);
     3192        assert (!strongInfo[5]);
     3193        int numberStrongIterations = model->numberStrongIterations();
     3194        int numberRows = solver->getNumRows();
     3195        if (numberStrongIterations>numberIterations+CoinMin(100,10*numberRows)&&depth_>=4&&numberNodes>100) {
     3196          if (20*numberInfeasible+4*numberFixed<numberNodes) {
     3197            // Say never do
     3198            skipAll=-1;
     3199          }
     3200        }
    34933201      }
    34943202      // make sure best will be first
    34953203      if (iBestGot>=0)
    3496         sort[iBestGot]=-COIN_DBL_MAX;
    3497 #ifdef RANGING
    3498       }
    3499 #endif          /* RANGING */
     3204        sort[iBestGot]=-COIN_DBL_MAX;
    35003205      // Actions 0 - exit for repeat, 1 resolve and try old choice,2 exit for continue
    3501 #define ACTION 0
    3502 #if ACTION<2
    35033206      if (anyAction)
    35043207        numberToDo=0; // skip as we will be trying again
    3505 #endif
    35063208      // Sort
    35073209      CoinSort_2(sort,sort+numberToDo,whichObject);
     
    35113213      if (!numberStrong)
    35123214        numberToDo=CoinMin(numberToDo,1);
    3513 #if NODE_NEW
    35143215      if (searchStrategy==2)
    35153216        numberToDo=CoinMin(numberToDo,20);
    3516 #endif
    35173217      iDo=0;
    35183218      int saveLimit2;
     
    35213221      if (searchStrategy==2)
    35223222        doQuickly=true;
    3523       //printf("todo %d, strong %d\n",numberToDo,numberStrong);
    35243223      int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
    3525       //double distanceToCutoff2 = model->getCutoff()-objectiveValue_;
    3526       if (!newWay) {
    35273224      if (searchStrategy==3) {
    3528         // Previously decided we need strong
    3529         doQuickly=false;
    3530         numberTest = numberStrong;
    3531       }
    3532       //if (searchStrategy<0||searchStrategy==1)
    3533 #if 0
    3534       if (numberBeforeTrust>20&&(numberNodes>20000||(numberNodes>200&&numberNotTrusted==0))) {
    3535         if ((numberNodes%20)!=0) {
    3536           numberTest=0;
    3537           doQuickly=true;
    3538         }
    3539       }
    3540 #else
     3225        // Previously decided we need strong
     3226        doQuickly=false;
     3227        numberTest = numberStrong;
     3228      }
    35413229      // Try nearly always off
    3542 #ifdef SKIPM1
    35433230      if (skipAll>=0) {
    3544 #endif
    35453231        if (searchStrategy<2) {
    3546           if ((numberNodes%20)!=0) {
     3232          //if ((numberNodes%20)!=0) {
    35473233            if ((model->specialOptions()&8)==0) {
    35483234              numberTest=0;
    35493235              doQuickly=true;
    35503236            }
    3551           } else {
    3552             doQuickly=false;
    3553             numberTest=2*numberStrong;
    3554             skipAll=0;
    3555           }
    3556         } else if (searchStrategy!=3) {
    3557           doQuickly=true;
    3558           numberTest=numberStrong;
     3237            //} else {
     3238            //doQuickly=false;
     3239            //numberTest=2*numberStrong;
     3240            //skipAll=0;
     3241            //}
    35593242        }
    3560 #ifdef SKIPM1
    35613243      } else {
    35623244        // Just take first
     
    35643246        numberTest=1;
    35653247      }
    3566 #endif
    3567 #endif
    3568 #ifdef SKIPM1
    35693248      int testDepth = (skipAll>=0) ? 8 : 4;
    3570 #else
    3571       int testDepth = 8;
    3572 #endif
    35733249      if (depth_<testDepth&&numberStrong) {
    3574         if (searchStrategy!=2) {
    3575           doQuickly=false;
     3250        if (searchStrategy!=2) {
     3251          doQuickly=false;
    35763252          int numberRows = solver->getNumRows();
    35773253          // whether to do this or not is important - think
     
    35823258              numberStrong=CoinMin(6*numberStrong,numberToDo);
    35833259          }
    3584           numberTest=numberStrong;
    3585           skipAll=0;
    3586         }
    3587         //model->setStateOfSearch(2); // use min min
    3588       }
    3589       // could adjust using average iterations per branch
    3590       // double average = ((double)model->getIterationCount())/
    3591       //((double) model->getNodeCount()+1.0);
    3592       // if too many and big then just do 10 its
    3593       if (!skipAll&&saveStateOfSearch) {
    3594         //if (numberNotTrusted>3*numberStrong&&numberRows>250&&numberColumns>1000&&saveLimit==100)
    3595           // off solver->setIntParam(OsiMaxNumIterationHotStart,10);
    3596       }
    3597       // make negative for test
    3598       distanceToCutoff = - distanceToCutoff;
    3599       if (numberObjects>-100) {
    3600         // larger
    3601         distanceToCutoff *= 100.0;
    3602       }
    3603       distanceToCutoff = -COIN_DBL_MAX;
     3260          numberTest=numberStrong;
     3261          skipAll=0;
     3262        }
     3263      }
    36043264      // Do at least 5 strong
    36053265      if (numberColumns<1000&&(depth_<15||numberNodes<1000000))
    3606         numberTest = CoinMax(numberTest,5);
     3266        numberTest = CoinMax(numberTest,5);
    36073267      if ((model->specialOptions()&8)==0) {
    3608         if (skipAll) {
    3609           numberTest=0;
    3610           doQuickly=true;
    3611         }
     3268        if (skipAll) {
     3269          numberTest=0;
     3270          doQuickly=true;
     3271        }
    36123272      } else {
    3613         // do 5 as strong is fixing
    3614         numberTest = CoinMax(numberTest,5);
    3615       }
    3616       } else {
    3617         if (!depth_&&numberToDo<200&&solver->getNumRows()<2000&&
    3618             numberColumns<2000&&false) {
    3619           numberStrong = numberToDo;
    3620           doQuickly = false;
    3621         }
    3622       int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
    3623       if (searchStrategy>=3) {
    3624         // Previously decided we need strong
    3625         doQuickly=false;
    3626         if (depth_<7)
    3627           numberStrong *=3;
    3628         if (!depth_)
    3629           numberStrong=CoinMin(6*numberStrong,numberToDo);
    3630         numberTest = numberStrong;
    3631       } else if (searchStrategy==2||(searchStrategy==1&&depth_<6)) {
    3632         numberStrong *=2;
    3633         if (!depth_)
    3634           numberStrong=CoinMin(2*numberStrong,numberToDo);
    3635         numberTest = numberStrong;
    3636       } else if (searchStrategy==1&&numberNotTrusted) {
    3637         numberTest = numberStrong;
    3638       } else {
    3639         numberTest=0;
    3640 #ifdef SKIPM1
    3641         if (skipAll==0)
    3642 #endif
    3643           skipAll=1;
    3644       }
    3645       distanceToCutoff=model->getCutoff()-objectiveValue_;
    3646       // make negative for test
    3647       distanceToCutoff = - distanceToCutoff;
    3648       if (numberObjects>-100) {
    3649         // larger
    3650         distanceToCutoff *= 100.0;
    3651       }
    3652       distanceToCutoff = -COIN_DBL_MAX;
    3653       if (skipAll) {
    3654         numberTest=0;
    3655         doQuickly=true;
    3656       }
    3657       }
    3658 #ifdef SKIPM1
     3273        // do 5 as strong is fixing
     3274        numberTest = CoinMax(numberTest,5);
     3275      }
    36593276      // see if switched off
    36603277      if (skipAll<0) {
    3661         newWay=false;
    36623278        numberTest=0;
    36633279        doQuickly=true;
    36643280      }
    3665 #endif
    3666 #if 0
    3667       // temp - always switch on
    3668       if (0) {
    3669         int numberIterations = model->getIterationCount();
    3670         int numberStrongIterations = model->numberStrongIterations();
    3671         if (2*numberStrongIterations<numberIterations||depth_<=5) {
    3672           skipAll=0;
    3673           newWay=false;
    3674           numberTest=CoinMax(numberTest,numberStrong);
    3675           doQuickly=false;
    3676         }
    3677       }
    3678 #endif
    3679       px[0]=numberTest;
    3680       px[1]=0;
    3681       px[2]= doQuickly ? 1 : -1;
    3682       px[3]=numberStrong;
    3683       if (!newWay) {
    3684         if (numberColumns>8*solver->getNumRows()&&false) {
    3685           printf("skipAll %c doQuickly %c numberTest %d numberNot %d\n",
    3686                  skipAll ? 'Y' : 'N',doQuickly ? 'Y' : 'N',numberTest,numberNotTrusted);
    3687           numberTest = CoinMin(numberTest,model->numberStrong());
    3688           printf("new test %d\n",numberTest);
    3689         }
    3690       }
    3691       bool couldChooseFirst = false ; //(skipAll&&numberTest==0&&doQuickly);
    3692       //skipAll=false;
    36933281      int realMaxHotIterations=999999;
    3694 #if 0
    3695       if (saveSearchStrategy==-1&&!model->parentModel()&&
    3696           !depth_&&saveLimit==100) {
    3697         realMaxHotIterations=saveLimit;
    3698         saveLimit2=200;
    3699         solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit2);
    3700       }
    3701 #endif
    3702 #ifdef SKIPM1
    37033282      if (skipAll<0)
    37043283        numberToDo=1;
    3705 #endif
    37063284#ifdef DO_ALL_AT_ROOT
    37073285      if (!numberNodes) {
     
    37473325        assert (choice.downMovement>=0.0);
    37483326        choice.fix=0; // say not fixed
    3749         double maxChange = 0.5*(choice.upMovement+choice.downMovement);
    3750         maxChange = CoinMin(choice.upMovement,choice.downMovement);
    3751         maxChange = CoinMax(choice.upMovement,choice.downMovement);
    3752         if (searchStrategy==2)
    3753           maxChange = COIN_DBL_MAX;
    3754         //maxChange *= 5.0;
    3755         if (dynamicObject&&dynamicObject->method()==1)
    3756           maxChange *= 0.1; // probing
    37573327        // see if can skip strong branching
    37583328        int canSkip = choice.possibleBranch->fillStrongInfo(choice);
    3759 #if 0
    3760         if (!newWay) {
    3761           if ((maxChange>distanceToCutoff2)&&(!doQuickly||(numberTest>0&&searchStrategy!=2)))
    3762           canSkip=0;
    3763         } else {
    3764         if (skipAll)
    3765           canSkip=1;
    3766         else if (numberTest>0&&searchStrategy>=3)
    3767           canSkip=0;
    3768         }
    3769         if (!numberBeforeTrust) {
    3770           canSkip=1;
    3771         }
    3772         if (sort[iDo]<distanceToCutoff)
    3773           canSkip=0;
    3774         if ((numberTest<=0||skipAll)&&sort[iDo]>distanceToCutoff) {
    3775           canSkip=1; // always skip
     3329        if ((numberTest<=0||skipAll)) {
    37763330          if (iDo>20) {
    37773331#ifdef DO_ALL_AT_ROOT
     
    37873341          }
    37883342        }
    3789 #else
    3790         if ((numberTest<=0||skipAll)&&sort[iDo]>distanceToCutoff) {
    3791           //canSkip=1; // always skip
    3792           if (iDo>20) {
    3793 #ifdef DO_ALL_AT_ROOT
    3794             if (!numberNodes)
    3795               printf("DOY test %d - iDo %d\n",
    3796                      numberTest,iDo);
    3797 #endif
    3798             if (!choiceObject) {
    3799               delete choice.possibleBranch;
    3800               choice.possibleBranch=NULL;
    3801             }
    3802             break; // give up anyway
    3803           }
    3804         }
    3805 #endif
    38063343        if (model->messageHandler()->logLevel()>3&&numberBeforeTrust&&dynamicObject)
    38073344          dynamicObject->print(1,choice.possibleBranch->value());
    3808 #ifdef SKIPM1
    38093345        if (skipAll<0)
    38103346          canSkip=true;
    3811 #endif
    38123347        if (!canSkip) {
    3813           //#ifndef RANGING
    38143348          if (!doneHotStart) {
    38153349            // Mark hot start
     
    38183352            xMark++;
    38193353          }
    3820           //#endif
    3821           assert (!couldChooseFirst);
    38223354          numberTest--;
    38233355          // just do a few
    3824 #if NODE_NEW == 5  || NODE_NEW == 2
    3825           //if (canSkip)
    38263356          if (searchStrategy==2)
    38273357            solver->setIntParam(OsiMaxNumIterationHotStart,10);
    3828 #endif
    38293358          double objectiveChange ;
    38303359          double newObjectiveValue=1.0e100;
     
    38323361          // status is 0 finished, 1 infeasible and other
    38333362          int iStatus;
    3834           if (0) {
    3835             CbcDynamicPseudoCostBranchingObject * cbcobj = dynamic_cast<CbcDynamicPseudoCostBranchingObject *> (choice.possibleBranch);
    3836             if (cbcobj) {
    3837               CbcSimpleIntegerDynamicPseudoCost * object = cbcobj->object();
    3838               printf("strong %d ",iDo);
    3839               object->print(1,0.5);
    3840             }
    3841           }
    38423363          /*
    38433364            Try the down direction first. (Specify the initial branching alternative as
     
    38473368          */
    38483369          choice.possibleBranch->way(-1) ;
    3849 #if NEW_UPDATE_OBJECT==0
    3850           decision->saveBranchingObject( choice.possibleBranch);
    3851 #endif
    38523370          choice.possibleBranch->branch() ;
    38533371          solver->solveFromHotStart() ;
     
    38763394          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
    38773395          // Update branching information if wanted
    3878 #if NEW_UPDATE_OBJECT==0
    3879           decision->updateInformation( solver,this);
    3880 #elif NEW_UPDATE_OBJECT<2
    3881           CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
    3882           if (cbcobj) {
    3883             CbcObject * object = cbcobj->object();
    3884             assert (object);
    3885             CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
    3886             object->updateInformation(update);
    3887           } else {
    3888             decision->updateInformation( solver,this);
    3889           }
    3890 #else
    38913396          CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
    38923397          if (cbcobj) {
     
    38993404            decision->updateInformation( solver,this);
    39003405          }
    3901 #endif
    39023406          if (!iStatus) {
    39033407            choice.finishedDown = true ;
     
    39763480#ifdef DO_ALL_AT_ROOT
    39773481          if (!numberNodes)
    3978           printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    3979                choice.objectNumber,iStatus,newObjectiveValue,choice.numItersDown,
    3980                choice.downMovement,choice.finishedDown,choice.numIntInfeasDown,
    3981                choice.numObjInfeasDown);
    3982 #endif
    3983          
     3482            printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
     3483                   choice.objectNumber,iStatus,newObjectiveValue,choice.numItersDown,
     3484                   choice.downMovement,choice.finishedDown,choice.numIntInfeasDown,
     3485                   choice.numObjInfeasDown);
     3486#endif
     3487         
    39843488          // repeat the whole exercise, forcing the variable up
    3985 #if NEW_UPDATE_OBJECT==0
    3986           decision->saveBranchingObject( choice.possibleBranch);
    3987 #endif
    39883489          choice.possibleBranch->branch();
    39893490          solver->solveFromHotStart() ;
     
    40113512          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
    40123513          // Update branching information if wanted
    4013 #if NEW_UPDATE_OBJECT==0
    4014           decision->updateInformation( solver,this);
    4015 #elif NEW_UPDATE_OBJECT<2
    4016           cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
    4017           if (cbcobj) {
    4018             CbcObject * object = cbcobj->object();
    4019             CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
    4020             object->updateInformation(update);
    4021           } else {
    4022             decision->updateInformation( solver,this);
    4023           }
    4024 #else
    40253514          cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
    40263515          if (cbcobj) {
     
    40333522            decision->updateInformation( solver,this);
    40343523          }
    4035 #endif
    40363524          if (!iStatus) {
    40373525            choice.finishedUp = true ;
     
    41103598#ifdef DO_ALL_AT_ROOT
    41113599          if (!numberNodes)
    4112           printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    4113                choice.objectNumber,iStatus,newObjectiveValue,choice.numItersUp,
    4114                choice.upMovement,choice.finishedUp,choice.numIntInfeasUp,
    4115                choice.numObjInfeasUp);
     3600            printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
     3601                   choice.objectNumber,iStatus,newObjectiveValue,choice.numItersUp,
     3602                   choice.upMovement,choice.finishedUp,choice.numIntInfeasUp,
     3603                   choice.numObjInfeasUp);
    41163604#endif
    41173605        }
    4118    
     3606       
    41193607        solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit2);
    41203608        /*
     
    41353623            choice.upMovement = CoinMax(0.0,choice.upMovement);
    41363624            choice.downMovement = CoinMax(0.0,choice.downMovement);
    4137             if (couldChooseFirst)
    4138               printf("candidate %d up %g down %g sort %g\n",iDo,choice.upMovement,choice.downMovement,sort[iDo]);
    41393625#if ZERO_ONE==2
    41403626            // branch on 0-1 first (temp)
     
    41463632            // feasible - see which best
    41473633            if (!canSkip) {
    4148               if (iColumn==-46) {
    4149                 printf("sort %g downest %g upest %g ",sort[iDo],downEstimate[iObject],
    4150                      upEstimate[iObject]);
    4151                 printf("downMove %g upMove %g value %g current pseudo %g %g\n",
    4152                        choice.downMovement,choice.upMovement,choice.possibleBranch->value(),
    4153                        dynamicObject->downDynamicPseudoCost(),dynamicObject->upDynamicPseudoCost());
    4154               }
    41553634              if (model->messageHandler()->logLevel()>3)
    41563635                printf("sort %g downest %g upest %g ",sort[iDo],downEstimate[iObject],
    4157                      upEstimate[iObject]);
     3636                       upEstimate[iObject]);
    41583637              model->messageHandler()->message(CBC_STRONG,*model->messagesPointer())
    41593638                << iObject << iColumn
     
    41633642                <<CoinMessageEol;
    41643643            }
    4165             double bestCriterion = -1.0;
    4166             //double gap = saveUpper[iColumn]-saveLower[iColumn];
    4167             // Give precedence to ones with gap of 1.0
    4168             //assert(gap>0.0);
    4169             double factor = 1.0; //changeFactor/CoinMin(gap,100.0);
    41703644            int betterWay;
    41713645            {
     
    41753649                assert (branchObj);
    41763650              betterWay = decision->betterBranch(choice.possibleBranch,
    4177                                                      branchObj,
    4178                                                      choice.upMovement*factor,
    4179                                                      choice.numIntInfeasUp ,
    4180                                                      choice.downMovement*factor,
    4181                                                      choice.numIntInfeasDown );
     3651                                                 branchObj,
     3652                                                 choice.upMovement,
     3653                                                 choice.numIntInfeasUp ,
     3654                                                 choice.downMovement,
     3655                                                 choice.numIntInfeasDown );
    41823656            }
    4183             if (iDo>=changeStrategy) {
    4184               // make less likely
    4185               changeStrategy+=numberStrong;
    4186               changeFactor *= 0.9;
    4187             }
    41883657            if (betterWay) {
    41893658              // C) create branching object
     
    42033672                branchObj->way(betterWay);
    42043673              }
    4205               if (couldChooseFirst)
    4206                 printf("choosing %d way %d\n",iDo,betterWay);
    42073674              bestChoice = choice.objectNumber;
    42083675              whichChoice = iDo;
     
    42543721            //printf("Down infeasible for choice %d sequence %d\n",i,
    42553722            // model->object(choice.objectNumber)->columnNumber());
    4256             if (!solveAll) {
    4257               choice.possibleBranch->way(1);
    4258               choice.possibleBranch->branch();
     3723            choice.fix=1;
     3724            numberToFix++;
     3725            choice.possibleBranch->fix(solver,saveLower,saveUpper,1);
     3726            if (!choiceObject) {
     3727              choice.possibleBranch=NULL;
     3728            } else {
     3729              choiceObject = new CbcDynamicPseudoCostBranchingObject(*choiceObject);
     3730              choice.possibleBranch=choiceObject;
     3731            }
     3732            assert(doneHotStart);
     3733            solver->unmarkHotStart();
     3734            model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
     3735            solver->markHotStart();
     3736            // may be infeasible (if other way stopped on iterations)
     3737            if (!solver->isProvenOptimal()) {
     3738              // neither side feasible
     3739              anyAction=-2;
    42593740              if (!choiceObject) {
    42603741                delete choice.possibleBranch;
    42613742                choice.possibleBranch=NULL;
    42623743              }
    4263               delete ws;
    4264               ws=NULL;
    4265               break;
    4266             } else {
    4267               choice.fix=1;
    4268               fixObject[numberToFix++]=choice;
    4269 #define FIXNOW
    4270 #ifdef FIXNOW
    4271 #if 0
    4272               double value = ceil(saveSolution[iColumn]);
    4273               saveLower[iColumn]=value;
    4274               solver->setColLower(iColumn,value);
    4275 #else
    4276               choice.possibleBranch->fix(solver,saveLower,saveUpper,1);
    4277 #endif
    4278 #endif
    4279               if (!choiceObject) {
    4280                 choice.possibleBranch=NULL;
    4281               } else {
    4282                 choiceObject = new CbcDynamicPseudoCostBranchingObject(*choiceObject);
    4283                 choice.possibleBranch=choiceObject;
    4284               }
    4285 #ifdef FIXNOW
    4286               assert(doneHotStart);
    4287               solver->unmarkHotStart();
    4288               model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
    4289               solver->markHotStart();
    4290               // may be infeasible (if other way stopped on iterations)
    4291               if (!solver->isProvenOptimal()) {
    4292                 // neither side feasible
    4293                 anyAction=-2;
    4294                 if (!choiceObject) {
    4295                   delete choice.possibleBranch;
    4296                   choice.possibleBranch=NULL;
    4297                 }
    4298                 //printf("Both infeasible for choice %d sequence %d\n",i,
    4299                 // model->object(choice.objectNumber)->columnNumber());
    4300                 delete ws;
    4301                 ws=NULL;
    4302                 break;
    4303               }
    4304 #endif
     3744              //printf("Both infeasible for choice %d sequence %d\n",i,
     3745              // model->object(choice.objectNumber)->columnNumber());
     3746              delete ws;
     3747              ws=NULL;
     3748              break;
    43053749            }
    43063750          }
     
    43163760              <<choice.possibleBranch->value()
    43173761              <<CoinMessageEol;
    4318             //printf("Up infeasible for choice %d sequence %d\n",i,
    4319             // model->object(choice.objectNumber)->columnNumber());
    4320             if (!solveAll) {
    4321               choice.possibleBranch->way(-1);
    4322               choice.possibleBranch->branch();
     3762            choice.fix=-1;
     3763            numberToFix++;
     3764            choice.possibleBranch->fix(solver,saveLower,saveUpper,-1);
     3765            if (!choiceObject) {
     3766              choice.possibleBranch=NULL;
     3767            } else {
     3768              choiceObject = new CbcDynamicPseudoCostBranchingObject(*choiceObject);
     3769              choice.possibleBranch=choiceObject;
     3770            }
     3771            assert(doneHotStart);
     3772            solver->unmarkHotStart();
     3773            model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
     3774            solver->markHotStart();
     3775            // may be infeasible (if other way stopped on iterations)
     3776            if (!solver->isProvenOptimal()) {
     3777              // neither side feasible
     3778              anyAction=-2;
    43233779              if (!choiceObject) {
    43243780                delete choice.possibleBranch;
    43253781                choice.possibleBranch=NULL;
    43263782              }
    4327               delete ws;
    4328               ws=NULL;
    4329               break;
    4330             } else {
    4331               choice.fix=-1;
    4332               fixObject[numberToFix++]=choice;
    4333 #ifdef FIXNOW
    4334 #if 0
    4335               double value = floor(saveSolution[iColumn]);
    4336               saveUpper[iColumn]=value;
    4337               solver->setColUpper(iColumn,value);
    4338 #else
    4339               choice.possibleBranch->fix(solver,saveLower,saveUpper,-1);
    4340 #endif
    4341 #endif
    4342               if (!choiceObject) {
    4343                 choice.possibleBranch=NULL;
    4344               } else {
    4345                 choiceObject = new CbcDynamicPseudoCostBranchingObject(*choiceObject);
    4346                 choice.possibleBranch=choiceObject;
    4347               }
    4348 #ifdef FIXNOW
    4349               assert(doneHotStart);
    4350               solver->unmarkHotStart();
    4351               model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
    4352               solver->markHotStart();
    4353               // may be infeasible (if other way stopped on iterations)
    4354               if (!solver->isProvenOptimal()) {
    4355                 // neither side feasible
    4356                 anyAction=-2;
    4357                 if (!choiceObject) {
    4358                   delete choice.possibleBranch;
    4359                   choice.possibleBranch=NULL;
    4360                 }
    4361                 //printf("Both infeasible for choice %d sequence %d\n",i,
    4362                 // model->object(choice.objectNumber)->columnNumber());
    4363                 delete ws;
    4364                 ws=NULL;
    4365                 break;
    4366               }
    4367 #endif
     3783              delete ws;
     3784              ws=NULL;
     3785              break;
    43683786            }
    43693787          } else {
     
    43743792              choice.possibleBranch=NULL;
    43753793            }
    4376             //printf("Both infeasible for choice %d sequence %d\n",i,
    4377             // model->object(choice.objectNumber)->columnNumber());
    43783794            delete ws;
    43793795            ws=NULL;
     
    43963812          }
    43973813          numberTest=0;
    4398           distanceToCutoff=-COIN_DBL_MAX;
    43993814        }
    44003815        if (!choiceObject) {
     
    44023817        }
    44033818      }
    4404       double averageChange = model->sumChangeObjective()/
    4405         static_cast<double> (model->getNodeCount());
    4406       if (depth_<10||worstFeasible>0.2*averageChange)
    4407         solveAll=false;
    4408       if (model->messageHandler()->logLevel()>3||false) {
     3819      if (model->messageHandler()->logLevel()>3) {
    44093820        if (anyAction==-2) {
    44103821          printf("infeasible\n");
    44113822        } else if(anyAction==-1) {
    4412           if (!solveAll)
    4413             printf("%d fixed\n",numberToFix);
    4414           else
    4415             printf("%d fixed AND choosing %d iDo %d iChosenWhen %d numberToDo %d\n",numberToFix,bestChoice,
     3823          printf("%d fixed AND choosing %d iDo %d iChosenWhen %d numberToDo %d\n",numberToFix,bestChoice,
    44163824                   iDo,whichChoice,numberToDo);
    44173825        } else {
     
    44393847      // But we could fix anyway
    44403848      if (numberToFix&&!hitMaxTime) {
    4441         if (anyAction==-2) {
    4442           // take off
    4443           for (i = 0 ; i < numberToFix ; i++) {
    4444             delete fixObject[i].possibleBranch;
    4445           }
    4446         } else {
     3849        if (anyAction!=-2) {
    44473850          // apply and take off
    4448           for (i = 0 ; i < numberToFix ; i++) {
    4449 #ifndef FIXNOW
    4450             fixObject[i].possibleBranch->way(fixObject[i].fix) ;
    4451             fixObject[i].possibleBranch->branch() ;
    4452 #endif
    4453             delete fixObject[i].possibleBranch;
    4454           }
    44553851          bool feasible=true;
    4456 #if ACTION <2
    4457           if (solveAll) {
    4458             // can do quick optimality check
    4459             int easy=2;
    4460             solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
    4461             model->resolve(NULL,11,saveSolution,saveLower,saveUpper) ;
    4462             solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
    4463             feasible = solver->isProvenOptimal();
    4464             if (feasible) {
    4465               anyAction=0;
    4466               // See if candidate still possible
    4467               if (branch_) {
    4468                 const OsiObject * object = model->object(bestChoice);
    4469                 int preferredWay;
    4470                 double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    4471                 if (!infeasibility) {
    4472                   // take out
    4473                   delete branch_;
    4474                   branch_=NULL;
    4475                 } else {
    4476                   CbcBranchingObject * branchObj =
    4477                     dynamic_cast <CbcBranchingObject *>(branch_) ;
    4478                   assert (branchObj);
    4479                   branchObj->way(preferredWay);
    4480                 }
    4481               }
    4482             } else {
    4483               anyAction=-2;
    4484               finished=true;
    4485             }
    4486           }
    4487 #endif
    4488           // If  fixed then round again
    4489           if (!branch_&&anyAction!=-2) {
    4490             finished=false;
    4491           }
    4492           // If these in then different action
    4493 #if ACTION == 1
    4494           if (!anyAction)
    4495             anyAction=-1;
    4496           finished=true;
    4497 #endif
     3852          // can do quick optimality check
     3853          int easy=2;
     3854          solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
     3855          model->resolve(NULL,11,saveSolution,saveLower,saveUpper) ;
     3856          solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
     3857          feasible = solver->isProvenOptimal();
     3858          if (feasible) {
     3859            anyAction=0;
     3860            // See if candidate still possible
     3861            if (branch_) {
     3862              const OsiObject * object = model->object(bestChoice);
     3863              int preferredWay;
     3864              double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
     3865              if (!infeasibility) {
     3866                // take out
     3867                delete branch_;
     3868                branch_=NULL;
     3869              } else {
     3870                CbcBranchingObject * branchObj =
     3871                  dynamic_cast <CbcBranchingObject *>(branch_) ;
     3872                assert (branchObj);
     3873                branchObj->way(preferredWay);
     3874              }
     3875            }
     3876          } else {
     3877            anyAction=-2;
     3878            finished=true;
     3879          }
    44983880        }
    44993881      }
     3882      // If  fixed then round again
     3883      if (!branch_&&anyAction!=-2) {
     3884        finished=false;
     3885      }
    45003886      delete ws;
    45013887    }
    45023888  }
    4503 #ifdef CBC_NODE7
    4504   delete [] weightModifier;
    4505 #endif
    4506   if (model->messageHandler()->logLevel()>2)
    4507     printf("%d strong, %d iters, %d pen, %d mark, %d fixed, action %d nnott %d nt %d, %d dq %s ns %d\n",
    4508          numberStrongDone,numberStrongIterations,xPen,xMark,
    4509            numberToFix,anyAction,numberNotTrusted,px[0],px[1],px[2]>0 ? "y" : "n",px[3]);
    45103889  // update number of strong iterations etc
    45113890  model->incrementStrongInfo(numberStrongDone,numberStrongIterations,
    45123891                             anyAction==-2 ? 0:numberToFix,anyAction==-2);
    4513 #if 0
    4514   if (!numberNodes&&!model->parentModel()) {
    4515     printf("DOZ %d strong, %d iterations, %d unfinished\n",
    4516            numberStrongDone,numberStrongIterations,numberUnfinished);
    4517     if (numberUnfinished>10&&4*numberUnfinished>numberStrongDone)
    4518     /model->setNumberBeforeTrust(CoinMin(numberBeforeTrust,5));
    4519   }
    4520 #endif
    4521   if (!newWay) {
    4522   if (((model->searchStrategy()+1)%1000)==0) {
     3892  if (model->searchStrategy()==-1) {
    45233893#ifndef COIN_DEVELOP
    45243894    if (solver->messageHandler()->logLevel()>1)
    45253895#endif
    45263896      printf("%d strong, %d iters, %d inf, %d not finished, %d not trusted\n",
    4527              numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
    4528              numberNotTrusted);
     3897             numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
     3898             numberNotTrusted);
    45293899    // decide what to do
    45303900    int strategy=1;
    45313901    if (((numberUnfinished*4>numberStrongDone&&
    4532          numberStrongInfeasible*40<numberStrongDone)||
     3902          numberStrongInfeasible*40<numberStrongDone)||
    45333903         numberStrongInfeasible<0)&&model->numberStrong()<10&&model->numberBeforeTrust()<=20&&model->numberObjects()>CoinMax(1000,solver->getNumRows())) {
    45343904      strategy=2;
    45353905#ifdef COIN_DEVELOP
    45363906      //if (model->logLevel()>1)
    4537         printf("going to strategy 2\n");
    4538 #endif
    4539 #if NODE_NEW==1
    4540       // Basically off
    4541       model->setNumberStrong(0);
    4542       model->setNumberBeforeTrust(-2);
    4543 #elif NODE_NEW==2
     3907      printf("going to strategy 2\n");
     3908#endif
    45443909      // Weaken
    45453910      model->setNumberStrong(2);
    45463911      model->setNumberBeforeTrust(1);
    4547 #elif NODE_NEW==3
    4548       // Off and ranging
    4549       model->setNumberStrong(0);
    4550       model->setNumberBeforeTrust(-1);
    4551 #elif NODE_NEW==4
    4552       // Off and pseudo shadow prices
    4553       model->setNumberStrong(0);
    4554       model->setNumberBeforeTrust(-2);
    4555 #elif NODE_NEW==5
    4556       // Just fewer iterations
    4557 #endif
    45583912      model->synchronizeNumberBeforeTrust();
    45593913    }
    45603914    if (numberNodes)
    45613915      strategy=1;  // should only happen after hot start
    4562     if (model->searchStrategy()<999)
    4563       model->setSearchStrategy(strategy);
     3916    model->setSearchStrategy(strategy);
    45643917  } else if (numberStrongDone) {
    45653918    //printf("%d strongB, %d iters, %d inf, %d not finished, %d not trusted\n",
     
    45723925#endif
    45733926      printf("after %d nodes - %d strong, %d iters, %d inf, %d not finished, %d not trusted\n",
    4574              numberNodes,numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
    4575              numberNotTrusted);
     3927             numberNodes,numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
     3928             numberNotTrusted);
    45763929    // decide what to do
    45773930    if (numberUnfinished*10>numberStrongDone+1||
    45783931        !numberStrongInfeasible) {
    4579       //if (model->logLevel()>1)
    4580         printf("going to strategy 2\n");
    4581 #if NODE_NEW==1
    4582       // Basically off
    4583       model->setNumberStrong(0);
    4584       model->setNumberBeforeTrust(-2);
    4585 #elif NODE_NEW==2
     3932      printf("going to strategy 2\n");
    45863933      // Weaken
    45873934      model->setNumberStrong(2);
    45883935      model->setNumberBeforeTrust(1);
    4589 #elif NODE_NEW==3
    4590       // Off and ranging
    4591       model->setNumberStrong(0);
    4592       model->setNumberBeforeTrust(-1);
    4593 #elif NODE_NEW==4
    4594       // Off and pseudo shadow prices
    4595       model->setNumberStrong(0);
    4596       model->setNumberBeforeTrust(-2);
    4597 #elif NODE_NEW==5
    4598       // Just fewer iterations
    4599 #endif
    46003936      model->synchronizeNumberBeforeTrust();
    46013937      model->setSearchStrategy(2);
    46023938    }
    46033939  }
    4604   }
    4605   //if (numberToFix&&depth_<5)
    4606   //printf("%d fixed by strong at depth %d\n",numberToFix,depth_);
    46073940  // Set guessed solution value
    46083941  guessedObjectiveValue_ = objectiveValue_+estimatedDegradation;
    46093942 
    4610 /*
    4611   Cleanup, then we're finished
    4612 */
     3943  /*
     3944    Cleanup, then we're finished
     3945  */
    46133946  if (!model->branchingMethod())
    46143947    delete decision;
    4615 
     3948 
    46163949  delete choiceObject;
    4617   delete [] fixObject;
    46183950  delete [] sort;
    46193951  delete [] whichObject;
     3952#ifdef RANGING
    46203953  delete [] objectMark;
     3954#endif
    46213955  delete [] saveLower;
    46223956  delete [] saveUpper;
     
    46984032  // and modify
    46994033  usefulInfo.depth_=depth_;
    4700      
     4034 
    47014035  // compute current state
    47024036  int numberObjectInfeasibilities; // just odd ones
     
    47564090  // Sort
    47574091  CoinSort_2(sort,sort+numberToDo,whichObject);
    4758   //double distanceToCutoff=model->getCutoff()-objectiveValue_;
    47594092  double * currentSolution = model->currentSolution();
    47604093  double objMin = 1.0e50;
     
    50194352  solver->setWarmStart(ws);
    50204353  delete ws;
    5021    
     4354 
    50224355  delete [] sort;
    50234356  delete [] whichObject;
     
    50814414    else
    50824415      branch_=NULL,
    5083     depth_ = rhs.depth_;
     4416        depth_ = rhs.depth_;
    50844417    numberUnsatisfied_ = rhs.numberUnsatisfied_;
    50854418    nodeNumber_ = rhs.nodeNumber_;
     
    50974430  if (nodeInfo_) {
    50984431    printf("CbcNode %x Destructor nodeInfo %x (%d)\n",
    5099          this,nodeInfo_,nodeInfo_->numberPointingToThis());
     4432           this,nodeInfo_,nodeInfo_->numberPointingToThis());
    51004433    //assert(nodeInfo_->numberPointingToThis()>=0);
    51014434  } else {
    51024435    printf("CbcNode %x Destructor nodeInfo %x (?)\n",
    5103          this,nodeInfo_);
     4436           this,nodeInfo_);
    51044437  }
    51054438#endif
     
    52064539}
    52074540/* Active arm of the attached OsiBranchingObject.
    5208  
     4541   
    52094542   In the simplest instance, coded -1 for the down arm of the branch, +1 for
    52104543   the up arm. But see OsiBranchingObject::way()
    5211      Use nodeInfo--.numberBranchesLeft_ to see how active
     4544   Use nodeInfo--.numberBranchesLeft_ to see how active
    52124545*/
    52134546int
     
    52214554    } else {
    52224555      OsiTwoWayBranchingObject * obj2 =
    5223       dynamic_cast <OsiTwoWayBranchingObject *>(branch_) ;
     4556        dynamic_cast <OsiTwoWayBranchingObject *>(branch_) ;
    52244557      assert (obj2);
    52254558      return obj2->way();
     
    52304563}
    52314564/* Create a branching object for the node
    5232 
    5233     The routine scans the object list of the model and selects a set of
    5234     unsatisfied objects as candidates for branching. The candidates are
    5235     evaluated, and an appropriate branch object is installed.
    5236 
    5237     The numberPassesLeft is decremented to stop fixing one variable each time
    5238     and going on and on (e.g. for stock cutting, air crew scheduling)
    5239 
    5240     If evaluation determines that an object is monotone or infeasible,
    5241     the routine returns immediately. In the case of a monotone object,
    5242     the branch object has already been called to modify the model.
    5243 
    5244     Return value:
    5245     <ul>
    5246       <li>  0: A branching object has been installed
    5247       <li> -1: A monotone object was discovered
    5248       <li> -2: An infeasible object was discovered
    5249     </ul>
    5250     Branch state:
    5251     <ul>
    5252       <li> -1: start
    5253       <li> -1: A monotone object was discovered
    5254       <li> -2: An infeasible object was discovered
    5255     </ul>
     4565   
     4566   The routine scans the object list of the model and selects a set of
     4567   unsatisfied objects as candidates for branching. The candidates are
     4568   evaluated, and an appropriate branch object is installed.
     4569   
     4570   The numberPassesLeft is decremented to stop fixing one variable each time
     4571   and going on and on (e.g. for stock cutting, air crew scheduling)
     4572   
     4573   If evaluation determines that an object is monotone or infeasible,
     4574   the routine returns immediately. In the case of a monotone object,
     4575   the branch object has already been called to modify the model.
     4576   
     4577   Return value:
     4578   <ul>
     4579   <li>  0: A branching object has been installed
     4580   <li> -1: A monotone object was discovered
     4581   <li> -2: An infeasible object was discovered
     4582   </ul>
     4583   Branch state:
     4584   <ul>
     4585   <li> -1: start
     4586   <li> -1: A monotone object was discovered
     4587   <li> -2: An infeasible object was discovered
     4588   </ul>
    52564589*/
    52574590int
     
    53534686    double objValue = choose->goodObjectiveValue();
    53544687    model->setBestSolution(CBC_STRONGSOL,
    5355                                      objValue,
    5356                                      choose->goodSolution()) ;
     4688                           objValue,
     4689                           choose->goodSolution()) ;
    53574690    model->setLastHeuristic(NULL);
    53584691    model->incrementUsed(choose->goodSolution());
     
    53634696int
    53644697CbcNode::chooseClpBranch (CbcModel * model,
    5365                        CbcNode * lastNode)
     4698                          CbcNode * lastNode)
    53664699{
    53674700  assert(lastNode);
     
    53844717  double * saveUpper = new double[numberColumns];
    53854718  double * saveLower = new double[numberColumns];
    5386 
     4719 
    53874720  // Save solution in case heuristics need good solution later
    53884721 
     
    54714804  //#define CHECK_PATH
    54724805#ifdef CHECK_PATH
    5473 extern int gotGoodNode_Z;
    5474  if (gotGoodNode_Z>=0)
    5475    printf("good node %d %g\n",gotGoodNode_Z,infeasibility);
     4806  extern int gotGoodNode_Z;
     4807  if (gotGoodNode_Z>=0)
     4808    printf("good node %d %g\n",gotGoodNode_Z,infeasibility);
    54764809#endif
    54774810  if (infeasibility>0.0) {
     
    54924825  }
    54934826#ifdef CHECK_PATH
    5494  gotGoodNode_Z=-1;
     4827  gotGoodNode_Z=-1;
    54954828#endif
    54964829  // Set guessed solution value
  • trunk/Cbc/src/CbcSolver.cpp

    r1141 r1165  
    66716671                babModel_->setMinimumDrop(CoinMin(5.0e-2,minimumDrop));
    66726672                if (cutPass==-1234567) {
    6673                   if (babModel_->getNumCols()<50000)
     6673                  if (babModel_->getNumCols()<500)
    66746674                    babModel_->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
    66756675                  else if (babModel_->getNumCols()<5000)
  • trunk/Cbc/src/unitTestClp.cpp

    r1132 r1165  
    363363        std::cout<<"Largest (scaled) away from bound "<<largestScaled
    364364                 <<" unscaled "<<largest<<std::endl;
    365 #if 1
     365#if 0
    366366        modelC->setDualBound(CoinMax(1.0001e8,
    367367                                     CoinMin(1000.0*largestScaled,1.00001e10)));
    368368#else
    369369        modelC->setDualBound(CoinMax(1.0001e9,
    370                                      CoinMin(1000.0*largestScaled,1.e10)));
     370                                     CoinMin(1000.0*largestScaled,1.0001e10)));
    371371#endif
    372372      }
     
    455455      //PUSH_MPS("gesa2",1392,1224,25779856.372,25476489.678,7);
    456456      // gesa2
     457      std::string problemName ;
     458      model->solver()->getStrParam(OsiProbName,problemName) ;
     459      model->solver()->activateRowCutDebugger(problemName.c_str()) ;
     460    }
     461    if (model->getNumCols()==-1152) {
     462      //PUSH_MPS("gesa3",1368,1152,27991042.648,27833632.451,7);
     463      // gesa3
    457464      std::string problemName ;
    458465      model->solver()->getStrParam(OsiProbName,problemName) ;
Note: See TracChangeset for help on using the changeset viewer.