Changeset 2094 for trunk/Cbc/src


Ignore:
Timestamp:
Nov 18, 2014 6:15:36 AM (5 years ago)
Author:
forrest
Message:

for memory leaks and heuristics and some experimental stuff

Location:
trunk/Cbc/src
Files:
27 edited

Legend:

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

    r1899 r2094  
    4444        : CbcObject(model)
    4545{
    46     id_ = identifier;
    4746    numberMembers_ = numberMembers;
     47    int * backward = NULL;
     48    if (identifier<0) {
     49      // which are variables in model - not in integers
     50      identifier=-identifier;
     51      int numberColumns = model->getNumCols();
     52      int numberIntegers = model->numberIntegers();
     53      const int * integerVariable = model->integerVariable();
     54      backward = new int [numberColumns];
     55      for (int i=0;i<numberColumns;i++)
     56        backward[i]=-1;
     57      for (int i=0;i<numberIntegers;i++) {
     58        backward[integerVariable[i]]=i;
     59      }
     60    }
    4861    if (numberMembers_) {
    4962        members_ = new int[numberMembers_];
    5063        memcpy(members_, which, numberMembers_*sizeof(int));
     64        if (backward) {
     65          for (int i=0;i<numberMembers_;i++) {
     66            int iColumn = which[i];
     67            iColumn = backward[iColumn];
     68            assert (iColumn>=0);
     69            members_[i]=iColumn;
     70#ifdef FULL_PRINT
     71            printf("%d column %d member %d\n",i,which[i],iColumn);
     72#endif
     73          }
     74        }
    5175        type_ = new char[numberMembers_];
    5276        if (type) {
     
    6892    cliqueType_ = cliqueType;
    6993    slack_ = slack;
     94    delete [] backward;
     95    id_ = identifier;
    7096}
    7197
     
    283309    const int * integer = model_->integerVariable();
    284310    //OsiSolverInterface * solver = model_->solver();
     311    CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart()) ;
    285312    const double * solution = model_->testSolution();
    286313    const double * lower = solver->getColLower();
     
    312339        } else if (upper[iColumn] > lower[iColumn]) {
    313340            upList[--numberFree] = j;
     341            sort[numberFree] = 0.0;
     342            if (basis && basis->getStructStatus(iColumn) == CoinWarmStartBasis::basic)
     343              sort[numberFree] = -1.0;
     344             
    314345        }
    315346    }
     
    318349        // sort
    319350        CoinSort_2(sort, sort + numberUnsatis, upList);
     351        // also try and spread out satisfied basic
     352        CoinSort_2(sort+numberFree, sort + numberMembers_, upList+numberFree);
    320353        // put first in up etc
    321354        int kWay = 1;
     
    459492#endif
    460493                    // fix weak way
    461                     if (clique_->type(i + 32*iWord))
     494                    if (clique_->type(i + 32*iWord)) {
     495#ifdef FULL_PRINT
     496                      printf("member %d int %d matcol %d bound %g %g to 0.0\n",
     497                             i,iColumn,integerVariables[iColumn],
     498                             model_->solver()->getColLower()[integerVariables[iColumn]],
     499                             model_->solver()->getColUpper()[integerVariables[iColumn]]);
     500#endif
    462501                        model_->solver()->setColUpper(integerVariables[iColumn], 0.0);
    463                     else
     502                    } else {
     503#ifdef FULL_PRINT
     504                      printf("member %d int %d matcol %d bound %g %g to 1.0\n",
     505                             i,iColumn,integerVariables[iColumn],
     506                             model_->solver()->getColLower()[integerVariables[iColumn]],
     507                             model_->solver()->getColUpper()[integerVariables[iColumn]]);
     508#endif
    464509                        model_->solver()->setColLower(integerVariables[iColumn], 1.0);
     510                    }
    465511                }
    466512            }
     
    481527#endif
    482528                    // fix weak way
    483                     if (clique_->type(i + 32*iWord))
     529                    if (clique_->type(i + 32*iWord)) {
     530#ifdef FULL_PRINT
     531                      printf("member %d int %d matcol %d bound %g %g to 0.0\n",
     532                             i,iColumn,integerVariables[iColumn],
     533                             model_->solver()->getColLower()[integerVariables[iColumn]],
     534                             model_->solver()->getColUpper()[integerVariables[iColumn]]);
     535#endif
    484536                        model_->solver()->setColUpper(integerVariables[iColumn], 0.0);
    485                     else
     537                    } else {
     538#ifdef FULL_PRINT
     539                      printf("member %d int %d matcol %d bound %g %g to 1.0\n",
     540                             i,iColumn,integerVariables[iColumn],
     541                             model_->solver()->getColLower()[integerVariables[iColumn]],
     542                             model_->solver()->getColUpper()[integerVariables[iColumn]]);
     543#endif
    486544                        model_->solver()->setColLower(integerVariables[iColumn], 1.0);
     545                    }
    487546                }
    488547            }
  • trunk/Cbc/src/CbcCountRowCut.cpp

    r1877 r2094  
    365365    ipos=k;
    366366  }
    367   delete cut;
     367  hash_[ipos].index=-1;
    368368  // move last to found
    369369  numberCuts_--;
    370   if (numberCuts_) {
     370  assert (found==numberCuts_); // debug when fails
     371  if (numberCuts_&&found<numberCuts_) {
    371372    ipos = hashCut(*rowCut_[numberCuts_],hashSize);
    372373    while ( true ) {
     
    375376        int k = hash_[ipos].next;
    376377        ipos = k;
     378        assert (ipos>=0);
    377379      } else {
    378380        // change
     
    384386    }
    385387  }
    386   assert (!rowCut_[numberCuts_]);
     388  delete cut;
     389  rowCut_[numberCuts_]=NULL;
     390  //assert (!rowCut_[numberCuts_-1]);
     391}
     392// Truncate
     393void
     394CbcRowCuts::truncate(int numberAfter)
     395{
     396  if (numberAfter<0||numberAfter>=numberCuts_)
     397    return;
     398  for (int i=numberAfter;i<numberCuts_;i++) {
     399    delete rowCut_[i];
     400    rowCut_[i]=NULL;
     401  }
     402  numberCuts_=numberAfter;
     403  int hashSize= size_*hashMultiplier_;
     404  for (int i=0;i<hashSize;i++) {
     405    hash_[i].index=-1;
     406    hash_[i].next=-1;
     407  }
     408  OsiRowCut2 ** temp = new  OsiRowCut2 * [size_];
     409  lastHash_=-1;
     410  for (int i=0;i<numberCuts_;i++) {
     411    temp[i]=rowCut_[i];
     412    int ipos = hashCut(*temp[i],hashSize);
     413    int found = -1;
     414    int jpos=ipos;
     415    while ( true ) {
     416      int j1 = hash_[ipos].index;
     417      if ( j1 >= 0 ) {
     418        if ( !same(*temp[i],*temp[j1]) ) {
     419          int k = hash_[ipos].next;
     420          if ( k != -1 )
     421            ipos = k;
     422          else
     423            break;
     424        } else {
     425          found = j1;
     426          break;
     427        }
     428      } else {
     429        break;
     430      }
     431    }
     432    if (found<0) {
     433      assert (hash_[ipos].next==-1);
     434      if (ipos==jpos) {
     435        // first
     436        hash_[ipos].index=i;
     437      } else {
     438        // find next space
     439        while ( true ) {
     440          ++lastHash_;
     441          assert (lastHash_<hashSize);
     442          if ( hash_[lastHash_].index == -1 )
     443            break;
     444        }
     445        hash_[ipos].next = lastHash_;
     446        hash_[lastHash_].index = i;
     447      }
     448    }
     449  }
     450  delete [] rowCut_;
     451  rowCut_ = temp;
    387452}
    388453// Return 0 if added, 1 if not, -1 if not added because of space
     
    391456{
    392457  int hashSize= size_*hashMultiplier_;
     458  bool globallyValid=cut.globallyValid();
    393459  if (numberCuts_==size_) {
    394460    size_ = 2*size_+100;
     
    401467      hash_[i].next=-1;
    402468    }
     469    lastHash_=-1;
    403470    for (int i=0;i<numberCuts_;i++) {
    404471      temp[i]=rowCut_[i];
     
    507574      newCutPtr->setUb(newUb);
    508575      newCutPtr->setRow(vector);
     576      newCutPtr->setGloballyValid(globallyValid);
    509577      rowCut_[numberCuts_++]=newCutPtr;
     578      //printf("addedGlobalCut of size %d to %x - cuts size %d\n",
     579      //     cut.row().getNumElements(),this,numberCuts_);
    510580      return 0;
    511581    } else {
     
    531601      hash_[i].next=-1;
    532602    }
     603    lastHash_=-1;
    533604    for (int i=0;i<numberCuts_;i++) {
    534605      temp[i]=rowCut_[i];
     
    638709      newCutPtr->setRow(vector);
    639710      rowCut_[numberCuts_++]=newCutPtr;
     711      printf("addedGreedyGlobalCut of size %d to %x - cuts size %d\n",
     712             cut.row().getNumElements(),this,numberCuts_);
    640713      return 0;
    641714    } else {
  • trunk/Cbc/src/CbcCountRowCut.hpp

    r1839 r2094  
    125125   The whichRow_ field in OsiRowCut2 is used for a type
    126126   0 - normal
    127    1 - processed cut
     127   1 - processed cut (conflict)
    128128   2 - unprocessed cut i.e. dual ray computation
    129129*/
     
    154154  // Add in cuts as normal cuts (and delete)
    155155  void addCuts(OsiCuts & cs);
     156  // Truncate
     157  void truncate(int numberAfter);
    156158private:
    157159  OsiRowCut2 ** rowCut_;
  • trunk/Cbc/src/CbcCutGenerator.cpp

    r1880 r2094  
    175175{
    176176    model_ = model;
    177     generator_->refreshSolver(model_->solver());
     177    // added test - helps if generator not thread safe
     178    if (whenCutGenerator_!=-100)
     179      generator_->refreshSolver(model_->solver());
    178180}
    179181/* Generate cuts for the model data contained in si.
  • trunk/Cbc/src/CbcHeuristic.cpp

    r2093 r2094  
    13241324                      clpSolver->zapDebugger();
    13251325#endif
     1326#ifdef CONFLICT_CUTS
     1327                    if ((model_->moreSpecialOptions()&4194304)!=0)
     1328                      model.zapGlobalCuts();
     1329#endif
    13261330                    model.branchAndBound();
    13271331                    model_->setHeuristicModel(NULL);
     
    17521756    up_ = NULL;
    17531757    equal_ = NULL;
    1754     //whereFrom_ |= 16; // allow more often
     1758    //whereFrom_ |= 16*(1+256); // allow more often
    17551759}
    17561760
     
    17701774    equal_ = NULL;
    17711775    seed_ = 7654321;
    1772     //whereFrom_ |= 16; // allow more often
     1776    //whereFrom_ |= 16*(1+256); // allow more often
    17731777}
    17741778
     
    18591863    validate();
    18601864}
     1865/* Check whether the heuristic should run at all
     1866   0 - before cuts at root node (or from doHeuristics)
     1867   1 - during cuts at root
     1868   2 - after root node cuts
     1869   3 - after cuts at other nodes
     1870   4 - during cuts at other nodes
     1871   8 added if previous heuristic in loop found solution
     1872*/
     1873bool
     1874CbcRounding::shouldHeurRun(int whereFrom)
     1875{
     1876  if (whereFrom!=4) {
     1877    return CbcHeuristic::shouldHeurRun(whereFrom);
     1878  } else {
     1879    numCouldRun_++;
     1880    return shouldHeurRun_randomChoice();
     1881  }
     1882}
    18611883// See if rounding will give solution
    18621884// Sets value of solution
     
    18761898        return 0; // switched off
    18771899    numRuns_++;
     1900#ifdef HEURISTIC_INFORM
     1901    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     1902           heuristicName(),numRuns_,numCouldRun_,when_);
     1903#endif
    18781904    OsiSolverInterface * solver = model_->solver();
    18791905    double direction = solver->getObjSense();
     
    27742800    if (fixPriority_ < 0)
    27752801        return 0; // switched off
     2802#ifdef HEURISTIC_INFORM
     2803    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     2804           heuristicName(),numRuns_,numCouldRun_,when_);
     2805#endif
    27762806    const double * hotstartSolution = model_->hotstartSolution();
    27772807    const int * hotstartPriorities = model_->hotstartPriorities();
     
    29132943    if (!model_)
    29142944        return 0;
     2945#ifdef HEURISTIC_INFORM
     2946    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     2947           heuristicName(),numRuns_,numCouldRun_,when_);
     2948#endif
    29152949    if (!inputSolution_) {
    29162950        // get information on solver type
  • trunk/Cbc/src/CbcHeuristic.hpp

    r2093 r2094  
    460460        seed_ = value;
    461461    }
     462    /** Check whether the heuristic should run at all
     463        0 - before cuts at root node (or from doHeuristics)
     464        1 - during cuts at root
     465        2 - after root node cuts
     466        3 - after cuts at other nodes
     467        4 - during cuts at other nodes
     468            8 added if previous heuristic in loop found solution
     469    */
     470    virtual bool shouldHeurRun(int whereFrom);
    462471
    463472protected:
  • trunk/Cbc/src/CbcHeuristicDINS.cpp

    r2093 r2094  
    168168    if (!bestSolution)
    169169        return 0; // No solution found yet
     170#ifdef HEURISTIC_INFORM
     171    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     172           heuristicName(),numRuns_,numCouldRun_,when_);
     173#endif
    170174    if (numberSolutions_ < model_->getSolutionCount()) {
    171175        // new solution - add info
  • trunk/Cbc/src/CbcHeuristicDW.cpp

    r1957 r2094  
    333333  if (numberBlocks_<3)
    334334    return 0; // no point
     335#ifdef HEURISTIC_INFORM
     336    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     337           heuristicName(),numRuns_,numCouldRun_,when_);
     338#endif
    335339  if (bestSolutionIn&&objectiveValue(bestSolutionIn)<bestObjective_-1.0e-5)
    336340    passInSolution(bestSolutionIn);
  • trunk/Cbc/src/CbcHeuristicDive.cpp

    r2093 r2094  
    2424//#define DIVE_DEBUG
    2525#ifdef DIVE_DEBUG
    26 #define DIVE_PRINT
    27 #endif
    28 #undef DIVE_PRINT
     26#define DIVE_PRINT=2
     27#endif
    2928
    3029// Default Constructor
     
    273272                           double * newSolution)
    274273{
    275 #ifdef DIVE_PRINT
     274#if DIVE_PRINT
    276275    int nRoundInfeasible = 0;
    277276    int nRoundFeasible = 0;
     
    441440            }
    442441            if (direction*(solver->getObjValue() + delta) < solutionValue) {
    443 #ifdef DIVE_PRINT
     442#if DIVE_PRINT
    444443                nRoundFeasible++;
    445444#endif
     
    488487                }
    489488            }
    490 #ifdef DIVE_PRINT
     489#if DIVE_PRINT
    491490            else
    492491                nRoundInfeasible++;
     
    495494
    496495        // do reduced cost fixing
    497 #ifdef DIVE_PRINT
     496#if DIVE_PRINT>1
    498497        numberReducedCostFixed = reducedCostFix(solver);
    499498#else
     
    772771            model_->setSpecialOptions(saveModelOptions | 2048);
    773772            solver->resolve();
    774 #ifdef DIVE_PRINT
     773            numberSimplexIterations += solver->getIterationCount();
     774#if DIVE_PRINT>1
    775775            int numberFractionalVariables = 0;
    776776            double sumFractionalVariables=0.0;
     
    833833            model_->setSpecialOptions(saveModelOptions);
    834834            if (!solver->isAbandoned()&&!solver->isIterationLimitReached()) {
    835                 numberSimplexIterations += solver->getIterationCount();
     835              //numberSimplexIterations += solver->getIterationCount();
    836836            } else {
    837837                numberSimplexIterations = maxSimplexIterations + 1;
     
    902902            reasonToStop += 4;
    903903            // also switch off
    904 #ifdef DIVE_PRINT
     904#if DIVE_PRINT
    905905            printf("switching off diving as too many iterations %d, %d allowed\n",
    906906                   numberSimplexIterations, maxSimplexIterations);
     
    910910            reasonToStop += 5;
    911911            // also switch off
    912 #ifdef DIVE_PRINT
     912#if DIVE_PRINT
    913913            printf("switching off diving one iteration took %d iterations (total %d)\n",
    914914                   solver->getIterationCount(), numberSimplexIterations);
     
    980980        // was good at start! - create fake
    981981        clpSolver->resolve();
     982        numberSimplexIterations += clpSolver->getIterationCount();
    982983        ClpSimplex * simplex = clpSolver->getModelPtr();
    983984        CbcSubProblem * sub =
     
    10761077    }
    10771078
    1078 #ifdef DIVE_PRINT
    1079     std::cout << "nRoundInfeasible = " << nRoundInfeasible
     1079#if DIVE_PRINT
     1080    std::cout << heuristicName_
     1081              << " nRoundInfeasible = " << nRoundInfeasible
    10801082              << ", nRoundFeasible = " << nRoundFeasible
    10811083              << ", returnCode = " << returnCode
     
    11201122        return 0; // switched off
    11211123#endif
     1124#ifdef HEURISTIC_INFORM
     1125    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     1126           heuristicName(),numRuns_,numCouldRun_,when_);
     1127#endif
    11221128#ifdef DIVE_DEBUG
    11231129    std::cout << "solutionValue = " << solutionValue << std::endl;
     
    11251131    // Get solution array for heuristic solution
    11261132    int numberColumns = model_->solver()->getNumCols();
    1127     double * newSolution = new double [numberColumns];
     1133    double * newSolution = CoinCopyOfArray(model_->solver()->getColSolution(),
     1134                                           numberColumns);
    11281135    int numberCuts=0;
    11291136    int numberNodes=-1;
  • trunk/Cbc/src/CbcHeuristicDiveCoefficient.cpp

    r2093 r2094  
    1818        : CbcHeuristicDive()
    1919{
     20  whereFrom_ |= 16*(1+256);
    2021}
    2122
     
    2425        : CbcHeuristicDive(model)
    2526{
     27  whereFrom_ |= 16*(1+256);
    2628}
    2729
  • trunk/Cbc/src/CbcHeuristicFPump.cpp

    r2093 r2094  
    240240    if (!when() || (when() == 1 && model_->phase() != 1))
    241241        return 0; // switched off
     242#ifdef HEURISTIC_INFORM
     243    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     244           heuristicName(),numRuns_,numCouldRun_,when_);
     245#endif
    242246    // See if at root node
    243247    bool atRoot = model_->getNodeCount() == 0;
     
    21232127                            if (nFixed*3 > numberColumns*2)
    21242128                                simplex->allSlackBasis(); // may as well go from all slack
     2129                            int logLevel=simplex->logLevel();
     2130                            if (logLevel<=1)
     2131                              simplex->setLogLevel(0);
    21252132                            simplex->primal(1);
     2133                            simplex->setLogLevel(logLevel);
    21262134                            clpSolver->setWarmStart(NULL);
    21272135                        }
  • trunk/Cbc/src/CbcHeuristicGreedy.cpp

    r2093 r2094  
    118118    if (model_->getNodeCount() > numberTimes_)
    119119        return 0;
     120#ifdef HEURISTIC_INFORM
     121    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     122           heuristicName(),numRuns_,numCouldRun_,when_);
     123#endif
    120124    // See if at root node
    121125    bool atRoot = model_->getNodeCount() == 0;
  • trunk/Cbc/src/CbcHeuristicLocal.cpp

    r2093 r2094  
    373373    if (nodeCount<lastRunDeep_+skip )
    374374      return 0;
     375#ifdef HEURISTIC_INFORM
     376    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     377           heuristicName(),numRuns_,numCouldRun_,when_);
     378#endif
    375379    lastRunDeep_ = nodeCount;
    376380    howOftenShallow_ = numberSolutions_;
  • trunk/Cbc/src/CbcHeuristicPivotAndFix.cpp

    r1899 r2094  
    9292    std::cout << "Entering Pivot-and-Fix Heuristic" << std::endl;
    9393
     94#ifdef HEURISTIC_INFORM
     95    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     96           heuristicName(),numRuns_,numCouldRun_,when_);
     97#endif
    9498#ifdef FORNOW
    9599    std::cout << "Lucky you! You're in the Pivot-and-Fix Heuristic" << std::endl;
  • trunk/Cbc/src/CbcHeuristicRENS.cpp

    r1899 r2094  
    9090        return 0;
    9191    numberTries_++;
     92#ifdef HEURISTIC_INFORM
     93    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     94           heuristicName(),numRuns_,numCouldRun_,when_);
     95#endif
    9296    double saveFractionSmall=fractionSmall_;
    9397    OsiSolverInterface * solver = model_->solver();
  • trunk/Cbc/src/CbcHeuristicRINS.cpp

    r2093 r2094  
    158158    if (!bestSolution)
    159159        return 0; // No solution found yet
     160#ifdef HEURISTIC_INFORM
     161    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     162           heuristicName(),numRuns_,numCouldRun_,when_);
     163#endif
    160164    if (numberSolutions_ < model_->getSolutionCount()) {
    161165        // new solution - add info
  • trunk/Cbc/src/CbcHeuristicRandRound.cpp

    r2093 r2094  
    124124    double start = CoinCpuTime();
    125125    numCouldRun_++; //
     126#ifdef HEURISTIC_INFORM
     127    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     128           heuristicName(),numRuns_,numCouldRun_,when_);
     129#endif
    126130    // Todo: Ask JJHF what "number of times
    127131    // the heuristic could run" means.
  • trunk/Cbc/src/CbcHeuristicVND.cpp

    r2093 r2094  
    168168    if (!bestSolution)
    169169        return 0; // No solution found yet
     170#ifdef HEURISTIC_INFORM
     171    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
     172           heuristicName(),numRuns_,numCouldRun_,when_);
     173#endif
    170174    if (numberSolutions_ < model_->getSolutionCount()) {
    171175        // new solution - add info
  • trunk/Cbc/src/CbcMessage.cpp

    r1943 r2094  
    5757    {CBC_FPUMP1, 38, 1, "%s"},
    5858    {CBC_FPUMP2, 39, 2, "%s"},
    59     {CBC_STATUS3, 40, 1, "%d nodes (+%d), %d on tree, best %g - possible %g depth %d unsat %d its %d (+%d) (%.2f seconds)"},
    60     {CBC_OTHER_STATS2, 41, 1, "Maximum depth %d, %g variables fixed on reduced cost (%d nodes in complete fathoming taking %d iterations)"},
     59    {CBC_STATUS3, 40, 1, "%d nodes (+%d/%d), %d on tree, best %g - possible %g depth %d unsat %d its %d (+%d) (%.2f seconds)"},
     60    {CBC_OTHER_STATS2, 41, 1, "Maximum depth %d, %g variables fixed on reduced cost (complete fathoming %d times, %d nodes taking %d iterations)"},
    6161    {CBC_RELAXED1, 42, 1, "Possible objective of %.18g but variable %d is %g from integer value, integer tolerance %g"},
    6262    {CBC_RELAXED2, 43, 2, "Possible objective of %.18g but had to fudge solution with tolerance of %g - check scaling of problem?"},
  • trunk/Cbc/src/CbcModel.cpp

    r2092 r2094  
    448448        if (!numberContinuousObj && numberIntegerObj <= 5 && numberIntegerWeight <= 100 &&
    449449                numberIntegerObj*3 < numberObjects_ && !parentModel_ && solver_->getNumRows() > 100)
    450           iType = 1 + 4 + ((moreSpecialOptions_&536870912)==0) ? 2 : 0;
     450          iType = 1 + 4 + (((moreSpecialOptions_&536870912)==0) ? 2 : 0);
    451451        else if (!numberContinuousObj && numberIntegerObj <= 100 &&
    452452                 numberIntegerObj*5 < numberObjects_ && numberIntegerWeight <= 100 &&
    453453                 !parentModel_ &&
    454454                 solver_->getNumRows() > 100 && cost != -COIN_DBL_MAX)
    455           iType = 4 + ((moreSpecialOptions_&536870912)==0) ? 2 : 0;
     455          iType = 4 + (((moreSpecialOptions_&536870912)==0) ? 2 : 0);
    456456        else if (!numberContinuousObj && numberIntegerObj <= 100 &&
    457457                 numberIntegerObj*5 < numberObjects_ &&
     
    590590                   !numberContinuousObj &&
    591591                   !numberGeneralIntegerObj &&
    592                    numberIntegerObj*2 < numberColumns) {
     592                   numberIntegerObj*2 < CoinMin(numberColumns,20)) {
    593593            // up priorities on costed
    594594            int iPriority = -1;
     
    601601            }
    602602            if (iPriority >= 100) {
    603 #ifdef CLP_INVESTIGATE
     603#if CBC_USEFUL_PRINTING>1
    604604                printf("Setting variables with obj to high priority\n");
    605605#endif
     
    10911091        int numberColumns = getNumCols();
    10921092        if (tryNewSearch) {
    1093 #ifdef CLP_INVESTIGATE
     1093#if CBC_USEFUL_PRINTING>1
    10941094            printf("after %d nodes, cutoff %g - looking\n",
    10951095                   numberNodes_, getCutoff());
     
    12371237    int numberColumns = continuousSolver_->getNumCols();
    12381238    int numberRows = continuousSolver_->getNumRows();
     1239    int numberOriginalIntegers = numberIntegers_;
    12391240    int * del = new int [CoinMax(numberColumns, numberRows)];
    12401241    int * original = new int [numberColumns];
     
    12951296        if (continuousSolver_->isInteger(i))
    12961297            del[nDel++] = i;
     1298    }
     1299    {
     1300      // we must not exclude current best solution (rounding errors)
     1301      // also not if large values
     1302      const int * row = continuousSolver_->getMatrixByCol()->getIndices();
     1303      const CoinBigIndex * columnStart = continuousSolver_->getMatrixByCol()->getVectorStarts();
     1304      const int * columnLength = continuousSolver_->getMatrixByCol()->getVectorLengths();
     1305      const double * solution = continuousSolver_->getColSolution();
     1306      for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
     1307        if (!continuousSolver_->isInteger(iColumn)) {
     1308          double value = bestSolution_ ? bestSolution_[iColumn] : 0.0;
     1309          double value2 = solution[iColumn];
     1310          if (fabs(value-floor(value+0.5))>1.0e-8 ||
     1311              fabs(value2)>1.0e3) {
     1312            CoinBigIndex start = columnStart[iColumn];
     1313            CoinBigIndex end = start + columnLength[iColumn];
     1314            for (CoinBigIndex j = start; j < end; j++) {
     1315              int iRow = row[j];
     1316              possibleRow[iRow]=0;
     1317            }
     1318          }
     1319        }
     1320      }
    12971321    }
    12981322    int nExtra = 0;
     
    14471471            int n = clpSolver->getModelPtr()->findNetwork(rotate, 1.0);
    14481472            delete [] rotate;
    1449 #ifdef CLP_INVESTIGATE
     1473#if CBC_USEFUL_PRINTING>1
    14501474            printf("INTA network %d rows out of %d\n", n, numberRows);
    14511475#endif
     
    14551479                    if (!possibleRow[i]) {
    14561480                        couldBeNetwork = false;
    1457 #ifdef CLP_INVESTIGATE
     1481#if CBC_USEFUL_PRINTING>1
    14581482                        printf("but row %d is bad\n", i);
    14591483#endif
     
    15351559                assert(solver_->isInteger(i));
    15361560        }
    1537 #ifdef CLP_INVESTIGATE
     1561#if CBC_USEFUL_PRINTING>1
    15381562        if (couldBeNetwork || nExtra)
    15391563            printf("INTA %d extra integers, %d left%s\n", nExtra,
     
    15441568        convertToDynamic();
    15451569    }
    1546 #ifdef CLP_INVESTIGATE
     1570#if CBC_USEFUL_PRINTING>1
    15471571    if (!couldBeNetwork && copy1->getNumCols() &&
    15481572            copy1->getNumRows()) {
     
    15621586    // double check increment
    15631587    analyzeObjective();
     1588    // If any changes - tell code
     1589    if(numberOriginalIntegers<numberIntegers_)
     1590      synchronizeModel();
    15641591}
    15651592/**
     
    15751602*/
    15761603
     1604#ifdef CONFLICT_CUTS
     1605#if PRINT_CONFLICT==1
     1606static int numberConflictCuts=0;
     1607static int lastNumberConflictCuts=0;
     1608static double lengthConflictCuts=0.0;
     1609#endif
     1610#endif
    15771611/*
    15781612  The overall flow can be divided into three stages:
     
    19922026            ClpSimplex * clpSimplex = clpSolver->getModelPtr();
    19932027            if ((specialOptions_&32) == 0) {
    1994                 // take off names
    1995                 clpSimplex->dropNames();
     2028                // take off names (unless going to be saving)
     2029                if (numberAnalyzeIterations_>=0||(-numberAnalyzeIterations_&64)==0)
     2030                  clpSimplex->dropNames();
    19962031            }
    19972032            // no crunch if mostly continuous
     
    22272262        if (numberThreads_ > 0) {
    22282263            // switch off fast nodes for now
    2229             fastNodeDepth_ = -1;
     2264            //fastNodeDepth_ = -1;
    22302265        }
    22312266    }
     
    22892324      constraint system (aka the continuous system).
    22902325    */
     2326    delete continuousSolver_;
    22912327    continuousSolver_ = solver_->clone() ;
    22922328#ifdef COIN_HAS_NTY
     
    22962332      symmetryInfo_->setupSymmetry(*continuousSolver_);
    22972333      int numberGenerators = symmetryInfo_->statsOrbits(this,0);
    2298       if (!numberGenerators&&(moreSpecialOptions2_&(128|256))!=(128|256)) {
     2334      if (!symmetryInfo_->numberUsefulOrbits()&&(moreSpecialOptions2_&(128|256))!=(128|256)) {
    22992335        delete symmetryInfo_;
    23002336        symmetryInfo_=NULL;
     
    25882624        rootModels[i]->setSpecialOptions(specialOptions_ |(4194304|8388608));
    25892625        rootModels[i]->setMoreSpecialOptions(moreSpecialOptions_ &
    2590                                              (~134217728));
     2626                                             (~(134217728|4194304)));
    25912627        rootModels[i]->setMoreSpecialOptions2(moreSpecialOptions2_ &
    2592                                              (~128));
     2628                                              (~(128|256)));
    25932629        rootModels[i]->solver_->setWarmStart(basis);
    25942630#ifdef COIN_HAS_CLP
     
    26362672            simplex->primal();
    26372673#endif
     2674#endif
    26382675          }
    26392676#ifdef NEW_RANDOM_BASIS
     
    26422679#endif
    26432680        }
    2644 #endif
    26452681        for (int j=0;j<numberHeuristics_;j++)
    26462682          rootModels[i]->heuristic_[j]->setSeed(rootModels[i]->heuristic_[j]->getSeed()+100000000*i);
     
    35393575    //solverCharacteristics_->setSolver(solver_);
    35403576    if (feasible) {
     3577      // mark all cuts as globally valid
     3578      int numberCuts=cuts.sizeRowCuts();
     3579      for (int i=0;i<numberCuts;i++) {
     3580        cuts.rowCutPtr(i)->setGloballyValid();
     3581        whichGenerator_[i]=20000+(whichGenerator_[i]%10000);
     3582      }
    35413583#define HOTSTART -1
    35423584#if HOTSTART<0
     
    36373679                        }
    36383680                    }
    3639 #ifdef CLP_INVESTIGATE
     3681#if CBC_USEFUL_PRINTING>1
    36403682                    printf("%d forced, %d naturally at lower, %d at upper - %d zero dj\n",
    36413683                           nForced, nAtLbNatural, nAtUbNatural, nZeroDj);
     
    38593901        int numberPassesLeft = 1000;
    38603902        // This is first crude step
    3861         if (numberAnalyzeIterations_) {
     3903        if (numberAnalyzeIterations_ && !parentModel_) {
    38623904            delete [] analyzeResults_;
    3863             analyzeResults_ = new double [4*numberIntegers_];
     3905            int numberColumns = solver_->getNumCols();
     3906            analyzeResults_ = new double [5*numberIntegers_];
    38643907            numberFixedAtRoot_ = newNode->analyze(this, analyzeResults_);
    38653908            if (numberFixedAtRoot_ > 0) {
     
    38763919        }
    38773920        OsiSolverBranch * branches = NULL;
    3878         anyAction = chooseBranch(newNode, numberPassesLeft, NULL, cuts, resolved,
     3921        if (feasible)
     3922          anyAction = chooseBranch(newNode, numberPassesLeft, NULL, cuts, resolved,
    38793923                                 NULL, NULL, NULL, branches);
    38803924        if (anyAction == -2 || newNode->objectiveValue() >= cutoff) {
     
    39724016            }
    39734017            if (probingInfo_->packDown()) {
    3974 #ifdef CLP_INVESTIGATE
     4018#if CBC_USEFUL_PRINTING>1
    39754019                printf("%d implications on %d 0-1\n", toZero[number01], number01);
    39764020#endif
     
    39794023                addCutGenerator(&implication, 1, "ImplicationCuts", true, false, false, -200);
    39804024                generator_[numberCutGenerators_-1]->setGlobalCuts(true);
     4025                generator_[numberCutGenerators_-1]->setTiming(true);
    39814026            } else {
    39824027                delete probingInfo_;
     
    42134258                ClpSimplex * simplex = clpSolver->getModelPtr();
    42144259                int perturbation = simplex->perturbation();
    4215 #ifdef CLP_INVESTIGATE
     4260#if CBC_USEFUL_PRINTING>1
    42164261                printf("Testing its n,s %d %d solves n,s %d %d - pert %d\n",
    42174262                       numberIterations_, saveNumberIterations,
     
    42224267                    // switch off perturbation
    42234268                    simplex->setPerturbation(100);
    4224 #ifdef CLP_INVESTIGATE
     4269#if CBC_USEFUL_PRINTING>1
    42254270                    printf("Perturbation switched off\n");
    42264271#endif
     
    42364281                int numberColumns = getNumCols();
    42374282                if (tryNewSearch) {
    4238                     checkCutoffForRestart = getCutoff() ;
    4239 #ifdef CLP_INVESTIGATE
     4283                    // adding increment back allows current best - tiny bit weaker
     4284                    checkCutoffForRestart = getCutoff() + getCutoffIncrement() ;
     4285#if CBC_USEFUL_PRINTING>1
    42404286                    printf("after %d nodes, cutoff %g - looking\n",
    42414287                           numberNodes_, getCutoff());
     
    43144360                        tryNewSearch = false;
    43154361                }
     4362#ifdef CONFLICT_CUTS
     4363                // temporary
     4364                if ((moreSpecialOptions_&4194304)!=0)
     4365                  tryNewSearch=false;
     4366#endif
    43164367                if (tryNewSearch) {
    43174368                    // back to solver without cuts?
     
    44464497                            break;
    44474498                        }
     4499                        // add as global cut
     4500                        objLower[i]=-COIN_DBL_MAX;
     4501                        OsiRowCut rc;
     4502                        rc.setLb(newLower[i]);
     4503                        rc.setUb(COIN_DBL_MAX);
     4504                        double one=1.0;
     4505                        rc.setRow(1,integerVariable_+i,&one,false);
     4506                        rc.setGloballyValidAsInteger(2);
     4507                        globalCuts_.addCutIfNotDuplicate(rc) ;
    44484508                    } else if (objUpper[i] > newCutoff) {
    44494509                        n++;
     4510                        // add as global cut
     4511                        objUpper[i]=-COIN_DBL_MAX;
     4512                        OsiRowCut rc;
     4513                        rc.setLb(-COIN_DBL_MAX);
     4514                        rc.setUb(newUpper[i]);
     4515                        double one=1.0;
     4516                        rc.setRow(1,integerVariable_+i,&one,false);
     4517                        rc.setGloballyValidAsInteger(2);
     4518                        globalCuts_.addCutIfNotDuplicate(rc) ;
    44504519                    }
    44514520                }
     
    45364605#endif
    45374606            unlockThread();
    4538 #ifdef CLP_INVESTIGATE
     4607#if CBC_USEFUL_PRINTING>1
    45394608            if (getCutoff() < 1.0e20) {
    45404609                if (fabs(getCutoff() - (bestObjective_ - getCutoffIncrement())) > 1.0e-6 &&
     
    45664635            } else {
    45674636                messageHandler()->message(CBC_STATUS3, messages())
    4568                 << numberNodes_ << numberExtraNodes_ << nNodes << bestObjective_ << bestPossibleObjective_
     4637                << numberNodes_ << numberFathoms_ << numberExtraNodes_ << nNodes
     4638                << bestObjective_ << bestPossibleObjective_
    45694639                << tree_->lastDepth() << tree_->lastUnsatisfied() << numberIterations_ << numberExtraIterations_
    45704640                << getCurrentSeconds()
     
    45744644            if (symmetryInfo_)
    45754645              symmetryInfo_->statsOrbits(this,1);
     4646#endif
     4647#if PRINT_CONFLICT==1
     4648            if (numberConflictCuts>lastNumberConflictCuts) {
     4649              double length = lengthConflictCuts/numberConflictCuts;
     4650              printf("%d new conflict cuts - total %d - average length %g\n",
     4651                     numberConflictCuts-lastNumberConflictCuts,
     4652                     numberConflictCuts,length);
     4653              lastNumberConflictCuts = numberConflictCuts;
     4654            }
    45764655#endif
    45774656            if (eventHandler && !eventHandler->event(CbcEventHandler::treeStatus)) {
     
    48014880        << CoinMessageEol ;
    48024881    }
     4882    if ((moreSpecialOptions_&4194304)!=0) {
     4883      // Conflict cuts
     4884      int numberCuts = globalCuts_.sizeRowCuts();
     4885      int nConflict=0;
     4886      double sizeConflict = 0.0;
     4887      for (int i=0;i<numberCuts;i++) {
     4888        OsiRowCut2 * cut = globalCuts_.cut(i);
     4889        if (cut->whichRow()==1) {
     4890          nConflict++;
     4891          sizeConflict += cut->row().getNumElements();
     4892        }
     4893      }
     4894      if (nConflict) {
     4895        sizeConflict /= nConflict;
     4896        char general[200];
     4897        sprintf(general, "%d conflict cuts generated - average length %g",
     4898                nConflict,sizeConflict);
     4899        messageHandler()->message(CBC_GENERAL,
     4900                                  messages())
     4901          << general << CoinMessageEol ;
     4902      }
     4903    }
    48034904    if (numberStrongIterations_)
    48044905        handler_->message(CBC_STRONG_STATS, messages_)
     
    48124913        handler_->message(CBC_OTHER_STATS2, messages_)
    48134914        << maximumDepthActual_
    4814         << numberDJFixed_ << numberExtraNodes_ << numberExtraIterations_
     4915        << numberDJFixed_ << numberFathoms_ << numberExtraNodes_ << numberExtraIterations_
    48154916        << CoinMessageEol ;
    48164917#ifdef COIN_HAS_NTY
     
    53465447        numberExtraIterations_(0),
    53475448        numberExtraNodes_(0),
     5449        numberFathoms_(0),
    53485450        continuousObjective_(COIN_DBL_MAX),
    53495451        originalContinuousObjective_(COIN_DBL_MAX),
     
    53835485        numberThreads_(0),
    53845486        threadMode_(0),
     5487        numberGlobalCutsIn_(0),
    53855488        master_(NULL),
    53865489        masterThread_(NULL)
     
    55145617        numberExtraIterations_(0),
    55155618        numberExtraNodes_(0),
     5619        numberFathoms_(0),
    55165620        continuousObjective_(COIN_DBL_MAX),
    55175621        originalContinuousObjective_(COIN_DBL_MAX),
     
    55515655        numberThreads_(0),
    55525656        threadMode_(0),
     5657        numberGlobalCutsIn_(0),
    55535658        master_(NULL),
    55545659        masterThread_(NULL)
     
    56115716        // Space for current solution
    56125717        currentSolution_ = new double[numberColumns];
    5613         continuousSolution_ = new double[numberColumns];
     5718        continuousSolution_ = CoinCopyOfArray(solver_->getColSolution(),numberColumns);
    56145719        usedInSolution_ = new int[numberColumns];
    56155720        CoinZeroN(usedInSolution_, numberColumns);
     
    57995904        numberExtraIterations_(rhs.numberExtraIterations_),
    58005905        numberExtraNodes_(rhs.numberExtraNodes_),
     5906        numberFathoms_(rhs.numberFathoms_),
    58015907        continuousObjective_(rhs.continuousObjective_),
    58025908        originalContinuousObjective_(rhs.originalContinuousObjective_),
     
    58365942        numberThreads_(rhs.numberThreads_),
    58375943        threadMode_(rhs.threadMode_),
     5944        numberGlobalCutsIn_(rhs.numberGlobalCutsIn_),
    58385945        master_(NULL),
    58395946        masterThread_(NULL)
     
    59956102    // Space for current solution
    59966103    currentSolution_ = new double[numberColumns];
    5997     continuousSolution_ = new double[numberColumns];
     6104    continuousSolution_ = CoinCopyOfArray(solver_->getColSolution(),numberColumns);
    59986105    usedInSolution_ = new int[numberColumns];
    59996106    CoinZeroN(usedInSolution_, numberColumns);
     
    61136220            // Space for current solution
    61146221            currentSolution_ = new double[numberColumns];
    6115             continuousSolution_ = new double[numberColumns];
     6222            continuousSolution_ = CoinCopyOfArray(solver_->getColSolution(),numberColumns);
    61166223            usedInSolution_ = new int[numberColumns];
    61176224            CoinZeroN(usedInSolution_, numberColumns);
     
    61646271        numberExtraIterations_ = rhs.numberExtraIterations_;
    61656272        numberExtraNodes_ = rhs.numberExtraNodes_;
     6273        numberFathoms_ = rhs.numberFathoms_;
    61666274        continuousObjective_ = rhs.continuousObjective_;
    61676275        originalContinuousObjective_ = rhs.originalContinuousObjective_;
     
    62246332        numberThreads_ = rhs.numberThreads_;
    62256333        threadMode_ = rhs.threadMode_;
     6334        numberGlobalCutsIn_ = rhs.numberGlobalCutsIn_;
    62266335        delete master_;
    62276336        master_ = NULL;
     
    65786687    numberExtraIterations_ = 0;
    65796688    numberExtraNodes_ = 0;
     6689    numberFathoms_ = 0;
    65806690    continuousObjective_ = 0.0;
    65816691    originalContinuousObjective_ = 0.0;
     
    66366746    numberThreads_ = rhs.numberThreads_;
    66376747    threadMode_ = rhs.threadMode_;
     6748    numberGlobalCutsIn_ = rhs.numberGlobalCutsIn_;
    66386749    delete master_;
    66396750    master_ = NULL;
     
    71007211  descendants.
    71017212*/
    7102 int CbcModel::addCuts (CbcNode *node, CoinWarmStartBasis *&lastws, bool canFix)
     7213int CbcModel::addCuts (CbcNode *node, CoinWarmStartBasis *&lastws)
    71037214{
    71047215    /*
     
    71177228    double cutoff = getCutoff() ;
    71187229    int currentNumberCuts = currentNumberCuts_;
    7119     if (canFix) {
    7120         bool feasible = true;
    7121         const double *lower = solver_->getColLower() ;
    7122         const double *upper = solver_->getColUpper() ;
    7123         double * newLower = analyzeResults_;
    7124         double * objLower = newLower + numberIntegers_;
    7125         double * newUpper = objLower + numberIntegers_;
    7126         double * objUpper = newUpper + numberIntegers_;
    7127         int n = 0;
    7128         for (i = 0; i < numberIntegers_; i++) {
    7129             int iColumn = integerVariable_[i];
    7130             bool changed = false;
    7131             double lo = 0.0;
    7132             double up = 0.0;
    7133             if (objLower[i] > cutoff) {
    7134                 lo = lower[iColumn];
    7135                 up = upper[iColumn];
    7136                 if (lo < newLower[i]) {
    7137                     lo = newLower[i];
    7138                     solver_->setColLower(iColumn, lo);
    7139                     changed = true;
    7140                     n++;
    7141                 }
    7142                 if (objUpper[i] > cutoff) {
    7143                     if (up > newUpper[i]) {
    7144                         up = newUpper[i];
    7145                         solver_->setColUpper(iColumn, up);
    7146                         changed = true;
    7147                         n++;
    7148                     }
    7149                 }
    7150             } else if (objUpper[i] > cutoff) {
    7151                 lo = lower[iColumn];
    7152                 up = upper[iColumn];
    7153                 if (up > newUpper[i]) {
    7154                     up = newUpper[i];
    7155                     solver_->setColUpper(iColumn, up);
    7156                     changed = true;
    7157                     n++;
    7158                 }
    7159             }
    7160             if (changed && lo > up) {
    7161                 feasible = false;
    7162                 break;
    7163             }
    7164         }
    7165         if (!feasible) {
    7166           COIN_DETAIL_PRINT(printf("analysis says node infeas\n"));
    7167             cutoff = -COIN_DBL_MAX;
    7168         }
    7169     }
    71707230    /*
    71717231      If the node can't be fathomed by bound, reinstall tight cuts in the
     
    72107270                           numberRowsAtContinuous_ + numberToAdd);
    72117271#         endif
     7272                    whichGenerator_[numberToAdd] = whichGenerator_[i];
    72127273                    addCuts[numberToAdd++] = addedCuts_[i];
    72137274#if 1
     
    73377398                }
    73387399#endif
    7339                 //int n2=solver_->getNumRows();
    7340                 //for (int j=0;j<numberToAdd;j++)
    7341                 //addCuts[j]->print();
    73427400                solver_->applyRowCuts(numberToAdd, addCuts);
    7343                 //int n3=solver_->getNumRows();
    7344                 //printf("NBefore %d, after del %d, now %d\n",n1,n2,n3);
    73457401            }
    73467402#     ifdef CBC_CHECK_BASIS
     
    73497405            lastws->print();
    73507406#     endif
    7351             //for (i=0;i<numberToAdd;i++)
    7352             //delete addCuts[i];
    73537407            delete [] addCuts;
    73547408            delete [] cutsToDrop ;
     
    76617715    int returnCode = resolve(node ? node->nodeInfo() : NULL, 1);
    76627716    moreSpecialOptions_=save;
    7663 #ifdef CONFLICT_CUTS
     7717#ifdef CONFLICT_CUTS 
    76647718#ifdef COIN_HAS_CLP
    76657719    // if infeasible conflict analysis
    76667720    if (solver_->isProvenPrimalInfeasible()&&!parentModel_&&
    76677721        (moreSpecialOptions_&4194304)!=0&&clpSolver) {
    7668       //printf("infeasible - do conflict analysis\n");
     7722      if (!topOfTree_ && masterThread_)
     7723        topOfTree_ = masterThread_->master_->baseModel_->topOfTree_;
    76697724      assert (topOfTree_);
    7670       int iType=1;
     7725      int iType=0;
    76717726      OsiRowCut * cut = clpSolver->modelCut(topOfTree_->lower(),
    76727727                                            topOfTree_->upper(),
    76737728                                            numberRowsAtContinuous_,whichGenerator_,iType);
    76747729      if (cut) {
    7675         printf("XXXXXX cut\n");
    76767730        //cut->print();
    76777731        if (!iType) {
    7678           makeGlobalCut(cut) ;
     7732          int badCut = makeGlobalCut(cut) ;
     7733          if (!badCut) {
     7734#if PRINT_CONFLICT==1
     7735            numberConflictCuts++;
     7736            lengthConflictCuts += cut->row().getNumElements();
     7737#endif
     7738#if PRINT_CONFLICT<2
     7739            if (handler_->logLevel() > 1) {
     7740#endif
     7741              printf("Conflict cut at depth %d (%d elements)\n",
     7742                     currentDepth_,cut->row().getNumElements());
     7743              if (cut->row().getNumElements()<3)
     7744                cut->print();
     7745#if PRINT_CONFLICT<2
     7746            }
     7747#endif
     7748          }
    76797749          if ((specialOptions_&1) != 0) {
    76807750            debugger = continuousSolver_->getRowCutDebugger() ;
     
    79247994    if ( maximumSecondsReached() )
    79257995        numberTries = 0; // exit
     7996    if ((moreSpecialOptions2_&(2048|4096))!=0 && currentDepth_>5) {
     7997      // howOftenGlobalScan_ = 10;
     7998      int type = (moreSpecialOptions2_&(2048|4096))>>11;
     7999      if (type==1) {
     8000        int n=0;
     8001        int k=currentDepth_;
     8002        while (k) {
     8003          if ((k&1)!=0)
     8004            n++;
     8005          k = k >>1;
     8006        }
     8007        if (n>1)
     8008          numberTries=0;
     8009      } else if (type==2) {
     8010        if ((currentDepth_%4)!=0)
     8011          numberTries=0;
     8012      } else {
     8013        if ((currentDepth_%8)!=0)
     8014          numberTries=0;
     8015      }
     8016    }
    79268017    //if ((numberNodes_%100)==0)
    79278018    //printf("XXa sum obj changed by %g\n",sumChangeObjective1_);
     
    80838174                       thisCut->violated(cbcColSolution_)) ;
    80848175#endif
    8085                 whichGenerator_[numberViolated++] = -1;
     8176                whichGenerator_[numberViolated++] = 20099;
    80868177#ifndef GLOBAL_CUTS_JUST_POINTERS
    80878178                theseCuts.insert(*thisCut) ;
     
    81348225            if (clpSolver)
    81358226                clpSolver->setSpecialOptions(save);
    8136 #ifdef CLP_INVESTIGATE
     8227#if CBC_USEFUL_PRINTING>1
    81378228            if (clpSolver->getModelPtr()->numberIterations())
    81388229                printf("ITS %d pass %d\n",
     
    81688259            resizeWhichGenerator(numberViolated, numberViolated + 1);
    81698260            // set whichgenerator (also serves as marker to say don't delete0
    8170             whichGenerator_[numberViolated++] = -2;
     8261            whichGenerator_[numberViolated++] = 20098;
    81718262        }
    81728263
     
    82508341                    incrementUsed(newSolution);
    82518342                    lastHeuristic_ = heuristic_[found];
    8252 #ifdef CLP_INVESTIGATE
     8343#ifdef HEURISTIC_INFORM
    82538344                    printf("HEUR %s where %d A\n",
    82548345                           lastHeuristic_->heuristicName(), whereFrom);
     
    84208511            if (numberToAdd > 0) {
    84218512                int i ;
     8513                int * whichGenerator = whichGenerator_-
     8514                  numberRowsAtContinuous_+solver_->getNumRows();
    84228515                // Faster to add all at once
    84238516                addCuts = new const OsiRowCut * [numberToAdd] ;
    84248517                for (i = 0 ; i < numberToAdd ; i++) {
    84258518                    addCuts[i] = &theseCuts.rowCut(i) ;
     8519                    whichGenerator[i]=90;
    84268520                }
    84278521                if ((specialOptions_&262144) != 0 && !parentModel_) {
     
    85678661                            }
    85688662                        }
    8569 #ifdef CLP_INVESTIGATE2
     8663#if CBC_USEFUL_PRINTING>12
    85708664                        if (!parentModel_ && !numberNodes_)
    85718665                            printf("badObj %s nBad %d maxBad %d goodDrop %g minDrop %g thisDrop %g obj %g\n",
     
    85908684                    if (thisObj - lastObjective > drop[currentDepth_]*minimumDrop) {
    85918685                        numberTries++;
    8592 #ifdef CLP_INVESTIGATE
     8686#if CBC_USEFUL_PRINTING>1
    85938687                        //printf("drop %g %g %d\n",thisObj,lastObjective,currentPassNumber_);
    85948688#endif
     
    87048798
    87058799                    for (int i = numberGlobalBefore ; i < numberGlobalAfter ; i++) {
    8706                         whichGenerator_[numberNewCuts_++] = -1;
     8800                        whichGenerator_[numberNewCuts_++] = 20099;
    87078801#ifndef GLOBAL_CUTS_JUST_POINTERS
    87088802                        cuts.insert(*globalCuts_.rowCutPtr(i)) ;
     
    87878881                    incrementUsed(newSolution);
    87888882                    lastHeuristic_ = heuristic_[found];
    8789 #ifdef CLP_INVESTIGATE
     8883#ifdef HEURISTIC_INFORM
    87908884                    printf("HEUR %s where %d B\n",
    87918885                           lastHeuristic_->heuristicName(), whereFrom);
     
    89069000                bool smallProblem = size <= 550;
    89079001                smallProblem = false;
    8908 #ifdef CLP_INVESTIGATE
     9002#if CBC_USEFUL_PRINTING>1
    89099003                int maxPass = maximumCutPasses_;
    89109004#endif
     
    90039097                    whenCuts_ += 100000;
    90049098                //// end
    9005 #ifdef CLP_INVESTIGATE
     9099#if CBC_USEFUL_PRINTING>1
    90069100                printf("changing whenCuts from %d to %d and cutPasses from %d to %d objchange %g\n",
    90079101                       whenC, whenCuts_, maxPass, maximumCutPasses_, thisObjective - startObjective);
     
    90609154            if (numberColumns < 200)
    90619155                value = CoinMax(minimumDrop_, 0.1 * value);
    9062 #ifdef CLP_INVESTIGATE
     9156#if CBC_USEFUL_PRINTING>1
    90639157            printf("Minimum drop for cuts was %g, now is %g\n", minimumDrop_, value);
    90649158#endif
     
    90709164        for (i = 0; i < numberNewCuts_; i++) {
    90719165            int iGenerator = whichGenerator_[i];
     9166            assert (iGenerator>=0);
    90729167            if (iGenerator>=0)
    90739168              iGenerator=iGenerator%10000;
     
    94559550                for (i = 0; i < numberNewCuts_; i++) {
    94569551                    int iGenerator = whichGenerator_[i];
     9552#ifdef CONFLICT_CUTS
     9553                    assert (iGenerator>=0);
     9554#endif
    94579555                    if (iGenerator>=0)
    94589556                      iGenerator=iGenerator%10000;
    9459                     if (iGenerator >= 0)
     9557                    if (iGenerator >= 0 && iGenerator < numberCutGenerators_)
    94609558                        generator_[iGenerator]->incrementNumberCutsActive();
    94619559                }
     
    96199717            }
    96209718#endif
    9621             if (mustResolve || (specialOptions_&1) != 0) {
     9719            if (mustResolve /*|| (specialOptions_&1) != 0*/) {
    96229720                int returnCode = resolve(node ? node->nodeInfo() : NULL, 2);
    96239721                if (returnCode  == 0)
     
    96909788                break;
    96919789            }
    9692             whichGenerator_[numberBefore++] = i ;
     9790            whichGenerator_[numberBefore++] = i+20000 ;
    96939791            if (!numberNodes_||generator_[i]->globalCuts())
    96949792              whichGenerator_[numberBefore-1]=i+10000;
     
    97159813            for (; j < numberRowCutsAfter; j++) {
    97169814                const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ;
    9717                 whichGenerator_[numberBefore++] = i ;
     9815                whichGenerator_[numberBefore++] = i+20000 ;
    97189816                if (!numberNodes_||generator_[i]->globalCuts())
    97199817                  whichGenerator_[numberBefore-1]=i+10000;
     
    97669864                    printf("Old cut added - violation %g\n",
    97679865                           thisCut->violated(cbcColSolution_)) ;
    9768                 whichGenerator_[numberOld++] = -3;
     9866                whichGenerator_[numberOld++] = 20097;
    97699867                theseCuts.insert(*thisCut) ;
    97709868            }
     
    98409938        int numberOldToDelete = 0 ;
    98419939        int i ;
     9940        int kCut=0;
    98429941        ws = dynamic_cast<const CoinWarmStartBasis*>(solver_->getWarmStart()) ;
    98439942        /*
     
    98659964                        if (slackCut->effectiveness() != -1.234) {
    98669965                            slackCut->setEffectiveness(-1.234);
     9966                            slackCut->setGloballyValid();
    98679967                            saveCuts->insert(*slackCut);
    98689968                        }
     
    98739973                    oldCutIndex++ ;
    98749974                } else {
    9875                     oldCutIndex++ ;
     9975                    whichGenerator_[kCut++] = whichGenerator_[oldCutIndex] ;
     9976                    oldCutIndex++;
    98769977                }
    98779978            }
     
    98869987        */
    98879988        int firstNewCut = firstOldCut + numberOldActiveCuts_ ;
    9888         int k = 0 ;
    98899989        int nCuts = newCuts.sizeRowCuts();
    98909990        for (i = 0 ; i < nCuts ; i++) {
     
    98959995                newCutIndices[numberNewToDelete++] = i ;
    98969996            } else { // save which generator did it
    9897                 // -2 means branch cut! assert (whichGenerator_[i]!=-2); // ?? what if it is - memory leak?
    9898                 whichGenerator_[k++] = whichGenerator_[i] ;
     9997                // 20098 means branch cut! assert (whichGenerator_[i]!=20098); // ?? what if it is - memory leak?
     9998                whichGenerator_[kCut++] = whichGenerator_[i] ;
    98999999            }
    990010000        }
     
    992710027                if (slackCut->effectiveness() != -1.234) {
    992810028                    slackCut->setEffectiveness(-1.234);
     10029                    slackCut->setGloballyValid();
    992910030                    saveCuts->insert(slackCut);
    993010031                } else {
     
    997610077        }
    997710078    }
     10079   
    997810080    /*
    997910081      Clean up and return.
     
    999910101    cbc_resolve_check(solver_);
    1000010102#endif
     10103    bool onOptimalPath = false;
     10104    if ((specialOptions_&1) != 0) {
     10105      const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ;
     10106      if (debugger) {
     10107        onOptimalPath = true;
     10108        printf("On optimal path d\n") ;
     10109      }
     10110    }
    1000110111    // We may have deliberately added in violated cuts - check to avoid message
    1000210112    int iRow;
     
    1003110141    */
    1003210142    if (feasible) {
    10033         bool onOptimalPath = false;
    10034         if ((specialOptions_&1) != 0) {
    10035             const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ;
    10036             if (debugger) {
    10037                 onOptimalPath = true;
    10038                 printf("On optimal path d\n") ;
    10039             }
    10040         }
    1004110143        int nTightened = 0;
    1004210144#ifdef COIN_HAS_CLP
     
    1007610178                //double cutoff = getCutoff();
    1007710179                if (bestObjective_ - getCutoffIncrement() < testValue) {
    10078 #ifdef CLP_INVESTIGATE
     10180#if CBC_USEFUL_PRINTING>1
    1007910181                    double value ;
    1008010182                    solver_->getDblParam(OsiDualObjectiveLimit, value) ;
     
    1032410426        }
    1032510427    }
     10428#if 0
     10429    if ((specialOptions_&1) != 0 && onOptimalPath) {
     10430      const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ;
     10431      if (!debugger) {
     10432        // tighten did something???
     10433        solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     10434        solver_->writeMpsNative("infeas4.mps", NULL, NULL, 2);
     10435        printf("Not on optimalpath aaaa\n");
     10436        //abort();
     10437      } else {
     10438        printf("Still on optimal path\n");
     10439      }
     10440    }
     10441#endif
    1032610442    return returnStatus ;
    1032710443}
     
    1189412010
    1189512011{
     12012    int numberContinuousColumns=continuousSolver_->getNumCols();
    1189612013    if (!solverCharacteristics_->solutionAddsCuts()) {
    1189712014        // Can trust solution
     
    1197712094        memcpy(saveLower, getColLower(), numberColumns*sizeof(double));
    1197812095        //#define CLP_INVESTIGATE4
    11979 #ifdef CLP_INVESTIGATE4
     12096#if CBC_USEFUL_PRINTING>14
    1198012097        {
    1198112098          int nBad=checkAssociated(solver_,solver_->getColSolution(),1);
     
    1209712214        for (i = 0; i < numberObjects_; i++)
    1209812215            object_[i]->feasibleRegion(solver_, &usefulInfo);
    12099 #ifdef CLP_INVESTIGATE4
     12216#if CBC_USEFUL_PRINTING>14
    1210012217        {
    1210112218          int nBad=checkAssociated(solver_,solver_->getColSolution(),1);
     
    1229812415#endif
    1229912416                    solver_->initialSolve();
     12417                    //solver_->writeMps("bad");
    1230012418#ifdef COIN_HAS_CLP
    1230112419                    if (!solver_->isProvenOptimal()&&modifiedTolerances) {
     
    1236012478            int nNotNeeded = 0;
    1236112479#endif
    12362             for (iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
     12480            for (iColumn = 0 ; iColumn < numberContinuousColumns ; iColumn++) {
    1236312481                double value = solution[iColumn] ;
    1236412482                value = CoinMax(value, saveLower[iColumn]) ;
     
    1282412942                    objectiveValue = objectiveValue2;
    1282512943                }
    12826             } else {
     12944            } else if (!parentModel_) {
    1282712945              // not good
    12828               messageHandler()->message(CBC_GENERAL, messages())
     12946              messageHandler()->message(CBC_FPUMP2, messages())
    1282912947                << "On closer inspection - solution discarded"
    1283012948                << CoinMessageEol ;
     
    1370313821}
    1370413822// Make given cut into a global cut
    13705 void
     13823int
    1370613824CbcModel::makeGlobalCut(const OsiRowCut * cut)
    1370713825{
     13826  if (cut->row().getNumElements()>1-1) {
    1370813827    OsiRowCut newCut(*cut);
    1370913828    newCut.setGloballyValidAsInteger(2);
    1371013829    newCut.mutableRow().setTestForDuplicateIndex(false);
    13711     globalCuts_.addCutIfNotDuplicate(newCut) ;
     13830    return globalCuts_.addCutIfNotDuplicate(newCut,1) ;
     13831  } else {
     13832    assert (cut->row().getNumElements()==1);
     13833    int iColumn = cut->row().getIndices()[0];
     13834    double value = cut->row().getElements()[0];
     13835    double lb = cut->lb();
     13836    double ub = cut->ub();
     13837    if (value>0) {
     13838      if (lb>-COIN_DBL_MAX)
     13839        lb /= value;
     13840      if (ub<COIN_DBL_MAX)
     13841        ub /= value;
     13842    } else {
     13843      double saveUb=ub;
     13844      if (lb>-COIN_DBL_MAX)
     13845        ub = lb/value;
     13846      else
     13847        ub = COIN_DBL_MAX;
     13848      if (saveUb<COIN_DBL_MAX)
     13849        lb = saveUb/value;
     13850      else
     13851        lb =- COIN_DBL_MAX;
     13852    }
     13853#if PRINT_CONFLICT==0
     13854    if (handler_->logLevel() > 1) {
     13855#endif
     13856      printf("Conflict cut at depth %d (%d elements)\n",
     13857             currentDepth_,cut->row().getNumElements());
     13858      cut->print();
     13859#if PRINT_CONFLICT==0
     13860    }
     13861#endif
     13862    const double * lower;
     13863    const double * upper;
     13864    if (topOfTree_) {
     13865      lower = topOfTree_->lower();
     13866      upper = topOfTree_->upper();
     13867      lb = CoinMax(lb,lower[iColumn]);
     13868      topOfTree_->setColLower(iColumn,lb);
     13869      ub = CoinMin(ub,upper[iColumn]);
     13870      topOfTree_->setColUpper(iColumn,ub);
     13871    } else {
     13872      lower = solver_->getColLower();
     13873      upper = solver_->getColUpper();
     13874      lb = CoinMax(lb,lower[iColumn]);
     13875      solver_->setColLower(iColumn,lb);
     13876      ub = CoinMin(ub,upper[iColumn]);
     13877      solver_->setColUpper(iColumn,ub);
     13878    }
     13879    return 1;
     13880  }
    1371213881}
    1371313882// Make given cut into a global cut
    13714 void
     13883int
    1371513884CbcModel::makeGlobalCut(const OsiRowCut & cut)
    1371613885{
     
    1371813887    newCut.setGloballyValid(true);
    1371913888    newCut.mutableRow().setTestForDuplicateIndex(false);
    13720     globalCuts_.addCutIfNotDuplicate(newCut) ;
     13889    return globalCuts_.addCutIfNotDuplicate(newCut) ;
    1372113890}
    1372213891// Make given column cut into a global cut
     
    1372413893CbcModel::makeGlobalCut(const OsiColCut * cut)
    1372513894{
     13895  abort(); // need to think about top of tree
    1372613896  const double * lower;
    1372713897  const double * upper;
     
    1384214012  newCut.setLb(lo);
    1384314013  newCut.setRow(nConflict,column,values);
    13844   printf("CUTa has %d (started at %d) - final bSum %g\n",nConflict,nC,bSum);
     14014  printf("CUTa has %d (started at %d) - final bSum %g - depth %d\n",nConflict,nC,bSum,currentDepth_);
    1384514015  if (nConflict>1) {
    1384614016    if ((specialOptions_&1) != 0) {
     
    1392214092CbcModel::incrementUsed(const double * solution)
    1392314093{
    13924     // might as well mark all including continuous
    13925     int numberColumns = solver_->getNumCols();
    13926     for (int i = 0; i < numberColumns; i++) {
     14094    if(usedInSolution_) {
     14095      // might as well mark all including continuous
     14096      int numberColumns = solver_->getNumCols();
     14097      for (int i = 0; i < numberColumns; i++) {
    1392714098        if (solution[i])
    13928             usedInSolution_[i]++;
     14099          usedInSolution_[i]++;
     14100      }
    1392914101    }
    1393014102}
     
    1408814260                                   clpSimplex->largestPrimalError());
    1408914261            if (error > 1.0e-2 || !clpSolver->isProvenOptimal()) {
    14090 #ifdef CLP_INVESTIGATE
     14262#if CBC_USEFUL_PRINTING>1
    1409114263                printf("Problem was %s largest dual error %g largest primal %g - safer cuts\n",
    1409214264                       clpSolver->isProvenOptimal() ? "optimal" : "!infeasible",
     
    1412214294        }
    1412314295        clpSolver->setSpecialOptions(save2);
    14124 #ifdef CLP_INVESTIGATE
     14296#if CBC_USEFUL_PRINTING>1
    1412514297        if (clpSimplex->numberIterations() > 1000)
    1412614298            printf("node %d took %d iterations\n", numberNodes_, clpSimplex->numberIterations());
     
    1415914331                             clpSimplex->largestPrimalError());
    1416014332      if (error > 1.0e-2 || !clpSolver->isProvenOptimal()) {
    14161 #ifdef CLP_INVESTIGATE
     14333#if CBC_USEFUL_PRINTING>1
    1416214334        printf("Problem was %s largest dual error %g largest primal %g - safer cuts\n",
    1416314335               clpSolver->isProvenOptimal() ? "optimal" : "!infeasible",
     
    1419314365    }
    1419414366    clpSolver->setSpecialOptions(save2);
    14195 #ifdef CLP_INVESTIGATE
     14367#if CBC_USEFUL_PRINTING>1
    1419614368    if (clpSimplex->numberIterations() > 1000)
    1419714369      printf("node %d took %d iterations\n", numberNodes_, clpSimplex->numberIterations());
     
    1509015262            solver_->getDblParam(OsiObjOffset, offset);
    1509115263            solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
     15264            if (continuousSolver_&&solver_->getNumCols()>continuousSolver_->getNumCols()) {
     15265              solver_->setRowUpper(cutoffRowNumber_,floor(cutoff)+offset);
     15266              solver_->setRowLower(cutoffRowNumber_,floor(cutoff)+offset);
     15267            }
    1509215268          }
    1509315269        }
     
    1532615502                            //                            numberSolutions_++;
    1532715503                            numberHeuristicSolutions_++;
    15328 #ifdef CLP_INVESTIGATE
     15504#ifdef HEURISTIC_INFORM
    1532915505                            printf("HEUR %s where %d C\n",
    1533015506                                   lastHeuristic_->heuristicName(), whereFrom);
     
    1535615532                        } else {
    1535715533                            // NOT better solution
    15358 #ifdef CLP_INVESTIGATE
     15534#if CBC_USEFUL_PRINTING>1
    1535915535                            printf("HEUR %s where %d REJECTED i==%d\n",
    1536015536                                   heuristic_[i]->heuristicName(), whereFrom, i);
     
    1570915885    }
    1571015886    int save2 = maximumDepth_;
    15711     int retCode = addCuts(node, lastws, numberFixedNow_ > numberFixedAtRoot_);
     15887    int retCode = addCuts(node, lastws);
    1571215888#ifdef SWITCH_VARIABLES
    1571315889    fixAssociated(solver_,0);
     
    1596516141                        simplex->setMoreSpecialOptions(saveMoreOptions);
    1596616142                        simplex->setPerturbation(perturbation);
    15967                         numberExtraNodes_ += info->numberNodesExplored_;
    15968                         numberExtraIterations_ += info->numberIterations_;
     16143                        incrementExtra(info->numberNodesExplored_,
     16144                                       info->numberIterations_);
    1596916145                        char general[200];
    1597016146                        int fathomStatus=info->nNodes_;
     
    1598516161                                FATHOM_BIAS - fastNodeDepth_ << CoinMessageEol ;
    1598616162#endif
    15987 #ifdef CLP_INVESTIGATE
     16163#if CBC_USEFUL_PRINTING>0
    1598816164                            printf(">10000 - depth now %d so at depth >= %d\n",
    1598916165                                   fastNodeDepth_, FATHOM_BIAS - fastNodeDepth_);
     
    1599316169                            // we gave up
    1599416170                            //abort();
    15995                             fastNodeDepth_ -= 3;
     16171                          fastNodeDepth_ -= (info->nNodes_==-10) ? 5 : 2;
    1599616172#ifndef NO_FATHOM_PRINT
    1599716173                          if ((moreSpecialOptions_&262144) != 0)
     
    1599916175                              FATHOM_BIAS - fastNodeDepth_ << CoinMessageEol ;
    1600016176#endif
    16001 #ifdef CLP_INVESTIGATE
    16002                             printf("fastNodeDepth now %d - so at depth >= %d\n",
     16177#if CBC_USEFUL_PRINTING>0
     16178                            printf("gave up fastNodeDepth now %d - so at depth >= %d\n",
    1600316179                                   fastNodeDepth_, FATHOM_BIAS - fastNodeDepth_);
    1600416180#endif
     
    1667816854                            } else {
    1667916855                                lastHeuristic_ = heuristic_[found];
    16680 #ifdef CLP_INVESTIGATE
     16856#ifdef HEURISTIC_INFORM
    1668116857                                printf("HEUR %s where %d D\n",
    1668216858                                       lastHeuristic_->heuristicName(), whereFrom);
     
    1669316869                    if (found >= 0 && parallelMode() > 0) {
    1669416870                        lastHeuristic_ = heuristic_[found];
    16695 #ifdef CLP_INVESTIGATE
     16871#if CBC_USEFUL_PRINTING>1
    1669616872                        printf("HEUR %s where %d D\n",
    1669716873                               lastHeuristic_->heuristicName(), whereFrom);
     
    1685217028            delete [] delRows ;
    1685317029        }
     17030        numberNewCuts_=0;
    1685417031    }
    1685517032#endif
     
    1699717174    for (i = 0; i < numberIntegers_; i++)
    1699817175        back[integerVariable_[i]] = i;
    16999 #ifdef CLP_INVESTIGATE
     17176#if CBC_USEFUL_PRINTING>1
    1700017177    int numberNot = 0;
    1700117178#endif
     
    1700517182        if (!obj)
    1700617183            continue;
    17007 #ifdef CLP_INVESTIGATE
     17184#if CBC_USEFUL_PRINTING>1
    1700817185        if (obj->numberTimesDown() < numberBeforeTrust_ ||
    1700917186                obj->numberTimesUp() < numberBeforeTrust_)
     
    1702617203        }
    1702717204    }
    17028 #ifdef CLP_INVESTIGATE5
     17205#if CBC_USEFUL_PRINTING>5
    1702917206    if (priority)
    1703017207        printf("Before fathom %d not trusted out of %d\n",
     
    1760617783                    // better solution save
    1760717784                    lastHeuristic_ = heuristic_[found];
    17608 #ifdef CLP_INVESTIGATE
     17785#ifdef HEURISTIC_INFORM
    1760917786                    printf("HEUR %s where %d oddE\n",
    1761017787                           lastHeuristic_->heuristicName(), whereFrom);
     
    1852518702    char general[200];
    1852618703    if (clpSolver) {
    18527       clpSolver->getModelPtr()->dual(); // probably not needed
     18704      sprintf(general,"Starting multiple root solver");
     18705      model->messageHandler()->message(CBC_GENERAL,
     18706                                       model->messages())
     18707        << general << CoinMessageEol ;
     18708      clpSolver->setHintParam(OsiDoReducePrint, true, OsiHintTry);
     18709      ClpSimplex * simplex = clpSolver->getModelPtr();
     18710      int logLevel=simplex->logLevel();
     18711      if (logLevel<=1)
     18712        simplex->setLogLevel(0);
     18713      simplex->dual();
     18714      simplex->setLogLevel(logLevel);
    1852818715      clpSolver->setWarmStart(NULL);
    18529       sprintf(general,"Starting multiple root solver");
    1853018716    } else {
    18531 #endif
    18532 #ifdef COIN_HAS_CLP
    1853318717      model->initialSolve();
    1853418718      sprintf(general,"Solver did %d iterations in initialSolve\n",
    1853518719             model->solver()->getIterationCount());
    18536     }
    18537 #endif
    18538     model->messageHandler()->message(CBC_GENERAL,
    18539                               model->messages())
    18540       << general << CoinMessageEol ;
     18720      model->messageHandler()->message(CBC_GENERAL,
     18721                                       model->messages())
     18722        << general << CoinMessageEol ;
     18723    }
     18724#endif
    1854118725    model->branchAndBound();
    1854218726    sprintf(general,"Ending multiple root solver");
     
    1861018794        for (int iRow=numberRowsAtContinuous_;iRow<numberRows;iRow++) {
    1861118795          int iType=whichGenerator[iRow];
    18612           if ((iType>=0&&iType<10000)||iType<-1) {
     18796          if ((iType>=0&&iType<20000)) {
    1861318797            if (fabs(ray[iRow])>1.0e-10) {
    1861418798              badRows++;
  • trunk/Cbc/src/CbcModel.hpp

    r2048 r2094  
    351351    void makeGlobalCuts(int numberRows, const int * which);
    352352    /// Make given cut into a global cut
    353     void makeGlobalCut(const OsiRowCut * cut);
     353    int makeGlobalCut(const OsiRowCut * cut);
    354354    /// Make given cut into a global cut
    355     void makeGlobalCut(const OsiRowCut & cut);
     355    int makeGlobalCut(const OsiRowCut & cut);
    356356    /// Make given column cut into a global cut
    357357    void makeGlobalCut(const OsiColCut * cut);
     
    938938    inline int getExtraNodeCount() const {
    939939       return numberExtraNodes_;
     940    }
     941    /// Get how many times complete fathoming B&B was done
     942    inline int getFathomCount() const {
     943       return numberFathoms_;
    940944    }
    941945    /** Final status of problem
     
    18651869        9 bit (512) - branching on objective (later)
    18661870        10 bit (1024) - branching on constraints (later)
     1871        11/12 bit 2048 - intermittent cuts
     1872        13/14 bit 8192 - go to bitter end in strong branching (first time)
    18671873    */
    18681874    inline void setMoreSpecialOptions2(int value) {
     
    21972203      addCuts() simply treats all the cuts as loose as it does the bookkeeping.
    21982204
    2199       canFix true if extra information being passed
    2200     */
    2201     int addCuts(CbcNode * node, CoinWarmStartBasis *&lastws, bool canFix);
     2205    */
     2206    int addCuts(CbcNode * node, CoinWarmStartBasis *&lastws);
    22022207
    22032208    /** Traverse the tree from node to root and prep the model
     
    22812286        return &globalCuts_;
    22822287    }
     2288    /// Get rid of global cuts
     2289    inline void zapGlobalCuts() {
     2290        globalCuts_ = CbcRowCuts();
     2291    }
    22832292    /// Copy and set a pointer to a row cut which will be added instead of normal branching.
    22842293    void setNextRowCut(const OsiRowCut & cut);
     
    23322341        continuousPriority_ = value;
    23332342    }
    2334     inline void incrementExtra(int nodes, int iterations) {
     2343    inline void incrementExtra(int nodes, int iterations, int fathoms=1) {
    23352344        numberExtraNodes_ += nodes;
    23362345        numberExtraIterations_ += iterations;
     2346        numberFathoms_ += fathoms;
     2347    }
     2348    /// Zero extra
     2349    inline void zeroExtra() {
     2350        numberExtraNodes_ = 0;
     2351        numberExtraIterations_ = 0;
     2352        numberFathoms_ = 0;
    23372353    }
    23382354    /// Number of extra iterations
     
    26452661        5 bit (32) - event handler needs to be cloned when parallel
    26462662        6 bit (64) - testing - use probing to make cliques
    2647         7 bit (128) - try orbital branching (if nauty)
    2648         8 bit (256) - branching on objective (later)
    2649         9 bit (512) - branching on constraints (later)
     2663        7/8 bit (128) - try orbital branching (if nauty)
     2664        9 bit (512) - branching on objective (later)
     2665        10 bit (1024) - branching on constraints (later)
     2666        11/12 bit 2048 - intermittent cuts
    26502667    */
    26512668    int moreSpecialOptions2_;
     
    27852802    /// Number of extra nodes in fast lp
    27862803    int numberExtraNodes_;
     2804    /// Number of times fast lp entered
     2805    int numberFathoms_;
    27872806    /** Value of objective at continuous
    27882807        (Well actually after initial round of cuts)
     
    28982917    */
    28992918    int threadMode_;
     2919    /// Number of global cuts on entry to a node
     2920    int numberGlobalCutsIn_;
    29002921    /// Thread stuff for master
    29012922    CbcBaseModel * master_;
  • trunk/Cbc/src/CbcNode.cpp

    r2092 r2094  
    4646#include "OsiClpSolverInterface.hpp"
    4747#include "ClpSimplexOther.hpp"
     48#include "ClpSolve.hpp"
     49#include "ClpDualRowSteepest.hpp"
     50#include "ClpPrimalColumnPivot.hpp"
    4851#endif
    4952using namespace std;
     
    882885            }
    883886        }
     887        //if (!model->parentModel())
     888        //solver->writeMps("query");
    884889        // If we have hit max time don't do strong branching
    885890        bool hitMaxTime = (model->getCurrentSeconds() >
     
    16141619    branch_ = NULL;
    16151620    OsiSolverInterface * solver = model->solver();
     1621    //#define CHECK_DEBUGGER_PATH
     1622#ifdef CHECK_DEBUGGER_PATH
     1623    bool onOptimalPath=false;
     1624    if ((model->specialOptions()&1) != 0) {
     1625      const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ;
     1626      if (debugger) {
     1627        onOptimalPath = true;
     1628      }
     1629    }
     1630#endif
    16161631    // get information on solver type
    16171632    const OsiAuxInfo * auxInfo = solver->getAuxiliaryInfo();
     
    19571972    choice.possibleBranch = choiceObject;
    19581973    numberPassesLeft = CoinMax(numberPassesLeft, 2);
     1974    /* How dogged to be in strong branching
     1975       0 - default
     1976       1 - go to end on first time
     1977       2 - always go to end
     1978     */
     1979    int goToEndInStrongBranching = (model->moreSpecialOptions2()&(3*8192))>>13;
    19591980#ifdef COIN_HAS_NTY
    19601981    // 1 after, 2 strong, 3 until depth 5
     
    26272648                        solver->unmarkHotStart();
    26282649                        model->resolve(NULL, 11, saveSolution, saveLower, saveUpper);
     2650#ifdef CHECK_DEBUGGER_PATH
     2651                        if ((model->specialOptions()&1) != 0 && onOptimalPath) {
     2652                          const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ;
     2653                          if (!debugger) {
     2654                            printf("Strong branching down on %d went off optimal path\n",iObject);
     2655                            abort();
     2656                          }
     2657                        }
     2658#endif
    26292659                        double newObjValue = solver->getObjSense()*solver->getObjValue();
    26302660                        objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
     
    28412871                orbits = symmetryInfo->whichOrbit();
    28422872                int iColumn=-1;
    2843                 if (orbits && symmetryInfo->numberUsefulObjects()) {
     2873                if (orbits && symmetryInfo->numberUsefulOrbits()) {
    28442874                  bool doBranch=true;
    2845                   int numberUsefulOrbits = symmetryInfo->numberUsefulObjects();
     2875                  int numberUsefulOrbits = symmetryInfo->numberUsefulOrbits();
    28462876                  if (numberUsefulOrbits<2) {
    28472877                    assert (numberUsefulOrbits);
     
    28752905                      const double * lower = solver->getColLower();
    28762906                      const double * upper = solver->getColUpper();
     2907                      const int * integerVariable = model->integerVariable();
    28772908                      for (int iOrbit = 0; iOrbit < numberUsefulOrbits; iOrbit++) {
    28782909                        double distance=1.0;
    28792910                        int iColumn = -1;
    2880                         for (int i=0;i<numberColumns;i++) {
     2911                        int numberIntegers = model->numberIntegers();
     2912                        for (int j=0;j<numberIntegers;j++) {
     2913                          int i=integerVariable[j];
    28812914                          if (orbits[i]==iOrbit &&lower[i]==0.0&&upper[i]==1.0) {
    28822915                            double away = fabs(saveSolution[i]-0.5);
    28832916                            if (away<distance&&away<0.4999) {
    28842917                              distance=away;
    2885                               iColumn=i;
     2918                              iColumn=j;
    28862919                            }
    28872920                          }
     
    30183051                    double newObjectiveValue = 1.0e100;
    30193052                    int j;
     3053#ifdef COIN_HAS_CLP
     3054                    int saveMaxHotIts=0;
     3055                    int saveOsiClpOptions=0;
     3056                    if (osiclp && goToEndInStrongBranching) {
     3057                      /* How dogged to be in strong branching
     3058                         0 - default
     3059                         1 - go to end on first time
     3060                         2 - always go to end
     3061                      */
     3062                      osiclp->getIntParam(OsiMaxNumIterationHotStart, saveMaxHotIts);
     3063                      saveOsiClpOptions=osiclp->specialOptions();
     3064                      if (goToEndInStrongBranching==2 ||
     3065                          dynamicObject->numberTimesBranched()==0) {
     3066                        osiclp->setIntParam(OsiMaxNumIterationHotStart,
     3067                                            10*(osiclp->getNumRows()+numberColumns));
     3068                        osiclp->setSpecialOptions(saveOsiClpOptions & (~32));
     3069                      }
     3070                    }
     3071#endif
    30203072                    // status is 0 finished, 1 infeasible and other
    30213073                    int iStatus;
     
    30603112                        iStatus = 1; // infeasible
    30613113#ifdef CONFLICT_CUTS
     3114#undef CONFLICT_CUTS
     3115                        //#define CONFLICT_CUTS 2
     3116#endif
     3117#ifdef CONFLICT_CUTS
    30623118# ifdef COIN_HAS_CLP
    30633119                        if (osiclp&&(model->moreSpecialOptions()&4194304)!=0) {
     
    30653121                            model->topOfTree();
    30663122                          if (topOfTree) {
     3123#if CONFLICT_CUTS==2
    30673124                            OsiRowCut * cut = osiclp->smallModelCut(topOfTree->lower(),
    30683125                                                                    topOfTree->upper(),
    30693126                                                                    model->numberRowsAtContinuous(),
    30703127                                                                    model->whichGenerator());
     3128#else
     3129                            OsiRowCut * cut = osiclp->modelCut(topOfTree->lower(),
     3130                                                               topOfTree->upper(),
     3131                                                               model->numberRowsAtContinuous(),
     3132                                                               model->whichGenerator(),0);
     3133#endif
    30713134                            if (cut) {
    3072                               printf("XXXXXX found conflict cut in strong branching\n");
     3135                              if (model->messageHandler()->logLevel() > 1)
     3136                                printf("Conflict cut found in strong branching (%d elements)\n",
     3137                                       cut->row().getNumElements());
    30733138                              //cut->print();
    30743139                              if ((model->specialOptions()&1) != 0) {
     
    31873252                        needHotStartUpdate = false;
    31883253                        model->resolve(NULL, 11, saveSolution, saveLower, saveUpper);
     3254#ifdef CHECK_DEBUGGER_PATH
     3255                        if ((model->specialOptions()&1) != 0 && onOptimalPath) {
     3256                          const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ;
     3257                          if (!debugger) {
     3258                            printf("Strong branching down on %d went off optimal path\n",iObject);
     3259                            model->solver()->writeMps("query");
     3260                            abort();
     3261                          }
     3262                        }
     3263#endif
    31893264                        double newObjValue = solver->getObjSense()*solver->getObjValue();
    31903265                        objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
     
    32333308                    predictedChange=choice.possibleBranch->branch();
    32343309                    solver->solveFromHotStart() ;
     3310#ifdef COIN_HAS_CLP
     3311                    if (osiclp && goToEndInStrongBranching) {
     3312                      osiclp->setIntParam(OsiMaxNumIterationHotStart, saveMaxHotIts);
     3313                      osiclp->setSpecialOptions(saveOsiClpOptions);
     3314                    }
     3315#endif
    32353316                    numberStrongDone++;
    32363317                    numberStrongIterations += solver->getIterationCount();
     
    32553336                            model->topOfTree();
    32563337                          if (topOfTree) {
     3338#if CONFLICT_CUTS==2
    32573339                            OsiRowCut * cut = osiclp->smallModelCut(topOfTree->lower(),
    32583340                                                                    topOfTree->upper(),
    32593341                                                                    model->numberRowsAtContinuous(),
    32603342                                                                    model->whichGenerator());
     3343#else
     3344                            OsiRowCut * cut = osiclp->modelCut(topOfTree->lower(),
     3345                                                               topOfTree->upper(),
     3346                                                               model->numberRowsAtContinuous(),
     3347                                                               model->whichGenerator(),0);
     3348#endif
    32613349                            if (cut) {
    3262                               printf("XXXXXX found conflict cut in strong branching\n");
     3350                              //printf("XXXXXX found conflict cut in strong branching\n");
    32633351                              //cut->print();
    32643352                              if ((model->specialOptions()&1) != 0) {
     
    33563444                                if (needHotStartUpdate) {
    33573445                                    model->resolve(NULL, 11, saveSolution, saveLower, saveUpper);
     3446#ifdef CHECK_DEBUGGER_PATH
     3447                                    if ((model->specialOptions()&1) != 0 && onOptimalPath) {
     3448                                      const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ;
     3449                                      if (!debugger) {
     3450                                        printf("Strong branching up on %d went off optimal path\n",iObject);
     3451                                        abort();
     3452                                      }
     3453                                    }
     3454#endif
    33583455                                    newObjectiveValue = solver->getObjSense() * solver->getObjValue();
    33593456                                    objectiveValue_ = CoinMax(objectiveValue_,newObjectiveValue);
     
    33913488                        needHotStartUpdate = false;
    33923489                        model->resolve(NULL, 11, saveSolution, saveLower, saveUpper);
     3490#ifdef CHECK_DEBUGGER_PATH
     3491                        if ((model->specialOptions()&1) != 0 && onOptimalPath) {
     3492                          const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ;
     3493                          if (!debugger) {
     3494                            printf("Strong branching up on %d went off optimal path\n",iObject);
     3495                            abort();
     3496                          }
     3497                        }
     3498#endif
    33933499                        double newObjValue = solver->getObjSense()*solver->getObjValue();
    33943500                        objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
     
    34053511                                                   solver->getColSolution()) ;
    34063512                            model->resolve(NULL, 11, saveSolution, saveLower, saveUpper);
     3513#ifdef CHECK_DEBUGGER_PATH
     3514                            if ((model->specialOptions()&1) != 0 && onOptimalPath) {
     3515                              const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ;
     3516                              if (!debugger) {
     3517                                printf("Strong branching up on %d went off optimal path\n",iObject);
     3518                                abort();
     3519                              }
     3520                            }
     3521#endif
    34073522                            double newObjValue = solver->getObjSense()*solver->getObjValue();
    34083523                            objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
     
    35603675                        solver->unmarkHotStart();
    35613676                        model->resolve(NULL, 11, saveSolution, saveLower, saveUpper);
     3677#ifdef CHECK_DEBUGGER_PATH
     3678                        if ((model->specialOptions()&1) != 0 && onOptimalPath) {
     3679                          const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ;
     3680                          if (!debugger) {
     3681                            printf("Strong branching down on %d went off optimal path\n",iObject);
     3682                            abort();
     3683                          }
     3684                        }
     3685#endif
    35623686                        double newObjValue = solver->getObjSense()*solver->getObjValue();
    35633687                        objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
     
    36123736                        solver->unmarkHotStart();
    36133737                        model->resolve(NULL, 11, saveSolution, saveLower, saveUpper);
     3738#ifdef CHECK_DEBUGGER_PATH
     3739                        if ((model->specialOptions()&1) != 0 && onOptimalPath) {
     3740                          const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ;
     3741                          if (!debugger) {
     3742                            printf("Strong branching down on %d went off optimal path\n",iObject);
     3743                            solver->writeMps("query");
     3744                            abort();
     3745                          }
     3746                        }
     3747#endif
    36143748                        double newObjValue = solver->getObjSense()*solver->getObjValue();
    36153749                        objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
     
    37053839                    solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, &easy) ;
    37063840                    model->resolve(NULL, 11, saveSolution, saveLower, saveUpper) ;
     3841#ifdef CHECK_DEBUGGER_PATH
     3842                    if ((model->specialOptions()&1) != 0 && onOptimalPath) {
     3843                      const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ;
     3844                      if (!debugger) {
     3845                        printf("Strong branching went off optimal path\n");
     3846                        abort();
     3847                      }
     3848                    }
     3849#endif
    37073850                    double newObjValue = solver->getObjSense()*solver->getObjValue();
    37083851                    objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
     
    38533996        const int * orbits = symmetryInfo->whichOrbit();
    38543997        if (orbits && orbits[kColumn]>=0) {
    3855           int numberUsefulOrbits = symmetryInfo->numberUsefulObjects();
     3998          int numberUsefulOrbits = symmetryInfo->numberUsefulOrbits();
    38563999          if (solver->messageHandler()->logLevel() > 1)
    38574000            printf("Orbital Branching on %d - way %d n %d\n",kColumn,way(),numberUsefulOrbits);
     
    39354078    return anyAction;
    39364079}
     4080// 0 is down, 1 is up
     4081typedef struct {
     4082  double initialValue; // initial value
     4083  double upLowerBound; // Lower bound when going up
     4084  double downUpperBound; // Upper bound when going down
     4085  double movement[2]; // cost  (and initial away from feasible)
     4086  double sumModified[2]; // Sum of integer changes
     4087  int modified[2]; // Number integers changed
     4088  int numIntInfeas[2]; // without odd ones
     4089  int numObjInfeas[2]; // just odd ones
     4090  bool finished[2]; // true if solver finished
     4091  int numIters[2]; // number of iterations in solver (-1 if never solved)
     4092  double * integerSolution; // output if thinks integer solution
     4093# ifdef COIN_HAS_CLP
     4094  ClpDualRowSteepest * steepest;
     4095#endif
     4096  int columnNumber; // Which column it is
     4097} StrongInfo;
     4098typedef struct {
     4099  double integerTolerance;
     4100  double * originalSolution;
     4101  CoinWarmStart * ws;
     4102# ifdef COIN_HAS_CLP
     4103  ClpDualRowSteepest * dualRowPivot;
     4104  ClpPrimalColumnPivot * primalColumnPivot;
     4105# endif
     4106  int * back;
     4107  int solveType;
     4108} StrongStaticInfo;
     4109typedef struct {
     4110  StrongStaticInfo *staticInfo;
     4111  StrongInfo * choice;
     4112  OsiSolverInterface * solver;
     4113  int whichChoice;
     4114} StrongBundle;
     4115/* return 1 if possible solution (for solveType 100 if infeasible)
     4116   2 set if down was infeasible
     4117   4 set if up was infeasible
     4118 */
     4119int solveAnalyze(void * info) {
     4120  StrongBundle * bundle = reinterpret_cast<StrongBundle *>(info);
     4121  StrongInfo * choice = bundle->choice;
     4122  StrongStaticInfo * staticInfo = bundle->staticInfo;
     4123  OsiSolverInterface * solver = bundle->solver;
     4124  int solveType = staticInfo->solveType;
     4125  if (solveType==77) {
     4126    return 0;
     4127  }
     4128  const double * saveSolution = staticInfo->originalSolution;
     4129  int iColumn = choice->columnNumber;
     4130  const int * back = staticInfo->back;
     4131  double newObjectiveValue = 1.0e100;
     4132  double integerTolerance = staticInfo->integerTolerance;
     4133  double bestSolutionValue=COIN_DBL_MAX;
     4134  int returnStatus=0;
     4135  // status is 0 finished, 1 infeasible and other
     4136  int iStatus;
     4137  /*
     4138    Try the down direction first. (Specify the initial branching alternative as
     4139    down with a call to way(-1). Each subsequent call to branch() performs the
     4140    specified branch and advances the branch object state to the next branch
     4141    alternative.)
     4142  */
     4143  for (int iWay=0;iWay<2;iWay++) {
     4144    if (choice->numIters[iWay]==0) {
     4145      if (solveType!=100) {
     4146        double saveBound;
     4147        if (iWay==0) {
     4148          saveBound = solver->getColUpper()[iColumn];
     4149          solver->setColUpper(iColumn,choice->downUpperBound);
     4150        } else {
     4151          saveBound = solver->getColLower()[iColumn];
     4152          solver->setColLower(iColumn,choice->upLowerBound);
     4153        }
     4154        if ((solveType&2)==0) {
     4155          solver->solveFromHotStart() ;
     4156        } else {
     4157          // restore basis
     4158          solver->setWarmStart(staticInfo->ws);
     4159# ifdef COIN_HAS_CLP
     4160          if (staticInfo->dualRowPivot) {
     4161            OsiClpSolverInterface * osiclp = dynamic_cast<OsiClpSolverInterface *>(solver);
     4162            ClpSimplex * simplex = osiclp->getModelPtr();
     4163            simplex->setDualRowPivotAlgorithm(*staticInfo->dualRowPivot);
     4164            //simplex->dualRowPivot()->saveWeights(simplex,4);
     4165            simplex->setWhatsChanged(ALL_SAME_EXCEPT_COLUMN_BOUNDS);
     4166            simplex->dual(0,5);
     4167          } else {
     4168#endif
     4169          solver->resolve();
     4170# ifdef COIN_HAS_CLP
     4171          }
     4172#endif
     4173        }
     4174        if (iWay==0)
     4175          solver->setColUpper(iColumn,saveBound);
     4176        else
     4177          solver->setColLower(iColumn,saveBound);
     4178        /*
     4179          We now have an estimate of objective degradation that we can use for strong
     4180          branching. If we're over the cutoff, the variable is monotone up.
     4181          If we actually made it to optimality, check for a solution, and if we have
     4182          a good one, call setBestSolution to process it. Note that this may reduce the
     4183          cutoff, so we check again to see if we can declare this variable monotone.
     4184        */
     4185        if (solver->isProvenOptimal()) {
     4186          iStatus = 0; // optimal
     4187        } else if (solver->isIterationLimitReached()
     4188                   && !solver->isDualObjectiveLimitReached()) {
     4189          iStatus = 2; // unknown
     4190        } else {
     4191          iStatus = 1; // infeasible
     4192        }
     4193        newObjectiveValue = solver->getObjSense() * solver->getObjValue();
     4194        choice->numIters[iWay] = solver->getIterationCount();
     4195        // Look at interaction
     4196        const double * thisSolution = solver->getColSolution();
     4197        int numberModified=0;
     4198        double sumModified=0.0;
     4199        int numberColumns=solver->getNumCols();
     4200        int numberInfeas=0;
     4201        for (int i=0;i<numberColumns;i++) {
     4202          if (back[i]>=0) {
     4203            double value = thisSolution[i];
     4204            if (iColumn!=i) {
     4205              double difference = fabs(saveSolution[i]-value);
     4206              if (difference>integerTolerance) {
     4207                numberModified++;
     4208                sumModified += difference;
     4209              }
     4210            }
     4211            if (fabs(value-floor(value+0.5))>integerTolerance)
     4212              numberInfeas++;;
     4213          }
     4214        }
     4215        choice->numIntInfeas[iWay]=numberInfeas;
     4216        choice->sumModified[iWay] = sumModified;
     4217        choice->modified[iWay] = numberModified;
     4218        if (!iStatus) {
     4219          choice->finished[iWay] = true ;
     4220          if (!numberInfeas) {
     4221            returnStatus=1;
     4222            if (!choice->integerSolution) {
     4223              bestSolutionValue=newObjectiveValue;
     4224              choice->integerSolution=CoinCopyOfArray(thisSolution,numberColumns);;
     4225            } else if (bestSolutionValue>newObjectiveValue) {
     4226              memcpy(choice->integerSolution,thisSolution,numberColumns*sizeof(double));
     4227            }
     4228          }
     4229        } else if (iStatus == 1) {
     4230          newObjectiveValue = 1.0e100 ;
     4231        } else {
     4232          // Can't say much as we did not finish
     4233          choice->finished[iWay] = false ;
     4234        }
     4235        choice->movement[iWay] = newObjectiveValue ;
     4236      } else {
     4237        // doing continuous and general integer
     4238        solver->setColSolution(staticInfo->originalSolution);
     4239        solver->setWarmStart(staticInfo->ws);
     4240        double saveBound;
     4241        double newBound;
     4242        if (iWay==0) {
     4243          solver->setObjCoeff(iColumn,1.0);
     4244          saveBound=solver->getColUpper()[iColumn];
     4245          solver->setColUpper(iColumn,choice->downUpperBound);
     4246          newBound=choice->downUpperBound;
     4247        } else {
     4248          solver->setObjCoeff(iColumn,-1.0);
     4249          saveBound=solver->getColLower()[iColumn];
     4250          solver->setColLower(iColumn,choice->upLowerBound);
     4251          newBound=choice->upLowerBound;
     4252        }
     4253        solver->setHintParam(OsiDoDualInResolve, true, OsiHintDo) ;
     4254        solver->resolve();
     4255        if (iWay==0) {
     4256          solver->setColUpper(iColumn,saveBound);
     4257        } else {
     4258          solver->setColLower(iColumn,saveBound);
     4259        }
     4260        choice->numIters[iWay] = solver->getIterationCount();
     4261        if (solver->isProvenOptimal()) {
     4262          //printf("Way %d - all way %d iterations - column %d\n",
     4263          //     iWay,solver->getIterationCount(),iColumn);
     4264          // can go all way
     4265          choice->movement[iWay] = newBound;
     4266        } else {
     4267          solver->setColSolution(staticInfo->originalSolution);
     4268          solver->setWarmStart(staticInfo->ws);
     4269          solver->setHintParam(OsiDoDualInResolve, false, OsiHintDo) ;
     4270          solver->resolve();
     4271          //printf("Way %d - first solve %d iterations, second %d - column %d\n",
     4272          //     iWay,choice->numIters[iWay],solver->getIterationCount(),iColumn);
     4273          choice->movement[iWay] = solver->getColSolution()[iColumn];
     4274          choice->numIters[iWay] += solver->getIterationCount();
     4275          if (!solver->isProvenOptimal()) {
     4276            choice->modified[0]=1;
     4277            returnStatus=1;
     4278          }
     4279        }
     4280        solver->setObjCoeff(iColumn,0.0);
     4281      }
     4282    }
     4283  }
     4284  return returnStatus;
     4285}
     4286#ifdef CBC_THREAD
     4287void * cbc_parallelManager(void * stuff)
     4288{
     4289  CoinPthreadStuff * driver = reinterpret_cast<CoinPthreadStuff *>(stuff);
     4290  int whichThread=driver->whichThread();
     4291  CoinThreadInfo * threadInfo = driver->threadInfoPointer(whichThread);
     4292  threadInfo->status=-1;
     4293  int * which = threadInfo->stuff;
     4294  pthread_barrier_wait(driver->barrierPointer());
     4295#if 0
     4296  int status=-1;
     4297  while (status!=100)
     4298    status=timedWait(driver,1000,2);
     4299  pthread_cond_signal(driver->conditionPointer(1));
     4300  pthread_mutex_unlock(driver->mutexPointer(1,whichThread));
     4301#endif
     4302  // so now mutex_ is locked
     4303  int whichLocked=0;
     4304  while (true) {
     4305    pthread_mutex_t * mutexPointer = driver->mutexPointer(whichLocked,whichThread);
     4306    // wait
     4307    //printf("Child waiting for %d - status %d %d %d\n",
     4308    //     whichLocked,lockedX[0],lockedX[1],lockedX[2]);
     4309#ifdef DETAIL_THREAD
     4310    printf("thread %d about to lock mutex %d\n",whichThread,whichLocked);
     4311#endif
     4312    pthread_mutex_lock (mutexPointer);
     4313    whichLocked++;
     4314    if (whichLocked==3)
     4315      whichLocked=0;
     4316    int unLock=whichLocked+1;
     4317    if (unLock==3)
     4318      unLock=0;
     4319    //printf("child pointer %x status %d\n",threadInfo,threadInfo->status);
     4320    assert(threadInfo->status>=0);
     4321    if (threadInfo->status==1000)
     4322      pthread_exit(NULL);
     4323    int type=threadInfo->status;
     4324    int & returnCode=which[0];
     4325    int iPass=which[1];
     4326    //CoinIndexedVector * array;
     4327    //double dummy;
     4328    switch(type) {
     4329      // dummy
     4330    case 0:
     4331      break;
     4332    case 1:
     4333      returnCode=solveAnalyze(threadInfo->extraInfo);
     4334      threadInfo->stuff[3]=0;
     4335      break;
     4336    case 100:
     4337      // initialization
     4338      break;
     4339    }
     4340    threadInfo->status= (type!=1) ? -1 : -2;
     4341#ifdef DETAIL_THREAD
     4342    printf("thread %d about to unlock mutex %d\n",whichThread,unLock);
     4343#endif
     4344    pthread_mutex_unlock (driver->mutexPointer(unLock,whichThread));
     4345  }
     4346}
     4347#endif
    39374348int CbcNode::analyze (CbcModel *model, double * results)
    39384349{
    3939     int i;
    3940     int numberIterationsAllowed = model->numberAnalyzeIterations();
    3941     OsiSolverInterface * solver = model->solver();
    3942     objectiveValue_ = solver->getObjSense() * solver->getObjValue();
    3943     double cutoff = model->getCutoff();
     4350#define COIN_DETAIL
     4351  int i;
     4352  int numberIterationsAllowed = model->numberAnalyzeIterations();
     4353  int numberColumns = model->getNumCols();
     4354  int numberRows = model->getNumRows();
     4355  int numberObjects = model->numberObjects();
     4356  int numberIntegers = model->numberIntegers();
     4357  int numberLookIntegers=0;
     4358  int highestPriority=COIN_INT_MAX;
     4359  int * back = new int[numberColumns];
     4360  const int * integerVariable = model->integerVariable();
     4361  for (i = 0; i < numberIntegers; i++) {
     4362    highestPriority = CoinMin(highestPriority,model->modifiableObject(i)->priority());
     4363  }
     4364  for (i = 0; i < numberColumns; i++)
     4365    back[i] = -1;
     4366  for (i = 0; i < numberIntegers; i++) {
     4367    int iColumn = integerVariable[i];
     4368    back[iColumn] = i;
     4369    if (model->modifiableObject(i)->priority()==highestPriority) {
     4370      numberLookIntegers++;
     4371    } else {
     4372      back[iColumn] = i+numberColumns;
     4373    }
     4374  }
     4375  /*
     4376    0 - just look
     4377    0 (1) bit - use to set priorities
     4378    1 (2) bit - look at bounds on all variables and more iterations
     4379    2 (4) bit - do threaded (if parallelMode()==1 then not repeatable if any fixed)
     4380    3 (8) bit -
     4381    4 (16) bit - do even if m*n>1,000,000
     4382    5 (32) bit - printing time
     4383    6 (64) bit - save mps file
     4384  */
     4385  int solveType;
     4386  char general[200];
     4387  if (numberIterationsAllowed>0) {
     4388    solveType = 0;
     4389  } else {
     4390    solveType = - numberIterationsAllowed;
     4391    if ((solveType&16)==0) {
     4392      double size=numberRows;
     4393      size*=numberLookIntegers;
     4394      if (size>1000000) {
     4395        if ((solveType&32)!=0)
     4396          model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     4397            << "Skipping analyze as problem too large"
     4398            << CoinMessageEol;
     4399        return 0;
     4400      }
     4401    }
     4402    sprintf(general,"Analyze options %d",solveType);
     4403    model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     4404      << general
     4405      << CoinMessageEol;
     4406    if ((solveType&1)!=0)
     4407      model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     4408        << "Using to set priorities (probably bad idea)"
     4409        << CoinMessageEol;
     4410    if ((solveType&2)!=0)
     4411      model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     4412        << "Use more iterations and look at continuous/general integer variables"
     4413        << CoinMessageEol;
     4414    if ((solveType&4)!=0)
     4415      model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     4416        << "Use threads"
     4417        << CoinMessageEol;
     4418    if ((solveType&32)!=0)
     4419      model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     4420        << "32 switches on more printing, (16 bit allows large problems)"
     4421        << CoinMessageEol;
     4422  }
     4423  OsiSolverInterface * solver = model->solver();
     4424  objectiveValue_ = solver->getObjSense() * solver->getObjValue();
     4425  const double * lower = solver->getColLower();
     4426  const double * upper = solver->getColUpper();
     4427  const double * dj = solver->getReducedCost();
     4428  // What results is
     4429  double * newLower = results;
     4430  double * objLower = newLower + numberIntegers;
     4431  double * newUpper = objLower + numberIntegers;
     4432  double * objUpper = newUpper + numberIntegers;
     4433  double * interAction = objUpper + numberIntegers;
     4434  for (i = 0; i < numberIntegers; i++) {
     4435    int iColumn = integerVariable[i];
     4436    newLower[i] = lower[iColumn];
     4437    objLower[i] = -COIN_DBL_MAX;
     4438    newUpper[i] = upper[iColumn];
     4439    objUpper[i] = -COIN_DBL_MAX;
     4440    interAction[i] = 0.0;
     4441  }
     4442  double * objMovement=new double[2*numberIntegers];
     4443  memset(objMovement,0,2*numberIntegers*sizeof(double));
     4444  double * saveUpper = new double[numberColumns];
     4445  double * saveLower = new double[numberColumns];
     4446  // Save solution in case heuristics need good solution later
     4447 
     4448  double * saveSolution = new double[numberColumns];
     4449  memcpy(saveSolution, solver->getColSolution(), numberColumns*sizeof(double));
     4450  model->reserveCurrentSolution(saveSolution);
     4451  for (i = 0; i < numberColumns; i++) {
     4452    saveLower[i] = lower[i];
     4453    saveUpper[i] = upper[i];
     4454  }
     4455  // Get arrays to sort
     4456  double * sort = new double[numberObjects];
     4457  int * whichObject = new int[numberObjects];
     4458  int numberToFix = 0;
     4459  int numberToDo = 0;
     4460  double integerTolerance =
     4461    model->getDblParam(CbcModel::CbcIntegerTolerance);
     4462  // point to useful information
     4463  OsiBranchingInformation usefulInfo = model->usefulInformation();
     4464  // and modify
     4465  usefulInfo.depth_ = depth_;
     4466 
     4467  // compute current state
     4468  int numberObjectInfeasibilities; // just odd ones
     4469  int numberIntegerInfeasibilities;
     4470  model->feasibleSolution(
     4471                          numberIntegerInfeasibilities,
     4472                          numberObjectInfeasibilities);
     4473  if (solveType) {
     4474    if ((solveType&2)==0)
     4475      numberIterationsAllowed=200*numberIntegerInfeasibilities;
     4476    else
     4477      numberIterationsAllowed=COIN_INT_MAX;
     4478  }
     4479  int saveAllowed=numberIterationsAllowed;
     4480# ifdef COIN_HAS_CLP
     4481  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
     4482  int saveClpOptions = 0;
     4483  bool fastIterations = (model->specialOptions() & 8) != 0;
     4484  if (osiclp) {
     4485    saveClpOptions = osiclp->specialOptions();
     4486    // for faster hot start
     4487    if (fastIterations)
     4488      osiclp->setSpecialOptions(saveClpOptions | 8192);
     4489    else
     4490      osiclp->setSpecialOptions(saveClpOptions | 2048); // switch off crunch
     4491  }
     4492# else
     4493  bool fastIterations = false ;
     4494# endif
     4495  /*
     4496    Scan for branching objects that indicate infeasibility.
     4497   
     4498    The algorithm is to fill the array with a set of good candidates (by
     4499    infeasibility).
     4500   
     4501  */
     4502  numberToDo = 0;
     4503  for (i = 0; i < numberObjects; i++) {
     4504    OsiObject * object = model->modifiableObject(i);
     4505    CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     4506      dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     4507    if (!dynamicObject)
     4508      continue;
     4509    if (dynamicObject->priority()!=highestPriority)
     4510      continue;
     4511    double infeasibility = object->checkInfeasibility(&usefulInfo);
     4512    int iColumn = dynamicObject->columnNumber();
     4513    if (saveUpper[iColumn] == saveLower[iColumn])
     4514      continue;
     4515    if (infeasibility)
     4516      sort[numberToDo] = -1.0e10 - infeasibility;
     4517    else
     4518      sort[numberToDo] = -fabs(dj[iColumn]);
     4519    whichObject[numberToDo++] = i;
     4520  }
     4521  // Save basis
     4522  CoinWarmStart * ws = solver->getWarmStart();
     4523  int saveLimit;
     4524  solver->getIntParam(OsiMaxNumIterationHotStart, saveLimit);
     4525  int targetIterations = CoinMax(500, numberIterationsAllowed / numberObjects);
     4526  if (saveLimit < targetIterations)
     4527    solver->setIntParam(OsiMaxNumIterationHotStart, targetIterations);
     4528  if ((solveType&2)==0) {
     4529    // Mark hot start
     4530    solver->markHotStart();
     4531  }
     4532  solver->setHintParam(OsiDoDualInResolve, true, OsiHintDo) ;
     4533  // Sort
     4534  CoinSort_2(sort, sort + numberToDo, whichObject);
     4535  double * currentSolution = model->currentSolution();
     4536  double objMin = 1.0e50;
     4537  double objMax = -1.0e50;
     4538  bool needResolve = false;
     4539  int maxChoices=1;
     4540  int currentChoice=0;
     4541  int numberThreads=0;
     4542  bool doAtEnd=false;
     4543  if (model->parallelMode() && (solveType&4)!=0) {
     4544    numberThreads=model->getNumberThreads();
     4545    sprintf(general,"Using %d threads in analysis\n",numberThreads);
     4546    model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     4547      << general
     4548      << CoinMessageEol;
     4549    if (model->parallelMode()==1) {
     4550      maxChoices=numberThreads;
     4551    } else {
     4552      maxChoices = numberToDo;
     4553      if ((solveType&2)!=0)
     4554        maxChoices = numberColumns;
     4555      doAtEnd=true;
     4556    }
     4557  }
     4558  StrongInfo * choices = new StrongInfo[maxChoices];
     4559  StrongStaticInfo staticInfo;
     4560  StrongBundle * bundles = new StrongBundle[CoinMax(1,numberThreads)];
     4561  /*
     4562    0 - available - no need to look at results
     4563    1 - not available
     4564    2 - available - need to look at results
     4565  */
     4566  int status[NUMBER_THREADS];
     4567  memset(status,0,sizeof(status));
     4568  memset(&staticInfo,0,sizeof(staticInfo));
     4569  staticInfo.solveType = solveType;
     4570  staticInfo.originalSolution=saveSolution;
     4571  staticInfo.back=back;
     4572  staticInfo.ws=ws;
     4573  staticInfo.integerTolerance=integerTolerance;
     4574  double time1 = model->getCurrentSeconds();
     4575#define DO_STEEPEST_SERIAL 1
     4576# ifdef COIN_HAS_CLP
     4577  if (osiclp&&(solveType&2)!=0&&(!numberThreads||DO_STEEPEST_SERIAL)) {
     4578    ClpSimplex * simplex = osiclp->getModelPtr();
     4579    simplex->setLogLevel(0);
     4580    simplex->dual(0,1);
     4581    ClpDualRowPivot * dualRowPivot=simplex->dualRowPivot();
     4582    ClpDualRowSteepest * steep = dynamic_cast<ClpDualRowSteepest *>(dualRowPivot);
     4583    if (steep) {
     4584      staticInfo.dualRowPivot=new ClpDualRowSteepest (*steep);
     4585      staticInfo.dualRowPivot->setMode(1); // full steepest edge
     4586      simplex->spareIntArray_[0]=0;
     4587      simplex->spareIntArray_[1]=numberRows;
     4588      staticInfo.dualRowPivot->saveWeights(simplex,7);
     4589    }
     4590  }
     4591#endif
     4592  for (int i=0;i<CoinMax(1,numberThreads);i++)
     4593    bundles[i].staticInfo=&staticInfo;
     4594#if defined (CBC_THREAD) && defined (COIN_HAS_CLP)
     4595#define USE_STRONG_THREADS
     4596  CoinPthreadStuff threadInfo(numberThreads,cbc_parallelManager);
     4597  int threadNeedsRefreshing[NUMBER_THREADS];
     4598  for (int i=0;i<numberThreads;i++) {
     4599    threadInfo.threadInfo_[i].extraInfo2 = solver->clone();
     4600    threadNeedsRefreshing[i]=0;
     4601  }
     4602# ifdef COIN_HAS_CLP
     4603  int numberSteepThreads=0;
     4604  int step=numberThreads ? (numberRows+numberThreads-1)/numberThreads : 0;
     4605  int first=0;
     4606  for (int i=0;i<numberThreads;i++) {
     4607    if (osiclp&&(solveType&2)!=0&&!DO_STEEPEST_SERIAL) {
     4608      OsiSolverInterface * solver=
     4609        reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[i].extraInfo2);
     4610      OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
     4611      ClpSimplex * simplex = osiclp->getModelPtr();
     4612      simplex->setLogLevel(0);
     4613      simplex->dual(0,1);
     4614      ClpDualRowPivot * dualRowPivot=simplex->dualRowPivot();
     4615      ClpDualRowSteepest * steep = dynamic_cast<ClpDualRowSteepest *>(dualRowPivot);
     4616      if (steep) {
     4617        numberSteepThreads=numberThreads;
     4618        ClpDualRowSteepest * dualRowPivot=new ClpDualRowSteepest (*steep);
     4619        dualRowPivot->setMode(1); // full steepest edge
     4620        simplex->spareIntArray_[0]=0;
     4621        simplex->spareIntArray_[1]=numberRows;
     4622        simplex->spareIntArray_[0]=first;
     4623        simplex->spareIntArray_[1]=CoinMin(first+step,numberRows);
     4624        first += step;
     4625        if (i==0)
     4626          staticInfo.dualRowPivot=dualRowPivot;
     4627        choices[i].steepest=dualRowPivot;
     4628        dualRowPivot->saveWeights(simplex,7);
     4629      }
     4630    }
     4631  }
     4632  if (numberSteepThreads&&false) {
     4633    int numberDone=0;
     4634    int iDo=0;
     4635    staticInfo.solveType = 200;
     4636    while (numberDone<numberSteepThreads) {
     4637      int iThread;
     4638      threadInfo.waitParallelTask(1,iThread,iDo<numberToDo);
     4639      int threadStatus = 1+threadInfo.threadInfo_[iThread].status;
     4640      iThread=iThread;
     4641      if (threadStatus==0&&iDo<numberSteepThreads) {
     4642        StrongInfo & choice = choices[iThread];
     4643        StrongBundle & bundle = bundles[iThread];
     4644        bundle.whichChoice=iThread;
     4645        memset(&choice,0,sizeof(StrongInfo));
     4646        iDo++; //started this one
     4647        bundle.choice=&choice;
     4648        bundle.solver = solver;
     4649        bundle.solver=reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2);
     4650        threadStatus=0;
     4651#ifdef DETAIL_THREAD
     4652        printf("Starting steep task on thread %d\n",
     4653               choice.iThread);
     4654#endif
     4655        threadInfo.startParallelTask(1,iThread,&bundle);
     4656      }
     4657      if (!threadStatus) {
     4658        usleep(1000);
     4659        continue;
     4660      }
     4661      if (threadStatus) {
     4662        numberDone++;
     4663        // say available
     4664        threadInfo.sayIdle(iThread);
     4665      }
     4666      staticInfo.solveType = solveType;
     4667    }
     4668    OsiSolverInterface * solver0=
     4669      reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[0].extraInfo2);
     4670    CoinIndexedVector * savedWeights0 = staticInfo.dualRowPivot->savedWeights();
     4671    int * index0 = savedWeights0->getIndices();
     4672    double * weight0 = savedWeights0->denseVector();
     4673    int step=(numberRows+numberSteepThreads-1)/numberSteepThreads;
     4674    int first=step;
     4675    //memset(weight0+first,0,(numberRows-first)*sizeof(double));
     4676    for (int i=1;i<numberSteepThreads;i++) {
     4677      int n=CoinMin(step,numberRows-first);
     4678      CoinIndexedVector * savedWeights = choices[i].steepest->savedWeights();
     4679      int * index = savedWeights->getIndices();
     4680      double * weight = savedWeights->denseVector();
     4681      memcpy(index0+first,index+first,n*sizeof(int));
     4682      memcpy(weight0+first,weight+first,n*sizeof(double));
     4683      first += step;
     4684      delete choices[i].steepest;
     4685      choices[i].steepest=NULL;
     4686    }
     4687    //for (int j=0;j<numberRows;j++)
     4688    //weight0[j]=1.0;
     4689  }
     4690#endif
     4691#endif
     4692  double bestSolutionValue = model->getMinimizationObjValue();
     4693  double * bestSolution = NULL;
     4694  double cutoff;
     4695  solver->getDblParam(OsiDualObjectiveLimit,cutoff);
     4696  double maxMovement = 2.0*(cutoff-objectiveValue_)+1.0e-6;
     4697  /*
     4698    Now calculate the cost forcing the variable up and down.
     4699  */
     4700  int iDo=0;
     4701  int iDone=-1;
     4702  int numberDone=0;
     4703  int iThread=0;
     4704  int threadStatus=0;
     4705  int whenPrint = (numberToDo+9)/10;
     4706  while (numberDone<numberToDo) {
     4707    if ((solveType&32)!=0&&numberDone==whenPrint) {
     4708      whenPrint += (numberToDo+9)/10;
     4709      sprintf(general,"%d variables looked at - %d changed by initial strong branching (%.2f seconds - %d iterations)",numberDone,numberToFix,model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed);
     4710      model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     4711        << general
     4712        << CoinMessageEol;
     4713    }
     4714#ifdef USE_STRONG_THREADS
     4715    if (numberThreads) {
     4716      threadInfo.waitParallelTask(1,iThread,iDo<numberToDo);
     4717      threadStatus = 1+threadInfo.threadInfo_[iThread].status;
     4718      if (!doAtEnd)
     4719        currentChoice=iThread;
     4720      if (threadNeedsRefreshing[iThread]) {
     4721        OsiSolverInterface * solver=
     4722          reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2);
     4723        if ((threadNeedsRefreshing[iThread]&1)!=0)
     4724          solver->setColLower(saveLower);
     4725        if ((threadNeedsRefreshing[iThread]&2)!=0)
     4726          solver->setColUpper(saveUpper);
     4727        threadNeedsRefreshing[iThread]=0;
     4728      }
     4729    }
     4730#endif
     4731    if (threadStatus==0&&iDo<numberToDo) {
     4732      StrongInfo & choice = choices[currentChoice];
     4733      StrongBundle & bundle = bundles[iThread];
     4734      bundle.whichChoice=currentChoice;
     4735      memset(&choice,0,sizeof(StrongInfo));
     4736      int iObject = whichObject[iDo];
     4737      iDo++; //started this one
     4738      OsiObject * object = model->modifiableObject(iObject);
     4739      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     4740        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     4741      int iColumn = dynamicObject->columnNumber();
     4742      double value = currentSolution[iColumn];
     4743      double nearest = floor(value + 0.5);
     4744      double lowerValue = floor(value);
     4745      bool satisfied = false;
     4746      if (fabs(value - nearest) <= integerTolerance ||
     4747          value < saveLower[iColumn] || value > saveUpper[iColumn]) {
     4748        satisfied = true;
     4749        if (nearest < saveUpper[iColumn]) {
     4750          lowerValue = nearest;
     4751        } else {
     4752          lowerValue = nearest - 1;
     4753        }
     4754      }
     4755      double upperValue = lowerValue + 1.0;
     4756      // Save which object it was
     4757      choice.columnNumber = iColumn;
     4758      choice.initialValue=value;
     4759      choice.upLowerBound=upperValue;
     4760      choice.downUpperBound=lowerValue;
     4761      choice.numIntInfeas[1] = numberUnsatisfied_;
     4762      choice.numIntInfeas[0] = numberUnsatisfied_;
     4763      choice.movement[0] = 0.0;
     4764      choice.movement[1] = 0.0;
     4765      choice.numIters[0] = 0;
     4766      choice.numIters[1] = 0;
     4767      if (fabs(value - lowerValue) <= integerTolerance)
     4768        choice.numIters[0]=-1; // mark as not done
     4769      if (fabs(value - upperValue) <= integerTolerance)
     4770        choice.numIters[1]=-1; // mark as not done
     4771      bundle.choice=&choice;
     4772      bundle.solver = solver;
     4773#ifdef USE_STRONG_THREADS
     4774      if (numberThreads) {
     4775        bundle.solver=reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2);
     4776        threadStatus=0;
     4777#ifdef DETAIL_THREAD
     4778        printf("Starting task for column %d on thread %d\n",
     4779               choice.columnNumber,iThread);
     4780#endif
     4781        threadInfo.startParallelTask(1,iThread,&bundle);
     4782      } else {
     4783#endif
     4784        threadStatus=2;
     4785        solveAnalyze(&bundle);
     4786#ifdef USE_STRONG_THREADS
     4787      }
     4788#endif
     4789    }
     4790    if (!threadStatus) {
     4791      usleep(1000);
     4792      continue;
     4793    }
     4794    if (threadStatus) {
     4795      int whichChoice = bundles[iThread].whichChoice; 
     4796      StrongInfo & choice = choices[whichChoice];
     4797      int iColumn=choice.columnNumber;
     4798      if (choice.integerSolution) {
     4799        double * foundSolution = choice.integerSolution;
     4800        solver->setColSolution(foundSolution);
     4801        // See if integer solution
     4802        int numberInfeas=0;
     4803        int numberOddInfeas=0;
     4804        if (model->feasibleSolution(numberInfeas,numberOddInfeas)
     4805            && model->problemFeasibility()->feasible(model, -1) >= 0) {
     4806          double newObjectiveValue;
     4807          solver->getDblParam(OsiObjOffset,newObjectiveValue);
     4808          newObjectiveValue=-newObjectiveValue;
     4809          const double * cost = solver->getObjCoefficients();
     4810          for ( int i = 0 ; i < numberColumns ; i++ )
     4811            newObjectiveValue += cost[i] * foundSolution[i];
     4812          if (newObjectiveValue<bestSolutionValue) {
     4813            if (doAtEnd) {
     4814              if (!bestSolution)
     4815                bestSolution = CoinCopyOfArray(foundSolution,numberColumns);
     4816              else
     4817                memcpy(bestSolution,foundSolution,numberColumns*sizeof(double));
     4818              bestSolutionValue=newObjectiveValue;
     4819            } else {
     4820              model->setBestSolution(CBC_STRONGSOL,
     4821                                     newObjectiveValue,
     4822                                     foundSolution) ;
     4823              model->setLastHeuristic(NULL);
     4824              model->incrementUsed(solver->getColSolution());
     4825              bestSolutionValue = model->getMinimizationObjValue();
     4826            }
     4827          }
     4828        }
     4829        delete [] foundSolution;
     4830      }
     4831      for (int iWay=0;iWay<2;iWay++) {
     4832        numberIterationsAllowed -= choice.numIters[iWay];
     4833        choice.movement[iWay] -= objectiveValue_;
     4834      }
     4835      // If objective goes above certain amount we can set bound
     4836      int jInt = back[iColumn];
     4837      OsiObject * object = model->modifiableObject(jInt);
     4838      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     4839        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     4840      if (dynamicObject) {
     4841        if (choice.numIters[0]>=0) {
     4842          dynamicObject->addToSumDownCost(CoinMin(choice.movement[0],maxMovement));
     4843          dynamicObject->addToSumDownChange(choice.initialValue-choice.downUpperBound);
     4844        }
     4845        if (choice.numIters[1]>=0) {
     4846          dynamicObject->addToSumUpCost(CoinMin(choice.movement[1],maxMovement));
     4847          dynamicObject->addToSumUpChange(choice.upLowerBound-choice.initialValue);
     4848        }
     4849      }
     4850      newLower[jInt] = choice.upLowerBound;
     4851      if (choice.finished[0])
     4852        objLower[jInt] = choice.movement[0] + objectiveValue_;
     4853      else
     4854        objLower[jInt] = objectiveValue_;
     4855      newUpper[jInt] = choice.downUpperBound;
     4856      if (choice.finished[1])
     4857        objUpper[jInt] = choice.movement[1] + objectiveValue_;
     4858      else
     4859        objUpper[jInt] = objectiveValue_;
     4860      objMin = CoinMin(CoinMin(objLower[jInt], objUpper[jInt]), objMin);
     4861      objMovement[2*jInt]=choice.movement[0];
     4862      objMovement[2*jInt+1]=choice.movement[1];
     4863      double sumModified = choice.modified[0] + choice.modified[1] +
     4864        1.0e-15*(choice.sumModified[0]+choice.sumModified[1]);
     4865      if (choice.numIters[0]>=0&&choice.numIters[1]>=0)
     4866        sumModified *= 0.6;
     4867      interAction[jInt] = sumModified;
     4868      /*
     4869        End of evaluation for this candidate variable. Possibilities are:
     4870        * Both sides below cutoff; this variable is a candidate for branching.
     4871        * Both sides infeasible or above the objective cutoff: no further action
     4872        here. Break from the evaluation loop and assume the node will be purged
     4873        by the caller.
     4874        * One side below cutoff: Install the branch (i.e., fix the variable). Break
     4875        from the evaluation loop and assume the node will be reoptimised by the
     4876        caller.
     4877      */
     4878      threadStatus=0;
     4879      currentChoice++;
     4880      numberDone++;
     4881#ifdef USE_STRONG_THREADS
     4882      // say available
     4883      if (numberThreads) {
     4884        threadInfo.sayIdle(iThread);
     4885      }
     4886#endif
     4887      if (doAtEnd)
     4888        continue;
     4889      if (choice.movement[1] < 1.0e100) {
     4890        if (choice.movement[0] < 1.0e100) {
     4891          objMax = CoinMax(CoinMax(objLower[jInt], objUpper[jInt]), objMax);
     4892          // In case solution coming in was odd
     4893          choice.movement[1] = CoinMax(0.0, choice.movement[1]);
     4894          choice.movement[0] = CoinMax(0.0, choice.movement[0]);
     4895          // feasible -
     4896          model->messageHandler()->message(CBC_STRONG, *model->messagesPointer())
     4897            << iColumn << iColumn
     4898            << choice.movement[0] << choice.numIntInfeas[0]
     4899            << choice.movement[1] << choice.numIntInfeas[1]
     4900            << choice.initialValue
     4901            << CoinMessageEol;
     4902        } else {
     4903          // up feasible, down infeasible
     4904          needResolve = true;
     4905          numberToFix++;
     4906          saveLower[iColumn] = choice.upLowerBound;
     4907          solver->setColLower(iColumn, choice.upLowerBound);
     4908#ifdef USE_STRONG_THREADS
     4909          for (int i=0;i<numberThreads;i++) {
     4910            threadNeedsRefreshing[i] |= 1;
     4911          }
     4912#endif
     4913        }
     4914      } else {
     4915        if (choice.movement[0] < 1.0e100) {
     4916          // down feasible, up infeasible
     4917          needResolve = true;
     4918          numberToFix++;
     4919          saveUpper[iColumn] = choice.downUpperBound;
     4920          solver->setColUpper(iColumn, choice.downUpperBound);
     4921#ifdef USE_STRONG_THREADS
     4922          for (int i=0;i<numberThreads;i++) {
     4923            threadNeedsRefreshing[i] |= 2;
     4924          }
     4925#endif
     4926        } else {
     4927          // neither side feasible
     4928          COIN_DETAIL_PRINT(printf("Both infeasible for choice %d sequence %d\n", i,
     4929                                   model->object(choice.objectNumber)->columnNumber()));
     4930          //solver->writeMps("bad");
     4931          numberToFix = -1;
     4932          break;
     4933        }
     4934      }
     4935      if (numberIterationsAllowed <= 0)
     4936        break;
     4937      if (currentChoice==maxChoices)
     4938        currentChoice=0;
     4939    }
     4940    //printf("obj %d, col %d, down %g up %g value %g\n",iObject,iColumn,
     4941    //     choice.downMovement,choice.upMovement,value);
     4942  }
     4943  // Do at end if deterministic
     4944  if (doAtEnd) {
     4945    if (bestSolution) {
     4946      model->setBestSolution(CBC_STRONGSOL,
     4947                             bestSolutionValue,
     4948                             bestSolution) ;
     4949      model->setLastHeuristic(NULL);
     4950      model->incrementUsed(solver->getColSolution());
     4951      delete [] bestSolution;
     4952    }
     4953    for (int iDo = 0; iDo < numberLookIntegers; iDo++) {
     4954      StrongInfo & choice = choices[iDo];
     4955      int iColumn = choice.columnNumber;
     4956      int iObject = iColumn;
     4957      int jInt = back[iColumn];
     4958      double value = choice.initialValue;
     4959      double lowerValue = choice.downUpperBound;
     4960      double upperValue = choice.upLowerBound;
     4961      if (choice.movement[1] < 1.0e100) {
     4962        if (choice.movement[0] < 1.0e100) {
     4963          objMax = CoinMax(CoinMax(objLower[jInt], objUpper[jInt]), objMax);
     4964          // In case solution coming in was odd
     4965          choice.movement[1] = CoinMax(0.0, choice.movement[1]);
     4966          choice.movement[0] = CoinMax(0.0, choice.movement[0]);
     4967          // feasible -
     4968          model->messageHandler()->message(CBC_STRONG, *model->messagesPointer())
     4969            << iObject << iColumn
     4970            << choice.movement[0] << choice.numIntInfeas[0]
     4971            << choice.movement[1] << choice.numIntInfeas[1]
     4972            << value
     4973            << CoinMessageEol;
     4974        } else {
     4975          // up feasible, down infeasible
     4976          numberToFix++;
     4977          saveLower[iColumn] = upperValue;
     4978          solver->setColLower(iColumn, upperValue);
     4979        }
     4980      } else {
     4981        if (choice.movement[0] < 1.0e100) {
     4982          // down feasible, up infeasible
     4983          needResolve = true;
     4984          numberToFix++;
     4985          saveUpper[iColumn] = lowerValue;
     4986          solver->setColUpper(iColumn, lowerValue);
     4987        } else {
     4988          // neither side feasible
     4989          COIN_DETAIL_PRINT(printf("Both infeasible for choice %d sequence %d\n", i,
     4990                                   model->object(choice.objectNumber)->columnNumber()));
     4991          //solver->writeMps("bad");
     4992          numberToFix = -1;
     4993          break;
     4994        }
     4995      }
     4996    }
     4997  }
     4998  if (false) {
    39444999    const double * lower = solver->getColLower();
    39455000    const double * upper = solver->getColUpper();
    3946     const double * dj = solver->getReducedCost();
    3947     int numberObjects = model->numberObjects();
    3948     int numberColumns = model->getNumCols();
    3949     // Initialize arrays
    3950     int numberIntegers = model->numberIntegers();
    3951     int * back = new int[numberColumns];
    3952     const int * integerVariable = model->integerVariable();
    3953     for (i = 0; i < numberColumns; i++)
    3954         back[i] = -1;
    3955     // What results is
    3956     double * newLower = results;
    3957     double * objLower = newLower + numberIntegers;
    3958     double * newUpper = objLower + numberIntegers;
    3959     double * objUpper = newUpper + numberIntegers;
    3960     for (i = 0; i < numberIntegers; i++) {
    3961         int iColumn = integerVariable[i];
    3962         back[iColumn] = i;
    3963         newLower[i] = 0.0;
    3964         objLower[i] = -COIN_DBL_MAX;
    3965         newUpper[i] = 0.0;
    3966         objUpper[i] = -COIN_DBL_MAX;
    3967     }
    3968     double * saveUpper = new double[numberColumns];
    3969     double * saveLower = new double[numberColumns];
    3970     // Save solution in case heuristics need good solution later
    3971 
    3972     double * saveSolution = new double[numberColumns];
    3973     memcpy(saveSolution, solver->getColSolution(), numberColumns*sizeof(double));
    3974     model->reserveCurrentSolution(saveSolution);
    3975     for (i = 0; i < numberColumns; i++) {
    3976         saveLower[i] = lower[i];
    3977         saveUpper[i] = upper[i];
    3978     }
    3979     // Get arrays to sort
    3980     double * sort = new double[numberObjects];
    3981     int * whichObject = new int[numberObjects];
    3982     int numberToFix = 0;
    3983     int numberToDo = 0;
    3984     double integerTolerance =
    3985         model->getDblParam(CbcModel::CbcIntegerTolerance);
    3986     // point to useful information
    3987     OsiBranchingInformation usefulInfo = model->usefulInformation();
    3988     // and modify
    3989     usefulInfo.depth_ = depth_;
    3990 
    3991     // compute current state
    3992     int numberObjectInfeasibilities; // just odd ones
    3993     int numberIntegerInfeasibilities;
    3994     model->feasibleSolution(
    3995         numberIntegerInfeasibilities,
    3996         numberObjectInfeasibilities);
    3997 # ifdef COIN_HAS_CLP
    3998     OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
    3999     int saveClpOptions = 0;
    4000     bool fastIterations = (model->specialOptions() & 8) != 0;
    4001     if (osiclp && fastIterations) {
    4002         // for faster hot start
    4003         saveClpOptions = osiclp->specialOptions();
    4004         osiclp->setSpecialOptions(saveClpOptions | 8192);
    4005     }
    4006 # else
    4007     bool fastIterations = false ;
    4008 # endif
    4009     /*
    4010       Scan for branching objects that indicate infeasibility. Choose candidates
    4011       using priority as the first criteria, then integer infeasibility.
    4012 
    4013       The algorithm is to fill the array with a set of good candidates (by
    4014       infeasibility) with priority bestPriority.  Finding a candidate with
    4015       priority better (less) than bestPriority flushes the choice array. (This
    4016       serves as initialization when the first candidate is found.)
    4017 
    4018     */
    4019     numberToDo = 0;
    4020     for (i = 0; i < numberObjects; i++) {
    4021         OsiObject * object = model->modifiableObject(i);
    4022         CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    4023             dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    4024         if (!dynamicObject)
    4025             continue;
    4026         double infeasibility = object->checkInfeasibility(&usefulInfo);
    4027         int iColumn = dynamicObject->columnNumber();
    4028         if (saveUpper[iColumn] == saveLower[iColumn])
    4029             continue;
    4030         if (infeasibility)
    4031             sort[numberToDo] = -1.0e10 - infeasibility;
    4032         else
    4033             sort[numberToDo] = -fabs(dj[iColumn]);
    4034         whichObject[numberToDo++] = i;
    4035     }
    4036     // Save basis
    4037     CoinWarmStart * ws = solver->getWarmStart();
    4038     int saveLimit;
    4039     solver->getIntParam(OsiMaxNumIterationHotStart, saveLimit);
    4040     int targetIterations = CoinMax(500, numberIterationsAllowed / numberObjects);
    4041     if (saveLimit < targetIterations)
    4042         solver->setIntParam(OsiMaxNumIterationHotStart, targetIterations);
    4043     // Mark hot start
    4044     solver->markHotStart();
    4045     // Sort
    4046     CoinSort_2(sort, sort + numberToDo, whichObject);
    4047     double * currentSolution = model->currentSolution();
    4048     double objMin = 1.0e50;
    4049     double objMax = -1.0e50;
    4050     bool needResolve = false;
    4051     /*
    4052       Now calculate the cost forcing the variable up and down.
    4053     */
    4054     int iDo;
    4055     for (iDo = 0; iDo < numberToDo; iDo++) {
    4056         CbcStrongInfo choice;
    4057         int iObject = whichObject[iDo];
    4058         OsiObject * object = model->modifiableObject(iObject);
    4059         CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    4060             dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    4061         if (!dynamicObject)
    4062             continue;
    4063         int iColumn = dynamicObject->columnNumber();
    4064         int preferredWay;
    4065         /*
    4066           Update the information held in the object.
    4067         */
    4068         object->infeasibility(&usefulInfo, preferredWay);
    4069         double value = currentSolution[iColumn];
    4070         double nearest = floor(value + 0.5);
    4071         double lowerValue = floor(value);
    4072         bool satisfied = false;
    4073         if (fabs(value - nearest) <= integerTolerance || value < saveLower[iColumn] || value > saveUpper[iColumn]) {
    4074             satisfied = true;
    4075             double newValue;
    4076             if (nearest < saveUpper[iColumn]) {
    4077                 newValue = nearest + 1.0001 * integerTolerance;
    4078                 lowerValue = nearest;
    4079             } else {
    4080                 newValue = nearest - 1.0001 * integerTolerance;
    4081                 lowerValue = nearest - 1;
    4082             }
    4083             currentSolution[iColumn] = newValue;
    4084         }
    4085         double upperValue = lowerValue + 1.0;
    4086         //CbcSimpleInteger * obj =
    4087         //dynamic_cast <CbcSimpleInteger *>(object) ;
    4088         //if (obj) {
    4089         //choice.possibleBranch=obj->createCbcBranch(solver,&usefulInfo,preferredWay);
    4090         //} else {
    4091         CbcObject * obj =
    4092             dynamic_cast <CbcObject *>(object) ;
    4093         assert (obj);
    4094         choice.possibleBranch = obj->createCbcBranch(solver, &usefulInfo, preferredWay);
    4095         //}
    4096         currentSolution[iColumn] = value;
    4097         // Save which object it was
    4098         choice.objectNumber = iObject;
    4099         choice.numIntInfeasUp = numberUnsatisfied_;
    4100         choice.numIntInfeasDown = numberUnsatisfied_;
    4101         choice.downMovement = 0.0;
    4102         choice.upMovement = 0.0;
    4103         choice.numItersDown = 0;
    4104         choice.numItersUp = 0;
    4105         choice.fix = 0; // say not fixed
    4106         double objectiveChange ;
    4107         double newObjectiveValue = 1.0e100;
    4108         int j;
    4109         // status is 0 finished, 1 infeasible and other
    4110         int iStatus;
    4111         /*
    4112           Try the down direction first. (Specify the initial branching alternative as
    4113           down with a call to way(-1). Each subsequent call to branch() performs the
    4114           specified branch and advances the branch object state to the next branch
    4115           alternative.)
    4116         */
    4117         choice.possibleBranch->way(-1) ;
    4118         choice.possibleBranch->branch() ;
    4119         if (fabs(value - lowerValue) > integerTolerance) {
    4120             solver->solveFromHotStart() ;
    4121             /*
    4122               We now have an estimate of objective degradation that we can use for strong
    4123               branching. If we're over the cutoff, the variable is monotone up.
    4124               If we actually made it to optimality, check for a solution, and if we have
    4125               a good one, call setBestSolution to process it. Note that this may reduce the
    4126               cutoff, so we check again to see if we can declare this variable monotone.
    4127             */
    4128             if (solver->isProvenOptimal())
    4129                 iStatus = 0; // optimal
    4130             else if (solver->isIterationLimitReached()
    4131                      && !solver->isDualObjectiveLimitReached())
    4132                 iStatus = 2; // unknown
    4133             else
    4134                 iStatus = 1; // infeasible
    4135             newObjectiveValue = solver->getObjSense() * solver->getObjValue();
    4136             choice.numItersDown = solver->getIterationCount();
    4137             numberIterationsAllowed -= choice.numItersDown;
    4138             objectiveChange = newObjectiveValue  - objectiveValue_;
    4139             if (!iStatus) {
    4140                 choice.finishedDown = true ;
    4141                 if (newObjectiveValue >= cutoff) {
    4142                     objectiveChange = 1.0e100; // say infeasible
    4143                 } else {
    4144                     // See if integer solution
    4145                     if (model->feasibleSolution(choice.numIntInfeasDown,
    4146                                                 choice.numObjInfeasDown)
    4147                             && model->problemFeasibility()->feasible(model, -1) >= 0) {
    4148                         model->setBestSolution(CBC_STRONGSOL,
    4149                                                newObjectiveValue,
    4150                                                solver->getColSolution()) ;
    4151                         model->setLastHeuristic(NULL);
    4152                         model->incrementUsed(solver->getColSolution());
    4153                         cutoff = model->getCutoff();
    4154                         if (newObjectiveValue >= cutoff)        //  *new* cutoff
    4155                             objectiveChange = 1.0e100 ;
    4156                     }
    4157                 }
    4158             } else if (iStatus == 1) {
    4159                 objectiveChange = 1.0e100 ;
    4160             } else {
    4161                 // Can't say much as we did not finish
    4162                 choice.finishedDown = false ;
    4163             }
    4164             choice.downMovement = objectiveChange ;
    4165         }
    4166         // restore bounds
    4167         for ( j = 0; j < numberColumns; j++) {
    4168             if (saveLower[j] != lower[j])
    4169                 solver->setColLower(j, saveLower[j]);
    4170             if (saveUpper[j] != upper[j])
    4171                 solver->setColUpper(j, saveUpper[j]);
    4172         }
    4173         // repeat the whole exercise, forcing the variable up
    4174         choice.possibleBranch->branch();
    4175         if (fabs(value - upperValue) > integerTolerance) {
    4176             solver->solveFromHotStart() ;
    4177             /*
    4178               We now have an estimate of objective degradation that we can use for strong
    4179               branching. If we're over the cutoff, the variable is monotone up.
    4180               If we actually made it to optimality, check for a solution, and if we have
    4181               a good one, call setBestSolution to process it. Note that this may reduce the
    4182               cutoff, so we check again to see if we can declare this variable monotone.
    4183             */
    4184             if (solver->isProvenOptimal())
    4185                 iStatus = 0; // optimal
    4186             else if (solver->isIterationLimitReached()
    4187                      && !solver->isDualObjectiveLimitReached())
    4188                 iStatus = 2; // unknown
    4189             else
    4190                 iStatus = 1; // infeasible
    4191             newObjectiveValue = solver->getObjSense() * solver->getObjValue();
    4192             choice.numItersUp = solver->getIterationCount();
    4193             numberIterationsAllowed -= choice.numItersUp;
    4194             objectiveChange = newObjectiveValue  - objectiveValue_;
    4195             if (!iStatus) {
    4196                 choice.finishedUp = true ;
    4197                 if (newObjectiveValue >= cutoff) {
    4198                     objectiveChange = 1.0e100; // say infeasible
    4199                 } else {
    4200                     // See if integer solution
    4201                     if (model->feasibleSolution(choice.numIntInfeasUp,
    4202                                                 choice.numObjInfeasUp)
    4203                             && model->problemFeasibility()->feasible(model, -1) >= 0) {
    4204                         model->setBestSolution(CBC_STRONGSOL,
    4205                                                newObjectiveValue,
    4206                                                solver->getColSolution()) ;
    4207                         model->setLastHeuristic(NULL);
    4208                         model->incrementUsed(solver->getColSolution());
    4209                         cutoff = model->getCutoff();
    4210                         if (newObjectiveValue >= cutoff)        //  *new* cutoff
    4211                             objectiveChange = 1.0e100 ;
    4212                     }
    4213                 }
    4214             } else if (iStatus == 1) {
    4215                 objectiveChange = 1.0e100 ;
    4216             } else {
    4217                 // Can't say much as we did not finish
    4218                 choice.finishedUp = false ;
    4219             }
    4220             choice.upMovement = objectiveChange ;
    4221 
    4222             // restore bounds
    4223             for ( j = 0; j < numberColumns; j++) {
    4224                 if (saveLower[j] != lower[j])
    4225                     solver->setColLower(j, saveLower[j]);
    4226                 if (saveUpper[j] != upper[j])
    4227                     solver->setColUpper(j, saveUpper[j]);
    4228             }
    4229         }
    4230         // If objective goes above certain amount we can set bound
    4231         int jInt = back[iColumn];
    4232         newLower[jInt] = upperValue;
    4233         if (choice.finishedDown)
    4234             objLower[jInt] = choice.downMovement + objectiveValue_;
    4235         else
    4236             objLower[jInt] = objectiveValue_;
    4237         newUpper[jInt] = lowerValue;
    4238         if (choice.finishedUp)
    4239             objUpper[jInt] = choice.upMovement + objectiveValue_;
    4240         else
    4241             objUpper[jInt] = objectiveValue_;
    4242         objMin = CoinMin(CoinMin(objLower[jInt], objUpper[jInt]), objMin);
    4243         /*
    4244           End of evaluation for this candidate variable. Possibilities are:
    4245           * Both sides below cutoff; this variable is a candidate for branching.
    4246           * Both sides infeasible or above the objective cutoff: no further action
    4247           here. Break from the evaluation loop and assume the node will be purged
    4248           by the caller.
    4249           * One side below cutoff: Install the branch (i.e., fix the variable). Break
    4250           from the evaluation loop and assume the node will be reoptimised by the
    4251           caller.
    4252         */
    4253         if (choice.upMovement < 1.0e100) {
    4254             if (choice.downMovement < 1.0e100) {
    4255                 objMax = CoinMax(CoinMax(objLower[jInt], objUpper[jInt]), objMax);
    4256                 // In case solution coming in was odd
    4257                 choice.upMovement = CoinMax(0.0, choice.upMovement);
    4258                 choice.downMovement = CoinMax(0.0, choice.downMovement);
    4259                 // feasible -
    4260                 model->messageHandler()->message(CBC_STRONG, *model->messagesPointer())
    4261                 << iObject << iColumn
    4262                 << choice.downMovement << choice.numIntInfeasDown
    4263                 << choice.upMovement << choice.numIntInfeasUp
    4264                 << value
    4265                 << CoinMessageEol;
    4266             } else {
    4267                 // up feasible, down infeasible
    4268                 if (!satisfied)
    4269                     needResolve = true;
    4270                 choice.fix = 1;
    4271                 numberToFix++;
    4272                 saveLower[iColumn] = upperValue;
    4273                 solver->setColLower(iColumn, upperValue);
    4274             }
    4275         } else {
    4276             if (choice.downMovement < 1.0e100) {
    4277                 // down feasible, up infeasible
    4278                 if (!satisfied)
    4279                     needResolve = true;
    4280                 choice.fix = -1;
    4281                 numberToFix++;
    4282                 saveUpper[iColumn] = lowerValue;
    4283                 solver->setColUpper(iColumn, lowerValue);
    4284             } else {
    4285                 // neither side feasible
    4286                 COIN_DETAIL_PRINT(printf("Both infeasible for choice %d sequence %d\n", i,
    4287                                          model->object(choice.objectNumber)->columnNumber()));
    4288                 delete ws;
    4289                 ws = NULL;
    4290                 //solver->writeMps("bad");
    4291                 numberToFix = -1;
    4292                 delete choice.possibleBranch;
    4293                 choice.possibleBranch = NULL;
    4294                 break;
    4295             }
    4296         }
    4297         delete choice.possibleBranch;
    4298         if (numberIterationsAllowed <= 0)
    4299             break;
    4300         //printf("obj %d, col %d, down %g up %g value %g\n",iObject,iColumn,
    4301         //     choice.downMovement,choice.upMovement,value);
    4302     }
    4303     COIN_DETAIL_PRINT(printf("Best possible solution %g, can fix more if solution of %g found - looked at %d variables in %d iterations\n",
    4304                              objMin, objMax, iDo, model->numberAnalyzeIterations() - numberIterationsAllowed));
    4305     model->setNumberAnalyzeIterations(numberIterationsAllowed);
     5001    for (int i=0;i<numberColumns;i++) {
     5002      if (lower[i]!=saveLower[i]||upper[i]!=saveUpper[i]) {
     5003        printf("%d changed- saved %g,%g now %g,%g\n",i,saveLower[i],saveUpper[i],
     5004               lower[i],upper[i]);
     5005      }
     5006    }
     5007  }
     5008  COIN_DETAIL_PRINT(printf("Best possible solution %g, can fix more if solution of %g found - looked at %d variables in %d iterations\n",
     5009                           objMin, objMax, iDo, model->numberAnalyzeIterations() - numberIterationsAllowed));
     5010  model->setNumberAnalyzeIterations(numberIterationsAllowed);
     5011  if (numberToFix>0) {
     5012    sprintf(general,"%d variable bounds modified by initial strong branching (%.2f seconds - %d iterations)",numberToFix,model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed);
     5013  } else if (numberToFix<0) {
     5014    sprintf(general,"initial strong branching found to be infeasible (%.2f seconds - %d iterations)",model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed);
     5015  } else if ((solveType&32)!=0) {
     5016    sprintf(general,"No variables fixed by initial strong branching (%.2f seconds - %d iterations)",model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed);
     5017  } else {
     5018    general[0]='\0';
     5019  }
     5020  if (general[0]!='\0')
     5021    model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     5022      << general
     5023      << CoinMessageEol;
     5024  double smallestEffect=COIN_DBL_MAX;
     5025  double largestEffect=0.0;
     5026  for (i = 0; i < numberIntegers; i++) {
     5027    int iColumn=integerVariable[i];
     5028    if (back[iColumn]>=numberColumns)
     5029      continue;
     5030    smallestEffect = CoinMin(smallestEffect,interAction[i]);
     5031    largestEffect = CoinMax(largestEffect,interAction[i]);
     5032  }
     5033  double groupValue[11];
     5034  int groupCounts[11]={0,0,0,0,0,0,0,0,0,0,0};
     5035  groupValue[10]=largestEffect;
     5036  for (int i=0;i<10;i++)
     5037    groupValue[i]=smallestEffect+i*0.1*(largestEffect-smallestEffect);
     5038  sprintf(general,"Looked at %d integer variables - smallest interaction %g",
     5039          numberLookIntegers,smallestEffect);
     5040  model->messageHandler()->message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1,
     5041                                    *model->messagesPointer())
     5042    << general
     5043    << CoinMessageEol;
     5044  for (int i = 0; i < numberIntegers; i++) {
     5045    int iColumn=integerVariable[i];
     5046    if (back[iColumn]>=numberColumns)
     5047      continue;
     5048    double value = interAction[i];
     5049    int j;
     5050    for (j=0;j<11;j++) {
     5051      if (value<=groupValue[j]||j==10)
     5052        break;
     5053    }
     5054    groupCounts[j]++;
     5055  }
     5056  general[0]='\0';
     5057  for (int i=0;i<11;i++)
     5058    sprintf(general+strlen(general),"%d <= %g ",groupCounts[i],groupValue[i]);
     5059  model->messageHandler()->message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1,
     5060                                    *model->messagesPointer())
     5061    << general
     5062    << CoinMessageEol;
     5063  smallestEffect=COIN_DBL_MAX;
     5064  largestEffect=0.0;
     5065  int numberChanged=0;
     5066  int numberZeroMoved=0;
     5067  for (i = 0; i < numberIntegers; i++) {
     5068    int iColumn=integerVariable[i];
     5069    if (back[iColumn]>=numberColumns)
     5070      continue;
     5071    for (int iWay=0;iWay<2;iWay++) {
     5072      double value=objMovement[2*i+iWay];
     5073      if (value<1.0e-7) {
     5074        numberZeroMoved++;
     5075      } else if (value<1.0e50) {
     5076        smallestEffect = CoinMin(smallestEffect,value);
     5077        largestEffect = CoinMax(largestEffect,value);
     5078      } else {
     5079        numberChanged++;
     5080      }
     5081    }
     5082  }
     5083  memset(groupCounts,0,sizeof(groupCounts));
     5084  groupValue[10]=largestEffect;
     5085  for (int i=0;i<10;i++)
     5086    groupValue[i]=smallestEffect+i*0.1*(largestEffect-smallestEffect);
     5087  sprintf(general,"Strong branching - %d bounds changed, %d zero objective changes and %d nonzero (smallest %g)",
     5088          numberChanged,numberZeroMoved,
     5089          2*numberLookIntegers-numberChanged-numberZeroMoved,smallestEffect);
     5090  model->messageHandler()->message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1,
     5091                                    *model->messagesPointer())
     5092    << general
     5093    << CoinMessageEol;
     5094  sprintf(general,"Breakdown ");
     5095  for (i = 0; i < numberIntegers; i++) {
     5096    int iColumn=integerVariable[i];
     5097    if (back[iColumn]>=numberColumns)
     5098      continue;
     5099    for (int iWay=0;iWay<2;iWay++) {
     5100      double value = objMovement[2*i+iWay];
     5101      int j;
     5102      for (j=0;j<11;j++) {
     5103        if (value<=groupValue[j]||j==10)
     5104          break;
     5105      }
     5106      groupCounts[j]++;
     5107    }
     5108  }
     5109  for (int i=0;i<11;i++)
     5110    sprintf(general+strlen(general),"%d <= %g ",groupCounts[i],groupValue[i]);
     5111  model->messageHandler()->message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1,
     5112                                    *model->messagesPointer())
     5113    << general
     5114    << CoinMessageEol;
     5115  delete [] objMovement;
     5116  if ((solveType&2)==0) {
    43065117    // Delete the snapshot
    43075118    solver->unmarkHotStart();
    4308     // back to normal
    4309     solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ;
    4310     solver->setIntParam(OsiMaxNumIterationHotStart, saveLimit);
    4311     // restore basis
    4312     solver->setWarmStart(ws);
     5119  }
     5120  // back to normal
     5121  solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ;
     5122  solver->setIntParam(OsiMaxNumIterationHotStart, saveLimit);
     5123  // restore basis
     5124  solver->setWarmStart(ws);
     5125  // skip if infeasible
     5126  if (numberToFix<0)
     5127    solveType=0;
     5128  int numberBoundsChanged=0;
     5129  if ((solveType&16)==0) {
     5130    double size=numberRows;
     5131    size*=numberColumns;
     5132    if (size>1000000) {
     5133      if ((solveType&32)!=0)
     5134        model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     5135          << "Skipping analyze on other columns as problem too large"
     5136          << CoinMessageEol;
     5137      solveType &= ~2;
     5138    }
     5139  }
     5140  if ((solveType&2)!=0) {
     5141# ifdef COIN_HAS_CLP
     5142  if (osiclp&&(solveType&2)!=0) {
     5143    ClpPrimalColumnPivot * primalColumnPivot=NULL;
     5144  }
     5145#endif
     5146    double * newLower = new double [2*numberColumns];
     5147    double * newUpper = newLower + numberColumns;
     5148    // look at ints/all - should be parametrics - for now primal
     5149    OsiSolverInterface * temp = solver->clone();
     5150    //temp->setHintParam(OsiDoDualInResolve, false, OsiHintDo) ;
     5151    temp->setHintParam(OsiDoReducePrint, true, OsiHintTry);
     5152    temp->setDblParam(OsiDualObjectiveLimit, COIN_DBL_MAX);
     5153    temp->resolve();
     5154    {
     5155      const double * lower =temp->getColLower();
     5156      const double * upper =temp->getColUpper();
     5157      for (int i=0;i<numberColumns;i++) {
     5158        assert (lower[i]==saveLower[i]);
     5159        assert (upper[i]==saveUpper[i]);
     5160      }
     5161    }
    43135162    delete ws;
    4314 
    4315     delete [] sort;
    4316     delete [] whichObject;
    4317     delete [] saveLower;
    4318     delete [] saveUpper;
    4319     delete [] back;
    4320     // restore solution
    4321     solver->setColSolution(saveSolution);
     5163    ws = temp->getWarmStart();
     5164    staticInfo.ws=ws;
     5165    // add constraint
     5166    int * indices = reinterpret_cast<int *>(newUpper);
     5167    double * obj = newLower;
     5168    memcpy(obj,solver->getObjCoefficients(),numberColumns*sizeof(double));
     5169    int n=0;
     5170    for (int i=0;i<numberColumns;i++) {
     5171      if (obj[i]) {
     5172        indices[n]=i;
     5173        obj[n++]=obj[i];
     5174      }
     5175    }
     5176    if (n) {
     5177      double cutoff=model->getCutoff();
     5178      // relax a little bit
     5179      cutoff += 1.0e-4;
     5180      double offset;
     5181      temp->getDblParam(OsiObjOffset, offset);
     5182      temp->addRow(n,indices,obj,-COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset);
     5183      for (int iThread=0;iThread<numberThreads;iThread++) {
     5184        OsiSolverInterface * solver=
     5185          reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2);
     5186        solver->addRow(n,indices,obj,-COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset);
     5187      }
     5188    }
     5189    // zero objective
     5190    for (int i = 0; i < numberColumns; i++) {
     5191      newLower[i]=0.0;
     5192    }
     5193    temp->setObjective(newLower);
     5194    for (int iThread=0;iThread<numberThreads;iThread++) {
     5195      OsiSolverInterface * solver=
     5196        reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2);
     5197      solver->setObjective(newLower);
     5198      solver->setDblParam(OsiDualObjectiveLimit, COIN_DBL_MAX);
     5199      threadNeedsRefreshing[iThread]=3;
     5200    }
     5201    for (int i = 0; i < numberColumns; i++) {
     5202      newLower[i]=lower[i];
     5203      newUpper[i]=upper[i];
     5204    }
     5205    double * thisSolution = CoinCopyOfArray(temp->getColSolution(),numberColumns);
     5206    double primalTolerance;
     5207    solver->getDblParam(OsiPrimalTolerance,primalTolerance);
     5208    iDo=0;
     5209    iDone=-1;
     5210    numberDone=0;
     5211    int iThread=0;
     5212    threadStatus=0;
     5213    currentChoice=0;
     5214    staticInfo.solveType=100; //mark for analyze
     5215    staticInfo.originalSolution=thisSolution;
     5216    whenPrint=(numberColumns+9)/10;
     5217    while (numberDone<numberColumns) {
     5218      if ((solveType&32)!=0&&numberDone==whenPrint) {
     5219        whenPrint += (numberColumns+9)/10;
     5220        sprintf(general,"%d variables looked at - %d bounds changed by secondary solves (%.2f seconds - %d iterations)",numberDone,numberBoundsChanged,model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed);
     5221        model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     5222          << general
     5223          << CoinMessageEol;
     5224      }
     5225#ifdef USE_STRONG_THREADS
     5226      if (numberThreads) {
     5227        threadInfo.waitParallelTask(1,iThread,iDo<numberColumns);
     5228        threadStatus = 1+threadInfo.threadInfo_[iThread].status;
     5229        currentChoice=iThread;
     5230        if (threadNeedsRefreshing[iThread]) {
     5231          OsiSolverInterface * solver=
     5232            reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2);
     5233          if ((threadNeedsRefreshing[iThread]&1)!=0)
     5234            solver->setColLower(saveLower);
     5235          if ((threadNeedsRefreshing[iThread]&2)!=0)
     5236            solver->setColUpper(saveUpper);
     5237          threadNeedsRefreshing[iThread]=0;
     5238        }
     5239      }
     5240#endif
     5241      if (threadStatus==0&&iDo<numberColumns) {
     5242        StrongInfo & choice = choices[currentChoice];
     5243        StrongBundle & bundle = bundles[currentChoice];
     5244        bundle.whichChoice=currentChoice;
     5245        memset(&choice,0,sizeof(StrongInfo));
     5246        int iColumn = iDo;
     5247        iDo++; //started this one
     5248        int typeSolve=0;
     5249        if (thisSolution[iColumn]>newLower[iColumn]+integerTolerance)
     5250          typeSolve=1;
     5251        if (thisSolution[iColumn]<newUpper[iColumn]-integerTolerance)
     5252          typeSolve += 2;
     5253        if (typeSolve&&back[iColumn]>=0) {
     5254          if (thisSolution[iColumn]<newLower[iColumn]+0.9999)
     5255            typeSolve &= ~1;
     5256          if (thisSolution[iColumn]>newUpper[iColumn]-0.9999)
     5257            typeSolve &= ~2;
     5258          if (temp->isBinary(iColumn))
     5259            typeSolve=0; // already done
     5260        }
     5261        if (typeSolve==0 || newUpper[iColumn]==newLower[iColumn]) {
     5262#ifdef USE_STRONG_THREADS
     5263          // say available
     5264          if (numberThreads) {
     5265            threadInfo.sayIdle(iThread);
     5266          }
     5267#endif
     5268          numberDone++;
     5269          continue;
     5270        }
     5271        // Save which object it was
     5272        choice.columnNumber = iColumn;
     5273        choice.initialValue=thisSolution[iColumn];
     5274        choice.movement[0]=COIN_DBL_MAX;
     5275        choice.movement[1]=-COIN_DBL_MAX;
     5276        choice.upLowerBound=newUpper[iColumn];
     5277        choice.downUpperBound=newLower[iColumn];
     5278        if ((typeSolve&1)==0)
     5279          choice.numIters[0]=-1; // mark as not done
     5280        if ((typeSolve&2)==0)
     5281          choice.numIters[1]=-1; // mark as not done
     5282        bundle.choice=&choice;
     5283        bundle.solver = temp;
     5284#ifdef USE_STRONG_THREADS
     5285        if (numberThreads) {
     5286          bundle.solver=reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[iThread].extraInfo2);
     5287          threadStatus=0;
     5288#ifdef DETAIL_THREAD
     5289          printf("Starting task for column %d on thread %d\n",
     5290                 choice.columnNumber,iThread);
     5291#endif
     5292          threadInfo.startParallelTask(1,iThread,&bundle);
     5293        } else {
     5294#endif
     5295          threadStatus=2;
     5296          solveAnalyze(&bundle);
     5297#ifdef USE_STRONG_THREADS
     5298        }
     5299#endif
     5300      }
     5301      if (threadStatus) {
     5302        int whichChoice = bundles[iThread].whichChoice; 
     5303        StrongInfo & choice = choices[whichChoice];
     5304        int iColumn=choice.columnNumber;
     5305        if(choice.modified[0]) {
     5306          numberToFix = -numberColumns-1;
     5307        }
     5308        double gotLower=COIN_DBL_MAX;
     5309        double gotUpper=-COIN_DBL_MAX;
     5310        if (choice.numIters[0]>=0) {
     5311          // go down
     5312          double value = choice.movement[0];
     5313          if (value>newLower[iColumn]+10.0*integerTolerance) {
     5314            if (back[iColumn]>=0)
     5315              value = ceil(value);
     5316            else
     5317              value = CoinMax(newLower[iColumn],value-1.0e-7-1.0e-8*fabs(value));
     5318            if (value>newLower[iColumn]+1.0e-8*(1.0+fabs(value))) {
     5319              sprintf(general,"Secondary analysis solve increases lower bound on %d from %g to %g%s",
     5320                      iColumn,newUpper[iColumn],value,(back[iColumn]>=0) ? "(integer)" : "");
     5321              model->messageHandler()->message(CBC_FPUMP2, *model->messagesPointer())
     5322                << general
     5323                << CoinMessageEol;
     5324              numberBoundsChanged++;
     5325              if (value>newUpper[iColumn]-primalTolerance) {
     5326                value=newUpper[iColumn];
     5327                if (value>newUpper[iColumn]+10.0*primalTolerance) {
     5328                  // infeasible
     5329                  numberToFix=-numberColumns-1;
     5330                }
     5331              }
     5332              gotLower = value;
     5333            }
     5334          }
     5335        }
     5336        if (choice.numIters[1]>=0) {
     5337          // go up
     5338          double value=choice.movement[1];
     5339          if (value<newUpper[iColumn]-10.0*integerTolerance) {
     5340            if (back[iColumn]>=0)
     5341              value = floor(value);
     5342            else
     5343              value = CoinMin(newUpper[iColumn],value+1.0e-7+1.0e-8*fabs(value));
     5344            if (value<newUpper[iColumn]-1.0e-8*(1.0+fabs(value))) {
     5345              sprintf(general,"Secondary analysis solve decreases upper bound on %d from %g to %g%s",
     5346                      iColumn,newUpper[iColumn],value,(back[iColumn]>=0) ? "(integer)" : "");
     5347              model->messageHandler()->message(CBC_FPUMP2, *model->messagesPointer())
     5348                << general
     5349                << CoinMessageEol;
     5350              numberBoundsChanged++;
     5351              if (value<newLower[iColumn]+primalTolerance) {
     5352                value=newLower[iColumn];
     5353                if (value<newLower[iColumn]-10.0*primalTolerance) {
     5354                  // infeasible
     5355                  numberToFix=-numberColumns-1;
     5356                }
     5357              }
     5358              gotUpper=value;
     5359            }
     5360          }
     5361        }
     5362        if (gotLower!=COIN_DBL_MAX) {
     5363          newLower[iColumn]=gotLower;
     5364          temp->setColLower(iColumn,gotLower);
     5365          if (!doAtEnd)
     5366            solver->setColLower(iColumn,gotLower);
     5367        }
     5368        if (gotUpper!=-COIN_DBL_MAX) {
     5369          gotUpper=CoinMax(gotUpper,newLower[iColumn]);
     5370          newUpper[iColumn]=gotUpper;
     5371          temp->setColUpper(iColumn,gotUpper);
     5372          if (!doAtEnd)
     5373            solver->setColUpper(iColumn,gotUpper);
     5374        }
     5375        threadStatus=0;
     5376        currentChoice++;
     5377        numberDone++;
     5378        for (int iWay=0;iWay<2;iWay++) {
     5379          if (choice.numIters[iWay]>0)
     5380            numberIterationsAllowed -= choice.numIters[iWay];
     5381        }
     5382        if (currentChoice==maxChoices)
     5383          currentChoice=0;
     5384#ifdef USE_STRONG_THREADS
     5385        // say available
     5386        if (numberThreads) {
     5387          threadInfo.sayIdle(iThread);
     5388        }
     5389#endif
     5390      }
     5391    }
     5392    delete [] thisSolution;
     5393    delete temp;
     5394    delete [] newLower;
     5395  }
    43225396# ifdef COIN_HAS_CLP
    4323     if (osiclp)
    4324         osiclp->setSpecialOptions(saveClpOptions);
     5397  if (osiclp) {
     5398    delete staticInfo.dualRowPivot;
     5399    delete staticInfo.primalColumnPivot;
     5400    ClpSimplex * simplex = osiclp->getModelPtr();
     5401    ClpDualRowPivot * dualRowPivot=simplex->dualRowPivot();
     5402    ClpDualRowSteepest * steep = dynamic_cast<ClpDualRowSteepest *>(dualRowPivot);
     5403    if (steep)
     5404      steep->setMode(3);
     5405  }
     5406#endif
     5407  if ((solveType&64)!=0) {
     5408    OsiSolverInterface * temp = solver->clone();
     5409    int numberRows=solver->getNumRows();
     5410    int numberContinuousRows=model->numberRowsAtContinuous();
     5411    int * del = new int[numberRows-numberContinuousRows];
     5412    for (int i=numberContinuousRows;i<numberRows;i++)
     5413      del[i-numberContinuousRows]=i;
     5414    temp->deleteRows(numberRows-numberContinuousRows,del);
     5415    delete [] del;
     5416# ifdef COIN_HAS_CLP
     5417    if (!osiclp) {
     5418#endif
     5419      solver->writeMps("analyzed");
     5420      temp->writeMps("analyzed2");
     5421# ifdef COIN_HAS_CLP
     5422    } else {
     5423      OsiClpSolverInterface * osiclp2 = dynamic_cast< OsiClpSolverInterface*> (temp);
     5424      osiclp->getModelPtr()->writeMps("analyzed.mps",2,1);
     5425      osiclp2->getModelPtr()->writeMps("analyzed2.mps",2,1);
     5426    }
     5427#endif
     5428    delete temp;
     5429    model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     5430      << "Models saved on 'analyzed' and 'analyzed2'"
     5431      << CoinMessageEol;
     5432  }
     5433  delete [] choices;
     5434  delete [] bundles;
     5435#ifdef USE_STRONG_THREADS
     5436  if (numberThreads) {
     5437    threadInfo.waitAllTasks();
     5438    for (int i=0;i<numberThreads;i++) {
     5439      delete reinterpret_cast<OsiSolverInterface *>(threadInfo.threadInfo_[i].extraInfo2);
     5440    }
     5441  }
     5442#endif
     5443  delete ws;
     5444 
     5445  delete [] sort;
     5446  delete [] whichObject;
     5447  delete [] saveLower;
     5448  delete [] saveUpper;
     5449  delete [] back;
     5450  // restore solution
     5451  solver->setColSolution(saveSolution);
     5452# ifdef COIN_HAS_CLP
     5453  if (osiclp)
     5454    osiclp->setSpecialOptions(saveClpOptions);
    43255455# endif
    4326     model->reserveCurrentSolution(saveSolution);
    4327     delete [] saveSolution;
    4328     if (needResolve)
    4329         solver->resolve();
     5456  delete [] saveSolution;
     5457  solver->resolve();
     5458  if (numberToFix<0&&!solver->isProvenOptimal()) {
     5459    // infeasible
     5460    model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     5461      << "Analysis shows problem to be infeasible"
     5462      << CoinMessageEol;
    43305463    return numberToFix;
     5464  }
     5465  if (numberBoundsChanged) {
     5466    sprintf(general,"%d bounds changed by secondary solves (%.2f seconds - %d iterations)",
     5467            numberBoundsChanged,model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed);
     5468    model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     5469      << general
     5470      << CoinMessageEol;
     5471  } else if ((solveType&32)!=0) {
     5472    sprintf(general,"No bounds changed by secondary solves (%.2f seconds - %d iterations)",
     5473            model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed);
     5474    model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer())
     5475      << general
     5476      << CoinMessageEol;
     5477  }
     5478  model->reserveCurrentSolution(solver->getColSolution());
     5479  if ((solveType&1)!=0) {
     5480    if (groupCounts[0]*4>numberIntegers) {
     5481      // change priority on this group
     5482      int generalPriority=-10000000;
     5483      for (int i = 0; i < numberIntegers; i++) {
     5484        OsiObject * object = model->modifiableObject(i);
     5485        CbcSimpleInteger * integerObject =
     5486          dynamic_cast <CbcSimpleInteger *>(object) ;
     5487        if (!integerObject)
     5488          continue;
     5489        generalPriority = CoinMax(generalPriority,integerObject->priority());
     5490      }
     5491      for (int i = 0; i < numberIntegers; i++) {
     5492        OsiObject * object = model->modifiableObject(i);
     5493        CbcSimpleInteger * integerObject =
     5494          dynamic_cast <CbcSimpleInteger *>(object) ;
     5495        if (!integerObject)
     5496          continue;
     5497        if (!interAction[i]&&integerObject->priority()==generalPriority)
     5498          integerObject->setPriority(generalPriority+1);
     5499      }
     5500    }
     5501  }
     5502  return numberToFix;
    43315503}
    43325504
  • trunk/Cbc/src/CbcSimpleIntegerDynamicPseudoCost.hpp

    r1943 r2094  
    250250    }
    251251
     252    /// Number times branched
     253    inline int numberTimesBranched() const {
     254        return numberTimesDown_ + numberTimesUp_;
     255    }
    252256    /// Down number times infeasible
    253257    inline int numberTimesDownInfeasible() const {
  • trunk/Cbc/src/CbcSolver.cpp

    r2093 r2094  
    22612261                            else if (parameters_[iParam].type() == CBC_PARAM_INT_EXPERIMENT) {
    22622262                                int addFlags=0;
     2263                                // switch on some later features if >999
     2264                                if (value>999) {
     2265                                  int switchValue=value/1000;
     2266                                  const char * message = NULL;
     2267                                  value -= 1000*switchValue;
     2268                                  parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_, parameters_)].setIntValue(0/*value*/);
     2269                                  switch (switchValue) {
     2270                                  default:
     2271                                  case 4:
     2272                                    // hotstart 500, -200 cut passes
     2273                                    message=parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValueWithMessage(500);
     2274                                    if (!noPrinting_&&message)
     2275                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2276                                        << message << CoinMessageEol;
     2277                                    message=parameters_[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters_, parameters_)].setIntValueWithMessage(-200);
     2278                                    if (!noPrinting_&&message)
     2279                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2280                                        << message << CoinMessageEol;
     2281                                  case 3:
     2282                                    // multiple 4
     2283                                    message=parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].setIntValueWithMessage(4);
     2284                                    if (!noPrinting_&&message)
     2285                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2286                                        << message << CoinMessageEol;
     2287                                  case 2:
     2288                                    // rens plus all diving at root
     2289                                    message=parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_)].setIntValueWithMessage(16);
     2290                                    if (!noPrinting_&&message)
     2291                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2292                                        << message << CoinMessageEol;
     2293                                    model_.setNumberAnalyzeIterations(-value);
     2294                                    // -tune 7 zero,lagomory,gmi at root - probing on
     2295                                  case 1:
     2296                                    tunePreProcess=7;
     2297                                    message=parameters_[whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_)].setIntValueWithMessage(7);
     2298                                    if (!noPrinting_&&message)
     2299                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2300                                        << message << CoinMessageEol;
     2301                                    //message = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].setIntValueWithMessage(1025);
     2302                                    //if (!noPrinting_&&message)
     2303                                    //    generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2304                                    //  << message << CoinMessageEol;
     2305                                    message=parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("on");
     2306                                    probingAction = 1;
     2307                                    if (!noPrinting_&&message)
     2308                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2309                                        << message << CoinMessageEol;
     2310                                    message=parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
     2311                                    if (!noPrinting_&&message)
     2312                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2313                                        << message << CoinMessageEol;
     2314                                    message=parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
     2315                                    if (!noPrinting_&&message)
     2316                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2317                                        << message << CoinMessageEol;
     2318                                    GMIAction = 2;
     2319                                    message=parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root");
     2320                                    if (!noPrinting_&&message)
     2321                                        generalMessageHandler->message(CLP_GENERAL, generalMessages)
     2322                                        << message << CoinMessageEol;
     2323                                  }
     2324                                  value = 0;
     2325                                }
    22632326                                if (value>=10) {
    22642327                                  addFlags = 1048576*(value/10);
     
    33163379                        // User can set options - main difference is lack of model and CglPreProcess
    33173380                        goodModel = true;
     3381                        parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].setIntValue(0);
    33183382                        /*
    33193383                          Run branch-and-cut. First set a few options -- node comparison, scaling.
     
    50035067                                babModel_->addCutGenerator(&flowGen, translate[flowAction], "FlowCover");
    50045068                                accuracyFlag[numberGenerators] = 2;
    5005                                 switches[numberGenerators++] = 1;
     5069                                switches[numberGenerators++] = 0;
    50065070                            }
    50075071                            if (twomirAction && (complicatedInteger != 1 ||
     
    52365300                            // Used to be automatically set
    52375301                            int mipOptions = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].intValue() % 10000;
    5238                             if (mipOptions != (1057)) {
     5302                            if (mipOptions != (1057) && mipOptions != 1025 ) {
    52395303                                sprintf(generalPrint, "mip options %d", mipOptions);
    52405304                                generalMessageHandler->message(CLP_GENERAL, generalMessages)
     
    55835647                                            int iStart = starts[iSOS];
    55845648                                            int n = starts[iSOS+1] - iStart;
     5649                                            //#define MAKE_SOS_CLIQUES
     5650#ifndef MAKE_SOS_CLIQUES
    55855651                                            objects[iSOS] = new CbcSOS(babModel_, n, which + iStart, weight + iStart,
    55865652                                                                       iSOS, type[iSOS]);
     5653#else
     5654                                            objects[iSOS] =
     5655                                              new CbcClique(babModel_, 1, n, which + iStart,
     5656                                                            NULL,-iSOS-1);
     5657#endif
    55875658                                            // branch on long sets first
    55885659                                            objects[iSOS]->setPriority(numberColumns - n);
     
    56775748                                        if (objSOS)
    56785749                                            continue;
     5750#ifdef MAKE_SOS_CLIQUES
     5751                                        // skip cliques
     5752                                        CbcClique * objClique =
     5753                                            dynamic_cast <CbcClique *>(objects[iObj]) ;
     5754                                        if (objClique)
     5755                                            continue;
     5756#endif
    56795757                                        int iColumn = objects[iObj]->columnNumber();
    56805758                                        assert (iColumn >= 0);
     
    66066684                                int jParam = whichParam(CBC_PARAM_STR_CUTOFF_CONSTRAINT,
    66076685                                                        numberParameters_, parameters_);
    6608                                 if(parameters_[jParam].currentOptionAsInteger())
     6686                                if(parameters_[jParam].currentOptionAsInteger()) {
    66096687                                  babModel_->setCutoffAsConstraint(true);
     6688                                  int moreOptions=babModel_->moreSpecialOptions();
     6689                                  if(parameters_[jParam].currentOptionAsInteger()==4)
     6690                                    babModel_->setMoreSpecialOptions(moreOptions|4194304);
     6691                                }
    66106692                                int multipleRoot = parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].intValue();
    66116693                                if (multipleRoot<10000) {
     
    69397021#ifndef CLP_INVESTIGATE
    69407022                                    CglImplication * implication = dynamic_cast<CglImplication*>(generator->generator());
    6941                                     if (implication)
     7023                                    if (implication && !generator->numberCutsInTotal())
    69427024                                        continue;
    69437025#endif
  • trunk/Cbc/src/CbcThread.cpp

    r2081 r2094  
    596596CbcBaseModel::stopThreads(int type)
    597597{
     598    CbcModel * baseModel = children_[0].baseModel();
    598599    if (type < 0) {
    599600        // max nodes ?
     
    608609          }
    609610        }
     611        for (int i = 0; i < numberThreads_; i++) {
     612          baseModel->incrementExtra(threadModel_[i]->getExtraNodeCount(),
     613                                    threadModel_[i]->numberExtraIterations(),
     614                                    threadModel_[i]->getFathomCount());
     615          threadModel_[i]->zeroExtra();
     616        }
    610617        return;
    611618    }
     
    613620        children_[i].wait(1, 0);
    614621        assert (children_[i].returnCode() == -1);
     622        baseModel->incrementExtra(threadModel_[i]->getExtraNodeCount(),
     623                                  threadModel_[i]->numberExtraIterations(),
     624                                  threadModel_[i]->getFathomCount());
    615625        threadModel_[i]->setInfoInChild(-2, NULL);
    616626        children_[i].setReturnCode( 0);
     
    14631473            }
    14641474        }
     1475        // add new global cuts
     1476        CbcRowCuts * baseGlobal = baseModel->globalCuts();
     1477        CbcRowCuts * thisGlobal = globalCuts();
     1478        int baseNumberCuts = baseGlobal->sizeRowCuts();
     1479        int thisNumberCuts = thisGlobal->sizeRowCuts();
     1480        for (int i=thisNumberCuts;i<baseNumberCuts;i++) {
     1481          thisGlobal->addCutIfNotDuplicate(*baseGlobal->cut(i));
     1482        }
     1483        numberGlobalCutsIn_ = baseNumberCuts;
    14651484    } else if (mode == 1) {
    14661485        lockThread();
     
    15021521        if (stuff->createdNode())
    15031522            baseModel->tree_->push(stuff->createdNode());
     1523        // add new global cuts to base and take off
     1524        CbcRowCuts * baseGlobal = baseModel->globalCuts();
     1525        CbcRowCuts * thisGlobal = globalCuts();
     1526        int thisNumberCuts = thisGlobal->sizeRowCuts();
     1527        for (int i=thisNumberCuts-1;i>=numberGlobalCutsIn_;i--) {
     1528          baseGlobal->addCutIfNotDuplicate(*thisGlobal->cut(i),thisGlobal->cut(i)->whichRow());
     1529          thisGlobal->eraseRowCut(i);
     1530        }
     1531        //thisGlobal->truncate(numberGlobalCutsIn_);
     1532        numberGlobalCutsIn_ = 999999;
    15041533        unlockThread();
    15051534    } else if (mode == 2) {
     
    15751604            tree_->setComparison(*nodeCompare_) ;
    15761605        }
     1606        delete continuousSolver_;
    15771607        continuousSolver_ = baseModel->continuousSolver_->clone();
    15781608        // make sure solvers have correct message handler
     
    18601890
    18611891        for (j = numberRowCutsBefore; j < numberRowCutsAfter; j++) {
    1862             whichGenerator_[numberBefore++] = i ;
     1892            whichGenerator_[numberBefore++] = i  ;
    18631893            const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ;
    18641894            if (thisCut->lb() > thisCut->ub())
     
    18961926                    printf("Old cut added - violation %g\n",
    18971927                           thisCut->violated(cbcColSolution_)) ;
    1898                 whichGenerator_[numberOld++] = -1;
     1928                whichGenerator_[numberOld++] = 999;
    18991929                theseCuts.insert(*thisCut) ;
    19001930            }
  • trunk/Cbc/src/CbcTree.cpp

    r2022 r2094  
    637637            if (status != CoinWarmStartBasis::basic &&
    638638                    model->addedCuts()[i]) {
    639                 if (!model->addedCuts()[i]->decrement(numberLeft))
     639                  if (!model->addedCuts()[i]->decrement(numberLeft))
    640640                    delete model->addedCuts()[i];
    641641            }
     
    646646            // take off node
    647647            if (model->addedCuts()[i]) {
    648                 if (!model->addedCuts()[i]->decrement(numberLeft))
     648                if (model->parallelMode()!=1) {
     649                  if (!model->addedCuts()[i]->decrement(numberLeft))
    649650                    delete model->addedCuts()[i];
     651                }
    650652            }
    651653          }
     
    750752        if (lastNode_->nodeInfo()->parent() == x->nodeInfo()) {
    751753            // x is parent of lastNode_ so put x on heap
    752             //#define CBCTREE_PRINT
     754          //#define CBCTREE_PRINT
    753755#ifdef CBCTREE_PRINT
    754756            printf("pushX x %x (%x at depth %d n %d) is parent of lastNode_ %x (%x at depth %d n %d)\n",
  • trunk/Cbc/src/unitTestClp.cpp

    r1984 r2094  
    201201  objective function.
    202202*/
     203#if 1
    203204    PUSH_MPS("10teams", 230, 2025, 924, 917, 1, false);
    204205    PUSH_MPS("air03", 124, 10757, 340160, 338864.25, 0, false);
     
    228229    PUSH_MPS("harp2", 112, 2993, -73899798.00, -74353341.502, 6, false);
    229230    PUSH_MPS("khb05250", 101, 1350, 106940226, 95919464.0, 0, false);
     231#endif
    230232    PUSH_MPS("l152lav", 97, 1989, 4722, 4656.36, 1, false);
    231233    PUSH_MPS("lseu", 28, 89, 1120, 834.68, 0, false);
     
    581583#     endif
    582584      if (stuff && stuff[8] >= 1) {
     585        printf("CCColumns %d rows %d - depth %d\n",
     586               modelC->numberColumns(),modelC->numberRows(),
     587               model->fastNodeDepth());
    583588          if (modelC->numberColumns() + modelC->numberRows() <= 10000 &&
    584589                  model->fastNodeDepth() == -1)
    585               model->setFastNodeDepth(-9);
    586       }
    587     }
    588     //OsiObject * obj = new CbcBranchToFixLots(model,0.3,0.0,3,3000003);
    589     //model->addObjects(1,&obj);
    590     //delete obj;
     590            model->setFastNodeDepth(-10/*-9*/);
     591      }
     592    }
     593#ifdef CONFLICT_CUTS
     594    {
     595      model->setCutoffAsConstraint(true);
     596      int moreOptions=model->moreSpecialOptions();
     597      model->setMoreSpecialOptions(moreOptions|4194304);
     598    }
     599#endif
    591600/*
    592601  Finally, the actual call to solve the MIP with branch-and-cut.
Note: See TracChangeset for help on using the changeset viewer.