Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • stable/2.8/Cbc/src/CbcModel.cpp

    r1790 r1902  
    2424#include <cmath>
    2525#include <cfloat>
    26 
    2726#ifdef COIN_HAS_CLP
    2827// include Presolve from Clp
     
    6261#include "CbcFeasibilityBase.hpp"
    6362#include "CbcFathom.hpp"
     63#include "CbcFullNodeInfo.hpp"
    6464// include Probing
    6565#include "CglProbing.hpp"
     
    8080#include "CbcThread.hpp"
    8181/* Various functions local to CbcModel.cpp */
     82
     83static void * doRootCbcThread(void * voidInfo);
    8284
    8385namespace {
     
    356358
    357359/* End unnamed namespace for CbcModel.cpp */
    358 
    359360
    360361
     
    397398        int numberColumns = solver_->getNumCols() ;
    398399        // Column copy of matrix
    399         bool allPlusOnes = true;
    400         bool allOnes = true;
    401400        int problemType = -1;
    402401        const double * element = solver_->getMatrixByCol()->getElements();
     
    445444        if (!numberContinuousObj && numberIntegerObj <= 5 && numberIntegerWeight <= 100 &&
    446445                numberIntegerObj*3 < numberObjects_ && !parentModel_ && solver_->getNumRows() > 100)
    447             iType = 3 + 4;
     446          iType = 1 + 4 + ((moreSpecialOptions_&536870912)==0) ? 2 : 0;
    448447        else if (!numberContinuousObj && numberIntegerObj <= 100 &&
    449448                 numberIntegerObj*5 < numberObjects_ && numberIntegerWeight <= 100 &&
    450449                 !parentModel_ &&
    451450                 solver_->getNumRows() > 100 && cost != -COIN_DBL_MAX)
    452             iType = 2 + 4;
     451          iType = 4 + ((moreSpecialOptions_&536870912)==0) ? 2 : 0;
    453452        else if (!numberContinuousObj && numberIntegerObj <= 100 &&
    454453                 numberIntegerObj*5 < numberObjects_ &&
     
    509508                << general << CoinMessageEol ;
    510509                // switch off clp type branching
    511                 fastNodeDepth_ = -1;
     510                // no ? fastNodeDepth_ = -1;
    512511                int highPriority = (branchOnSatisfied) ? -999 : 100;
    513512                for (int i = 0; i < numberObjects_; i++) {
     
    669668                        } else if (value == -1.0) {
    670669                            rhs[row[j]] = -0.5;
    671                             allPlusOnes = false;
    672670                        } else {
    673671                            rhs[row[j]] = -COIN_DBL_MAX;
    674                             allOnes = false;
    675672                        }
    676673                    }
     
    10701067                                          messages())
    10711068                << value << CoinMessageEol ;
    1072                 setDblParam(CbcModel::CbcCutoffIncrement, value*0.999) ;
     1069                setDblParam(CbcModel::CbcCutoffIncrement, CoinMax(value*0.999,value-1.0e-4)) ;
    10731070            }
    10741071        }
     
    15941591
    15951592{
     1593  if (!parentModel_)
    15961594    /*
    15971595      Capture a time stamp before we start (unless set).
     
    16071605    dblParam_[CbcLargestChange] = 0.0;
    16081606    intParam_[CbcNumberBranches] = 0;
    1609     // Double check optimization directions line up
    1610     dblParam_[CbcOptimizationDirection] = solver_->getObjSense();
     1607    // Force minimization !!!!
     1608    bool flipObjective = (solver_->getObjSense()<0.0);
     1609    if (flipObjective)
     1610      flipModel();
     1611    dblParam_[CbcOptimizationDirection] = 1.0; // was solver_->getObjSense();
    16111612    strongInfo_[0] = 0;
    16121613    strongInfo_[1] = 0;
     
    16351636            CbcDisasterHandler handler(this);
    16361637            clpSolver->passInDisasterHandler(&handler);
    1637             // Initialise solvers seed
    1638             clpSolver->getModelPtr()->setRandomSeed(1234567);
     1638            // Initialise solvers seed (unless users says not)
     1639            if ((specialOptions_&4194304)==0)
     1640              clpSolver->getModelPtr()->setRandomSeed(1234567);
    16391641#ifdef JJF_ZERO
    16401642            // reduce factorization frequency
     
    16681670            // pre-processing done
    16691671            if (strategy_->preProcessState() < 0) {
    1670                 // infeasible
    1671                 handler_->message(CBC_INFEAS, messages_) << CoinMessageEol ;
     1672                // infeasible (or unbounded)
    16721673                status_ = 0 ;
    1673                 secondaryStatus_ = 1;
     1674                if (!solver_->isProvenDualInfeasible()) {
     1675                  handler_->message(CBC_INFEAS, messages_) << CoinMessageEol ;
     1676                  secondaryStatus_ = 1;
     1677                } else {
     1678                  handler_->message(CBC_UNBOUNDED,
     1679                                    messages_) << CoinMessageEol ;
     1680                  secondaryStatus_ = 7;
     1681                }
    16741682                originalContinuousObjective_ = COIN_DBL_MAX;
     1683                if (flipObjective)
     1684                  flipModel();
    16751685                return ;
    16761686            } else if (numberObjects_ && object_) {
     
    16871697                // try and redo debugger
    16881698                OsiRowCutDebugger * debugger = const_cast<OsiRowCutDebugger *> (solver_->getRowCutDebuggerAlways());
    1689                 if (debugger)
     1699                if (debugger) {
     1700                  if (numberColumns<=debugger->numberColumns())
    16901701                    debugger->redoSolution(numberColumns, originalColumns);
     1702                  else
     1703                    debugger=NULL; // no idea how to handle (SOS?)
     1704                }
    16911705                // User-provided solution might have been best. Synchronise.
    16921706                if (bestSolution_) {
     
    20222036        originalContinuousObjective_ = COIN_DBL_MAX;
    20232037        solverCharacteristics_ = NULL;
     2038        if (flipObjective)
     2039          flipModel();
    20242040        return ;
    20252041    } else if (!numberObjects_ && (!strategy_ || strategy_->preProcessState() <= 0)) {
    20262042        // nothing to do
     2043        if (flipObjective)
     2044          flipModel();
    20272045        solverCharacteristics_ = NULL;
    20282046        bestObjective_ = solver_->getObjValue() * solver_->getObjSense();
     
    20482066    */
    20492067    // Convert to Osi if wanted
    2050     bool useOsiBranching = false;
    20512068    //OsiBranchingInformation * persistentInfo = NULL;
    20522069    if (branchingMethod_ && branchingMethod_->chooseMethod()) {
    2053         useOsiBranching = true;
    20542070        //persistentInfo = new OsiBranchingInformation(solver_);
    20552071        if (numberOriginalObjects) {
     
    21372153                handler_->message(CBC_HEURISTICS_OFF, messages_) << numberOdd << CoinMessageEol ;
    21382154            }
     2155            // If odd switch off AddIntegers
     2156            specialOptions_ &= ~65536;
    21392157        } else if (numberSOS) {
    21402158            specialOptions_ |= 128; // say can do SOS in dynamic mode
    21412159            // switch off fast nodes for now
    21422160            fastNodeDepth_ = -1;
     2161            moreSpecialOptions_ &= ~33554432; // no diving
    21432162        }
    21442163        if (numberThreads_ > 0) {
     
    22082227    continuousSolver_ = solver_->clone() ;
    22092228
     2229    // add cutoff as constraint if wanted
     2230    if (cutoffRowNumber_==-2) {
     2231      if (!parentModel_) {
     2232        int numberColumns=solver_->getNumCols();
     2233        double * obj = CoinCopyOfArray(solver_->getObjCoefficients(),numberColumns);
     2234        int * indices = new int [numberColumns];
     2235        int n=0;
     2236        for (int i=0;i<numberColumns;i++) {
     2237          if (obj[i]) {
     2238            indices[n]=i;
     2239            obj[n++]=obj[i];
     2240          }
     2241        }
     2242        if (n) {
     2243          double cutoff=getCutoff();
     2244          // relax a little bit
     2245          cutoff += 1.0e-4;
     2246          double offset;
     2247          solver_->getDblParam(OsiObjOffset, offset);
     2248          cutoffRowNumber_ = solver_->getNumRows();
     2249          solver_->addRow(n,indices,obj,-COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset);
     2250        } else {
     2251          // no objective!
     2252          cutoffRowNumber_ = -1;
     2253        }
     2254        delete [] indices;
     2255        delete [] obj;
     2256      } else {
     2257        // switch off
     2258        cutoffRowNumber_ = -1;
     2259      }
     2260    }
    22102261    numberRowsAtContinuous_ = getNumRows() ;
    22112262    solver_->saveBaseModel();
     
    23362387        CglCutGenerator * generator = generator_[iCutGenerator]->generator();
    23372388        generator->setAggressiveness(generator->getAggressiveness() + 100);
     2389        if (!generator->canDoGlobalCuts())
     2390          generator->setGlobalCuts(false);
    23382391    }
    23392392    OsiCuts cuts ;
     
    24042457      will be removed from the heuristics list by doHeuristicsAtRoot.
    24052458    */
     2459    // See if multiple runs wanted
     2460    CbcModel ** rootModels=NULL;
     2461    if (!parentModel_&&multipleRootTries_%100) {
     2462      double rootTimeCpu=CoinCpuTime();
     2463      double startTimeRoot=CoinGetTimeOfDay();
     2464      int numberRootThreads=1;
     2465      /* undocumented fine tuning
     2466         aabbcc where cc is number of tries
     2467         bb if nonzero is number of threads
     2468         aa if nonzero just do heuristics
     2469      */
     2470      int numberModels = multipleRootTries_%100;
     2471#ifdef CBC_THREAD
     2472      numberRootThreads = (multipleRootTries_/100)%100;
     2473      if (!numberRootThreads)
     2474        numberRootThreads=numberModels;
     2475#endif
     2476      int otherOptions = (multipleRootTries_/10000)%100;
     2477      rootModels = new CbcModel * [numberModels];
     2478      unsigned int newSeed = randomSeed_;
     2479      if (newSeed==0) {
     2480        double time = fabs(CoinGetTimeOfDay());
     2481        while (time>=COIN_INT_MAX)
     2482          time *= 0.5;
     2483        newSeed = static_cast<unsigned int>(time);
     2484      } else if (newSeed<0) {
     2485        newSeed = 123456789;
     2486#ifdef COIN_HAS_CLP
     2487        OsiClpSolverInterface * clpSolver
     2488          = dynamic_cast<OsiClpSolverInterface *> (solver_);
     2489        if (clpSolver) {
     2490          newSeed += clpSolver->getModelPtr()->randomNumberGenerator()->getSeed();
     2491        }
     2492#endif
     2493      }
     2494      CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis *> (solver_->getEmptyWarmStart());
     2495      int numberIterations=0;
     2496      for (int i=0;i<numberModels;i++) {
     2497        rootModels[i]=new CbcModel(*this);
     2498        rootModels[i]->setNumberThreads(0);
     2499        rootModels[i]->setMaximumNodes(otherOptions ? -1 : 0);
     2500        rootModels[i]->setRandomSeed(newSeed+10000000*i);
     2501        rootModels[i]->randomNumberGenerator()->setSeed(newSeed+50000000*i);
     2502        rootModels[i]->setMultipleRootTries(0);
     2503        // use seed
     2504        rootModels[i]->setSpecialOptions(specialOptions_ |(4194304|8388608));
     2505        rootModels[i]->setMoreSpecialOptions(moreSpecialOptions_ &
     2506                                             (~134217728));
     2507        rootModels[i]->solver_->setWarmStart(basis);
     2508#ifdef COIN_HAS_CLP
     2509        OsiClpSolverInterface * clpSolver
     2510          = dynamic_cast<OsiClpSolverInterface *> (rootModels[i]->solver_);
     2511        if (clpSolver) {
     2512          ClpSimplex * simplex = clpSolver->getModelPtr();
     2513          if (defaultHandler_)
     2514            simplex->setDefaultMessageHandler();
     2515          simplex->setRandomSeed(newSeed+20000000*i);
     2516          simplex->allSlackBasis();
     2517          int logLevel=simplex->logLevel();
     2518          if (logLevel==1)
     2519            simplex->setLogLevel(0);
     2520          if (i!=0) {
     2521            double random = simplex->randomNumberGenerator()->randomDouble();
     2522            int bias = static_cast<int>(random*(numberIterations/4));
     2523            simplex->setMaximumIterations(numberIterations/2+bias);
     2524            simplex->primal();
     2525            simplex->setMaximumIterations(COIN_INT_MAX);
     2526            simplex->dual();
     2527          } else {
     2528            simplex->primal();
     2529            numberIterations=simplex->numberIterations();
     2530          }
     2531          simplex->setLogLevel(logLevel);
     2532          clpSolver->setWarmStart(NULL);
     2533        }
     2534#endif
     2535        for (int j=0;j<numberHeuristics_;j++)
     2536          rootModels[i]->heuristic_[j]->setSeed(rootModels[i]->heuristic_[j]->getSeed()+100000000*i);
     2537        for (int j=0;j<numberCutGenerators_;j++)
     2538          rootModels[i]->generator_[j]->generator()->refreshSolver(rootModels[i]->solver_);
     2539      }
     2540      delete basis;
     2541#ifdef CBC_THREAD
     2542      if (numberRootThreads==1) {
     2543#endif
     2544        for (int iModel=0;iModel<numberModels;iModel++) {
     2545          doRootCbcThread(rootModels[iModel]);
     2546          // see if solved at root node
     2547          if (rootModels[iModel]->getMaximumNodes()) {
     2548            feasible=false;
     2549            break;
     2550          }
     2551        }
     2552#ifdef CBC_THREAD
     2553      } else {
     2554        Coin_pthread_t * threadId = new Coin_pthread_t [numberRootThreads];
     2555        for (int kModel=0;kModel<numberModels;kModel+=numberRootThreads) {
     2556          bool finished=false;
     2557          for (int iModel=kModel;iModel<CoinMin(numberModels,kModel+numberRootThreads);iModel++) {
     2558            pthread_create(&(threadId[iModel-kModel].thr), NULL,
     2559                           doRootCbcThread,
     2560                           rootModels[iModel]);
     2561          }
     2562          // wait
     2563          for (int iModel=kModel;iModel<CoinMin(numberModels,kModel+numberRootThreads);iModel++) {
     2564            pthread_join(threadId[iModel-kModel].thr, NULL);
     2565          }
     2566          // see if solved at root node
     2567          for (int iModel=kModel;iModel<CoinMin(numberModels,kModel+numberRootThreads);iModel++) {
     2568            if (rootModels[iModel]->getMaximumNodes())
     2569              finished=true;
     2570          }
     2571          if (finished) {
     2572            feasible=false;
     2573            break;
     2574          }
     2575        }
     2576        delete [] threadId;
     2577      }
     2578#endif
     2579      // sort solutions
     2580      int * which = new int [numberModels];
     2581      double * value = new double [numberModels];
     2582      int numberSolutions=0;
     2583      for (int iModel=0;iModel<numberModels;iModel++) {
     2584        if (rootModels[iModel]->bestSolution()) {
     2585          which[numberSolutions]=iModel;
     2586          value[numberSolutions++]=
     2587            -rootModels[iModel]->getMinimizationObjValue();
     2588        }
     2589      }
     2590      char general[100];
     2591      rootTimeCpu=CoinCpuTime()-rootTimeCpu;
     2592      if (numberRootThreads==1)
     2593        sprintf(general,"Multiple root solvers took a total of %.2f seconds\n",
     2594                rootTimeCpu);
     2595      else
     2596        sprintf(general,"Multiple root solvers took a total of %.2f seconds (%.2f elapsed)\n",
     2597                rootTimeCpu,CoinGetTimeOfDay()-startTimeRoot);
     2598      messageHandler()->message(CBC_GENERAL,
     2599                                messages())
     2600        << general << CoinMessageEol ;
     2601      CoinSort_2(value,value+numberSolutions,which);
     2602      // to get name
     2603      CbcHeuristicRINS dummyHeuristic;
     2604      dummyHeuristic.setHeuristicName("Multiple root solvers");
     2605      lastHeuristic_=&dummyHeuristic;
     2606      for (int i=0;i<numberSolutions;i++) {
     2607        double objValue = - value[i];
     2608        if (objValue<getCutoff()) {
     2609          int iModel=which[i];
     2610          setBestSolution(CBC_ROUNDING,objValue,
     2611                          rootModels[iModel]->bestSolution());
     2612        }
     2613      }
     2614      lastHeuristic_=NULL;
     2615      delete [] which;
     2616      delete [] value;
     2617    }
    24062618    // Do heuristics
    2407     if (numberObjects_)
     2619    if (numberObjects_&&!rootModels)
    24082620        doHeuristicsAtRoot();
    24092621    if (solverCharacteristics_->solutionAddsCuts()) {
     
    24212633      User hook, says John.
    24222634    */
    2423     if ( intParam_[CbcMaxNumNode] < 0)
    2424         eventHappened_ = true; // stop as fast as possible
     2635    if ( intParam_[CbcMaxNumNode] < 0
     2636      ||numberSolutions_>=getMaximumSolutions())
     2637      eventHappened_ = true; // stop as fast as possible
    24252638    stoppedOnGap_ = false ;
    24262639    // See if can stop on gap
    24272640    bestPossibleObjective_ = solver_->getObjValue() * solver_->getObjSense();
    2428     double testGap = CoinMax(dblParam_[CbcAllowableGap],
    2429                              CoinMax(fabs(bestObjective_), fabs(bestPossibleObjective_))
    2430                              * dblParam_[CbcAllowableFractionGap]);
    2431     if (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0
    2432         && bestObjective_ < 1.0e50) {
     2641    if(canStopOnGap()) {
    24332642        if (bestPossibleObjective_ < getCutoff())
    24342643            stoppedOnGap_ = true ;
     
    24842693    }
    24852694    // replace solverType
     2695    double * tightBounds = NULL;
    24862696    if (solverCharacteristics_->tryCuts())  {
    24872697
     
    24892699            // User event
    24902700            if (!eventHappened_ && feasible) {
     2701                if (rootModels) {
     2702                  // for fixings
     2703                  int numberColumns=solver_->getNumCols();
     2704                  tightBounds = new double [2*numberColumns];
     2705                  {
     2706                    const double * lower = solver_->getColLower();
     2707                    const double * upper = solver_->getColUpper();
     2708                    for (int i=0;i<numberColumns;i++) {
     2709                      tightBounds[2*i+0]=lower[i];
     2710                      tightBounds[2*i+1]=upper[i];
     2711                    }
     2712                  }
     2713                  int numberModels = multipleRootTries_%100;
     2714                  const OsiSolverInterface ** solvers = new
     2715                    const OsiSolverInterface * [numberModels];
     2716                  int numberRows=continuousSolver_->getNumRows();
     2717                  int maxCuts=0;
     2718                  for (int i=0;i<numberModels;i++) {
     2719                    solvers[i]=rootModels[i]->solver();
     2720                    const double * lower = solvers[i]->getColLower();
     2721                    const double * upper = solvers[i]->getColUpper();
     2722                    for (int j=0;j<numberColumns;j++) {
     2723                      tightBounds[2*j+0]=CoinMax(lower[j],tightBounds[2*j+0]);
     2724                      tightBounds[2*j+1]=CoinMin(upper[j],tightBounds[2*j+1]);
     2725                    }
     2726                    int numberRows2=solvers[i]->getNumRows();
     2727                    assert (numberRows2>=numberRows);
     2728                    maxCuts += numberRows2-numberRows;
     2729                    // accumulate statistics
     2730                    for (int j=0;j<numberCutGenerators_;j++) {
     2731                      generator_[j]->addStatistics(rootModels[i]->cutGenerator(j));
     2732                    }
     2733                  }
     2734                  for (int j=0;j<numberCutGenerators_;j++) {
     2735                    generator_[j]->scaleBackStatistics(numberModels);
     2736                  }
     2737                  //CbcRowCuts rowCut(maxCuts);
     2738                  const OsiRowCutDebugger *debugger = NULL;
     2739                  if ((specialOptions_&1) != 0)
     2740                    debugger = solver_->getRowCutDebugger() ;
     2741                  for (int iModel=0;iModel<numberModels;iModel++) {
     2742                    int numberRows2=solvers[iModel]->getNumRows();
     2743                    const CoinPackedMatrix * rowCopy = solvers[iModel]->getMatrixByRow();
     2744                    const int * rowLength = rowCopy->getVectorLengths();
     2745                    const double * elements = rowCopy->getElements();
     2746                    const int * column = rowCopy->getIndices();
     2747                    const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
     2748                    const double * rowLower = solvers[iModel]->getRowLower();
     2749                    const double * rowUpper = solvers[iModel]->getRowUpper();
     2750                    for (int iRow=numberRows;iRow<numberRows2;iRow++) {
     2751                      OsiRowCut rc;
     2752                      rc.setLb(rowLower[iRow]);
     2753                      rc.setUb(rowUpper[iRow]);
     2754                      CoinBigIndex start = rowStart[iRow];
     2755                      rc.setRow(rowLength[iRow],column+start,elements+start,false);
     2756                      if (debugger)
     2757                        CoinAssert (!debugger->invalidCut(rc));
     2758                      globalCuts_.addCutIfNotDuplicate(rc);
     2759                    }
     2760                    //int cutsAdded=globalCuts_.numberCuts()-numberCuts;
     2761                    //numberCuts += cutsAdded;
     2762                    //printf("Model %d gave %d cuts (out of %d possible)\n",
     2763                    //     iModel,cutsAdded,numberRows2-numberRows);
     2764                  }
     2765                  // normally replace global cuts
     2766                  //if (!globalCuts_.())
     2767                  //globalCuts_=rowCutrowCut.addCuts(globalCuts_);
     2768                  //rowCut.addCuts(globalCuts_);
     2769                  int nTightened=0;
     2770                  bool feasible=true;
     2771                  {
     2772                    double tolerance=1.0e-5;
     2773                    const double * lower = solver_->getColLower();
     2774                    const double * upper = solver_->getColUpper();
     2775                    for (int i=0;i<numberColumns;i++) {
     2776                      if (tightBounds[2*i+0]>tightBounds[2*i+1]) {
     2777                        feasible=false;
     2778                        printf("Bad bounds on %d %g,%g was %g,%g\n",
     2779                               i,tightBounds[2*i+0],tightBounds[2*i+1],
     2780                               lower[i],upper[i]);
     2781                      }
     2782                      //int k=0;
     2783                      double oldLower=lower[i];
     2784                      double oldUpper=upper[i];
     2785                      if (tightBounds[2*i+0]>oldLower+tolerance) {
     2786                        nTightened++;
     2787                        //k++;
     2788                        solver_->setColLower(i,tightBounds[2*i+0]);
     2789                      }
     2790                      if (tightBounds[2*i+1]<oldUpper-tolerance) {
     2791                        nTightened++;
     2792                        //k++;
     2793                        solver_->setColUpper(i,tightBounds[2*i+1]);
     2794                      }
     2795                      //if (k)
     2796                      //printf("new bounds on %d %g,%g was %g,%g\n",
     2797                      //       i,tightBounds[2*i+0],tightBounds[2*i+1],
     2798                      //       oldLower,oldUpper);
     2799                    }
     2800                    if (!feasible)
     2801                      abort(); // deal with later
     2802                  }
     2803                  delete [] tightBounds;
     2804                  tightBounds=NULL;
     2805                  char printBuffer[200];
     2806                  sprintf(printBuffer,"%d solvers added %d different cuts out of pool of %d",
     2807                          numberModels,globalCuts_.sizeRowCuts(),maxCuts);
     2808                  messageHandler()->message(CBC_GENERAL, messages())
     2809                    << printBuffer << CoinMessageEol ;
     2810                  if (nTightened) {
     2811                    sprintf(printBuffer,"%d bounds were tightened",
     2812                          nTightened);
     2813                    messageHandler()->message(CBC_GENERAL, messages())
     2814                      << printBuffer << CoinMessageEol ;
     2815                  }
     2816                  delete [] solvers;
     2817                }
     2818                if (!parentModel_&&(moreSpecialOptions_&67108864) != 0) {
     2819                  // load cuts from file
     2820                  FILE * fp = fopen("global.cuts","rb");
     2821                  if (fp) {
     2822                    size_t nRead;
     2823                    int numberColumns=solver_->getNumCols();
     2824                    int numCols;
     2825                    nRead = fread(&numCols, sizeof(int), 1, fp);
     2826                    if (nRead != 1)
     2827                      throw("Error in fread");
     2828                    if (numberColumns!=numCols) {
     2829                      printf("Mismatch on columns %d %d\n",numberColumns,numCols);
     2830                      fclose(fp);
     2831                    } else {
     2832                      // If rootModel just do some
     2833                      double threshold=-1.0;
     2834                      if (!multipleRootTries_)
     2835                        threshold=0.5;
     2836                      int initialCuts=0;
     2837                      int initialGlobal = globalCuts_.sizeRowCuts();
     2838                      double * elements = new double [numberColumns+2];
     2839                      int * indices = new int [numberColumns];
     2840                      int numberEntries=1;
     2841                      while (numberEntries>0) {
     2842                        nRead = fread(&numberEntries, sizeof(int), 1, fp);
     2843                        if (nRead != 1)
     2844                          throw("Error in fread");
     2845                        double randomNumber=randomNumberGenerator_.randomDouble();
     2846                        if (numberEntries>0) {
     2847                          initialCuts++;
     2848                          nRead = fread(elements, sizeof(double), numberEntries+2, fp);
     2849                          if (nRead != static_cast<size_t>(numberEntries+2))
     2850                            throw("Error in fread");
     2851                          nRead = fread(indices, sizeof(int), numberEntries, fp);
     2852                          if (nRead != static_cast<size_t>(numberEntries))
     2853                            throw("Error in fread");
     2854                          if (randomNumber>threshold) {
     2855                            OsiRowCut rc;
     2856                            rc.setLb(elements[numberEntries]);
     2857                            rc.setUb(elements[numberEntries+1]);
     2858                            rc.setRow(numberEntries,indices,elements,
     2859                                      false);
     2860                            rc.setGloballyValidAsInteger(2);
     2861                            globalCuts_.addCutIfNotDuplicate(rc) ;
     2862                          }
     2863                        }
     2864                      }
     2865                      fclose(fp);
     2866                      // fixes
     2867                      int nTightened=0;
     2868                      fp = fopen("global.fix","rb");
     2869                      if (fp) {
     2870                        nRead = fread(indices, sizeof(int), 2, fp);
     2871                        if (nRead != 2)
     2872                          throw("Error in fread");
     2873                        if (numberColumns!=indices[0]) {
     2874                          printf("Mismatch on columns %d %d\n",numberColumns,
     2875                                 indices[0]);
     2876                        } else {
     2877                          indices[0]=1;
     2878                          while (indices[0]>=0) {
     2879                            nRead = fread(indices, sizeof(int), 2, fp);
     2880                            if (nRead != 2)
     2881                              throw("Error in fread");
     2882                            int iColumn=indices[0];
     2883                            if (iColumn>=0) {
     2884                              nTightened++;
     2885                              nRead = fread(elements, sizeof(double), 4, fp);
     2886                              if (nRead != 4)
     2887                                throw("Error in fread");
     2888                              solver_->setColLower(iColumn,elements[0]);
     2889                              solver_->setColUpper(iColumn,elements[1]);
     2890                            }
     2891                          }
     2892                        }
     2893                      }
     2894                      if (fp)
     2895                        fclose(fp);
     2896                      char printBuffer[200];
     2897                      sprintf(printBuffer,"%d cuts read in of which %d were unique, %d bounds tightened",
     2898                             initialCuts,
     2899                             globalCuts_.sizeRowCuts()-initialGlobal,nTightened);
     2900                      messageHandler()->message(CBC_GENERAL, messages())
     2901                        << printBuffer << CoinMessageEol ;
     2902                      delete [] elements;
     2903                      delete [] indices;
     2904                    }
     2905                  }
     2906                }
    24912907                feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_,
    24922908                                         NULL);
     2909                if (multipleRootTries_&&
     2910                    (moreSpecialOptions_&134217728)!=0) {
     2911                  FILE * fp=NULL;
     2912                  size_t nRead;
     2913                  int numberColumns=solver_->getNumCols();
     2914                  int initialCuts=0;
     2915                  if ((moreSpecialOptions_&134217728)!=0) {
     2916                    // append so go down to end
     2917                    fp = fopen("global.cuts","r+b");
     2918                    if (fp) {
     2919                      int numCols;
     2920                      nRead = fread(&numCols, sizeof(int), 1, fp);
     2921                      if (nRead != 1)
     2922                        throw("Error in fread");
     2923                      if (numberColumns!=numCols) {
     2924                        printf("Mismatch on columns %d %d\n",numberColumns,numCols);
     2925                        fclose(fp);
     2926                        fp=NULL;
     2927                      }
     2928                    }
     2929                  }
     2930                  double * elements = new double [numberColumns+2];
     2931                  int * indices = new int [numberColumns];
     2932                  if (fp) {
     2933                    int numberEntries=1;
     2934                    while (numberEntries>0) {
     2935                      fpos_t position;
     2936                      fgetpos(fp, &position);
     2937                      nRead = fread(&numberEntries, sizeof(int), 1, fp);
     2938                      if (nRead != 1)
     2939                        throw("Error in fread");
     2940                      if (numberEntries>0) {
     2941                        initialCuts++;
     2942                        nRead = fread(elements, sizeof(double), numberEntries+2, fp);
     2943                        if (nRead != static_cast<size_t>(numberEntries+2))
     2944                          throw("Error in fread");
     2945                        nRead = fread(indices, sizeof(int), numberEntries, fp);
     2946                        if (nRead != static_cast<size_t>(numberEntries))
     2947                          throw("Error in fread");
     2948                      } else {
     2949                        // end
     2950                        fsetpos(fp, &position);
     2951                      }
     2952                    }
     2953                  } else {
     2954                    fp = fopen("global.cuts","wb");
     2955                    size_t nWrite;
     2956                    nWrite=fwrite(&numberColumns,sizeof(int),1,fp);
     2957                    if (nWrite != 1)
     2958                      throw("Error in fwrite");
     2959                  }
     2960                  size_t nWrite;
     2961                  // now append binding cuts
     2962                  int numberC=continuousSolver_->getNumRows();
     2963                  int numberRows=solver_->getNumRows();
     2964                  printf("Saving %d cuts (up from %d)\n",
     2965                         initialCuts+numberRows-numberC,initialCuts);
     2966                  const double * rowLower = solver_->getRowLower();
     2967                  const double * rowUpper = solver_->getRowUpper();
     2968                  // Row copy
     2969                  CoinPackedMatrix matrixByRow(*solver_->getMatrixByRow());
     2970                  const double * elementByRow = matrixByRow.getElements();
     2971                  const int * column = matrixByRow.getIndices();
     2972                  const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
     2973                  const int * rowLength = matrixByRow.getVectorLengths();
     2974                  for (int iRow=numberC;iRow<numberRows;iRow++) {
     2975                    int n=rowLength[iRow];
     2976                    assert (n);
     2977                    CoinBigIndex start=rowStart[iRow];
     2978                    memcpy(elements,elementByRow+start,n*sizeof(double));
     2979                    memcpy(indices,column+start,n*sizeof(int));
     2980                    elements[n]=rowLower[iRow];
     2981                    elements[n+1]=rowUpper[iRow];
     2982                    nWrite=fwrite(&n,sizeof(int),1,fp);
     2983                    if (nWrite != 1)
     2984                      throw("Error in fwrite");
     2985                    nWrite=fwrite(elements,sizeof(double),n+2,fp);
     2986                    if (nWrite != static_cast<size_t>(n+2))
     2987                      throw("Error in fwrite");
     2988                    nWrite=fwrite(indices,sizeof(int),n,fp);
     2989                    if (nWrite != static_cast<size_t>(n))
     2990                      throw("Error in fwrite");
     2991                  }
     2992                  // eof marker
     2993                  int eofMarker=-1;
     2994                  nWrite=fwrite(&eofMarker,sizeof(int),1,fp);
     2995                  if (nWrite != 1)
     2996                    throw("Error in fwrite");
     2997                  fclose(fp);
     2998                  // do tighter bounds (? later extra to original columns)
     2999                  int nTightened=0;
     3000                  const double * lower = solver_->getColLower();
     3001                  const double * upper = solver_->getColUpper();
     3002                  const double * originalLower = continuousSolver_->getColLower();
     3003                  const double * originalUpper = continuousSolver_->getColUpper();
     3004                  double tolerance=1.0e-5;
     3005                  for (int i=0;i<numberColumns;i++) {
     3006                    if (lower[i]>originalLower[i]+tolerance) {
     3007                      nTightened++;
     3008                    }
     3009                    if (upper[i]<originalUpper[i]-tolerance) {
     3010                      nTightened++;
     3011                    }
     3012                  }
     3013                  if (nTightened) {
     3014                    fp = fopen("global.fix","wb");
     3015                    size_t nWrite;
     3016                    indices[0]=numberColumns;
     3017                    if (originalColumns_)
     3018                      indices[1]=COIN_INT_MAX;
     3019                    else
     3020                      indices[1]=-1;
     3021                    nWrite=fwrite(indices,sizeof(int),2,fp);
     3022                    if (nWrite != 2)
     3023                      throw("Error in fwrite");
     3024                    for (int i=0;i<numberColumns;i++) {
     3025                      int nTightened=0;
     3026                      if (lower[i]>originalLower[i]+tolerance) {
     3027                        nTightened++;
     3028                      }
     3029                      if (upper[i]<originalUpper[i]-tolerance) {
     3030                        nTightened++;
     3031                      }
     3032                      if (nTightened) {
     3033                        indices[0]=i;
     3034                        if (originalColumns_)
     3035                          indices[1]=originalColumns_[i];
     3036                        elements[0]=lower[i];
     3037                        elements[1]=upper[i];
     3038                        elements[2]=originalLower[i];
     3039                        elements[3]=originalUpper[i];
     3040                        nWrite=fwrite(indices,sizeof(int),2,fp);
     3041                        if (nWrite != 2)
     3042                          throw("Error in fwrite");
     3043                        nWrite=fwrite(elements,sizeof(double),4,fp);
     3044                        if (nWrite != 4)
     3045                          throw("Error in fwrite");
     3046                      }
     3047                    }
     3048                    // eof marker
     3049                    indices[0]=-1;
     3050                    nWrite=fwrite(indices,sizeof(int),2,fp);
     3051                    if (nWrite != 2)
     3052                      throw("Error in fwrite");
     3053                    fclose(fp);
     3054                  }
     3055                  delete [] elements;
     3056                  delete [] indices;
     3057                }
    24933058                if ((specialOptions_&524288) != 0 && !parentModel_
    24943059                        && storedRowCuts_) {
     
    25813146        }
    25823147    }
     3148    if (rootModels) {
     3149      int numberModels = multipleRootTries_%100;
     3150      for (int i=0;i<numberModels;i++)
     3151        delete rootModels[i];
     3152      delete [] rootModels;
     3153    }
    25833154    // check extra info on feasibility
    25843155    if (!solverCharacteristics_->mipFeasible())
    25853156        feasible = false;
    2586 
     3157    // If max nodes==0 - don't do strong branching
     3158    if (!getMaximumNodes()) {
     3159      if (feasible)
     3160        feasible=false;
     3161      else
     3162        setMaximumNodes(1); //allow to stop on success
     3163    }
     3164    topOfTree_=NULL;
    25873165#ifdef CLP_RESOLVE
    25883166    if ((moreSpecialOptions_&2097152)!=0&&!parentModel_&&feasible) {
     
    26083186    // See if can stop on gap
    26093187    bestPossibleObjective_ = solver_->getObjValue() * solver_->getObjSense();
    2610     testGap = CoinMax(dblParam_[CbcAllowableGap],
    2611                       CoinMax(fabs(bestObjective_), fabs(bestPossibleObjective_))
    2612                       * dblParam_[CbcAllowableFractionGap]);
    2613     if (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0
    2614         && bestObjective_ < 1.0e50) {
     3188    if(canStopOnGap()) {
    26153189        if (bestPossibleObjective_ < getCutoff())
    26163190            stoppedOnGap_ = true ;
     
    27383312    }
    27393313#endif
     3314    if (!parentModel_&&(moreSpecialOptions_&268435456) != 0) {
     3315      // try idiotic idea
     3316      CbcObject * obj = new CbcIdiotBranch(this);
     3317      obj->setPriority(1); // temp
     3318      addObjects(1, &obj);
     3319      delete obj;
     3320    }
     3321   
    27403322    /*
    27413323      A hook to use clp to quickly explore some part of the tree.
     
    27473329        obj->setPriority(1);
    27483330        addObjects(1, &obj);
     3331        delete obj;
    27493332    }
    27503333    int saveNumberSolves = numberSolves_;
    27513334    int saveNumberIterations = numberIterations_;
    2752     if (fastNodeDepth_ >= 0 &&/*!parentModel_*/(specialOptions_&2048) == 0) {
     3335    if ((fastNodeDepth_ >= 0||(moreSpecialOptions_&33554432)!=0)
     3336        &&/*!parentModel_*/(specialOptions_&2048) == 0) {
    27533337        // add in a general depth object doClp
    27543338        int type = (fastNodeDepth_ <= 100) ? fastNodeDepth_ : -(fastNodeDepth_ - 100);
     3339        if ((moreSpecialOptions_&33554432)!=0)
     3340          type=12;
     3341        else
     3342          fastNodeDepth_ += 1000000;     // mark as done
    27553343        CbcObject * obj =
    27563344            new CbcGeneralDepth(this, type);
    27573345        addObjects(1, &obj);
    2758         // mark as done
    2759         fastNodeDepth_ += 1000000;
    27603346        delete obj;
    27613347        // fake number of objects
     
    27973383        delete [] upperBefore;
    27983384        delete saveSolver;
     3385        if (flipObjective)
     3386          flipModel();
    27993387        return;
    28003388    }
     
    28213409    //solverCharacteristics_->setSolver(solver_);
    28223410    if (feasible) {
    2823         //#define HOTSTART -1
     3411#define HOTSTART -1
    28243412#if HOTSTART<0
    28253413        if (bestSolution_ && !parentModel_ && !hotstartSolution_ &&
     
    29263514                        changed = true;
    29273515                    } else {
    2928                         if (nForced + nZeroDj > 50 ||
    2929                                 (nForced + nZeroDj)*4 > numberIntegers_)
     3516                        if (nForced + nZeroDj > 5000 ||
     3517                                (nForced + nZeroDj)*2 > numberIntegers_)
    29303518                            possible = false;
    29313519                    }
     
    32053793                CglImplication implication(probingInfo_);
    32063794                addCutGenerator(&implication, 1, "ImplicationCuts", true, false, false, -200);
     3795                generator_[numberCutGenerators_-1]->setGlobalCuts(true);
    32073796            } else {
    32083797                delete probingInfo_;
     
    32863875      this node is still live, push it onto the heap that holds the live set.
    32873876    */
    3288     double bestValue = 0.0 ;
    32893877    if (newNode) {
    3290         bestValue = newNode->objectiveValue();
    32913878        if (newNode->branchingObject()) {
    32923879            newNode->initializeInfo() ;
    32933880            tree_->push(newNode) ;
     3881            // save pointer to root node - so can pick up bounds
     3882            if (!topOfTree_)
     3883              topOfTree_ = dynamic_cast<CbcFullNodeInfo *>(newNode->nodeInfo()) ;
    32943884            if (statistics_) {
    32953885                if (numberNodes2_ == maximumStatistics_) {
     
    34534043              Decide if we want to do a restart.
    34544044            */
    3455             if (saveSolver) {
     4045            if (saveSolver && (specialOptions_&(512 + 32768)) != 0) {
    34564046                bool tryNewSearch = solverCharacteristics_->reducedCostsAccurate() &&
    34574047                                    (getCutoff() < 1.0e20 && getCutoff() < checkCutoffForRestart);
     
    37834373        }
    37844374        // See if can stop on gap
    3785         double testGap = CoinMax(dblParam_[CbcAllowableGap],
    3786                                  CoinMax(fabs(bestObjective_), fabs(bestPossibleObjective_))
    3787                                  * dblParam_[CbcAllowableFractionGap]);
    3788         if (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0
    3789             && bestObjective_ < 1.0e50) {
     4375        if(canStopOnGap()) {
    37904376            stoppedOnGap_ = true ;
    37914377        }
     
    38124398            if (!node || node->objectiveValue() > cutoff)
    38134399                continue;
    3814             // Do main work of solving node here
    3815             doOneNode(this, node, createdNode);
     4400            // Do main work of solving node here
     4401            doOneNode(this, node, createdNode);
    38164402#ifdef JJF_ZERO
    3817             if (node) {
    3818                 if (createdNode) {
    3819                     printf("Node %d depth %d, created %d depth %d\n",
    3820                            node->nodeNumber(), node->depth(),
    3821                            createdNode->nodeNumber(), createdNode->depth());
    3822                 } else {
    3823                     printf("Node %d depth %d,  no created node\n",
    3824                            node->nodeNumber(), node->depth());
    3825                 }
    3826             } else if (createdNode) {
    3827                 printf("Node exhausted, created %d depth %d\n",
    3828                        createdNode->nodeNumber(), createdNode->depth());
    3829             } else {
    3830                 printf("Node exhausted,  no created node\n");
    3831                 numberConsecutiveInfeasible = 2;
    3832             }
     4403            if (node) {
     4404              if (createdNode) {
     4405                printf("Node %d depth %d, created %d depth %d\n",
     4406                       node->nodeNumber(), node->depth(),
     4407                       createdNode->nodeNumber(), createdNode->depth());
     4408              } else {
     4409                printf("Node %d depth %d,  no created node\n",
     4410                       node->nodeNumber(), node->depth());
     4411              }
     4412            } else if (createdNode) {
     4413              printf("Node exhausted, created %d depth %d\n",
     4414                     createdNode->nodeNumber(), createdNode->depth());
     4415            } else {
     4416              printf("Node exhausted,  no created node\n");
     4417              numberConsecutiveInfeasible = 2;
     4418            }
    38334419#endif
    38344420            //if (createdNode)
     
    39594545            secondaryStatus_ = 4;
    39604546            status_ = 1 ;
    3961         } else if (eventHappened_) {
    3962             handler_->message(CBC_EVENT, messages_) << CoinMessageEol ;
    3963             secondaryStatus_ = 5;
    3964             status_ = 5 ;
     4547        } else if (numberSolutions_ >= intParam_[CbcMaxNumSol]) {
     4548            handler_->message(CBC_MAXSOLS, messages_) << CoinMessageEol ;
     4549            secondaryStatus_ = 6;
     4550            status_ = 1 ;
    39654551        } else if (isNodeLimitReached()) {
    39664552            handler_->message(CBC_MAXNODES, messages_) << CoinMessageEol ;
     
    39684554            status_ = 1 ;
    39694555        } else if (maximumNumberIterations_ >= 0 && numberIterations_ >= maximumNumberIterations_) {
    3970            handler_->message(CBC_MAXITERS, messages_) << CoinMessageEol ;
    3971            secondaryStatus_ = 3; /* do not have secondary status for iterlimit yet, so pretend nodelimit */
    3972            status_ = 1 ;
     4556            handler_->message(CBC_MAXITERS, messages_) << CoinMessageEol ;
     4557            secondaryStatus_ = 8;
     4558            status_ = 1 ;
    39734559        } else {
    3974             assert(numberSolutions_ >= intParam_[CbcMaxNumSol]);
    3975             handler_->message(CBC_MAXSOLS, messages_) << CoinMessageEol ;
    3976             secondaryStatus_ = 6;
    3977             status_ = 1 ;
     4560            handler_->message(CBC_EVENT, messages_) << CoinMessageEol ;
     4561            secondaryStatus_ = 5;
     4562            status_ = 5 ;
    39784563        }
    39794564    }
     
    42074792      outside world will be able to obtain information about the solution using
    42084793      public methods.
     4794
     4795      Don't replace if we are trying to save cuts
    42094796    */
    4210     if (bestSolution_ && (solverCharacteristics_->solverType() < 2 || solverCharacteristics_->solverType() == 4)) {
     4797    if (bestSolution_ && (solverCharacteristics_->solverType() < 2 || solverCharacteristics_->solverType() == 4) &&
     4798        ((specialOptions_&8388608)==0||(specialOptions_&2048)!=0)) {
    42114799        setCutoff(1.0e50) ; // As best solution should be worse than cutoff
     4800        // change cutoff as constraint if wanted
     4801        if (cutoffRowNumber_>=0) {
     4802          if (solver_->getNumRows()>cutoffRowNumber_)
     4803            solver_->setRowUpper(cutoffRowNumber_,1.0e50);
     4804        }
    42124805        // also in continuousSolver_
    42134806        if (continuousSolver_) {
     
    42684861      Destroy global cuts by replacing with an empty OsiCuts object.
    42694862    */
    4270     globalCuts_ = OsiCuts() ;
    4271     if (!bestSolution_) {
     4863    globalCuts_ = CbcRowCuts() ;
     4864    delete globalConflictCuts_;
     4865    globalConflictCuts_=NULL;
     4866    if (!bestSolution_ && (specialOptions_&8388608)==0) {
    42724867        // make sure lp solver is infeasible
    42734868        int numberColumns = solver_->getNumCols();
     
    42964891    }
    42974892#endif
    4298     if (fastNodeDepth_ >= 1000000 && !parentModel_) {
    4299         // delete object off end
    4300         delete object_[numberObjects_];
     4893    if ((fastNodeDepth_ >= 1000000 || (moreSpecialOptions_&33554432)!=0)
     4894         && !parentModel_) {
     4895      // delete object off end
     4896      delete object_[numberObjects_];
     4897      if ((moreSpecialOptions_&33554432)==0)
    43014898        fastNodeDepth_ -= 1000000;
    43024899    }
     
    43444941        }
    43454942    }
     4943    if (flipObjective)
     4944      flipModel();
    43464945#ifdef COIN_HAS_CLP
    43474946    {
     
    44595058        currentSolution_(NULL),
    44605059        testSolution_(NULL),
     5060        globalConflictCuts_(NULL),
    44615061        minimumDrop_(1.0e-4),
    44625062        numberSolutions_(0),
     
    44765076        numberIntegers_(0),
    44775077        numberRowsAtContinuous_(0),
     5078        cutoffRowNumber_(-1),
    44785079        maximumNumberCuts_(0),
    44795080        phase_(0),
     
    44965097        specialOptions_(0),
    44975098        moreSpecialOptions_(0),
     5099        topOfTree_(NULL),
    44985100        subTreeModel_(NULL),
     5101        heuristicModel_(NULL),
    44995102        numberStoppedSubTrees_(0),
    45005103        presolve_(0),
     
    45215124        ownObjects_(true),
    45225125        originalColumns_(NULL),
    4523         howOftenGlobalScan_(1),
     5126        howOftenGlobalScan_(3),
    45245127        numberGlobalViolations_(0),
    45255128        numberExtraIterations_(0),
     
    45345137        maximumWhich_(1000),
    45355138        maximumRows_(0),
     5139        randomSeed_(-1),
     5140        multipleRootTries_(0),
    45365141        currentDepth_(0),
    45375142        whichGenerator_(NULL),
     
    45495154        numberNewCuts_(0),
    45505155        searchStrategy_(-1),
     5156        strongStrategy_(0),
    45515157        numberStrongIterations_(0),
    45525158        resolveAfterTakeOffCuts_(true),
     
    46205226        sumChangeObjective1_(0.0),
    46215227        sumChangeObjective2_(0.0),
     5228        globalConflictCuts_(NULL),
    46225229        minimumDrop_(1.0e-4),
    46235230        numberSolutions_(0),
     
    46365243        secondaryStatus_(-1),
    46375244        numberRowsAtContinuous_(0),
     5245        cutoffRowNumber_(-1),
    46385246        maximumNumberCuts_(0),
    46395247        phase_(0),
     
    46535261        specialOptions_(0),
    46545262        moreSpecialOptions_(0),
     5263        topOfTree_(NULL),
    46555264        subTreeModel_(NULL),
     5265        heuristicModel_(NULL),
    46565266        numberStoppedSubTrees_(0),
    46575267        presolve_(0),
     
    46785288        ownObjects_(true),
    46795289        originalColumns_(NULL),
    4680         howOftenGlobalScan_(1),
     5290        howOftenGlobalScan_(3),
    46815291        numberGlobalViolations_(0),
    46825292        numberExtraIterations_(0),
     
    46915301        maximumWhich_(1000),
    46925302        maximumRows_(0),
     5303        randomSeed_(-1),
     5304        multipleRootTries_(0),
    46935305        currentDepth_(0),
    46945306        whichGenerator_(NULL),
     
    47065318        numberNewCuts_(0),
    47075319        searchStrategy_(-1),
     5320        strongStrategy_(0),
    47085321        numberStrongIterations_(0),
    47095322        resolveAfterTakeOffCuts_(true),
     
    48025415}
    48035416
     5417static int * resizeInt(int * array,int oldLength, int newLength)
     5418{
     5419  if (!array)
     5420    return NULL;
     5421  assert (newLength>oldLength);
     5422  int * newArray = new int [newLength];
     5423  memcpy(newArray,array,oldLength*sizeof(int));
     5424  delete [] array;
     5425  memset(newArray+oldLength,0,(newLength-oldLength)*sizeof(int));
     5426  return newArray;
     5427}
     5428static double * resizeDouble(double * array,int oldLength, int newLength)
     5429{
     5430  if (!array)
     5431    return NULL;
     5432  assert (newLength>oldLength);
     5433  double * newArray = new double [newLength];
     5434  memcpy(newArray,array,oldLength*sizeof(double));
     5435  delete [] array;
     5436  memset(newArray+oldLength,0,(newLength-oldLength)*sizeof(double));
     5437  return newArray;
     5438}
    48045439/*
    48055440  Assign a solver to the model (model assumes ownership)
     
    48255460
    48265461{
    4827     // resize best solution if exists
    4828     if (bestSolution_ && solver && solver_) {
     5462    // resize stuff if exists
     5463    if (solver && solver_) {
    48295464        int nOld = solver_->getNumCols();
    48305465        int nNew = solver->getNumCols();
    48315466        if (nNew > nOld) {
    4832             double * temp = new double[nNew];
    4833             memcpy(temp, bestSolution_, nOld*sizeof(double));
    4834             memset(temp + nOld, 0, (nNew - nOld)*sizeof(double));
    4835             delete [] bestSolution_;
    4836             bestSolution_ = temp;
     5467          originalColumns_ = resizeInt(originalColumns_,nOld,nNew);
     5468          usedInSolution_ = resizeInt(usedInSolution_,nOld,nNew);
     5469          continuousSolution_ = resizeDouble(continuousSolution_,nOld,nNew);
     5470          hotstartSolution_ = resizeDouble(hotstartSolution_,nOld,nNew);
     5471          bestSolution_ = resizeDouble(bestSolution_,nOld,nNew);
     5472          currentSolution_ = resizeDouble(currentSolution_,nOld,nNew);
     5473          if (savedSolutions_) {
     5474            for (int i = 0; i < maximumSavedSolutions_; i++)
     5475              savedSolutions_[i] = resizeDouble(savedSolutions_[i],nOld,nNew);
     5476          }
    48375477        }
    48385478    }
     
    48935533        sumChangeObjective1_(rhs.sumChangeObjective1_),
    48945534        sumChangeObjective2_(rhs.sumChangeObjective2_),
     5535        globalConflictCuts_(NULL),
    48955536        minimumDrop_(rhs.minimumDrop_),
    48965537        numberSolutions_(rhs.numberSolutions_),
     
    49085549        specialOptions_(rhs.specialOptions_),
    49095550        moreSpecialOptions_(rhs.moreSpecialOptions_),
     5551        topOfTree_(NULL),
    49105552        subTreeModel_(rhs.subTreeModel_),
     5553        heuristicModel_(NULL),
    49115554        numberStoppedSubTrees_(rhs.numberStoppedSubTrees_),
    49125555        presolve_(rhs.presolve_),
     
    49355578        maximumWhich_(rhs.maximumWhich_),
    49365579        maximumRows_(0),
     5580        randomSeed_(rhs.randomSeed_),
     5581        multipleRootTries_(rhs.multipleRootTries_),
    49375582        currentDepth_(0),
    49385583        whichGenerator_(NULL),
     
    49505595        numberNewCuts_(rhs.numberNewCuts_),
    49515596        searchStrategy_(rhs.searchStrategy_),
     5597        strongStrategy_(rhs.strongStrategy_),
    49525598        numberStrongIterations_(rhs.numberStrongIterations_),
    49535599        resolveAfterTakeOffCuts_(rhs.resolveAfterTakeOffCuts_),
     
    51195765    testSolution_ = currentSolution_;
    51205766    numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_;
     5767    cutoffRowNumber_ = rhs.cutoffRowNumber_;
    51215768    maximumNumberCuts_ = rhs.maximumNumberCuts_;
    51225769    phase_ = rhs.phase_;
     
    52575904        moreSpecialOptions_ = rhs.moreSpecialOptions_;
    52585905        subTreeModel_ = rhs.subTreeModel_;
     5906        heuristicModel_ = NULL;
    52595907        numberStoppedSubTrees_ = rhs.numberStoppedSubTrees_;
    52605908        presolve_ = rhs.presolve_;
     
    52795927        maximumCutPassesAtRoot_ = rhs.maximumCutPassesAtRoot_;
    52805928        maximumCutPasses_ = rhs.maximumCutPasses_;
     5929        randomSeed_ = rhs.randomSeed_;
     5930        multipleRootTries_ = rhs.multipleRootTries_;
    52815931        preferredWay_ = rhs.preferredWay_;
    52825932        currentPassNumber_ = rhs.currentPassNumber_;
     
    52845934        memcpy(dblParam_, rhs.dblParam_, sizeof(dblParam_));
    52855935        globalCuts_ = rhs.globalCuts_;
     5936        delete globalConflictCuts_;
     5937        globalConflictCuts_=NULL;
    52865938        int i;
    52875939        for (i = 0; i < numberCutGenerators_; i++) {
     
    53345986        masterThread_ = NULL;
    53355987        searchStrategy_ = rhs.searchStrategy_;
     5988        strongStrategy_ = rhs.strongStrategy_;
    53365989        numberStrongIterations_ = rhs.numberStrongIterations_;
    53375990        strongInfo_[0] = rhs.strongInfo_[0];
     
    54406093        }
    54416094        numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_;
     6095        cutoffRowNumber_ = rhs.cutoffRowNumber_;
    54426096        maximumNumberCuts_ = rhs.maximumNumberCuts_;
    54436097        phase_ = rhs.phase_;
     
    55626216    delete cutModifier_;
    55636217    cutModifier_ = NULL;
     6218    topOfTree_ = NULL;
    55646219    resetModel();
    55656220}
     
    56106265    maximumDepthActual_ = 0;
    56116266    numberDJFixed_ = 0.0;
    5612     delete probingInfo_;
    5613     probingInfo_ = NULL;
     6267    if (probingInfo_) {
     6268      delete probingInfo_;
     6269      probingInfo_ = NULL;
     6270      if (!generator_)
     6271        numberCutGenerators_=0;
     6272      // also get rid of cut generator
     6273      int n=0;
     6274      for (int i = 0; i < numberCutGenerators_; i++) {
     6275        CglImplication * cutGen;
     6276        cutGen = dynamic_cast<CglImplication *>(generator_[i]->generator());
     6277        if (!cutGen) {
     6278          generator_[n]=generator_[i];
     6279          virginGenerator_[n]=virginGenerator_[i];
     6280          n++;
     6281        } else {
     6282          cutGen->setProbingInfo(NULL);
     6283          delete generator_[i];
     6284          cutGen = dynamic_cast<CglImplication *>(virginGenerator_[i]->generator());
     6285          assert (cutGen);
     6286          cutGen->setProbingInfo(NULL);
     6287          delete virginGenerator_[i];
     6288        }
     6289      }
     6290      numberCutGenerators_=n;
     6291    }
    56146292    maximumStatistics_ = 0;
    56156293    delete [] analyzeResults_;
     
    56426320        tree_->cleanTree(this, -1.0e100, bestPossibleObjective_) ;
    56436321    subTreeModel_ = NULL;
     6322    heuristicModel_ = NULL;
    56446323    numberStoppedSubTrees_ = 0;
    56456324    numberInfeasibleNodes_ = 0;
     
    56586337    numberNewCuts_ = 0;
    56596338    searchStrategy_ = -1;
     6339    strongStrategy_ = 0;
    56606340    numberStrongIterations_ = 0;
    56616341    // Parameters which need to be reset
     
    56656345    dblParam_[CbcCurrentObjectiveValue] = 1.0e100;
    56666346    dblParam_[CbcCurrentMinimizationObjectiveValue] = 1.0e100;
     6347    delete globalConflictCuts_;
     6348    globalConflictCuts_=NULL;
    56676349}
    56686350/* Most of copy constructor
     
    56856367    maximumCutPassesAtRoot_ = rhs.maximumCutPassesAtRoot_;
    56866368    maximumCutPasses_ =  rhs.maximumCutPasses_;
     6369    randomSeed_ = rhs.randomSeed_;
     6370    multipleRootTries_ = rhs.multipleRootTries_;
    56876371    preferredWay_ = rhs.preferredWay_;
    56886372    resolveAfterTakeOffCuts_ = rhs.resolveAfterTakeOffCuts_;
     
    57256409        int i;
    57266410        for (i = 0; i < numberCutGenerators_; i++) {
    5727             if (mode < 2)
     6411            if (mode < 2) {
    57286412                generator_[i] = new CbcCutGenerator(*rhs.generator_[i]);
    5729             else
     6413            } else {
    57306414                generator_[i] = new CbcCutGenerator(*rhs.virginGenerator_[i]);
     6415                // But copy across maximumTries
     6416                generator_[i]->setMaximumTries(rhs.generator_[i]->maximumTries());
     6417            }
    57316418            virginGenerator_[i] = new CbcCutGenerator(*rhs.virginGenerator_[i]);
    57326419        }
     
    57906477    strongInfo_[6] = rhs.strongInfo_[6];
    57916478    numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_;
     6479    cutoffRowNumber_ = rhs.cutoffRowNumber_;
    57926480    maximumDepth_ = rhs.maximumDepth_;
    57936481}
     
    60046692{
    60056693    int nNode = 0;
     6694    CbcNodeInfo * nodeInfo = node->nodeInfo();
    60066695    int numberColumns = getNumCols();
    6007     CbcNodeInfo * nodeInfo = node->nodeInfo();
    60086696
    60096697    /*
     
    62616949#         endif
    62626950                    addCuts[numberToAdd++] = addedCuts_[i];
     6951#if 1
     6952                    if ((specialOptions_&1) != 0) {
     6953                      const OsiRowCutDebugger * debugger = solver_->getRowCutDebugger() ;
     6954                      if (debugger)
     6955                        CoinAssert (!debugger->invalidCut(*addedCuts_[i]));
     6956                    }
     6957#endif
    62636958                } else {
    62646959#         ifdef CHECK_CUT_COUNTS
     
    63687063                    delete [] which;
    63697064                }
     7065                //#define CHECK_DEBUGGER
     7066#ifdef CHECK_DEBUGGER
     7067                if ((specialOptions_&1) != 0 ) {
     7068                  const OsiRowCutDebugger * debugger =
     7069                    solver_->getRowCutDebugger();
     7070                  if (debugger) {
     7071                    for (int j=0;j<numberToAdd;j++)
     7072                      CoinAssert (!debugger->invalidCut(*addCuts[j]));
     7073                    //addCuts[j]->print();
     7074                  }
     7075                }
     7076#endif
    63707077                //int n2=solver_->getNumRows();
    63717078                //for (int j=0;j<numberToAdd;j++)
     
    64257132CbcModel::synchronizeHandlers(int /*makeDefault*/)
    64267133{
     7134    bool defaultHandler = defaultHandler_;
    64277135    if (!defaultHandler_) {
    64287136        // Must have clone
     
    64317139    }
    64327140#ifdef COIN_HAS_CLP
    6433     OsiClpSolverInterface * solver;
    6434     solver = dynamic_cast<OsiClpSolverInterface *>(solver_) ;
    6435     if (solver) {
     7141    if (!defaultHandler) {
     7142      OsiClpSolverInterface * solver;
     7143      solver = dynamic_cast<OsiClpSolverInterface *>(solver_) ;
     7144      if (solver) {
    64367145        solver->passInMessageHandler(handler_);
    64377146        solver->getModelPtr()->passInMessageHandler(handler_);
    6438     }
    6439     solver = dynamic_cast<OsiClpSolverInterface *>(continuousSolver_) ;
    6440     if (solver) {
     7147      }
     7148      solver = dynamic_cast<OsiClpSolverInterface *>(continuousSolver_) ;
     7149      if (solver) {
    64417150        solver->passInMessageHandler(handler_);
    64427151        solver->getModelPtr()->passInMessageHandler(handler_);
     7152      }
    64437153    }
    64447154#endif
     
    66237333#endif
    66247334    bool feasible = true ;
    6625     int lastNumberCuts = 0 ;
    66267335    int violated = 0 ;
    66277336    int numberRowsAtStart = solver_->getNumRows() ;
     
    66317340
    66327341    numberOldActiveCuts_ = numberRowsAtStart - numberRowsAtContinuous_ ;
    6633     numberNewCuts_ = 0 ;
     7342    numberNewCuts_ = cuts.sizeRowCuts();
     7343    int lastNumberCuts = numberNewCuts_ ;
     7344    if (numberNewCuts_) {
     7345      // from multiple root passes
     7346      const OsiRowCut **addCuts = new const OsiRowCut* [numberNewCuts_];
     7347      for (int i = 0; i < numberNewCuts_; i++) {
     7348        addCuts[i] = cuts.rowCutPtr(i);
     7349      }
     7350      solver_->applyRowCuts(numberNewCuts_, addCuts);
     7351      delete [] addCuts;
     7352    }
    66347353
    66357354    bool onOptimalPath = false ;
     
    66717390        objectiveValue = node->objectiveValue();
    66727391    }
     7392    int save = moreSpecialOptions_;
     7393    if ((moreSpecialOptions_&4194304)!=0)
     7394      moreSpecialOptions_ |= 8388608;
    66737395    int returnCode = resolve(node ? node->nodeInfo() : NULL, 1);
     7396    moreSpecialOptions_=save;
     7397#ifdef CONFLICT_CUTS
     7398#ifdef COIN_HAS_CLP
     7399    // if infeasible conflict analysis
     7400    if (solver_->isProvenPrimalInfeasible()&&!parentModel_&&
     7401        (moreSpecialOptions_&4194304)!=0&&clpSolver) {
     7402      //printf("infeasible - do conflict analysis\n");
     7403      assert (topOfTree_);
     7404      int iType=1;
     7405      OsiRowCut * cut = clpSolver->modelCut(topOfTree_->lower(),
     7406                                            topOfTree_->upper(),
     7407                                            numberRowsAtContinuous_,whichGenerator_,iType);
     7408      if (cut) {
     7409        printf("XXXXXX cut\n");
     7410        //cut->print();
     7411        if (!iType) {
     7412          makeGlobalCut(cut) ;
     7413          if ((specialOptions_&1) != 0) {
     7414            debugger = continuousSolver_->getRowCutDebugger() ;
     7415            if (debugger) {
     7416              if (debugger->invalidCut(*cut)) {
     7417                continuousSolver_->applyRowCuts(1,cut);
     7418                continuousSolver_->writeMps("bad");
     7419              }
     7420              CoinAssert (!debugger->invalidCut(*cut));
     7421            }
     7422          }
     7423        } else {
     7424          makePartialCut(cut);
     7425        }
     7426        delete cut;
     7427      }
     7428    }
     7429    if ((moreSpecialOptions_&4194304)!=0&&solver_->isProvenPrimalInfeasible()
     7430        &&clpSolver&&clpSolver->lastAlgorithm()==2&&
     7431        clpSolver->getModelPtr()->infeasibilityRay()&&
     7432        !parentModel_) {
     7433      printf("ray exists\n");
     7434    }
     7435#endif
     7436#endif   
    66747437#if COIN_DEVELOP>1
    66757438    //if (!solver_->getIterationCount()&&solver_->isProvenOptimal())
     
    69387701        allowZeroIterations = true;
    69397702    }
     7703    int saveNumberTries=numberTries;
    69407704    /*
    69417705      Is it time to scan the cuts in order to remove redundant cuts? If so, set
     
    69567720    // Really primalIntegerTolerance; relates to an illposed problem with various
    69577721    // integer solutions depending on integer tolerance.
    6958     double primalTolerance = 1.0e-7 ;
     7722    //double primalTolerance = 1.0e-7 ;
    69597723    // We may need to keep going on
    69607724    bool keepGoing = false;
     
    70067770        */
    70077771        int numberViolated = 0;
    7008         if (currentPassNumber_ == 1 && howOftenGlobalScan_ > 0 &&
     7772        if ((currentPassNumber_ == 1 ||!numberNodes_) && howOftenGlobalScan_ > 0 &&
    70097773                (numberNodes_ % howOftenGlobalScan_) == 0 &&
    70107774                (doCutsNow(1) || true)) {
    7011             int numberCuts = globalCuts_.sizeColCuts() ;
    7012             int i;
    7013             // possibly extend whichGenerator
    7014             resizeWhichGenerator(numberViolated, numberViolated + numberCuts);
    7015             for ( i = 0 ; i < numberCuts ; i++) {
    7016                 OsiColCut *thisCut = globalCuts_.colCutPtr(i) ;
    7017                 if (thisCut->violated(cbcColSolution_) > primalTolerance ||
    7018                         thisCut->effectiveness() == COIN_DBL_MAX) {
    7019 #ifdef CLP_INVESTIGATE
    7020                     if (thisCut->violated(cbcColSolution_) > primalTolerance)
    7021                         printf("Global cut added - violation %g\n",
    7022                                thisCut->violated(cbcColSolution_)) ;
    7023 #endif
    7024                     whichGenerator_[numberViolated++] = -1;
     7775            // global column cuts now done in node at top of tree
     7776            int numberCuts = numberCutGenerators_ ? globalCuts_.sizeRowCuts() : 0;
     7777            if (numberCuts) {
     7778              // possibly extend whichGenerator
     7779              resizeWhichGenerator(numberViolated, numberViolated + numberCuts);
     7780              // only add new cuts up to 10% of current elements
     7781              int numberElements = solver_->getNumElements();
     7782              int numberColumns = solver_->getNumCols();
     7783              int maximumAdd = CoinMax(numberElements/10,2*numberColumns)+100;
     7784              double * violations = new double[numberCuts];
     7785              int * which = new int[numberCuts];
     7786              int numberPossible=0;
     7787              for (int i = 0; i < numberCuts; i++) {
     7788                OsiRowCut * thisCut = globalCuts_.rowCutPtr(i) ;
     7789                double violation = thisCut->violated(cbcColSolution_);
     7790                if(thisCut->effectiveness() == COIN_DBL_MAX) {
     7791                  // see if already there
     7792                  int j;
     7793                  for (j = 0; j < currentNumberCuts_; j++) {
     7794                    if (addedCuts_[j]==thisCut)
     7795                      break;
     7796                  }
     7797                  if (j==currentNumberCuts_)
     7798                    violation = COIN_DBL_MAX;
     7799                  //else
     7800                  //printf("already done??\n");
     7801                }
     7802                if (violation > 0.005) {
     7803                  violations[numberPossible]=-violation;
     7804                  which[numberPossible++]=i;
     7805                }
     7806              }
     7807              CoinSort_2(violations,violations+numberPossible,which);
     7808              for (int i = 0; i < numberPossible; i++) {
     7809                int k=which[i];
     7810                OsiRowCut * thisCut = globalCuts_.rowCutPtr(k) ;
     7811                assert (thisCut->violated(cbcColSolution_) > 0.005/*primalTolerance*/ ||
     7812                        thisCut->effectiveness() == COIN_DBL_MAX);
     7813#define CHECK_DEBUGGER
     7814#ifdef CHECK_DEBUGGER
     7815                if ((specialOptions_&1) != 0 ) {
     7816                  CoinAssert (!solver_->getRowCutDebuggerAlways()->invalidCut(*thisCut));
     7817                }
     7818#endif
     7819#if 0 //ndef NDEBUG
     7820                printf("Global cut added - violation %g\n",
     7821                       thisCut->violated(cbcColSolution_)) ;
     7822#endif
     7823                whichGenerator_[numberViolated++] = -1;
    70257824#ifndef GLOBAL_CUTS_JUST_POINTERS
    7026                     theseCuts.insert(*thisCut) ;
     7825                theseCuts.insert(*thisCut) ;
    70277826#else
    7028                     theseCuts.insert(thisCut) ;
    7029 #endif
    7030                 }
    7031             }
    7032             numberCuts = globalCuts_.sizeRowCuts() ;
    7033             // possibly extend whichGenerator
    7034             resizeWhichGenerator(numberViolated, numberViolated + numberCuts);
    7035             for ( i = 0; i < numberCuts; i++) {
    7036                 OsiRowCut * thisCut = globalCuts_.rowCutPtr(i) ;
    7037                 if (thisCut->violated(cbcColSolution_) > primalTolerance ||
    7038                         thisCut->effectiveness() == COIN_DBL_MAX) {
    7039                     //printf("Global cut added - violation %g\n",
    7040                     // thisCut->violated(cbcColSolution_)) ;
    7041                     whichGenerator_[numberViolated++] = -1;
    7042 #ifndef GLOBAL_CUTS_JUST_POINTERS
    7043                     theseCuts.insert(*thisCut) ;
    7044 #else
    7045                     theseCuts.insert(thisCut) ;
    7046 #endif
    7047                 }
    7048             }
    7049             numberGlobalViolations_ += numberViolated;
     7827                theseCuts.insert(thisCut) ;
     7828#endif
     7829                if (violations[i]!=-COIN_DBL_MAX)
     7830                  maximumAdd -= thisCut->row().getNumElements();
     7831                if (maximumAdd<0)
     7832                  break;
     7833              }
     7834              delete [] which;
     7835              delete [] violations;
     7836              numberGlobalViolations_ += numberViolated;
     7837            }
    70507838        }
    70517839        /*
     
    74038191            //solver_->setHintParam(OsiDoDualInResolve,true,OsiHintTry);
    74048192            if ( maximumSecondsReached() ) {
    7405                 numberTries = 0; // exit
     8193                numberTries = -1000; // exit
    74068194                feasible = false;
    74078195                break;
     
    75618349                    // maybe give it one more try
    75628350                    if (numberLastAttempts > 2 || currentDepth_ || experimentBreak < 2)
    7563                         break ;
     8351                        numberTries=0 ;
    75648352                    else
    75658353                        numberLastAttempts++;
     
    75958383            keepGoing=false;
    75968384        }
    7597         if (numberTries <=0 && feasible && !keepGoing && !parentModel_ && !numberNodes_) {
     8385        if (numberTries ==0 && feasible && !keepGoing && !parentModel_ && !numberNodes_) {
    75988386          for (int i = 0; i < numberCutGenerators_; i++) {
    75998387            if (generator_[i]->whetherCallAtEnd()
    76008388                &&!generator_[i]->whetherInMustCallAgainMode()) {
    7601               keepGoing= true;
    7602               break;
     8389              // give it some goes and switch off
     8390              numberTries=(saveNumberTries+4)/5;
     8391              generator_[i]->setWhetherCallAtEnd(false);
    76038392            }
    76048393          }
     
    76568445                        whichGenerator_[numberNewCuts_++] = -1;
    76578446#ifndef GLOBAL_CUTS_JUST_POINTERS
    7658                         cuts.insert(globalCuts_.rowCut(i)) ;
     8447                        cuts.insert(*globalCuts_.rowCutPtr(i)) ;
    76598448#else
    76608449                        OsiRowCut * rowCutPointer = globalCuts_.rowCutPtr(i);
     
    76708459                }
    76718460                if (!feasible) { //node will be fathomed
     8461                    lockThread();
    76728462                    for (int i = 0; i < currentNumberCuts_; i++) {
    76738463                        // take off node
     
    76788468                        }
    76798469                    }
     8470                    unlockThread();
    76808471                }
    76818472            }
     
    78218612        */
    78228613        if (!numberNodes_) {
     8614          if (!parentModel_) {
     8615            //printf("%d global cuts\n",globalCuts_.sizeRowCuts()) ;
     8616            if ((specialOptions_&1) != 0) {
     8617              //specialOptions_ &= ~1;
     8618              int numberCuts = globalCuts_.sizeRowCuts();
     8619              const OsiRowCutDebugger *debugger =
     8620                continuousSolver_->getRowCutDebugger() ;
     8621              if (debugger) {
     8622                for (int i = 0; i < numberCuts; i++) {
     8623                  OsiRowCut * cut = globalCuts_.rowCutPtr(i) ;
     8624                  if (debugger->invalidCut(*cut)) {
     8625                    continuousSolver_->applyRowCuts(1,cut);
     8626                    continuousSolver_->writeMps("bad");
     8627                    printf("BAD cut\n");
     8628                  }
     8629                  //CoinAssert (!debugger->invalidCut(*cut));
     8630                }
     8631              }
     8632            }
     8633          }
     8634          //solver_->writeMps("second");
    78238635            if (numberRowsAdded)
    78248636                handler_->message(CBC_CUTS_STATS, messages_)
     
    79688780                willBeCutsInTree = 0;
    79698781        }
    7970         if (!numberNodes_)
     8782        if (!numberNodes_) {
    79718783            handler_->message(CBC_ROOT, messages_)
    79728784            << numberNewCuts_
     
    79748786            << currentPassNumber_
    79758787            << CoinMessageEol ;
     8788        }
    79768789        /*
    79778790          Count the number of cuts produced by each cut generator on this call. Not
     
    79968809        for (i = 0; i < numberNewCuts_; i++) {
    79978810            int iGenerator = whichGenerator_[i];
     8811            if (iGenerator>=0)
     8812              iGenerator=iGenerator%10000;
    79988813            if (iGenerator >= 0 && iGenerator < numberCutGenerators_)
    79998814                count[iGenerator]++ ;
    80008815        }
     8816        // add in any active cuts if at root node (for multiple solvers)
     8817        if (!numberNodes_) {
     8818          for (i = 0; i < numberCutGenerators_; i++)
     8819            count[i] += generator_[i]->numberCutsActive();
     8820        }
    80018821        double totalCuts = 0.0 ;
    80028822        //#define JUST_ACTIVE
     
    80778897                    howOften = -99; // switch off
    80788898            }
     8899            if (generator_[i]->maximumTries()!=-1)
     8900                howOften = -99; // switch off
    80798901            /*
    80808902              Below -99, this generator is switched off. There's no need to consider
    80818903              further. Then again, there was no point in persisting this far!
    80828904            */
    8083             if (howOften < -99)
    8084                 continue ;
     8905            if (howOften < -99) {
     8906              // may have been switched off - report
     8907              if (!numberNodes_) {
     8908                int n = generator_[i]->numberCutsInTotal();
     8909                if (n) {
     8910                  double average = 0.0;
     8911                  average = generator_[i]->numberElementsInTotal();
     8912                  average /= n;
     8913                  handler_->message(CBC_GENERATOR, messages_)
     8914                    << i
     8915                    << generator_[i]->cutGeneratorName()
     8916                    << n
     8917                    << average
     8918                    << generator_[i]->numberColumnCuts()
     8919                    << generator_[i]->numberCutsActive()
     8920                    + generator_[i]->numberColumnCuts();
     8921                  handler_->printing(generator_[i]->timing())
     8922                    << generator_[i]->timeInCutGenerator();
     8923                  handler_->message()
     8924                    << -100
     8925                    << CoinMessageEol ;
     8926                }
     8927              }
     8928              continue ;
     8929            }
    80858930            /*
    80868931              Adjust, if howOften is adjustable.
     
    83499194                for (i = 0; i < numberNewCuts_; i++) {
    83509195                    int iGenerator = whichGenerator_[i];
     9196                    if (iGenerator>=0)
     9197                      iGenerator=iGenerator%10000;
    83519198                    if (iGenerator >= 0)
    83529199                        generator_[iGenerator]->incrementNumberCutsActive();
     
    84029249        specialOptions_ &= ~256; // mark as full scan done
    84039250    }
    8404 # ifdef COIN_HAS_CLP
    8405     if (!node && !parentModel_ && intParam_[CbcMaxNumNode] == -123456) {
    8406         OsiClpSolverInterface * clpSolver
    8407         = dynamic_cast<OsiClpSolverInterface *> (solver_);
    8408         if (clpSolver) {
    8409             clpSolver->lexSolve();
    8410         }
     9251# if 0 //def COIN_HAS_CLP
     9252    // check basis
     9253    OsiClpSolverInterface * clpSolver
     9254      = dynamic_cast<OsiClpSolverInterface *> (solver_);
     9255    if (clpSolver) {
     9256      ClpSimplex * simplex = clpSolver->getModelPtr();
     9257      int numberTotal=simplex->numberRows()+simplex->numberColumns();
     9258      int superbasic=0;
     9259      for (int i=0;i<numberTotal;i++) {
     9260        if (simplex->getStatus(i)==ClpSimplex::superBasic)
     9261          superbasic++;
     9262      }
     9263      if (superbasic) {
     9264        printf("%d superbasic!\n",superbasic);
     9265        clpSolver->resolve();
     9266        superbasic=0;
     9267        for (int i=0;i<numberTotal;i++) {
     9268          if (simplex->getStatus(i)==ClpSimplex::superBasic)
     9269            superbasic++;
     9270        }
     9271        assert (!superbasic);
     9272      }
    84119273    }
    84129274# endif
     
    84369298            }
    84379299        }
     9300        if (generator_[i]->whetherCallAtEnd())
     9301          generate=false;
    84389302        const OsiRowCutDebugger * debugger = NULL;
    84399303        bool onOptimalPath = false;
     
    84949358            }
    84959359#endif
    8496             if (mustResolve) {
     9360            if (mustResolve || (specialOptions_&1) != 0) {
    84979361                int returnCode = resolve(node ? node->nodeInfo() : NULL, 2);
    84989362                if (returnCode  == 0)
     
    85669430            }
    85679431            whichGenerator_[numberBefore++] = i ;
     9432            if (!numberNodes_||generator_[i]->globalCuts())
     9433              whichGenerator_[numberBefore-1]=i+10000;
    85689434            if (thisCut->lb() > thisCut->ub())
    85699435                status = -1; // sub-problem is infeasible
    8570             if (thisCut->globallyValid()) {
     9436            if (thisCut->globallyValid()||!numberNodes_) {
    85719437                // add to global list
    85729438                OsiRowCut newCut(*thisCut);
    85739439                newCut.setGloballyValid(true);
    85749440                newCut.mutableRow().setTestForDuplicateIndex(false);
    8575                 globalCuts_.insert(newCut) ;
     9441                globalCuts_.addCutIfNotDuplicate(newCut) ;
     9442                whichGenerator_[numberBefore-1] = i+10000 ;
    85769443            }
    85779444        }
     
    85889455                const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ;
    85899456                whichGenerator_[numberBefore++] = i ;
     9457                if (!numberNodes_||generator_[i]->globalCuts())
     9458                  whichGenerator_[numberBefore-1]=i+10000;
    85909459                if (thisCut->globallyValid()) {
    85919460                    // add to global list
     
    85939462                    newCut.setGloballyValid(true);
    85949463                    newCut.mutableRow().setTestForDuplicateIndex(false);
    8595                     globalCuts_.insert(newCut) ;
     9464                    globalCuts_.addCutIfNotDuplicate(newCut) ;
     9465                    whichGenerator_[numberBefore-1]=i+10000;
    85969466                }
    85979467            }
     
    86019471            const OsiColCut * thisCut = theseCuts.colCutPtr(j) ;
    86029472            if (thisCut->globallyValid()) {
    8603                 // add to global list
    8604                 OsiColCut newCut(*thisCut);
    8605                 newCut.setGloballyValid(true);
    8606                 globalCuts_.insert(newCut) ;
     9473                // fix
     9474                makeGlobalCut(thisCut);
    86079475            }
    86089476        }
     
    86379505                    printf("Old cut added - violation %g\n",
    86389506                           thisCut->violated(cbcColSolution_)) ;
    8639                 whichGenerator_[numberOld++] = -1;
     9507                whichGenerator_[numberOld++] = -3;
    86409508                theseCuts.insert(*thisCut) ;
    86419509            }
     
    88919759        }
    88929760    }
    8893 #ifdef COIN_HAS_CLP
     9761  #ifdef COIN_HAS_CLP
    88949762    OsiClpSolverInterface * clpSolver
    88959763    = dynamic_cast<OsiClpSolverInterface *> (solver_);
     
    916810036#ifdef COIN_HAS_CLP
    916910037    if (clpSolver && !feasible) {
    9170         // make sure marked infeasible
     10038      // make sure marked infeasible
     10039      if (!clpSolver->isProvenDualInfeasible())
    917110040        clpSolver->getModelPtr()->setProblemStatus(1);
    917210041    }
     
    1018211051                int n = CoinMax(obj2->numberTimesDown(),
    1018311052                                obj2->numberTimesUp());
    10184                 if (n >= value)
    10185                     obj2->setNumberBeforeTrust(n + 1);
     11053                if (n >= value) {
     11054                  value = CoinMin(CoinMin(n+1,3*(value+1)/2),5*numberBeforeTrust_);
     11055                  obj2->setNumberBeforeTrust(value);
     11056                }
    1018611057            }
    1018711058        }
     
    1088611757                            newCut.setGloballyValid(true);
    1088711758                            newCut.mutableRow().setTestForDuplicateIndex(false);
    10888                             globalCuts_.insert(newCut) ;
     11759                            globalCuts_.addCutIfNotDuplicate(newCut) ;
    1088911760                        } else {
    1089011761                            // obviously wrong
     
    1101911890                int iAway = -1;
    1102011891                double largestInfeasibility = tolerance;
     11892#if COIN_DEVELOP>1
    1102111893                int iInfeas = -1;
     11894#endif
    1102211895                const double * columnLower = continuousSolver_->getColLower();
    1102311896                const double * columnUpper = continuousSolver_->getColUpper();
     
    1102611899                    double value = solution2[i];
    1102711900                    if (value > columnUpper[i] + largestInfeasibility) {
     11901#if COIN_DEVELOP>1
    1102811902                        iInfeas = i;
     11903#endif
    1102911904                        largestInfeasibility = value - columnUpper[i];
    1103011905                    } else if (value < columnLower[i] - largestInfeasibility) {
     11906#if COIN_DEVELOP>1
    1103111907                        iInfeas = i;
     11908#endif
    1103211909                        largestInfeasibility = columnLower[i] - value;
    1103311910                    }
     
    1111911996            //setCutoff(cutoff*direction);
    1112011997            setCutoff(cutoff);
     11998            // change cutoff as constraint if wanted
     11999            if (cutoffRowNumber_>=0) {
     12000              if (solver_->getNumRows()>cutoffRowNumber_) {
     12001                double offset;
     12002                solver_->getDblParam(OsiObjOffset, offset);
     12003                solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
     12004              }
     12005            }
    1112112006
    1112212007            if (how == CBC_ROUNDING)
     
    1118212067                            newCut.setGloballyValid(true);
    1118312068                            newCut.mutableRow().setTestForDuplicateIndex(false);
    11184                             globalCuts_.insert(newCut) ;
     12069                            globalCuts_.addCutIfNotDuplicate(newCut) ;
    1118512070                            generator_[i]->incrementNumberCutsInTotal();
    1118612071                        }
     
    1119212077                const OsiColCut * thisCut = theseCuts.colCutPtr(i);
    1119312078                if (thisCut->globallyValid()) {
    11194                     // add to global list
    11195                     OsiColCut newCut(*thisCut);
    11196                     newCut.setGloballyValid(true);
    11197                     globalCuts_.insert(newCut) ;
     12079                    // fix
     12080                    makeGlobalCut(thisCut);
    1119812081                }
    1119912082            }
     
    1129312176                //setCutoff(cutoff*direction);
    1129412177                setCutoff(cutoff);
     12178                // change cutoff as constraint if wanted
     12179                if (cutoffRowNumber_>=0) {
     12180                  if (solver_->getNumRows()>cutoffRowNumber_) {
     12181                    double offset;
     12182                    solver_->getDblParam(OsiObjOffset, offset);
     12183                    solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
     12184                  }
     12185                }
    1129512186
    1129612187                numberSolutions_++;
     
    1191112802                thisCut.setRow(rowLength[iRow], column + start, elementByRow + start, false);
    1191212803                thisCut.setGloballyValid(true);
    11913                 globalCuts_.insert(thisCut) ;
     12804                globalCuts_.addCutIfNotDuplicate(thisCut) ;
    1191412805            }
    1191512806        }
     
    1192612817    newCut.setGloballyValidAsInteger(2);
    1192712818    newCut.mutableRow().setTestForDuplicateIndex(false);
    11928     globalCuts_.insert(newCut) ;
     12819    globalCuts_.addCutIfNotDuplicate(newCut) ;
    1192912820}
    1193012821// Make given cut into a global cut
     
    1193512826    newCut.setGloballyValid(true);
    1193612827    newCut.mutableRow().setTestForDuplicateIndex(false);
    11937     globalCuts_.insert(newCut) ;
     12828    globalCuts_.addCutIfNotDuplicate(newCut) ;
    1193812829}
    1193912830// Make given column cut into a global cut
     
    1194112832CbcModel::makeGlobalCut(const OsiColCut * cut)
    1194212833{
    11943     OsiColCut newCut(*cut);
    11944     newCut.setGloballyValidAsInteger(2);
    11945     globalCuts_.insert(newCut) ;
     12834  const double * lower;
     12835  const double * upper;
     12836  if (topOfTree_) {
     12837    lower = topOfTree_->lower();
     12838    upper = topOfTree_->upper();
     12839  } else {
     12840    lower = solver_->getColLower();
     12841    upper = solver_->getColUpper();
     12842  }
     12843  int nLower=cut->lbs().getNumElements();
     12844  const int * indexLower=cut->lbs().getIndices();
     12845  const double * boundLower=cut->lbs().getElements();
     12846  for (int i=0;i<nLower;i++) {
     12847    int iColumn=indexLower[i];
     12848    double newValue=CoinMax(lower[iColumn],boundLower[iColumn]);
     12849    if (topOfTree_)
     12850      topOfTree_->setColLower(iColumn,newValue);
     12851    else
     12852      solver_->setColLower(iColumn,newValue);
     12853  }
     12854  int nUpper=cut->ubs().getNumElements();
     12855  const int * indexUpper=cut->ubs().getIndices();
     12856  const double * boundUpper=cut->ubs().getElements();
     12857  for (int i=0;i<nUpper;i++) {
     12858    int iColumn=indexUpper[i];
     12859    double newValue=CoinMin(upper[iColumn],boundUpper[iColumn]);
     12860    if (topOfTree_)
     12861      topOfTree_->setColUpper(iColumn,newValue);
     12862    else
     12863      solver_->setColUpper(iColumn,newValue);
     12864  }
    1194612865}
    1194712866// Make given column cut into a global cut
     
    1194912868CbcModel::makeGlobalCut(const OsiColCut & cut)
    1195012869{
    11951     OsiColCut newCut(cut);
     12870  const double * lower;
     12871  const double * upper;
     12872  if (topOfTree_) {
     12873    lower = topOfTree_->lower();
     12874    upper = topOfTree_->upper();
     12875  } else {
     12876    lower = solver_->getColLower();
     12877    upper = solver_->getColUpper();
     12878  }
     12879  int nLower=cut.lbs().getNumElements();
     12880  const int * indexLower=cut.lbs().getIndices();
     12881  const double * boundLower=cut.lbs().getElements();
     12882  for (int i=0;i<nLower;i++) {
     12883    int iColumn=indexLower[i];
     12884    double newValue=CoinMax(lower[iColumn],boundLower[iColumn]);
     12885    if (topOfTree_)
     12886      topOfTree_->setColLower(iColumn,newValue);
     12887    else
     12888      solver_->setColLower(iColumn,newValue);
     12889  }
     12890  int nUpper=cut.ubs().getNumElements();
     12891  const int * indexUpper=cut.ubs().getIndices();
     12892  const double * boundUpper=cut.ubs().getElements();
     12893  for (int i=0;i<nUpper;i++) {
     12894    int iColumn=indexUpper[i];
     12895    double newValue=CoinMin(upper[iColumn],boundUpper[iColumn]);
     12896    if (topOfTree_)
     12897      topOfTree_->setColUpper(iColumn,newValue);
     12898    else
     12899      solver_->setColUpper(iColumn,newValue);
     12900  }
     12901}
     12902// Make partial cut into a global cut and save
     12903void
     12904CbcModel::makePartialCut(const OsiRowCut * partialCut,
     12905                         const OsiSolverInterface * solver)
     12906{
     12907  // get greedy cut
     12908  double bSum = partialCut->lb();
     12909  assert (bSum<0.0);
     12910  if (!solver)
     12911    solver=solver_;
     12912  int nConflict = partialCut->row().getNumElements();
     12913  const int * column = partialCut->row().getIndices();
     12914  const double * element = partialCut->row().getElements();
     12915  double * originalLower = topOfTree_->mutableLower();
     12916  const double * columnLower = solver->getColLower();
     12917  double * originalUpper = topOfTree_->mutableUpper();
     12918  const double * columnUpper = solver->getColUpper();
     12919  int nC=nConflict;
     12920  while (nConflict) {
     12921    int iColumn = column[nConflict-1];
     12922    double farkasValue = element[nConflict-1];
     12923    double change;
     12924    if (farkasValue>0.0) {
     12925      change=farkasValue*(originalUpper[iColumn]-columnUpper[iColumn]);
     12926    } else {
     12927      change=farkasValue*(originalLower[iColumn]-columnLower[iColumn]);
     12928    }
     12929    if (bSum+change>-1.0e-4)
     12930      break;
     12931    nConflict--;
     12932    bSum += change;
     12933  }
     12934  OsiRowCut newCut;
     12935  newCut.setUb(COIN_DBL_MAX);
     12936  double lo=1.0;
     12937  double * values = new double[nConflict];
     12938  for (int i=0;i<nConflict;i++) {
     12939    int iColumn = column[i];
     12940    if (originalLower[iColumn]==columnLower[iColumn]) {
     12941      // must be at least one higher
     12942      values[i]=1.0;
     12943      lo += originalLower[iColumn];
     12944    } else {
     12945      // must be at least one lower
     12946      values[i]=-1.0;
     12947      lo -= originalUpper[iColumn];
     12948    }
     12949  }
     12950  newCut.setLb(lo);
     12951  newCut.setRow(nConflict,column,values);
     12952  printf("CUTa has %d (started at %d) - final bSum %g\n",nConflict,nC,bSum);
     12953  if (nConflict>1) {
     12954    if ((specialOptions_&1) != 0) {
     12955      const OsiRowCutDebugger *debugger = continuousSolver_->getRowCutDebugger() ;
     12956      if (debugger) {
     12957        if (debugger->invalidCut(newCut)) {
     12958          continuousSolver_->applyRowCuts(1,&newCut);
     12959          continuousSolver_->writeMps("bad");
     12960        }
     12961        CoinAssert (!debugger->invalidCut(newCut));
     12962      }
     12963    }
    1195212964    newCut.setGloballyValidAsInteger(2);
    11953     globalCuts_.insert(newCut) ;
     12965    newCut.mutableRow().setTestForDuplicateIndex(false);
     12966    globalCuts_.addCutIfNotDuplicate(newCut) ;
     12967  } else {
     12968    // change bounds
     12969    int iColumn=column[0];
     12970    if (values[0]<0.0) {
     12971      // change upper bound
     12972      double newUpper = -lo;
     12973      assert (newUpper<originalUpper[iColumn]);
     12974      printf("Changing upper bound on %d from %g to %g\n",
     12975             iColumn,originalUpper[iColumn],newUpper);
     12976      originalUpper[iColumn]=newUpper;
     12977    } else {
     12978      // change lower bound
     12979      double newLower = lo;
     12980      assert (newLower>originalLower[iColumn]);
     12981      printf("Changing lower bound on %d from %g to %g\n",
     12982             iColumn,originalLower[iColumn],newLower);
     12983      originalLower[iColumn]=newLower;
     12984    }
     12985  }
     12986  // add to partial cuts
     12987  if (globalConflictCuts_) {
     12988    globalConflictCuts_->addCutIfNotDuplicateWhenGreedy(*partialCut,2);
     12989  }
     12990  delete [] values;
     12991}
     12992// Make partial cuts into global cuts
     12993void
     12994CbcModel::makeGlobalCuts()
     12995{
    1195412996}
    1195512997void
     
    1212113163        ClpSimplex * clpSimplex = clpSolver->getModelPtr();
    1212213164        int save = clpSimplex->specialOptions();
    12123         clpSimplex->setSpecialOptions(save | 0x11000000); // say is Cbc (and in branch and bound)
     13165        if ((moreSpecialOptions_&8388608)==0)
     13166          clpSimplex->setSpecialOptions(save | 0x11000000); // say is Cbc (and in branch and bound)
     13167        else
     13168          clpSimplex->setSpecialOptions(save | 0x11200000); // say is Cbc (and in branch and bound - but save ray)
    1212413169        int save2 = clpSolver->specialOptions();
    1212513170        if (false && (save2&2048) == 0) {
     
    1265913704            int totalNodes = numberNodes_ + numberExtraNodes_;
    1266013705            int totalIterations = numberIterations_ + numberExtraIterations_;
     13706            bool diving=false;
     13707            if ((moreSpecialOptions_&33554432)!=0) {
     13708              testDepth=COIN_INT_MAX;
     13709              if (oldNode&&(oldNode->depth()==-2||oldNode->depth()==4))
     13710                diving=true;
     13711            }
    1266113712            if (totalNodes*40 < totalIterations || numberNodes_ < 1000) {
    1266213713                doClp = false;
     
    1266613717                //     totalNodes,totalIterations,doClp ? 'Y' : 'N');
    1266713718            }
    12668             if (oldNode && fastNodeDepth_ >= 0 && oldNode->depth() >= testDepth &&/*!parentModel_*/(specialOptions_&2048) == 0
    12669                     && doClp && !cuts.sizeRowCuts()) {
     13719            if (oldNode &&
     13720                ((fastNodeDepth_ >= 0 && oldNode->depth() >= testDepth && doClp)||diving) &&/*!parentModel_*/(specialOptions_&2048) == 0
     13721                && !cuts.sizeRowCuts()) {
    1267013722                OsiClpSolverInterface * clpSolver
    1267113723                = dynamic_cast<OsiClpSolverInterface *> (solver_);
     
    1267713729            }
    1267813730#endif
     13731#ifdef COIN_HAS_CLP
     13732            int save=0;
     13733            OsiClpSolverInterface * clpSolver
     13734              = dynamic_cast<OsiClpSolverInterface *> (solver_);
     13735            if (clpSolver&&(moreSpecialOptions_&4194304)!=0) {
     13736              ClpSimplex * clpSimplex = clpSolver->getModelPtr();
     13737              save=clpSimplex->specialOptions();
     13738              clpSimplex->setSpecialOptions(save | 0x11200000); // say is Cbc (and in branch and bound - but save ray)
     13739            }
     13740#endif
    1267913741            if (numberBeforeTrust_ == 0 ) {
    1268013742                anyAction = newNode->chooseBranch(this, oldNode, numberPassesLeft) ;
     
    1268413746                    anyAction = newNode->chooseBranch(this, oldNode, numberPassesLeft) ; // dynamic did nothing
    1268513747            }
     13748#ifdef COIN_HAS_CLP
     13749            if (clpSolver&&(moreSpecialOptions_&4194304)!=0) {
     13750              ClpSimplex * clpSimplex = clpSolver->getModelPtr();
     13751              clpSimplex->setSpecialOptions(save);
     13752            }
     13753#endif
    1268613754            /*
    1268713755              We're on the new (Osi) side of the branching hierarchy.
     
    1284213910                assert (numberProblems);
    1284313911                int nProbMinus1 = numberProblems - 1;
     13912                lockThread();
    1284413913                for (int i = 0; i < currentNumberCuts_; i++) {
    1284513914                    if (addedCuts_[i])
    1284613915                        addedCuts_[i]->increment(nProbMinus1) ;
    1284713916                }
     13917                unlockThread();
    1284813918                for (int i = 0; i < numberProblems; i++) {
    1284913919                    double objectiveValue;
     
    1306314133        cutoff = objectiveValue - increment ;
    1306414134        setCutoff(cutoff) ;
     14135        // change cutoff as constraint if wanted
     14136        if (cutoffRowNumber_>=0) {
     14137          if (solver_->getNumRows()>cutoffRowNumber_) {
     14138            double offset;
     14139            solver_->getDblParam(OsiObjOffset, offset);
     14140            solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
     14141          }
     14142        }
    1306514143    }
    1306614144    int n = CoinMax(numberColumns, solver_->getNumCols());
     
    1312414202        // Modify based on size etc
    1312514203        adjustHeuristics();
    13126         // See if already withing allowable gap
     14204        // See if already within allowable gap
    1312714205        bool exitNow = false;
    1312814206        for (i = 0; i < numberHeuristics_; i++) {
     
    1313114209        }
    1313214210        if (!exitNow) {
     14211          /** -1 first time otherwise number of solutions last time */
     14212          int lastSolutionCount = -1;
     14213          while (lastSolutionCount) {
     14214            int thisSolutionCount=0;
    1313314215#ifdef CBC_THREAD
    1313414216            if ((threadMode_&4) != 0) {
     
    1315314235                        if (!heuristic_[i]->shouldHeurRun(0))
    1315414236                            continue;
     14237                        if (lastSolutionCount>0&&
     14238                            (heuristic_[i]->switches()&16)==0)
     14239                          continue; // no point
    1315514240                        parameters[i-iChunk].solutionValue = heuristicValue;
    1315614241                        // Don't want a strategy object
     
    1320014285                                    incrementUsed(newSolution);
    1320114286                                    // increment number of solutions so other heuristics can test
    13202                                     numberSolutions_++;
     14287                                    thisSolutionCount++;
    1320314288                                    numberHeuristicSolutions_++;
    1320414289                                    found = i + iChunk ;
     
    1322414309                    if (!heuristic_[i]->shouldHeurRun(whereFrom))
    1322514310                        continue;
    13226                     if (maximumSecondsReached())
     14311                    if (lastSolutionCount>0&&
     14312                        (heuristic_[i]->switches()&16)==0)
     14313                      continue; // no point
     14314                    if (maximumSecondsReached()) {
     14315                        thisSolutionCount=-1000000;
    1322714316                        break;
     14317                    }
    1322814318                    // see if heuristic will do anything
    1322914319                    double saveValue = heuristicValue ;
     
    1324714337                        setBestSolution(CBC_ROUNDING, heuristicValue, newSolution) ;
    1324814338                        if (bestObjective_ < currentObjective) {
     14339                            thisSolutionCount++;
    1324914340                            heuristic_[i]->incrementNumberSolutionsFound();
    1325014341                            found = i ;
    1325114342                            incrementUsed(newSolution);
    1325214343                            // increment number of solutions so other heuristics can test
    13253                             numberSolutions_++;
     14344                            //                            numberSolutions_++;
    1325414345                            numberHeuristicSolutions_++;
    1325514346#ifdef CLP_INVESTIGATE
     
    1325814349#endif
    1325914350                            whereFrom |= 8; // say solution found
    13260                             if (heuristic_[i]->exitNow(bestObjective_))
     14351                            if (heuristic_[i]->exitNow(bestObjective_)
     14352                                ||numberSolutions_>=getMaximumSolutions()) {
     14353                              thisSolutionCount=-1000000;
    1326114354                                break;
     14355                            }
    1326214356                            if (eventHandler) {
    1326314357                              if (!eventHandler->event(CbcEventHandler::heuristicSolution)) {
    1326414358                                eventHappened_ = true; // exit
     14359                                thisSolutionCount=-1000000;
    1326514360                                break;
    1326614361                              }
     
    1326914364                                                     CoinMax(fabs(bestObjective_), fabs(bestPossibleObjective_))
    1327014365                                                     * dblParam_[CbcAllowableFractionGap]);
    13271                             if (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0
    13272                                 && bestObjective_ < 1.0e50) {
     14366                            if (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0 &&bestPossibleObjective_ < 1.0e30) {
    1327314367                              if (bestPossibleObjective_ < getCutoff())
    1327414368                                stoppedOnGap_ = true ;
    1327514369                              //eventHappened_=true; // stop as fast as possible
     14370                              thisSolutionCount=-1000000;
    1327614371                              break;
    1327714372                            }
     
    1329214387                      if (!eventHandler->event(CbcEventHandler::afterHeuristic)) {
    1329314388                        eventHappened_ = true; // exit
     14389                        thisSolutionCount=-1000000;
    1329414390                        break;
    1329514391                      }
     
    1329914395            }
    1330014396#endif
     14397            if (thisSolutionCount<=0)
     14398              break;
     14399            lastSolutionCount=thisSolutionCount;
     14400          }
    1330114401        }
    1330214402        currentPassNumber_ = 0;
     
    1353514635// Set original columns as created by preprocessing
    1353614636void
    13537 CbcModel::setOriginalColumns(const int * originalColumns)
     14637CbcModel::setOriginalColumns(const int * originalColumns,int numberGood)
    1353814638{
    1353914639    int numberColumns = getNumCols();
    1354014640    delete [] originalColumns_;
    13541     originalColumns_ = CoinCopyOfArray(originalColumns, numberColumns);
     14641    originalColumns_ = new int [numberColumns];
     14642    int numberCopy=CoinMin(numberColumns,numberGood);
     14643    memcpy(originalColumns_,originalColumns,numberCopy*sizeof(int));
     14644    for (int i=numberCopy;i<numberColumns;i++)
     14645      originalColumns_[i]=-1;
    1354214646}
    1354314647// Set the cut modifier method
     
    1356614670{
    1356714671    int foundSolution = 0;
    13568     int currentNumberCuts = 0 ;
     14672    int saveNumberCutGenerators=numberCutGenerators_;
     14673    if ((moreSpecialOptions_&33554432)!=0 && (specialOptions_&2048)==0) {
     14674      if (node&&(node->depth()==-2||node->depth()==4))
     14675        numberCutGenerators_=0; // so can dive and branch
     14676    }
    1356914677    currentNode_ = node; // so can be accessed elsewhere
    1357014678    double bestObjective = bestObjective_;
     
    1366314771            CbcBranchingObject * branch = static_cast <CbcBranchingObject *>(branch2) ;
    1366414772#endif
     14773#if 1
    1366514774            branch->setModel(this);
    1366614775            branchesLeft = node->branch(NULL); // old way
     14776#else
     14777            branchesLeft = node->branch(solver_);
     14778#endif
    1366714779            if (parallelMode() >= 0)
    1366814780                branch->setModel(baseModel);
     
    1369614808        phase_ = 2;
    1369714809        OsiCuts cuts ;
    13698         currentNumberCuts = solver_->getNumRows() - numberRowsAtContinuous_ ;
    1369914810        int saveNumber = numberIterations_;
    1370014811        if (solverCharacteristics_->solutionAddsCuts()) {
     
    1374614857            = dynamic_cast<OsiClpSolverInterface *> (solver_);
    1374714858            if ((clpSolver || (specialOptions_&16384) != 0) && fastNodeDepth_ < -1
    13748                     && (specialOptions_&2048) == 0) {
     14859                && (specialOptions_&2048) == 0) {
    1374914860#define FATHOM_BIAS -2
    1375014861                if (numberNodes_ == 1) {
     
    1387314984                        numberExtraNodes_ += info->numberNodesExplored_;
    1387414985                        numberExtraIterations_ += info->numberIterations_;
     14986                        char general[200];
     14987                        int fathomStatus=info->nNodes_;
     14988                        if (feasible)
     14989                          fathomStatus=1;
     14990                        sprintf(general, "fathom took %d nodes, %d iterations - status %d",
     14991                                info->numberNodesExplored_,
     14992                                info->numberIterations_,fathomStatus);
     14993                        messageHandler()->message(CBC_FPUMP2,
     14994                                          messages())
     14995                          << general << CoinMessageEol ;
    1387514996                        if (info->numberNodesExplored_ > 10000 /* && !feasible */
    1387614997                            && (moreSpecialOptions_&524288) == 0  && info->nNodes_>=0) {
     
    1405415175        }
    1405515176        if ((specialOptions_&1) != 0 && onOptimalPath) {
    14056             if (!solver_->getRowCutDebugger() || !feasible) {
    14057                 // dj fix did something???
    14058                 solver_->writeMpsNative("infeas2.mps", NULL, NULL, 2);
    14059                 solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
    14060                 assert (solver_->getRowCutDebugger()) ;
    14061                 assert (feasible);
     15177            if(solver_->getRowCutDebuggerAlways()->optimalValue()<getCutoff()) {
     15178                if (!solver_->getRowCutDebugger() || !feasible) {
     15179                  // dj fix did something???
     15180                  solver_->writeMpsNative("infeas2.mps", NULL, NULL, 2);
     15181                  solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     15182#ifndef NDEBUG
     15183                  const OsiRowCutDebugger * debugger = solver_->getRowCutDebugger() ;
     15184#endif
     15185                  assert (debugger) ;
     15186                  int numberRows0=continuousSolver_->getNumRows();
     15187                  int numberRows=solver_->getNumRows();
     15188                  const CoinPackedMatrix * rowCopy = solver_->getMatrixByRow();
     15189                  const int * rowLength = rowCopy->getVectorLengths();
     15190                  const double * elements = rowCopy->getElements();
     15191                  const int * column = rowCopy->getIndices();
     15192                  const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
     15193                  const double * rowLower = solver_->getRowLower();
     15194                  const double * rowUpper = solver_->getRowUpper();
     15195                  for (int iRow=numberRows0;iRow<numberRows;iRow++) {
     15196                    OsiRowCut rc;
     15197                    rc.setLb(rowLower[iRow]);
     15198                    rc.setUb(rowUpper[iRow]);
     15199                    CoinBigIndex start = rowStart[iRow];
     15200                    rc.setRow(rowLength[iRow],column+start,elements+start,false);
     15201                    CoinAssert (!debugger->invalidCut(rc));
     15202                  }
     15203                  assert (feasible);
     15204                }
    1406215205            }
    1406315206        }
     
    1408615229            bool objLim = solver_->isDualObjectiveLimitReached() ;
    1408715230            if (!feasible && !objLim) {
     15231              if(solver_->getRowCutDebuggerAlways()->optimalValue()<getCutoff()) {
    1408815232                printf("infeas2\n");
    1408915233                solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     
    1409615240                solver_->initialSolve();
    1409715241                assert (!solver_->isProvenOptimal());
    14098             }
    14099             assert (feasible || objLim);
     15242                assert (feasible || objLim);
     15243              }
     15244            }
    1410015245        }
    1410115246        bool checkingNode = false;
    1410215247        if (feasible) {
    14103 #ifdef FUNNY_BRANCHING
     15248#ifdef FUNNY_BRANCHING2
    1410415249            // Far too clever
    1410515250            if ((numberThreads_ == -10 || true) && node->numberBranches() == 2) {
     
    1432615471            if (parallelMode() >= 0)
    1432715472                newNode = new CbcNode() ;
     15473#if 0
     15474            // Try diving
     15475            if (parallelMode() >= 0 && (specialOptions_&2048) == 0) {
     15476              // See if any diving heuristics set to do dive+save
     15477              CbcHeuristicDive * dive=NULL;
     15478              for (int i = 0; i < numberHeuristics_; i++) {
     15479                CbcHeuristicDive * possible = dynamic_cast<CbcHeuristicDive *>(heuristic_[i]);
     15480                if (possible&&possible->maxSimplexIterations()==COIN_INT_MAX) {
     15481                  // if more than one then rotate later?
     15482                  //if (possible->canHeuristicRun()) {
     15483                  if (node->depth()==0||node->depth()==5) {
     15484                    dive=possible;
     15485                    break;
     15486                  }
     15487                }
     15488              }
     15489              if (dive) {
     15490                int numberNodes;
     15491                CbcSubProblem ** nodes=NULL;
     15492                int branchState=dive->fathom(this,numberNodes,nodes);
     15493                if (branchState) {
     15494                  printf("new solution\n");
     15495                }
     15496                if (0) {
     15497                  for (int iNode=0;iNode<numberNodes;iNode++) {
     15498                    //tree_->push(nodes[iNode]) ;
     15499                  }
     15500                  assert (node->nodeInfo());
     15501                  if (node->nodeInfo()->numberBranchesLeft()) {
     15502                    tree_->push(node) ;
     15503                  } else {
     15504                    node->setActive(false);
     15505                  }
     15506                }
     15507                delete [] nodes;
     15508              }
     15509            }
     15510            // end try diving
     15511#endif
    1432815512            // Set objective value (not so obvious if NLP etc)
    1432915513            setObjectiveValue(newNode, node);
     
    1469815882    if (bestObjective > bestObjective_)
    1469915883        foundSolution = 2;
    14700     if (parallelMode() >= 0 && foundSolution) {
     15884    if (parallelMode() > 0 && foundSolution) {
    1470115885        lockThread();
    1470215886        // might as well mark all including continuous
     
    1470615890            usedInSolution_[i] = 0;
    1470715891        }
    14708         baseModel->numberSolutions_ = numberSolutions_;
     15892        baseModel->numberSolutions_++;
    1470915893        if (bestObjective_ < baseModel->bestObjective_ && bestObjective_ < baseModel->getCutoff()) {
    1471015894            baseModel->bestObjective_ = bestObjective_ ;
     
    1471715901        unlockThread();
    1471815902    }
     15903    numberCutGenerators_=saveNumberCutGenerators;
    1471915904    return foundSolution;
    1472015905}
     
    1495116136    return doCuts;
    1495216137}
     16138// See if can stop on gap
     16139bool
     16140CbcModel::canStopOnGap() const
     16141{
     16142  bool returnCode=false;
     16143  if (bestObjective_<1.0e50) {
     16144    double testGap = CoinMax(dblParam_[CbcAllowableGap],
     16145                             CoinMax(fabs(bestObjective_), fabs(bestPossibleObjective_))
     16146                             * dblParam_[CbcAllowableFractionGap]);
     16147    returnCode = (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0);
     16148  }
     16149  return returnCode;
     16150}
    1495316151// Adjust heuristics based on model
    1495416152void
     
    1496116159    for (int i = 0; i < numberHeuristics_; i++) {
    1496216160        CbcHeuristicDive * heuristic = dynamic_cast<CbcHeuristicDive *> (heuristic_[i]);
    14963         if (heuristic) {
     16161        if (heuristic && heuristic->maxSimplexIterations()!=COIN_INT_MAX) {
    1496416162            heuristic->setMaxSimplexIterations(nTree);
    1496516163            heuristic->setMaxSimplexIterationsAtRoot(nRoot);
     
    1508716285        savedSolutions_[i] = NULL;
    1508816286    }
     16287    numberSavedSolutions_ = 0;
     16288}
     16289// Delete a saved solution and move others up
     16290void
     16291CbcModel::deleteSavedSolution(int which)
     16292{
     16293  if (which >0 && which <= numberSavedSolutions_) {
     16294    delete [] savedSolutions_[which-1];
     16295    // move up
     16296    numberSavedSolutions_--;
     16297    for (int j =  which-1; j <numberSavedSolutions_; j++) {
     16298      savedSolutions_[j] = savedSolutions_[j+1];
     16299    }
     16300    savedSolutions_[numberSavedSolutions_]=NULL;
     16301    --numberSavedSolutions_;
     16302  }
    1508916303}
    1509016304#ifdef COIN_HAS_CLP
     
    1511916333        }
    1512016334    }
     16335}
     16336#else
     16337CbcModel::goToDantzig(int numberNodes, ClpDualRowPivot *& savePivotMethod)
     16338{
     16339   printf("Need Clp to go to Dantzig\n");
     16340   abort();
    1512116341}
    1512216342#endif
     
    1562916849    }
    1563016850    specialOptions_ |= setFlag;
     16851}
     16852static void flipSolver(OsiSolverInterface * solver, double newCutoff)
     16853{
     16854  if (solver) {
     16855    double objValue = solver->getObjValue();
     16856    double objectiveOffset;
     16857    solver->setObjSense(-solver->getObjSense());
     16858    solver->getDblParam(OsiObjOffset,objectiveOffset);
     16859    solver->setDblParam(OsiObjOffset,-objectiveOffset);
     16860    int numberColumns = solver->getNumCols();
     16861    double * array = CoinCopyOfArray(solver->getObjCoefficients(),numberColumns);
     16862    for (int i=0;i<numberColumns;i++)
     16863      array[i] = - array[i];
     16864    solver->setObjective(array);
     16865    delete [] array;
     16866    solver->setDblParam(OsiDualObjectiveLimit,newCutoff);
     16867#ifdef COIN_HAS_CLP
     16868    OsiClpSolverInterface * clpSolver
     16869      = dynamic_cast<OsiClpSolverInterface *> (solver);
     16870    if (clpSolver) {
     16871      double * dj = clpSolver->getModelPtr()->dualColumnSolution();
     16872      for (int i=0;i<numberColumns;i++)
     16873        dj[i] = - dj[i];
     16874      int numberRows=clpSolver->getNumRows();
     16875      double * pi = clpSolver->getModelPtr()->dualRowSolution();
     16876      for (int i=0;i<numberRows;i++)
     16877        pi[i] = - pi[i];
     16878      clpSolver->getModelPtr()->setObjectiveValue(-objValue);
     16879    } else {
     16880#endif
     16881      // update values
     16882      solver->resolve();
     16883#ifdef COIN_HAS_CLP
     16884    }
     16885#endif
     16886  }
     16887}
     16888/*
     16889  Flip direction of optimization on all models
     16890*/
     16891void
     16892CbcModel::flipModel()
     16893{
     16894  if (parentModel_)
     16895    return;
     16896  // I think cutoff is always minimization
     16897  double cutoff=getCutoff();
     16898  flipSolver(referenceSolver_,cutoff);
     16899  flipSolver(continuousSolver_,cutoff);
     16900  flipSolver(solver_,cutoff);
    1563116901}
    1563216902#ifdef CBC_KEEP_DEPRECATED
     
    1600817278    */
    1600917279    globalCuts_ = OsiCuts() ;
     17280    delete globalConflictCuts_;
     17281    globalConflictCuts_=NULL;
    1601017282    numberHeuristics_ = saveNumberHeuristics;
    1601117283
     
    1625417526#endif
    1625517527
     17528static void * doRootCbcThread(void * voidInfo)
     17529{
     17530    CbcModel * model = reinterpret_cast<CbcModel *> (voidInfo);
     17531#ifdef COIN_HAS_CLP
     17532    OsiClpSolverInterface * clpSolver
     17533      = dynamic_cast<OsiClpSolverInterface *> (model->solver());
     17534    char general[200];
     17535    if (clpSolver) {
     17536      clpSolver->getModelPtr()->dual(); // probably not needed
     17537      clpSolver->setWarmStart(NULL);
     17538      sprintf(general,"Starting multiple root solver");
     17539    } else {
     17540#endif
     17541#ifdef COIN_HAS_CLP
     17542      model->initialSolve();
     17543      sprintf(general,"Solver did %d iterations in initialSolve\n",
     17544             model->solver()->getIterationCount());
     17545    }
     17546#endif
     17547    model->messageHandler()->message(CBC_GENERAL,
     17548                              model->messages())
     17549      << general << CoinMessageEol ;
     17550    model->branchAndBound();
     17551    sprintf(general,"Ending multiple root solver");
     17552    model->messageHandler()->message(CBC_GENERAL,
     17553                              model->messages())
     17554      << general << CoinMessageEol ;
     17555    return NULL;
     17556}
     17557OsiRowCut *
     17558CbcModel::conflictCut(const OsiSolverInterface * solver, bool & localCuts)
     17559{
     17560  OsiRowCut * cut=NULL;
     17561  localCuts=false;
     17562# ifdef COIN_HAS_CLP
     17563  const OsiClpSolverInterface * clpSolver
     17564    = dynamic_cast<const OsiClpSolverInterface *> (solver);
     17565  if (clpSolver&&topOfTree_) {
     17566    int debugMode=0;
     17567    const double * originalLower = topOfTree_->lower();
     17568    const double * originalUpper = topOfTree_->upper();
     17569    int typeCut = 1;
     17570    ClpSimplex * simplex = clpSolver->getModelPtr();
     17571    assert(simplex->status()==1);
     17572    if(simplex->ray()) {
     17573      {
     17574        int numberRows=simplex->numberRows();
     17575        double * saveRay=CoinCopyOfArray(simplex->ray(),numberRows);
     17576#define SAFE_RAY
     17577#ifdef SAFE_RAY
     17578        ClpSimplex & tempSimplex=*simplex;
     17579#else
     17580        ClpSimplex tempSimplex=*simplex;
     17581#endif
     17582        int logLevel=simplex->logLevel();
     17583        tempSimplex.setLogLevel(63);
     17584        tempSimplex.scaling(0);
     17585        tempSimplex.dual();
     17586        tempSimplex.setLogLevel(logLevel);
     17587        if (!tempSimplex.numberIterations()) {
     17588          double * ray = tempSimplex.ray();
     17589          int nBad=0;
     17590          for (int i=0;i<numberRows;i++) {
     17591            if (fabs(ray[i]-saveRay[i])>1.0e-3) {
     17592              if (debugMode)
     17593                printf("row %d true %g bad %g - diff %g\n",
     17594                       i,ray[i],saveRay[i],ray[i]-saveRay[i]);
     17595              nBad++;
     17596            }
     17597          }
     17598          if (nBad)
     17599            printf("%d mismatch crunch ray values\n",nBad);
     17600        }
     17601        delete [] saveRay;
     17602      }
     17603     // make sure we use non-scaled versions
     17604      ClpPackedMatrix * saveMatrix = simplex->swapScaledMatrix(NULL);
     17605      double * saveScale = simplex->swapRowScale(NULL);
     17606      //printf("Could do normal cut\n");
     17607      // could use existing arrays
     17608      int numberRows=simplex->numberRows();
     17609      int numberColumns=simplex->numberColumns();
     17610      double * farkas = new double [2*numberColumns+numberRows];
     17611      double * bound = farkas + numberColumns;
     17612      double * effectiveRhs = bound + numberColumns;
     17613      // sign as internally for dual - so swap if primal
     17614      /*const*/ double * ray = simplex->ray();
     17615      // have to get rid of local cut rows
     17616      if (whichGenerator_) {
     17617        const int * whichGenerator = whichGenerator_ - numberRowsAtContinuous_;
     17618        int badRows=0;
     17619        for (int iRow=numberRowsAtContinuous_;iRow<numberRows;iRow++) {
     17620          int iType=whichGenerator[iRow];
     17621          if ((iType>=0&&iType<10000)||iType<-1) {
     17622            if (fabs(ray[iRow])>1.0e-10) {
     17623              badRows++;
     17624            } else {
     17625              ray[iRow]=0.0;
     17626            }
     17627          }
     17628        }
     17629        if (badRows) {
     17630          if ((debugMode&1)!=0)
     17631            printf("%d rows from local cuts\n",badRows);
     17632          localCuts=true;
     17633        }
     17634      }
     17635      // get farkas row
     17636      memset(farkas,0,(2*numberColumns+numberRows)*sizeof(double));
     17637      simplex->transposeTimes(-1.0,ray,farkas);
     17638      //const char * integerInformation = simplex->integerType_;
     17639      //assert (integerInformation);
     17640
     17641      int sequenceOut = simplex->sequenceOut();
     17642      // Put nonzero bounds in bound
     17643      const double * columnLower = simplex->columnLower();
     17644      const double * columnUpper = simplex->columnUpper();
     17645      int numberBad=0;
     17646      for (int i=0;i<numberColumns;i++) {
     17647        double value = farkas[i];
     17648        double boundValue=0.0;
     17649        if (simplex->getStatus(i)==ClpSimplex::basic) {
     17650          // treat as zero if small
     17651          if (fabs(value)<1.0e-8) {
     17652            value=0.0;
     17653            farkas[i]=0.0;
     17654          }
     17655          if (value) {
     17656            //printf("basic %d direction %d farkas %g\n",
     17657            //     i,simplex->directionOut(),value);
     17658            if (value<0.0)
     17659              boundValue=columnLower[i];
     17660            else
     17661              boundValue=columnUpper[i];
     17662          }
     17663        } else if (fabs(value)>1.0e-10) {
     17664          if (value<0.0)
     17665            boundValue=columnLower[i];
     17666          else
     17667            boundValue=columnUpper[i];
     17668        }
     17669        bound[i]=boundValue;
     17670        if (fabs(boundValue)>1.0e10)
     17671          numberBad++;
     17672      }
     17673      const double * rowLower = simplex->rowLower();
     17674      const double * rowUpper = simplex->rowUpper();
     17675      //int pivotRow = simplex->spareIntArray_[3];
     17676      //bool badPivot=pivotRow<0;
     17677      for (int i=0;i<numberRows;i++) {
     17678        double value = ray[i];
     17679        double rhsValue=0.0;
     17680        if (simplex->getRowStatus(i)==ClpSimplex::basic) {
     17681          // treat as zero if small
     17682          if (fabs(value)<1.0e-8) {
     17683            value=0.0;
     17684            ray[i]=0.0;
     17685          }
     17686          if (value) {
     17687            //printf("row basic %d direction %d ray %g\n",
     17688            //     i,simplex->directionOut(),value);
     17689            if (value<0.0)
     17690              rhsValue=rowLower[i];
     17691            else
     17692              rhsValue=rowUpper[i];
     17693          }
     17694        } else if (fabs(value)>1.0e-10) {
     17695          if (value<0.0)
     17696            rhsValue=rowLower[i];
     17697          else
     17698              rhsValue=rowUpper[i];
     17699        }
     17700        effectiveRhs[i]=rhsValue;
     17701      }
     17702      simplex->times(-1.0,bound,effectiveRhs);
     17703      simplex->swapRowScale(saveScale);
     17704      simplex->swapScaledMatrix(saveMatrix);
     17705      double bSum=0.0;
     17706      for (int i=0;i<numberRows;i++) {
     17707        bSum += effectiveRhs[i]*ray[i];
     17708      }
     17709      if (numberBad||bSum>-1.0e-4) {
     17710#ifndef NDEBUG
     17711        printf("bad BOUND bSum %g  - %d bad\n",
     17712               bSum,numberBad);
     17713#endif
     17714      } else {
     17715        const char * integerInformation = simplex->integerInformation();
     17716        assert (integerInformation);
     17717        int * conflict = new int[numberColumns];
     17718        double * sort = new double [numberColumns];
     17719        double relax=0.0;
     17720        int nConflict=0;
     17721        int nOriginal=0;
     17722        int nFixed=0;
     17723        for (int iColumn=0;iColumn<numberColumns;iColumn++) {
     17724          if (integerInformation[iColumn]) {
     17725            if ((debugMode&1)!=0)
     17726            printf("%d status %d %g <= %g <=%g (orig %g, %g) farkas %g\n",
     17727                   iColumn,simplex->getStatus(iColumn),columnLower[iColumn],
     17728                   simplex->primalColumnSolution()[iColumn],columnUpper[iColumn],
     17729                   originalLower[iColumn],originalUpper[iColumn],
     17730                   farkas[iColumn]);
     17731            double gap = originalUpper[iColumn]-originalLower[iColumn];
     17732            if (!gap)
     17733              continue;
     17734            if (gap==columnUpper[iColumn]-columnLower[iColumn])
     17735              nOriginal++;
     17736            if (columnUpper[iColumn]==columnLower[iColumn])
     17737              nFixed++;
     17738            if (fabs(farkas[iColumn])<1.0e-15) {
     17739              farkas[iColumn]=0.0;
     17740              continue;
     17741            }
     17742            // temp
     17743            if (gap>=20000.0&&false) {
     17744              // can't use
     17745              if (farkas[iColumn]<0.0) {
     17746                assert(originalLower[iColumn]-columnLower[iColumn]<=0.0);
     17747                // farkas is negative - relax lower bound all way
     17748                relax +=
     17749                  farkas[iColumn]*(originalLower[iColumn]-columnLower[iColumn]);
     17750              } else {
     17751                assert(originalUpper[iColumn]-columnUpper[iColumn]>=0.0);
     17752                // farkas is positive - relax upper bound all way
     17753                relax +=
     17754                  farkas[iColumn]*(originalUpper[iColumn]-columnUpper[iColumn]);
     17755              }
     17756              continue;
     17757            }
     17758            if (originalLower[iColumn]==columnLower[iColumn]) {
     17759              if (farkas[iColumn]>0.0&&(simplex->getStatus(iColumn)==ClpSimplex::atUpperBound
     17760                                        ||simplex->getStatus(iColumn)==ClpSimplex::isFixed
     17761                                        ||iColumn==sequenceOut)) {
     17762                // farkas is positive - add to list
     17763                gap=originalUpper[iColumn]-columnUpper[iColumn];
     17764                if (gap) {
     17765                  sort[nConflict]=-farkas[iColumn]*gap;
     17766                  conflict[nConflict++]=iColumn;
     17767                }
     17768                //assert (gap>columnUpper[iColumn]-columnLower[iColumn]);
     17769              }
     17770            } else if (originalUpper[iColumn]==columnUpper[iColumn]) {
     17771              if (farkas[iColumn]<0.0&&(simplex->getStatus(iColumn)==ClpSimplex::atLowerBound
     17772                                        ||simplex->getStatus(iColumn)==ClpSimplex::isFixed
     17773                                        ||iColumn==sequenceOut)) {
     17774                // farkas is negative - add to list
     17775                gap=columnLower[iColumn]-originalLower[iColumn];
     17776                if (gap) {
     17777                  sort[nConflict]=farkas[iColumn]*gap;
     17778                  conflict[nConflict++]=iColumn;
     17779                }
     17780                //assert (gap>columnUpper[iColumn]-columnLower[iColumn]);
     17781              }
     17782            } else {
     17783              // can't use
     17784              if (farkas[iColumn]<0.0) {
     17785                assert(originalLower[iColumn]-columnLower[iColumn]<=0.0);
     17786                // farkas is negative - relax lower bound all way
     17787                relax +=
     17788                  farkas[iColumn]*(originalLower[iColumn]-columnLower[iColumn]);
     17789              } else {
     17790                assert(originalUpper[iColumn]-columnUpper[iColumn]>=0.0);
     17791                // farkas is positive - relax upper bound all way
     17792                relax +=
     17793                  farkas[iColumn]*(originalUpper[iColumn]-columnUpper[iColumn]);
     17794              }
     17795            }
     17796            assert(relax>=0.0);
     17797          } else {
     17798            // not integer - but may have been got at
     17799            double gap = originalUpper[iColumn]-originalLower[iColumn];
     17800            if (gap>columnUpper[iColumn]-columnLower[iColumn]) {
     17801              // can't use
     17802              if (farkas[iColumn]<0.0) {
     17803                assert(originalLower[iColumn]-columnLower[iColumn]<=0.0);
     17804                // farkas is negative - relax lower bound all way
     17805                relax +=
     17806                  farkas[iColumn]*(originalLower[iColumn]-columnLower[iColumn]);
     17807              } else {
     17808                assert(originalUpper[iColumn]-columnUpper[iColumn]>=0.0);
     17809                // farkas is positive - relax upper bound all way
     17810                relax +=
     17811                  farkas[iColumn]*(originalUpper[iColumn]-columnUpper[iColumn]);
     17812              }
     17813            }
     17814          }
     17815        }
     17816        if (relax+bSum>-1.0e-4||!nConflict) {
     17817          if (relax+bSum>-1.0e-4) {
     17818#ifndef NDEBUG
     17819            printf("General integers relax bSum to %g\n",relax+bSum);
     17820#endif
     17821          } else {
     17822            printf("All variables relaxed and still infeasible - what does this mean?\n");
     17823            int nR=0;
     17824            for (int i=0;i<numberRows;i++) {
     17825              if (fabs(ray[i])>1.0e-10)
     17826                nR++;
     17827              else
     17828                ray[i]=0.0;
     17829            }
     17830            int nC=0;
     17831            for (int i=0;i<numberColumns;i++) {
     17832              if (fabs(farkas[i])>1.0e-10)
     17833                nC++;
     17834              else
     17835                farkas[i]=0.0;
     17836            }
     17837            if (nR<3&&nC<5) {
     17838              printf("BAD %d nonzero rows, %d nonzero columns\n",nR,nC);
     17839            }
     17840          }
     17841        } else {
     17842          printf("BOUNDS violation bSum %g (relaxed %g) - %d at original bounds, %d fixed - %d in conflict\n",bSum,
     17843                 relax+bSum,nOriginal,nFixed,nConflict);
     17844          CoinSort_2(sort,sort+nConflict,conflict);
     17845          int nC=nConflict;
     17846          bSum+=relax;
     17847          double saveBsum = bSum;
     17848          while (nConflict) {
     17849            //int iColumn=conflict[nConflict-1];
     17850            double change=-sort[nConflict-1];
     17851            if (bSum+change>-1.0e-4)
     17852              break;
     17853            nConflict--;
     17854            bSum += change;
     17855          }
     17856          if (!nConflict) {
     17857            int nR=0;
     17858            for (int i=0;i<numberRows;i++) {
     17859              if (fabs(ray[i])>1.0e-10)
     17860                nR++;
     17861              else
     17862                ray[i]=0.0;
     17863            }
     17864            int nC=0;
     17865            for (int i=0;i<numberColumns;i++) {
     17866              if (fabs(farkas[i])>1.0e-10)
     17867                nC++;
     17868              else
     17869                farkas[i]=0.0;
     17870            }
     17871            if (nR<3&&nC<5) {
     17872              printf("BAD2 %d nonzero rows, %d nonzero columns\n",nR,nC);
     17873            }
     17874          }
     17875          // no point doing if no reduction (or big?) ?
     17876          if (nConflict<nC+1&&nConflict<500) {
     17877            cut=new OsiRowCut();
     17878            cut->setUb(COIN_DBL_MAX);
     17879            if (!typeCut) {
     17880              double lo=1.0;
     17881              for (int i=0;i<nConflict;i++) {
     17882                int iColumn = conflict[i];
     17883                if (originalLower[iColumn]==columnLower[iColumn]) {
     17884                  // must be at least one higher
     17885                  sort[i]=1.0;
     17886                  lo += originalLower[iColumn];
     17887                } else {
     17888                  // must be at least one lower
     17889                  sort[i]=-1.0;
     17890                  lo -= originalUpper[iColumn];
     17891                }
     17892              }
     17893              cut->setLb(lo);
     17894              cut->setRow(nConflict,conflict,sort);
     17895              printf("CUT has %d (started at %d) - final bSum %g\n",nConflict,nC,bSum);
     17896            } else {
     17897              // just save for use later
     17898              // first take off small
     17899              int nC2=nC;
     17900              while (nC2) {
     17901                //int iColumn=conflict[nConflict-1];
     17902                double change=-sort[nC2-1];
     17903                if (saveBsum+change>-1.0e-4||change>1.0e-4)
     17904                  break;
     17905                nC2--;
     17906                saveBsum += change;
     17907              }
     17908              cut->setLb(saveBsum);
     17909              for (int i=0;i<nC2;i++) {
     17910                int iColumn = conflict[i];
     17911                sort[i]=farkas[iColumn];
     17912              }
     17913              cut->setRow(nC2,conflict,sort);
     17914              printf("Stem CUT has %d (greedy %d - with small %d) - saved bSum %g final greedy bSum %g\n",
     17915                     nC2,nConflict,nC,saveBsum,bSum);
     17916            }
     17917          }
     17918        }
     17919        delete [] conflict;
     17920        delete [] sort;
     17921      }
     17922      delete [] farkas;
     17923    } else {
     17924      printf("No dual ray\n");
     17925    }
     17926  }
     17927#endif
     17928  return cut;
     17929}
     17930
Note: See TracChangeset for help on using the changeset viewer.