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

for deterministic parallel

File:
1 edited

Legend:

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

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