Ignore:
Timestamp:
Jun 26, 2007 5:17:15 AM (12 years ago)
Author:
forrest
Message:

trunk from branches/devel

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property svn:externals
      •  

        old new  
        1 MSVisualStudio   https://projects.coin-or.org/svn/MSVisualStudio/trunk/ExternalsDirs/Cbc
        2 BuildTools    https://projects.coin-or.org/svn/BuildTools/stable/0.5
         1MSVisualStudio   https://projects.coin-or.org/svn/MSVisualStudio/branches/devel/ExternalsDirs/Cbc
         2BuildTools    https://projects.coin-or.org/svn/BuildTools/trunk
        33ThirdParty/ASL https://projects.coin-or.org/svn/BuildTools/ThirdParty/ASL/stable/1.0
         4ThirdParty/Blas https://projects.coin-or.org/svn/BuildTools/ThirdParty/Blas/stable/1.0
         5ThirdParty/Lapack https://projects.coin-or.org/svn/BuildTools/ThirdParty/Lapack/stable/1.0
        46Data/Netlib   https://projects.coin-or.org/svn/Data/stable/1.0/Netlib
        57Data/Sample   https://projects.coin-or.org/svn/Data/stable/1.0/Sample
  • trunk/Cbc/src/CbcNode.cpp

    r460 r640  
    1717#define CUTS
    1818#include "OsiSolverInterface.hpp"
     19#include "OsiChooseVariable.hpp"
    1920#include "OsiAuxInfo.hpp"
    2021#include "OsiSolverBranch.hpp"
     
    7273  if (parent_) {
    7374    numberRows_ = parent_->numberRows_+parent_->numberCuts_;
     75    //parent_->increment();
    7476  }
    7577}
     
    137139  assert(!numberPointingToThis_);
    138140  // But they may be some left (max nodes?)
    139   for (int i=0;i<numberCuts_;i++)
     141  for (int i=0;i<numberCuts_;i++) {
     142#ifndef GLOBAL_CUTS_JUST_POINTERS
    140143    delete cuts_[i];
    141 
     144#else
     145    if (cuts_[i]->globallyValidAsInteger()!=2)
     146      delete cuts_[i];
     147#endif
     148  }
    142149  delete [] cuts_;
    143150  if (owner_)
     
    167174      if (!number) {
    168175        //printf("info %x del cut %d %x\n",this,i,cuts_[i]);
     176#ifndef GLOBAL_CUTS_JUST_POINTERS
    169177        delete cuts_[i];
     178#else
     179        if (cuts_[i]->globallyValidAsInteger()!=2)
     180          delete cuts_[i];
     181#endif
    170182        cuts_[i]=NULL;
    171183      }
     
    212224          }
    213225          if (!number) {
     226#ifndef GLOBAL_CUTS_JUST_POINTERS
    214227            delete thisInfo->cuts_[i];
     228#else
     229            if (thisInfo->cuts_[i]->globallyValidAsInteger()!=2)
     230              delete thisInfo->cuts_[i];
     231#endif
    215232            thisInfo->cuts_[i]=NULL;
    216233          }
     
    372389    last=j;
    373390    int number = cuts_[j]->decrement();
    374     if (!number)
     391    if (!number) {
     392#ifndef GLOBAL_CUTS_JUST_POINTERS
    375393      delete cuts_[j];
     394#else
     395      if (cuts_[j]->globallyValidAsInteger()!=2)
     396        delete cuts_[j];
     397#endif
     398    }
    376399    cuts_[j]=NULL;
    377400  }
     
    392415    int iCut=which[i];
    393416    int number = cuts_[iCut]->decrement();
    394     if (!number)
     417    if (!number) {
     418#ifndef GLOBAL_CUTS_JUST_POINTERS
    395419      delete cuts_[iCut];
     420#else
     421      if (cuts_[iCut]->globallyValidAsInteger()!=2)
     422        delete cuts_[iCut];
     423#endif
     424    }
    396425    cuts_[iCut]=NULL;
    397426  }
     
    622651  for (i=0;i<numberChangedBounds_;i++) {
    623652    int variable = variables_[i];
     653    int k = variable&0x7fffffff;
    624654    if ((variable&0x80000000)==0) {
    625655      // lower bound changing
    626       solver->setColLower(variable,newBounds_[i]);
     656#ifndef NDEBUG
     657      double oldValue = solver->getColLower()[k];
     658      assert (newBounds_[i]>oldValue-1.0e-8);
     659      if (newBounds_[i]<oldValue+1.0e-8)
     660        printf("bad null lower change for column %d - bound %g\n",k,oldValue);
     661#endif
     662      solver->setColLower(k,newBounds_[i]);
    627663    } else {
    628664      // upper bound changing
    629       solver->setColUpper(variable&0x7fffffff,newBounds_[i]);
     665#ifndef NDEBUG
     666      double oldValue = solver->getColUpper()[k];
     667      assert (newBounds_[i]<oldValue+1.0e-8);
     668      if (newBounds_[i]>oldValue-1.0e-8)
     669        printf("bad null upper change for column %d - bound %g\n",k,oldValue);
     670#endif
     671      solver->setColUpper(k,newBounds_[i]);
    630672    }
    631673  }
     
    684726
    685727  if (lastNode)
     728    if (lastNode->nodeInfo_)
    686729    lastNode->nodeInfo_->increment();
    687730}
    688731
     732#define CBC_NEW_CREATEINFO
     733#ifdef CBC_NEW_CREATEINFO
     734
     735/*
     736  New createInfo, with basis manipulation hidden inside mergeBasis. Allows
     737  solvers to override and carry over all information from one basis to
     738  another.
     739*/
     740
     741void
     742CbcNode::createInfo (CbcModel *model,
     743                     CbcNode *lastNode,
     744                     const CoinWarmStartBasis *lastws,
     745                     const double *lastLower, const double *lastUpper,
     746                     int numberOldActiveCuts, int numberNewCuts)
     747
     748{ OsiSolverInterface *solver = model->solver();
     749  CbcStrategy *strategy = model->strategy();
     750/*
     751  The root --- no parent. Create full basis and bounds information.
     752*/
     753  if (!lastNode)
     754  {
     755    if (!strategy)
     756      nodeInfo_=new CbcFullNodeInfo(model,solver->getNumRows());
     757    else
     758      nodeInfo_ = strategy->fullNodeInfo(model,solver->getNumRows());
     759  } else {
     760/*
     761  Not the root. Create an edit from the parent's basis & bound information.
     762  This is not quite as straightforward as it seems. We need to reintroduce
     763  cuts we may have dropped out of the basis, in the correct position, because
     764  this whole process is strictly positional. Start by grabbing the current
     765  basis.
     766*/
     767    const CoinWarmStartBasis *ws =
     768      dynamic_cast<const CoinWarmStartBasis*>(solver->getWarmStart());
     769    assert(ws!=NULL); // make sure not volume
     770    //int numberArtificials = lastws->getNumArtificial();
     771    int numberColumns = solver->getNumCols();
     772    int numberRowsAtContinuous = model->numberRowsAtContinuous();
     773    int currentNumberCuts = model->currentNumberCuts();
     774#   ifdef CBC_CHECK_BASIS
     775    std::cout
     776      << "Before expansion: orig " << numberRowsAtContinuous
     777      << ", old " << numberOldActiveCuts
     778      << ", new " << numberNewCuts
     779      << ", current " << currentNumberCuts << "." << std::endl ;
     780    ws->print();
     781#   endif
     782/*
     783  Clone the basis and resize it to hold the structural constraints, plus
     784  all the cuts: old cuts, both active and inactive (currentNumberCuts),
     785  and new cuts (numberNewCuts). This will become the expanded basis.
     786*/
     787    CoinWarmStartBasis *expanded =
     788      dynamic_cast<CoinWarmStartBasis *>(ws->clone()) ;
     789    int iCompact = numberRowsAtContinuous+numberOldActiveCuts+numberNewCuts ;
     790    // int nPartial = numberRowsAtContinuous+currentNumberCuts;
     791    int iFull = numberRowsAtContinuous+currentNumberCuts+numberNewCuts;
     792    // int maxBasisLength = ((iFull+15)>>4)+((numberColumns+15)>>4);
     793    // printf("l %d full %d\n",maxBasisLength,iFull);
     794    expanded->resize(iFull,numberColumns);
     795#   ifdef CBC_CHECK_BASIS
     796    std::cout
     797      << "\tFull basis " << iFull << " rows, "
     798      << numberColumns << " columns; compact "
     799      << iCompact << " rows." << std::endl ;
     800#   endif
     801/*
     802  Now flesh out the expanded basis. The clone already has the
     803  correct status information for the variables and for the structural
     804  (numberRowsAtContinuous) constraints. Any indices beyond nPartial must be
     805  cuts created while processing this node --- they can be copied en bloc
     806  into the correct position in the expanded basis. The space reserved for
     807  xferRows is a gross overestimate.
     808*/
     809    CoinWarmStartBasis::XferVec xferRows ;
     810    xferRows.reserve(iFull-numberRowsAtContinuous+1) ;
     811    if (numberNewCuts) {
     812      xferRows.push_back(
     813          CoinWarmStartBasis::XferEntry(iCompact-numberNewCuts,
     814                                        iFull-numberNewCuts,numberNewCuts)) ;
     815    }
     816/*
     817  From nPartial down, record the entries we want to copy from the current
     818  basis (the entries for the active cuts; non-zero in the list returned
     819  by addedCuts). Fill the expanded basis with entries showing a status of
     820  basic for the deactivated (loose) cuts.
     821*/
     822    CbcCountRowCut **cut = model->addedCuts();
     823    iFull -= (numberNewCuts+1) ;
     824    iCompact -= (numberNewCuts+1) ;
     825    int runLen = 0 ;
     826    CoinWarmStartBasis::XferEntry entry(-1,-1,-1) ;
     827    while (iFull >= numberRowsAtContinuous) {
     828      for ( ; iFull >= numberRowsAtContinuous &&
     829              cut[iFull-numberRowsAtContinuous] ; iFull--)
     830        runLen++ ;
     831      if (runLen) {
     832        iCompact -= runLen ;
     833        entry.first = iCompact+1 ;
     834        entry.second = iFull+1 ;
     835        entry.third = runLen ;
     836        runLen = 0 ;
     837        xferRows.push_back(entry) ;
     838      }
     839      for ( ; iFull >= numberRowsAtContinuous &&
     840              !cut[iFull-numberRowsAtContinuous] ; iFull--)
     841        expanded->setArtifStatus(iFull,CoinWarmStartBasis::basic);
     842    }
     843/*
     844  Finally, call mergeBasis to copy over entries from the current basis to
     845  the expanded basis. Since we cloned the expanded basis from the active basis
     846  and haven't changed the number of variables, only row status entries need
     847  to be copied.
     848*/
     849    expanded->mergeBasis(ws,&xferRows,0) ;
     850
     851#ifdef CBC_CHECK_BASIS
     852    std::cout << "Expanded basis:" << std::endl ;
     853    expanded->print() ;
     854    std::cout << "Diffing against:" << std::endl ;
     855    lastws->print() ;
     856#endif   
     857
     858/*
     859  Now that we have two bases in proper positional correspondence, creating
     860  the actual diff is dead easy.
     861
     862  Note that we're going to compare the expanded basis here to the stripped
     863  basis (lastws) produced by addCuts. It doesn't affect the correctness (the
     864  diff process has no knowledge of the meaning of an entry) but it does
     865  mean that we'll always generate a whack of diff entries because the expanded
     866  basis is considerably larger than the stripped basis.
     867*/
     868    CoinWarmStartDiff *basisDiff = expanded->generateDiff(lastws) ;
     869/*
     870  Diff the bound vectors. It's assumed the number of structural variables
     871  is not changing. For branching objects that change bounds on integer
     872  variables, we should see at least one bound change as a consequence
     873  of applying the branch that generated this subproblem from its parent.
     874  This need not hold for other types of branching objects (hyperplane
     875  branches, for example).
     876*/
     877    const double * lower = solver->getColLower();
     878    const double * upper = solver->getColUpper();
     879
     880    double *boundChanges = new double [2*numberColumns] ;
     881    int *variables = new int [2*numberColumns] ;
     882    int numberChangedBounds=0;
     883   
     884    int i;
     885    for (i=0;i<numberColumns;i++) {
     886      if (lower[i]!=lastLower[i]) {
     887        variables[numberChangedBounds]=i;
     888        boundChanges[numberChangedBounds++]=lower[i];
     889      }
     890      if (upper[i]!=lastUpper[i]) {
     891        variables[numberChangedBounds]=i|0x80000000;
     892        boundChanges[numberChangedBounds++]=upper[i];
     893      }
     894#ifdef CBC_DEBUG
     895      if (lower[i] != lastLower[i]) {
     896        std::cout
     897          << "lower on " << i << " changed from "
     898          << lastLower[i] << " to " << lower[i] << std::endl ;
     899      }
     900      if (upper[i] != lastUpper[i]) {
     901        std::cout
     902          << "upper on " << i << " changed from "
     903          << lastUpper[i] << " to " << upper[i] << std::endl ;
     904      }
     905#endif
     906    }
     907#ifdef CBC_DEBUG
     908    std::cout << numberChangedBounds << " changed bounds." << std::endl ;
     909#endif
     910    //if (lastNode->branchingObject()->boundBranch())
     911    //assert (numberChangedBounds);
     912/*
     913  Hand the lot over to the CbcPartialNodeInfo constructor, then clean up and
     914  return.
     915*/
     916    if (!strategy)
     917      nodeInfo_ =
     918        new CbcPartialNodeInfo(lastNode->nodeInfo_,this,numberChangedBounds,
     919                               variables,boundChanges,basisDiff) ;
     920    else
     921      nodeInfo_ =
     922        strategy->partialNodeInfo(model,lastNode->nodeInfo_,this,
     923                                  numberChangedBounds,variables,boundChanges,
     924                                  basisDiff) ;
     925    delete basisDiff ;
     926    delete [] boundChanges;
     927    delete [] variables;
     928    delete expanded ;
     929    delete ws;
     930  }
     931  // Set node number
     932  nodeInfo_->setNodeNumber(model->getNodeCount2());
     933}
     934
     935#else   // CBC_NEW_CREATEINFO
     936
     937/*
     938  Original createInfo, with bare manipulation of basis vectors. Fails if solver
     939  maintains additional information in basis.
     940*/
    689941
    690942void
     
    8601112}
    8611113
     1114#endif  // CBC_NEW_CREATEINFO
     1115
    8621116/*
    8631117  The routine scans through the object list of the model looking for objects
     
    9061160  double integerTolerance =
    9071161    model->getDblParam(CbcModel::CbcIntegerTolerance);
     1162  // point to useful information
     1163  OsiBranchingInformation usefulInfo = model->usefulInformation();
     1164  // and modify
     1165  usefulInfo.depth_=depth_;
    9081166  int i;
    9091167  bool beforeSolution = model->getSolutionCount()==0;
     
    9341192  */
    9351193  CbcBranchDecision *decision = model->branchingMethod();
    936   if (!decision)
     1194  CbcDynamicPseudoCostBranchingObject * dynamicBranchingObject =
     1195    dynamic_cast<CbcDynamicPseudoCostBranchingObject *>(decision);
     1196  if (!decision||dynamicBranchingObject)
    9371197    decision = new CbcBranchDefaultDecision();
    938 
     1198  decision->initialize(model);
    9391199  CbcStrongInfo * choice = new CbcStrongInfo[maximumStrong];
    9401200  for (i=0;i<numberColumns;i++) {
     
    9941254      bool canDoOneHot=false;
    9951255      for (i=0;i<numberObjects;i++) {
    996         CbcObject * object = model->modifiableObject(i);
     1256        OsiObject * object = model->modifiableObject(i);
    9971257        int preferredWay;
    998         double infeasibility = object->infeasibility(preferredWay);
     1258        double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    9991259        int priorityLevel = object->priority();
    10001260        if (hotstartSolution) {
     
    10021262          const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
    10031263          if (thisOne) {
    1004             int iColumn = thisOne->modelSequence();
     1264            int iColumn = thisOne->columnNumber();
    10051265            bool canDoThisHot=true;
    10061266            double targetValue = hotstartSolution[iColumn];
     
    10821342            choice[iSmallest].upMovement=infeasibility;
    10831343            delete choice[iSmallest].possibleBranch;
    1084             choice[iSmallest].possibleBranch=object->createBranch(preferredWay);
     1344            CbcSimpleInteger * obj =
     1345              dynamic_cast <CbcSimpleInteger *>(object) ;
     1346            if (obj) {
     1347              choice[iSmallest].possibleBranch=obj->createBranch(solver,&usefulInfo,preferredWay);
     1348            } else {
     1349              CbcObject * obj =
     1350                dynamic_cast <CbcObject *>(object) ;
     1351              assert (obj);
     1352              choice[iSmallest].possibleBranch=obj->createBranch(preferredWay);
     1353            }
    10851354            numberStrong = CoinMax(numberStrong,iSmallest+1);
    10861355            // Save which object it was
     
    12731542          clp->primal(1);
    12741543          if (clp->numberIterations())
    1275             model->messageHandler()->message(CBC_ITERATE_STRONG,model->messages())
     1544            model->messageHandler()->message(CBC_ITERATE_STRONG,*model->messagesPointer())
    12761545              << clp->numberIterations()
    12771546              <<CoinMessageEol;
     
    12831552        for (i=0;i<numberStrong;i++) {
    12841553          int iObject = choice[i].objectNumber;
    1285           const CbcObject * object = model->object(iObject);
     1554          const OsiObject * object = model->object(iObject);
    12861555          const CbcSimpleInteger * simple = dynamic_cast <const CbcSimpleInteger *> (object);
    1287           int iSequence = simple->modelSequence();
     1556          int iSequence = simple->columnNumber();
    12881557          newLower[i]= ceil(saveSolution[iSequence]);
    12891558          newUpper[i]= floor(saveSolution[iSequence]);
     
    13181587          for (i=0;i<numberStrong;i++) {
    13191588            int iObject = choice[i].objectNumber;
    1320             const CbcObject * object = model->object(iObject);
     1589            const OsiObject * object = model->object(iObject);
    13211590            const CbcSimpleInteger * simple = dynamic_cast <const CbcSimpleInteger *> (object);
    1322             int iSequence = simple->modelSequence();
     1591            int iSequence = simple->columnNumber();
    13231592            which[i]=iSequence;
    13241593            double * sol = outputSolution[2*i];
     
    17001969            CbcStrongInfo thisChoice = choice[i];
    17011970            choice[i].possibleBranch=NULL;
    1702             const CbcObject * object = model->object(thisChoice.objectNumber);
     1971            const OsiObject * object = model->object(thisChoice.objectNumber);
    17031972            int preferredWay;
    1704             double infeasibility = object->infeasibility(preferredWay);
     1973            double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    17051974            if (!infeasibility) {
    17061975              // take out
     
    17792048        for (i = 0 ; i < numberStrong ; i++) {
    17802049          int iColumn = choice[i].possibleBranch->variable() ;
    1781           model->messageHandler()->message(CBC_STRONG,model->messages())
     2050          model->messageHandler()->message(CBC_STRONG,*model->messagesPointer())
    17822051            << i << iColumn
    17832052            <<choice[i].downMovement<<choice[i].numIntInfeasDown
     
    18312100  Cleanup, then we're outta here.
    18322101*/
    1833   if (!model->branchingMethod())
     2102  if (!model->branchingMethod()||dynamicBranchingObject)
    18342103    delete decision;
    18352104   
     
    18962165    auxiliaryInfo = model->solverCharacteristics();
    18972166  }
     2167  // point to useful information
     2168  OsiBranchingInformation usefulInfo = model->usefulInformation();
     2169  // and modify
     2170  usefulInfo.depth_=depth_;
    18982171  assert (auxiliaryInfo);
    18992172  //assert(objectiveValue_ == solver->getObjSense()*solver->getObjValue());
     
    19652238  double estimatedDegradation=0.0;
    19662239  int numberNodes=model->getNodeCount();
     2240  int saveLogLevel = model->logLevel();
     2241  if ((numberNodes%500)==0&&false) {
     2242    model->setLogLevel(6);
     2243    // Get average up and down costs
     2244    double averageUp=0.0;
     2245    double averageDown=0.0;
     2246    int numberUp=0;
     2247    int numberDown=0;
     2248    int i;
     2249    for ( i=0;i<numberObjects;i++) {
     2250      OsiObject * object = model->modifiableObject(i);
     2251      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     2252        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     2253      assert(dynamicObject);
     2254      int  numberUp2=0;
     2255      int numberDown2=0;
     2256      double up=0.0;
     2257      double down=0.0;
     2258      if (dynamicObject->numberTimesUp()) {
     2259        numberUp++;
     2260        averageUp += dynamicObject->upDynamicPseudoCost();
     2261        numberUp2 += dynamicObject->numberTimesUp();
     2262        up = dynamicObject->upDynamicPseudoCost();
     2263      }
     2264      if (dynamicObject->numberTimesDown()) {
     2265        numberDown++;
     2266        averageDown += dynamicObject->downDynamicPseudoCost();
     2267        numberDown2 += dynamicObject->numberTimesDown();
     2268        down = dynamicObject->downDynamicPseudoCost();
     2269      }
     2270      if (numberUp2||numberDown2)
     2271        printf("col %d - up %d times cost %g, - down %d times cost %g\n",
     2272               dynamicObject->columnNumber(),numberUp2,up,numberDown2,down);
     2273    }
     2274    if (numberUp)
     2275      averageUp /= (double) numberUp;
     2276    else
     2277      averageUp=1.0;
     2278    if (numberDown)
     2279      averageDown /= (double) numberDown;
     2280    else
     2281      averageDown=1.0;
     2282    printf("total - up %d vars average %g, - down %d vars average %g\n",
     2283           numberUp,averageUp,numberDown,averageDown);
     2284  }
    19672285  int numberBeforeTrust = model->numberBeforeTrust();
    19682286  int numberPenalties = model->numberPenalties();
     
    19882306  OsiSolverInterface *osiclp = 0 ;
    19892307# endif
     2308  const CglTreeProbingInfo * probingInfo = model->probingInfo();
    19902309  int saveSearchStrategy2 = model->searchStrategy();
    19912310  if (saveSearchStrategy2<999) {
     
    19982317      int i;
    19992318      for ( i=0;i<numberObjects;i++) {
    2000         CbcObject * object = model->modifiableObject(i);
     2319        OsiObject * object = model->modifiableObject(i);
    20012320        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    20022321          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    20202339        averageDown=1.0;
    20212340      for ( i=0;i<numberObjects;i++) {
    2022         CbcObject * object = model->modifiableObject(i);
     2341        OsiObject * object = model->modifiableObject(i);
    20232342        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    20242343          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    20722391    int * which = objectMark+numberObjects+1;
    20732392    int neededPenalties;
     2393    int branchingMethod=-1;
    20742394    // We may go round this loop three times (only if we think we have solution)
    20752395    for (int iPass=0;iPass<3;iPass++) {
     
    20872407      sumInfeasibilities_ = 0.0;
    20882408      int bestPriority=INT_MAX;
     2409      int number01 = 0;
     2410      const fixEntry * entry = NULL;
     2411      const int * toZero = NULL;
     2412      const int * toOne = NULL;
     2413      const int * backward = NULL;
     2414      int numberUnsatisProbed=0;
     2415      int numberUnsatisNotProbed=0; // 0-1
     2416      if (probingInfo) {
     2417        number01 = probingInfo->numberIntegers();
     2418        entry = probingInfo->fixEntries();
     2419        toZero = probingInfo->toZero();
     2420        toOne = probingInfo->toOne();
     2421        backward = probingInfo->backward();
     2422        if (!toZero[number01]) {
     2423          // no info
     2424          probingInfo=NULL;
     2425        }
     2426      }
    20892427      /*
    20902428        Scan for branching objects that indicate infeasibility. Choose candidates
     
    21052443#define PRINT_STUFF -1
    21062444      for (i=0;i<numberObjects;i++) {
    2107         CbcObject * object = model->modifiableObject(i);
     2445        OsiObject * object = model->modifiableObject(i);
    21082446        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    21092447          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    21102448        assert(dynamicObject);
    21112449        int preferredWay;
    2112         double infeasibility = object->infeasibility(preferredWay);
     2450        double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    21132451        int priorityLevel = object->priority();
    21142452#define ZERO_ONE 0
     
    21242462#endif
    21252463        if (infeasibility) {
     2464          // check branching method
     2465          if (branchingMethod!=dynamicObject->method()) {
     2466            if (branchingMethod==-1)
     2467              branchingMethod = dynamicObject->method();
     2468            else
     2469              branchingMethod = 100;
     2470          }
    21262471          int iColumn = dynamicObject->columnNumber();
     2472          if (probingInfo) {
     2473            int iSeq = backward[iColumn];
     2474            if (iSeq>=0) {
     2475              if (toZero[iSeq+1]>toZero[iSeq]) {
     2476                numberUnsatisProbed++;
     2477              } else {
     2478                numberUnsatisNotProbed++;
     2479              }
     2480            }
     2481          }
    21272482          //double gap = saveUpper[iColumn]-saveLower[iColumn];
    21282483          // Give precedence to ones with gap of 1.0
     
    21922547      }
    21932548      if (numberUnsatisfied_) {
     2549        if (probingInfo&&false)
     2550          printf("nunsat %d, %d probed, %d other 0-1\n",numberUnsatisfied_,
     2551                 numberUnsatisProbed,numberUnsatisNotProbed);
    21942552        // some infeasibilities - go to next steps
    21952553        break;
     
    22602618    bool skipAll = numberNotTrusted==0;
    22612619    bool doneHotStart=false;
     2620    int searchStrategy = saveSearchStrategy>=0 ? (saveSearchStrategy%10) : -1;
    22622621#ifndef CBC_WEAK_STRONG
    2263     if ((numberNodes%20)==0||(model->specialOptions()&8)!=0)
     2622    if (((numberNodes%20)==0&&searchStrategy!=2)||(model->specialOptions()&8)!=0)
    22642623      skipAll=false;
    22652624#endif
    2266     int searchStrategy = saveSearchStrategy>=0 ? (saveSearchStrategy%10) : -1;
    22672625    if (!newWay) {
    22682626    // 10 up always use %10, 20 up as 10 and allow penalties
     
    22712629      if (numberBeforeTrust>=5&&numberBeforeTrust<=10) {
    22722630        if (searchStrategy!=2) {
    2273           int numberIterations = model->getIterationCount();
    2274           int numberStrongIterations = model->numberStrongIterations();
    2275           if (numberStrongIterations>numberIterations+10000) {
    2276             searchStrategy=2;
    2277             //skipAll=true;
    2278           } else if (numberStrongIterations*4+1000<numberIterations||depth_<5) {
    2279             searchStrategy=3;
    2280             skipAll=false;
    2281           }
     2631          if (depth_>5) {
     2632            int numberIterations = model->getIterationCount();
     2633            int numberStrongIterations = model->numberStrongIterations();
     2634            if (numberStrongIterations>numberIterations+10000) {
     2635              searchStrategy=2;
     2636              //skipAll=true;
     2637            } else if (numberStrongIterations*4+1000<numberIterations||depth_<5) {
     2638              searchStrategy=3;
     2639              skipAll=false;
     2640            }
     2641          } else {
     2642            searchStrategy=3;
     2643            skipAll=false;
     2644          }
    22822645        } else {
    2283           skipAll=true;
     2646          //skipAll=true;
    22842647        }
    22852648      }
     
    23462709                        model->getDblParam(CbcModel::CbcMaximumSeconds));
    23472710    // also give up if we are looping round too much
    2348     if (hitMaxTime||numberPassesLeft<=0||(!numberNotTrusted&&false)) {
     2711    if (hitMaxTime||numberPassesLeft<=0||(!numberNotTrusted&&false)||branchingMethod==11) {
    23492712      int iObject = whichObject[bestChoice];
    2350       CbcObject * object = model->modifiableObject(iObject);
     2713      OsiObject * object = model->modifiableObject(iObject);
    23512714      int preferredWay;
    2352       object->infeasibility(preferredWay);
    2353       branch_=object->createBranch(preferredWay);
    2354       branch_->way(preferredWay);
     2715      object->infeasibility(&usefulInfo,preferredWay);
     2716      CbcSimpleInteger * obj =
     2717        dynamic_cast <CbcSimpleInteger *>(object) ;
     2718      if (obj) {
     2719        branch_=obj->createBranch(solver,&usefulInfo,preferredWay);
     2720      } else {
     2721        CbcObject * obj =
     2722          dynamic_cast <CbcObject *>(object) ;
     2723        assert (obj);
     2724        branch_=obj->createBranch(preferredWay);
     2725      }
     2726      {
     2727        CbcBranchingObject * branchObj =
     2728          dynamic_cast <CbcBranchingObject *>(branch_) ;
     2729        assert (branchObj);
     2730        branchObj->way(preferredWay);
     2731      }
    23552732      delete ws;
    23562733      ws=NULL;
     
    24022779          int j = objectMark[i];
    24032780          int iObject = whichObject[j];
    2404           CbcObject * object = model->modifiableObject(iObject);
     2781          OsiObject * object = model->modifiableObject(iObject);
    24052782          CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    24062783            dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    24802857      solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit2);
    24812858      bool doQuickly = false; // numberToDo>2*numberStrong;
     2859      if (searchStrategy==2)
     2860        doQuickly=true;
    24822861      //printf("todo %d, strong %d\n",numberToDo,numberStrong);
    24832862      int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
    24842863      int numberTest2 = 2*numberStrong;
     2864      double distanceToCutoff2 = model->getCutoff()-objectiveValue_;
    24852865      if (!newWay) {
    24862866      if (searchStrategy==3) {
     
    25172897      }
    25182898#endif
    2519       if (depth_<10&&numberStrong) {
     2899      if (depth_<8&&numberStrong) {
    25202900        if (searchStrategy!=2) {
    25212901          doQuickly=false;
    2522           if (depth_<7)
    2523             numberStrong *=3;
    2524           if (!depth_)
    2525             numberStrong=CoinMin(6*numberStrong,numberToDo);
     2902          int numberRows = solver->getNumRows();
     2903          // whether to do this or not is important - think
     2904          if (numberRows<300||numberRows+numberColumns<2500) {
     2905            if (depth_<7)
     2906              numberStrong = CoinMin(3*numberStrong,numberToDo);
     2907            if (!depth_)
     2908              numberStrong=CoinMin(6*numberStrong,numberToDo);
     2909          }
    25262910          numberTest=numberStrong;
    25272911          skipAll=false;
     
    26203004      px[2]= doQuickly ? 1 : -1;
    26213005      px[3]=numberStrong;
     3006      if (!newWay) {
     3007        if (numberColumns>8*solver->getNumRows()&&false) {
     3008          printf("skipAll %c doQuickly %c numberTest %d numberTest2 %d numberNot %d\n",
     3009                 skipAll ? 'Y' : 'N',doQuickly ? 'Y' : 'N',numberTest,numberTest2,numberNotTrusted);
     3010          numberTest = CoinMin(numberTest,model->numberStrong());
     3011          numberTest2 = CoinMin(numberTest2,model->numberStrong());
     3012          printf("new test,test2 %d %d\n",numberTest,numberTest2);
     3013        }
     3014      }
    26223015      //printf("skipAll %c doQuickly %c numberTest %d numberTest2 %d numberNot %d\n",
    2623       //     skipAll ? 'Y' : 'N',doQuickly ? 'Y' : 'N',numberTest,numberTest2,numberNotTrusted);
     3016      //   skipAll ? 'Y' : 'N',doQuickly ? 'Y' : 'N',numberTest,numberTest2,numberNotTrusted);
    26243017      // See if we want mini tree
    26253018      bool wantMiniTree=false;
     
    26303023      //numberToDo = 1; // trust previous stuff
    26313024      bool couldChooseFirst = false ; //(skipAll&&numberTest==0&&doQuickly);
     3025      //skipAll=false;
    26323026      for ( iDo=0;iDo<numberToDo;iDo++) {
    26333027        CbcStrongInfo choice;
    26343028        int iObject = whichObject[iDo];
    2635         CbcObject * object = model->modifiableObject(iObject);
     3029        OsiObject * object = model->modifiableObject(iObject);
    26363030        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    26373031          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    26383032        int iColumn = dynamicObject->columnNumber();
    26393033        int preferredWay;
    2640         object->infeasibility(preferredWay);
    2641         choice.possibleBranch=object->createBranch(preferredWay);
     3034        double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
     3035        // may have become feasible
     3036        if (!infeasibility)
     3037          continue;
     3038        CbcSimpleInteger * obj =
     3039          dynamic_cast <CbcSimpleInteger *>(object) ;
     3040        if (obj) {
     3041          choice.possibleBranch=obj->createBranch(solver,&usefulInfo,preferredWay);
     3042        } else {
     3043          CbcObject * obj =
     3044            dynamic_cast <CbcObject *>(object) ;
     3045          assert (obj);
     3046          choice.possibleBranch=obj->createBranch(preferredWay);
     3047        }
    26423048        // Save which object it was
    26433049        choice.objectNumber=iObject;
     
    26493055        assert (choice.downMovement>=0.0);
    26503056        choice.fix=0; // say not fixed
     3057        double maxChange = 0.5*(choice.upMovement+choice.downMovement);
     3058        maxChange = CoinMin(choice.upMovement,choice.downMovement);
     3059        maxChange = CoinMax(choice.upMovement,choice.downMovement);
     3060        if (searchStrategy==2)
     3061          maxChange = COIN_DBL_MAX;
     3062        //maxChange *= 5.0;
     3063        if (dynamicObject->method()==1)
     3064          maxChange *= 0.1; // probing
    26513065        // see if can skip strong branching
    26523066        int canSkip = choice.possibleBranch->fillStrongInfo(choice);
    26533067        if (!newWay) {
    2654         if (!doQuickly||(numberTest>0&&searchStrategy!=2))
     3068          if ((maxChange>distanceToCutoff2)&&(!doQuickly||(numberTest>0&&searchStrategy!=2)))
    26553069          canSkip=0;
    26563070        } else {
     
    29543368                printf("sort %g downest %g upest %g ",sort[iDo],downEstimate[iObject],
    29553369                     upEstimate[iObject]);
    2956               model->messageHandler()->message(CBC_STRONG,model->messages())
     3370              model->messageHandler()->message(CBC_STRONG,*model->messagesPointer())
    29573371                << iObject << iColumn
    29583372                <<choice.downMovement<<choice.numIntInfeasDown
     
    29703384            //assert(gap>0.0);
    29713385            double factor = 1.0; //changeFactor/CoinMin(gap,100.0);
    2972             int betterWay = decision->betterBranch(choice.possibleBranch,
    2973                                                    branch_,
    2974                                                    choice.upMovement*factor,
    2975                                                    choice.numIntInfeasUp ,
    2976                                                    choice.downMovement*factor,
    2977                                                    choice.numIntInfeasDown );
     3386            int betterWay;
     3387            {
     3388              CbcBranchingObject * branchObj =
     3389                dynamic_cast <CbcBranchingObject *>(branch_) ;
     3390              if (branch_)
     3391                assert (branchObj);
     3392              betterWay = decision->betterBranch(choice.possibleBranch,
     3393                                                     branchObj,
     3394                                                     choice.upMovement*factor,
     3395                                                     choice.numIntInfeasUp ,
     3396                                                     choice.downMovement*factor,
     3397                                                     choice.numIntInfeasDown );
     3398            }
    29783399            if (wantMiniTree) {
    29793400              double criterion = decision->getBestCriterion();
     
    29963417              branch_ = choice.possibleBranch;
    29973418              choice.possibleBranch=NULL;
    2998               branch_->way(betterWay);
     3419              {
     3420                CbcBranchingObject * branchObj =
     3421                  dynamic_cast <CbcBranchingObject *>(branch_) ;
     3422                assert (branchObj);
     3423                //branchObj->way(preferredWay);
     3424                branchObj->way(betterWay);
     3425              }
    29993426              if (couldChooseFirst)
    30003427                printf("choosing %d way %d\n",iDo,betterWay);
     
    30553482              assert(doneHotStart);
    30563483              solver->unmarkHotStart();
     3484              solver->resolve();
    30573485              solver->markHotStart();
     3486              // may be infeasible (if other way stopped on iterations)
     3487              if (!solver->isProvenOptimal()) {
     3488                // neither side feasible
     3489                anyAction=-2;
     3490                delete choice.possibleBranch;
     3491                choice.possibleBranch=NULL;
     3492                //printf("Both infeasible for choice %d sequence %d\n",i,
     3493                // model->object(choice.objectNumber)->columnNumber());
     3494                delete ws;
     3495                ws=NULL;
     3496                break;
     3497              }
    30583498#endif
    30593499            }
     
    30843524              assert(doneHotStart);
    30853525              solver->unmarkHotStart();
     3526              solver->resolve();
    30863527              solver->markHotStart();
     3528              // may be infeasible (if other way stopped on iterations)
     3529              if (!solver->isProvenOptimal()) {
     3530                // neither side feasible
     3531                anyAction=-2;
     3532                delete choice.possibleBranch;
     3533                choice.possibleBranch=NULL;
     3534                //printf("Both infeasible for choice %d sequence %d\n",i,
     3535                // model->object(choice.objectNumber)->columnNumber());
     3536                delete ws;
     3537                ws=NULL;
     3538                break;
     3539              }
    30873540#endif
    30883541            }
     
    31073560          for ( int jDo=iDo+1;jDo<numberToDo;jDo++) {
    31083561            int iObject = whichObject[iDo];
    3109             CbcObject * object = model->modifiableObject(iObject);
     3562            OsiObject * object = model->modifiableObject(iObject);
    31103563            CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    31113564              dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    31213574        solveAll=false;
    31223575      if (model->messageHandler()->logLevel()>3||false) {
    3123         if (anyAction==-2)
     3576        if (anyAction==-2) {
    31243577          printf("infeasible\n");
    3125         else if(anyAction==-1)
     3578        } else if(anyAction==-1) {
    31263579          if (!solveAll)
    31273580            printf("%d fixed\n",numberToFix);
     
    31293582            printf("%d fixed AND choosing %d iDo %d iChosenWhen %d numberToDo %d\n",numberToFix,bestChoice,
    31303583                   iDo,whichChoice,numberToDo);
    3131         else
    3132           printf("choosing %d iDo %d iChosenWhen %d numberToDo %d\n",bestChoice,
     3584        } else {
     3585          printf("choosing %d  iDo %d iChosenWhen %d numberToDo %d\n",bestChoice,
    31333586                 iDo,whichChoice,numberToDo);
     3587        }
    31343588      }
    31353589      if (doneHotStart) {
     
    31783632              // See if candidate still possible
    31793633              if (branch_) {
    3180                 const CbcObject * object = model->object(bestChoice);
     3634                const OsiObject * object = model->object(bestChoice);
    31813635                int preferredWay;
    3182                 double infeasibility = object->infeasibility(preferredWay);
     3636                double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    31833637                if (!infeasibility) {
    31843638                  // take out
     
    31863640                  branch_=NULL;
    31873641                } else {
    3188                   branch_->way(preferredWay);
     3642                  CbcBranchingObject * branchObj =
     3643                    dynamic_cast <CbcBranchingObject *>(branch_) ;
     3644                  assert (branchObj);
     3645                  branchObj->way(preferredWay);
    31893646                }
    31903647              }
     
    32513708    for (int iDo=0;iDo<numberMini;iDo++) {
    32523709      int iObject = whichObject[iDo];
    3253       CbcObject * object = model->modifiableObject(iObject);
    3254       OsiSolverBranch * oneBranch = object->solverBranch();
     3710      OsiObject * object = model->modifiableObject(iObject);
     3711      CbcSimpleInteger * obj =
     3712        dynamic_cast <CbcSimpleInteger *>(object) ;
     3713      OsiSolverBranch * oneBranch;
     3714      if (obj) {
     3715        oneBranch = obj->solverBranch(solver,&usefulInfo);
     3716      } else {
     3717        CbcObject * obj =
     3718          dynamic_cast <CbcObject *>(object) ;
     3719        assert (obj);
     3720        oneBranch = obj->solverBranch();
     3721      }
    32553722      branches[iDo]=*oneBranch;
    32563723      delete oneBranch;
     
    32803747  delete [] saveSolution;
    32813748  model->setStateOfSearch(saveStateOfSearch);
     3749  model->setLogLevel(saveLogLevel);
    32823750  return anyAction;
    32833751}
     
    33303798  int numberToFix=0;
    33313799  int numberToDo=0;
     3800  double integerTolerance =
     3801    model->getDblParam(CbcModel::CbcIntegerTolerance);
     3802  // point to useful information
     3803  OsiBranchingInformation usefulInfo = model->usefulInformation();
     3804  // and modify
     3805  usefulInfo.depth_=depth_;
    33323806     
    33333807  // compute current state
     
    33613835  numberToDo=0;
    33623836  for (i=0;i<numberObjects;i++) {
    3363     CbcObject * object = model->modifiableObject(i);
     3837    OsiObject * object = model->modifiableObject(i);
    33643838    CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    33653839      dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    33673841      continue;
    33683842    int preferredWay;
    3369     double infeasibility = object->infeasibility(preferredWay);
     3843    double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    33703844    int iColumn = dynamicObject->columnNumber();
    33713845    if (saveUpper[iColumn]==saveLower[iColumn])
     
    33903864  //double distanceToCutoff=model->getCutoff()-objectiveValue_;
    33913865  double * currentSolution = model->currentSolution();
    3392   double integerTolerance =
    3393     model->getDblParam(CbcModel::CbcIntegerTolerance);
    33943866  double objMin = 1.0e50;
    33953867  double objMax = -1.0e50;
     
    33993871    CbcStrongInfo choice;
    34003872    int iObject = whichObject[iDo];
    3401     CbcObject * object = model->modifiableObject(iObject);
     3873    OsiObject * object = model->modifiableObject(iObject);
    34023874    CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    34033875      dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    34043876    int iColumn = dynamicObject->columnNumber();
    34053877    int preferredWay;
    3406     object->infeasibility(preferredWay);
     3878    object->infeasibility(&usefulInfo,preferredWay);
    34073879    double value = currentSolution[iColumn];
    34083880    double nearest = floor(value+0.5);
     
    34223894    }
    34233895    double upperValue = lowerValue+1.0;
    3424     choice.possibleBranch=object->createBranch(preferredWay);
     3896    CbcSimpleInteger * obj =
     3897      dynamic_cast <CbcSimpleInteger *>(object) ;
     3898    if (obj) {
     3899      choice.possibleBranch=obj->createBranch(solver,&usefulInfo,preferredWay);
     3900    } else {
     3901      CbcObject * obj =
     3902        dynamic_cast <CbcObject *>(object) ;
     3903      assert (obj);
     3904      choice.possibleBranch=obj->createBranch(preferredWay);
     3905    }
    34253906    currentSolution[iColumn]=value;
    34263907    // Save which object it was
     
    35874068        choice.downMovement = CoinMax(0.0,choice.downMovement);
    35884069        // feasible -
    3589         model->messageHandler()->message(CBC_STRONG,model->messages())
     4070        model->messageHandler()->message(CBC_STRONG,*model->messagesPointer())
    35904071          << iObject << iColumn
    35914072          <<choice.downMovement<<choice.numIntInfeasDown
     
    36754156  objectiveValue_=rhs.objectiveValue_;
    36764157  guessedObjectiveValue_ = rhs.guessedObjectiveValue_;
     4158  sumInfeasibilities_ = rhs.sumInfeasibilities_;
    36774159  if (rhs.branch_)
    36784160    branch_=rhs.branch_->clone();
     
    36884170  if (this != &rhs) {
    36894171    delete nodeInfo_;
    3690     if (nodeInfo_)
     4172    if (rhs.nodeInfo_)
    36914173      nodeInfo_ = rhs.nodeInfo_->clone();
    36924174    else
     
    36944176    objectiveValue_=rhs.objectiveValue_;
    36954177    guessedObjectiveValue_ = rhs.guessedObjectiveValue_;
     4178    sumInfeasibilities_ = rhs.sumInfeasibilities_;
    36964179    if (rhs.branch_)
    36974180      branch_=rhs.branch_->clone();
     
    37194202    int numberToDelete=nodeInfo_->numberBranchesLeft();
    37204203    //    CbcNodeInfo * parent = nodeInfo_->parent();
     4204    //assert (nodeInfo_->numberPointingToThis()>0);
    37214205    if (nodeInfo_->decrement(numberToDelete)==0) {
    37224206      delete nodeInfo_;
     
    37644248
    37654249int
    3766 CbcNode::branch()
     4250CbcNode::branch(OsiSolverInterface * solver)
    37674251{
    3768   double changeInGuessed=branch_->branch(true);
     4252  double changeInGuessed;
     4253  if (!solver)
     4254    changeInGuessed=branch_->branch();
     4255  else
     4256    changeInGuessed=branch_->branch(solver);
    37694257  guessedObjectiveValue_+= changeInGuessed;
    37704258  //#define PRINTIT
     
    37744262  int parentNodeNumber = -1;
    37754263  //CbcBranchingObject * object1 = branch_->object_;
    3776   //CbcObject * object = object1->
     4264  //OsiObject * object = object1->
    37774265  //int sequence = object->columnNumber);
    37784266  int id=-1;
     
    37914279  return nodeInfo_->branchedOn();
    37924280}
     4281/* Active arm of the attached OsiBranchingObject.
     4282 
     4283   In the simplest instance, coded -1 for the down arm of the branch, +1 for
     4284   the up arm. But see OsiBranchingObject::way()
     4285     Use nodeInfo--.numberBranchesLeft_ to see how active
     4286*/
     4287int
     4288CbcNode::way() const
     4289{
     4290  if (branch_) {
     4291    CbcBranchingObject * obj =
     4292      dynamic_cast <CbcBranchingObject *>(branch_) ;
     4293    assert (obj);
     4294    return obj->way();
     4295  } else {
     4296    return 0;
     4297  }
     4298}
     4299/* Create a branching object for the node
     4300
     4301    The routine scans the object list of the model and selects a set of
     4302    unsatisfied objects as candidates for branching. The candidates are
     4303    evaluated, and an appropriate branch object is installed.
     4304
     4305    The numberPassesLeft is decremented to stop fixing one variable each time
     4306    and going on and on (e.g. for stock cutting, air crew scheduling)
     4307
     4308    If evaluation determines that an object is monotone or infeasible,
     4309    the routine returns immediately. In the case of a monotone object,
     4310    the branch object has already been called to modify the model.
     4311
     4312    Return value:
     4313    <ul>
     4314      <li>  0: A branching object has been installed
     4315      <li> -1: A monotone object was discovered
     4316      <li> -2: An infeasible object was discovered
     4317    </ul>
     4318    Branch state:
     4319    <ul>
     4320      <li> -1: start
     4321      <li> -1: A monotone object was discovered
     4322      <li> -2: An infeasible object was discovered
     4323    </ul>
     4324*/
     4325int
     4326CbcNode::chooseOsiBranch (CbcModel * model,
     4327                          CbcNode * lastNode,
     4328                          OsiBranchingInformation * usefulInfo,
     4329                          int branchState)
     4330{
     4331  int returnStatus=0;
     4332  if (lastNode)
     4333    depth_ = lastNode->depth_+1;
     4334  else
     4335    depth_ = 0;
     4336  OsiSolverInterface * solver = model->solver();
     4337  objectiveValue_ = solver->getObjValue()*solver->getObjSense();
     4338  usefulInfo->objectiveValue_ = objectiveValue_;
     4339  usefulInfo->depth_ = depth_;
     4340  const double * saveInfoSol = usefulInfo->solution_;
     4341  double * saveSolution = new double[solver->getNumCols()];
     4342  memcpy(saveSolution,solver->getColSolution(),solver->getNumCols()*sizeof(double));
     4343  usefulInfo->solution_ = saveSolution;
     4344  OsiChooseVariable * choose = model->branchingMethod()->chooseMethod();
     4345  int numberUnsatisfied=-1;
     4346  if (branchState<0) {
     4347    // initialize
     4348    // initialize sum of "infeasibilities"
     4349    sumInfeasibilities_ = 0.0;
     4350    numberUnsatisfied = choose->setupList(usefulInfo,true);
     4351    numberUnsatisfied_ = numberUnsatisfied;
     4352    branchState=0;
     4353    if (numberUnsatisfied_<0) {
     4354      // infeasible
     4355      delete [] saveSolution;
     4356      return -2;
     4357    }
     4358  }
     4359  // unset best
     4360  int best=-1;
     4361  choose->setBestObjectIndex(-1);
     4362  if (numberUnsatisfied) {
     4363    if (branchState>0||!choose->numberOnList()) {
     4364      // we need to return at once - don't do strong branching or anything
     4365      if (choose->numberOnList()||!choose->numberStrong()) {
     4366        best = choose->candidates()[0];
     4367        choose->setBestObjectIndex(best);
     4368      } else {
     4369        // nothing on list - need to try again - keep any solution
     4370        numberUnsatisfied = choose->setupList(usefulInfo, false);
     4371        numberUnsatisfied_ = numberUnsatisfied;
     4372        if (numberUnsatisfied) {
     4373          best = choose->candidates()[0];
     4374          choose->setBestObjectIndex(best);
     4375        }
     4376      }
     4377    } else {
     4378      // carry on with strong branching or whatever
     4379      int returnCode = choose->chooseVariable(solver, usefulInfo,true);
     4380      // update number of strong iterations etc
     4381      model->incrementStrongInfo(choose->numberStrongDone(),choose->numberStrongIterations(),
     4382                                 returnCode==-1 ? 0:choose->numberStrongFixed(),returnCode==-1);
     4383      if (returnCode>1) {
     4384        // has fixed some
     4385        returnStatus=-1;
     4386      } else if (returnCode==-1) {
     4387        // infeasible
     4388        returnStatus=-2;
     4389      } else if (returnCode==0) {
     4390        // normal
     4391        returnStatus=0;
     4392        numberUnsatisfied=1;
     4393      } else {
     4394        // ones on list satisfied - double check
     4395        numberUnsatisfied = choose->setupList(usefulInfo, false);
     4396        numberUnsatisfied_ = numberUnsatisfied;
     4397        if (numberUnsatisfied) {
     4398          best = choose->candidates()[0];
     4399          choose->setBestObjectIndex(best);
     4400        }
     4401      }
     4402    }
     4403  }
     4404  delete branch_;
     4405  branch_ = NULL;
     4406  guessedObjectiveValue_ = objectiveValue_; // for now
     4407  if (!returnStatus) {
     4408    if (numberUnsatisfied) {
     4409      // create branching object
     4410      const OsiObject * obj = model->solver()->object(choose->bestObjectIndex());
     4411      //const OsiSolverInterface * solver = usefulInfo->solver_;
     4412      branch_ = obj->createBranch(model->solver(),usefulInfo,obj->whichWay());
     4413    }
     4414  }
     4415  usefulInfo->solution_=saveInfoSol;
     4416  delete [] saveSolution;
     4417  // may have got solution
     4418  if (choose->goodSolution()
     4419      &&model->problemFeasibility()->feasible(model,-1)>=0) {
     4420    // yes
     4421    double objValue = choose->goodObjectiveValue();
     4422    model->setBestSolution(CBC_STRONGSOL,
     4423                                     objValue,
     4424                                     choose->goodSolution()) ;
     4425    model->setLastHeuristic(NULL);
     4426    model->incrementUsed(choose->goodSolution());
     4427    choose->clearGoodSolution();
     4428  }
     4429  return returnStatus;
     4430}
Note: See TracChangeset for help on using the changeset viewer.