Ignore:
Timestamp:
Apr 1, 2013 1:09:22 PM (7 years ago)
Author:
forrest
Message:

make it easier to use slow exotic cuts
more on cutoff as constraint and multiple root solver fixes
general fixing of bugs found on MIQP etc

File:
1 edited

Legend:

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

    r1876 r1880  
    2424#include <cmath>
    2525#include <cfloat>
    26 
    2726#ifdef COIN_HAS_CLP
    2827// include Presolve from Clp
     
    447446        if (!numberContinuousObj && numberIntegerObj <= 5 && numberIntegerWeight <= 100 &&
    448447                numberIntegerObj*3 < numberObjects_ && !parentModel_ && solver_->getNumRows() > 100)
    449             iType = 3 + 4;
     448          iType = 1 + 4 + ((moreSpecialOptions_&536870912)==0) ? 2 : 0;
    450449        else if (!numberContinuousObj && numberIntegerObj <= 100 &&
    451450                 numberIntegerObj*5 < numberObjects_ && numberIntegerWeight <= 100 &&
    452451                 !parentModel_ &&
    453452                 solver_->getNumRows() > 100 && cost != -COIN_DBL_MAX)
    454             iType = 2 + 4;
     453          iType = 4 + ((moreSpecialOptions_&536870912)==0) ? 2 : 0;
    455454        else if (!numberContinuousObj && numberIntegerObj <= 100 &&
    456455                 numberIntegerObj*5 < numberObjects_ &&
     
    511510                << general << CoinMessageEol ;
    512511                // switch off clp type branching
    513                 fastNodeDepth_ = -1;
     512                // no ? fastNodeDepth_ = -1;
    514513                int highPriority = (branchOnSatisfied) ? -999 : 100;
    515514                for (int i = 0; i < numberObjects_; i++) {
     
    10721071                                          messages())
    10731072                << value << CoinMessageEol ;
    1074                 setDblParam(CbcModel::CbcCutoffIncrement, value*0.999) ;
     1073                setDblParam(CbcModel::CbcCutoffIncrement, CoinMax(value*0.999,value-1.0e-4)) ;
    10751074            }
    10761075        }
     
    15961595
    15971596{
     1597  if (!parentModel_)
    15981598    /*
    15991599      Capture a time stamp before we start (unless set).
     
    21592159            // switch off fast nodes for now
    21602160            fastNodeDepth_ = -1;
     2161            moreSpecialOptions_ &= ~33554432; // no diving
    21612162        }
    21622163        if (numberThreads_ > 0) {
     
    22272228
    22282229    // add cutoff as constraint if wanted
    2229     if ((moreSpecialOptions_&16777216)!=0) {
     2230    if (cutoffRowNumber_==-2) {
    22302231      if (!parentModel_) {
    22312232        int numberColumns=solver_->getNumCols();
     
    22412242        if (n) {
    22422243          double cutoff=getCutoff();
     2244          // relax a little bit
     2245          cutoff += 1.0e-4;
    22432246          double offset;
    22442247          solver_->getDblParam(OsiObjOffset, offset);
     2248          cutoffRowNumber_ = solver_->getNumRows();
    22452249          solver_->addRow(n,indices,obj,-COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset);
    22462250        } else {
    22472251          // no objective!
    2248           moreSpecialOptions_ &= ~16777216;
     2252          cutoffRowNumber_ = -1;
    22492253        }
    22502254        delete [] indices;
     
    22522256      } else {
    22532257        // switch off
    2254         moreSpecialOptions_ &= ~16777216;
     2258        cutoffRowNumber_ = -1;
    22552259      }
    22562260    }
     
    24892493      }
    24902494      CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis *> (solver_->getEmptyWarmStart());
     2495      int numberIterations=0;
    24912496      for (int i=0;i<numberModels;i++) {
    24922497        rootModels[i]=new CbcModel(*this);
     
    24982503        // use seed
    24992504        rootModels[i]->setSpecialOptions(specialOptions_ |(4194304|8388608));
     2505        rootModels[i]->setMoreSpecialOptions(moreSpecialOptions_ &
     2506                                             (~134217728));
    25002507        rootModels[i]->solver_->setWarmStart(basis);
    25012508#ifdef COIN_HAS_CLP
     
    25032510          = dynamic_cast<OsiClpSolverInterface *> (rootModels[i]->solver_);
    25042511        if (clpSolver) {
    2505           clpSolver->getModelPtr()->setRandomSeed(newSeed+20000000*i);
    2506           clpSolver->getModelPtr()->allSlackBasis();
     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);
    25072533        }
    25082534#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_);
    25092539      }
    25102540      delete basis;
     
    26632693    }
    26642694    // replace solverType
     2695    double * tightBounds = NULL;
    26652696    if (solverCharacteristics_->tryCuts())  {
    26662697
     
    26692700            if (!eventHappened_ && feasible) {
    26702701                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                  }
    26712713                  int numberModels = multipleRootTries_%100;
    26722714                  const OsiSolverInterface ** solvers = new
     
    26762718                  for (int i=0;i<numberModels;i++) {
    26772719                    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                    }
    26782726                    int numberRows2=solvers[i]->getNumRows();
    26792727                    assert (numberRows2>=numberRows);
     
    26872735                    generator_[j]->scaleBackStatistics(numberModels);
    26882736                  }
    2689                   CbcRowCuts rowCut(maxCuts);
     2737                  //CbcRowCuts rowCut(maxCuts);
     2738                  const OsiRowCutDebugger *debugger = NULL;
     2739                  if ((specialOptions_&1) != 0)
     2740                    debugger = solver_->getRowCutDebugger() ;
    26902741                  for (int iModel=0;iModel<numberModels;iModel++) {
    26912742                    int numberRows2=solvers[iModel]->getNumRows();
     
    27032754                      CoinBigIndex start = rowStart[iRow];
    27042755                      rc.setRow(rowLength[iRow],column+start,elements+start,false);
    2705                       rowCut.addCutIfNotDuplicate(rc);
     2756                      if (debugger)
     2757                        CoinAssert (!debugger->invalidCut(rc));
     2758                      globalCuts_.addCutIfNotDuplicate(rc);
    27062759                    }
    2707                     //int cutsAdded=rowCut.numberCuts()-numberCuts;
     2760                    //int cutsAdded=globalCuts_.numberCuts()-numberCuts;
    27082761                    //numberCuts += cutsAdded;
    27092762                    //printf("Model %d gave %d cuts (out of %d possible)\n",
    27102763                    //     iModel,cutsAdded,numberRows2-numberRows);
    27112764                  }
    2712                   rowCut.addCuts(cuts);
     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;
    27132805                  char printBuffer[200];
    27142806                  sprintf(printBuffer,"%d solvers added %d different cuts out of pool of %d",
    2715                           numberModels,cuts.sizeRowCuts(),maxCuts);
     2807                          numberModels,globalCuts_.sizeRowCuts(),maxCuts);
    27162808                  messageHandler()->message(CBC_GENERAL, messages())
    27172809                    << printBuffer << CoinMessageEol ;
     2810                  if (nTightened) {
     2811                    sprintf(printBuffer,"%d bounds were tightened",
     2812                          nTightened);
     2813                    messageHandler()->message(CBC_GENERAL, messages())
     2814                      << printBuffer << CoinMessageEol ;
     2815                  }
    27182816                  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                  }
    27192906                }
    27202907                feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_,
    27212908                                         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                }
    27223058                if ((specialOptions_&524288) != 0 && !parentModel_
    27233059                        && storedRowCuts_) {
     
    29763312    }
    29773313#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   
    29783322    /*
    29793323      A hook to use clp to quickly explore some part of the tree.
     
    29853329        obj->setPriority(1);
    29863330        addObjects(1, &obj);
     3331        delete obj;
    29873332    }
    29883333    int saveNumberSolves = numberSolves_;
    29893334    int saveNumberIterations = numberIterations_;
    2990     if (fastNodeDepth_ >= 0 &&/*!parentModel_*/(specialOptions_&2048) == 0) {
     3335    if ((fastNodeDepth_ >= 0||(moreSpecialOptions_&33554432)!=0)
     3336        &&/*!parentModel_*/(specialOptions_&2048) == 0) {
    29913337        // add in a general depth object doClp
    29923338        int type = (fastNodeDepth_ <= 100) ? fastNodeDepth_ : -(fastNodeDepth_ - 100);
     3339        if ((moreSpecialOptions_&33554432)!=0)
     3340          type=12;
     3341        else
     3342          fastNodeDepth_ += 1000000;     // mark as done
    29933343        CbcObject * obj =
    29943344            new CbcGeneralDepth(this, type);
    29953345        addObjects(1, &obj);
    2996         // mark as done
    2997         fastNodeDepth_ += 1000000;
    29983346        delete obj;
    29993347        // fake number of objects
     
    40524400            if (!node || node->objectiveValue() > cutoff)
    40534401                continue;
    4054             // Do main work of solving node here
    4055             doOneNode(this, node, createdNode);
     4402            // Do main work of solving node here
     4403            doOneNode(this, node, createdNode);
    40564404#ifdef JJF_ZERO
    4057             if (node) {
    4058                 if (createdNode) {
    4059                     printf("Node %d depth %d, created %d depth %d\n",
    4060                            node->nodeNumber(), node->depth(),
    4061                            createdNode->nodeNumber(), createdNode->depth());
    4062                 } else {
    4063                     printf("Node %d depth %d,  no created node\n",
    4064                            node->nodeNumber(), node->depth());
    4065                 }
    4066             } else if (createdNode) {
    4067                 printf("Node exhausted, created %d depth %d\n",
    4068                        createdNode->nodeNumber(), createdNode->depth());
    4069             } else {
    4070                 printf("Node exhausted,  no created node\n");
    4071                 numberConsecutiveInfeasible = 2;
    4072             }
     4405            if (node) {
     4406              if (createdNode) {
     4407                printf("Node %d depth %d, created %d depth %d\n",
     4408                       node->nodeNumber(), node->depth(),
     4409                       createdNode->nodeNumber(), createdNode->depth());
     4410              } else {
     4411                printf("Node %d depth %d,  no created node\n",
     4412                       node->nodeNumber(), node->depth());
     4413              }
     4414            } else if (createdNode) {
     4415              printf("Node exhausted, created %d depth %d\n",
     4416                     createdNode->nodeNumber(), createdNode->depth());
     4417            } else {
     4418              printf("Node exhausted,  no created node\n");
     4419              numberConsecutiveInfeasible = 2;
     4420            }
    40734421#endif
    40744422            //if (createdNode)
     
    44534801        setCutoff(1.0e50) ; // As best solution should be worse than cutoff
    44544802        // change cutoff as constraint if wanted
    4455         if ((moreSpecialOptions_&16777216)!=0) {
    4456           if (solver_->getNumRows()>=numberRowsAtContinuous_)
    4457             solver_->setRowUpper(numberRowsAtContinuous_-1,1.0e50);
     4803        if (cutoffRowNumber_>=0) {
     4804          if (solver_->getNumRows()>cutoffRowNumber_)
     4805            solver_->setRowUpper(cutoffRowNumber_,1.0e50);
    44584806        }
    44594807        // also in continuousSolver_
     
    45184866    delete globalConflictCuts_;
    45194867    globalConflictCuts_=NULL;
    4520     if (!bestSolution_) {
     4868    if (!bestSolution_ && (specialOptions_&8388608)==0) {
    45214869        // make sure lp solver is infeasible
    45224870        int numberColumns = solver_->getNumCols();
     
    45454893    }
    45464894#endif
    4547     if (fastNodeDepth_ >= 1000000 && !parentModel_) {
    4548         // delete object off end
    4549         delete object_[numberObjects_];
     4895    if ((fastNodeDepth_ >= 1000000 || (moreSpecialOptions_&33554432)!=0)
     4896         && !parentModel_) {
     4897      // delete object off end
     4898      delete object_[numberObjects_];
     4899      if ((moreSpecialOptions_&33554432)==0)
    45504900        fastNodeDepth_ -= 1000000;
    45514901    }
     
    47285078        numberIntegers_(0),
    47295079        numberRowsAtContinuous_(0),
     5080        cutoffRowNumber_(-1),
    47305081        maximumNumberCuts_(0),
    47315082        phase_(0),
     
    47755126        ownObjects_(true),
    47765127        originalColumns_(NULL),
    4777         howOftenGlobalScan_(1),
     5128        howOftenGlobalScan_(3),
    47785129        numberGlobalViolations_(0),
    47795130        numberExtraIterations_(0),
     
    48945245        secondaryStatus_(-1),
    48955246        numberRowsAtContinuous_(0),
     5247        cutoffRowNumber_(-1),
    48965248        maximumNumberCuts_(0),
    48975249        phase_(0),
     
    49385290        ownObjects_(true),
    49395291        originalColumns_(NULL),
    4940         howOftenGlobalScan_(1),
     5292        howOftenGlobalScan_(3),
    49415293        numberGlobalViolations_(0),
    49425294        numberExtraIterations_(0),
     
    50655417}
    50665418
     5419static int * resizeInt(int * array,int oldLength, int newLength)
     5420{
     5421  if (!array)
     5422    return NULL;
     5423  assert (newLength>oldLength);
     5424  int * newArray = new int [newLength];
     5425  memcpy(newArray,array,oldLength*sizeof(int));
     5426  delete [] array;
     5427  memset(newArray+oldLength,0,(newLength-oldLength)*sizeof(int));
     5428  return newArray;
     5429}
     5430static double * resizeDouble(double * array,int oldLength, int newLength)
     5431{
     5432  if (!array)
     5433    return NULL;
     5434  assert (newLength>oldLength);
     5435  double * newArray = new double [newLength];
     5436  memcpy(newArray,array,oldLength*sizeof(double));
     5437  delete [] array;
     5438  memset(newArray+oldLength,0,(newLength-oldLength)*sizeof(double));
     5439  return newArray;
     5440}
    50675441/*
    50685442  Assign a solver to the model (model assumes ownership)
     
    50885462
    50895463{
    5090     // resize best solution if exists
    5091     if (bestSolution_ && solver && solver_) {
     5464    // resize stuff if exists
     5465    if (solver && solver_) {
    50925466        int nOld = solver_->getNumCols();
    50935467        int nNew = solver->getNumCols();
    50945468        if (nNew > nOld) {
    5095             double * temp = new double[nNew];
    5096             memcpy(temp, bestSolution_, nOld*sizeof(double));
    5097             memset(temp + nOld, 0, (nNew - nOld)*sizeof(double));
    5098             delete [] bestSolution_;
    5099             bestSolution_ = temp;
     5469          originalColumns_ = resizeInt(originalColumns_,nOld,nNew);
     5470          usedInSolution_ = resizeInt(usedInSolution_,nOld,nNew);
     5471          continuousSolution_ = resizeDouble(continuousSolution_,nOld,nNew);
     5472          hotstartSolution_ = resizeDouble(hotstartSolution_,nOld,nNew);
     5473          bestSolution_ = resizeDouble(bestSolution_,nOld,nNew);
     5474          currentSolution_ = resizeDouble(currentSolution_,nOld,nNew);
     5475          if (savedSolutions_) {
     5476            for (int i = 0; i < maximumSavedSolutions_; i++)
     5477              savedSolutions_[i] = resizeDouble(savedSolutions_[i],nOld,nNew);
     5478          }
    51005479        }
    51015480    }
     
    53885767    testSolution_ = currentSolution_;
    53895768    numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_;
     5769    cutoffRowNumber_ = rhs.cutoffRowNumber_;
    53905770    maximumNumberCuts_ = rhs.maximumNumberCuts_;
    53915771    phase_ = rhs.phase_;
     
    57156095        }
    57166096        numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_;
     6097        cutoffRowNumber_ = rhs.cutoffRowNumber_;
    57176098        maximumNumberCuts_ = rhs.maximumNumberCuts_;
    57186099        phase_ = rhs.phase_;
     
    60076388        int i;
    60086389        for (i = 0; i < numberCutGenerators_; i++) {
    6009             if (mode < 2)
     6390            if (mode < 2) {
    60106391                generator_[i] = new CbcCutGenerator(*rhs.generator_[i]);
    6011             else
     6392            } else {
    60126393                generator_[i] = new CbcCutGenerator(*rhs.virginGenerator_[i]);
     6394                // But copy across maximumTries
     6395                generator_[i]->setMaximumTries(rhs.generator_[i]->maximumTries());
     6396            }
    60136397            virginGenerator_[i] = new CbcCutGenerator(*rhs.virginGenerator_[i]);
    60146398        }
     
    60726456    strongInfo_[6] = rhs.strongInfo_[6];
    60736457    numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_;
     6458    cutoffRowNumber_ = rhs.cutoffRowNumber_;
    60746459    maximumDepth_ = rhs.maximumDepth_;
    60756460}
     
    62616646        heuristic_[where]->setHeuristicName(name) ;
    62626647    heuristic_[where]->setSeed(987654321 + where);
    6263     if (randomSeed_!=-1)
    6264       heuristic_[where]->setSeed(randomSeed_);
    62656648    numberHeuristics_++ ;
    62666649}
     
    62886671{
    62896672    int nNode = 0;
     6673    CbcNodeInfo * nodeInfo = node->nodeInfo();
    62906674    int numberColumns = getNumCols();
    6291     CbcNodeInfo * nodeInfo = node->nodeInfo();
    62926675
    62936676    /*
     
    65456928#         endif
    65466929                    addCuts[numberToAdd++] = addedCuts_[i];
     6930#if 1
     6931                    if ((specialOptions_&1) != 0) {
     6932                      const OsiRowCutDebugger * debugger = solver_->getRowCutDebugger() ;
     6933                      if (debugger)
     6934                        CoinAssert (!debugger->invalidCut(*addedCuts_[i]));
     6935                    }
     6936#endif
    65476937                } else {
    65486938#         ifdef CHECK_CUT_COUNTS
     
    66527042                    delete [] which;
    66537043                }
     7044                //#define CHECK_DEBUGGER
     7045#ifdef CHECK_DEBUGGER
     7046                if ((specialOptions_&1) != 0 ) {
     7047                  const OsiRowCutDebugger * debugger =
     7048                    solver_->getRowCutDebugger();
     7049                  if (debugger) {
     7050                    for (int j=0;j<numberToAdd;j++)
     7051                      CoinAssert (!debugger->invalidCut(*addCuts[j]));
     7052                    //addCuts[j]->print();
     7053                  }
     7054                }
     7055#endif
    66547056                //int n2=solver_->getNumRows();
    66557057                //for (int j=0;j<numberToAdd;j++)
     
    67097111CbcModel::synchronizeHandlers(int /*makeDefault*/)
    67107112{
     7113    bool defaultHandler = defaultHandler_;
    67117114    if (!defaultHandler_) {
    67127115        // Must have clone
     
    67157118    }
    67167119#ifdef COIN_HAS_CLP
    6717     OsiClpSolverInterface * solver;
    6718     solver = dynamic_cast<OsiClpSolverInterface *>(solver_) ;
    6719     if (solver) {
     7120    if (!defaultHandler) {
     7121      OsiClpSolverInterface * solver;
     7122      solver = dynamic_cast<OsiClpSolverInterface *>(solver_) ;
     7123      if (solver) {
    67207124        solver->passInMessageHandler(handler_);
    67217125        solver->getModelPtr()->passInMessageHandler(handler_);
    6722     }
    6723     solver = dynamic_cast<OsiClpSolverInterface *>(continuousSolver_) ;
    6724     if (solver) {
     7126      }
     7127      solver = dynamic_cast<OsiClpSolverInterface *>(continuousSolver_) ;
     7128      if (solver) {
    67257129        solver->passInMessageHandler(handler_);
    67267130        solver->getModelPtr()->passInMessageHandler(handler_);
     7131      }
    67277132    }
    67287133#endif
     
    69877392          if ((specialOptions_&1) != 0) {
    69887393            debugger = continuousSolver_->getRowCutDebugger() ;
    6989             if (debugger)
     7394            if (debugger) {
    69907395              if (debugger->invalidCut(*cut)) {
    69917396                continuousSolver_->applyRowCuts(1,cut);
     
    69937398              }
    69947399              CoinAssert (!debugger->invalidCut(*cut));
     7400            }
    69957401          }
    69967402        } else {
     
    72747680        allowZeroIterations = true;
    72757681    }
     7682    int saveNumberTries=numberTries;
    72767683    /*
    72777684      Is it time to scan the cuts in order to remove redundant cuts? If so, set
     
    72927699    // Really primalIntegerTolerance; relates to an illposed problem with various
    72937700    // integer solutions depending on integer tolerance.
    7294     double primalTolerance = 1.0e-7 ;
     7701    //double primalTolerance = 1.0e-7 ;
    72957702    // We may need to keep going on
    72967703    bool keepGoing = false;
     
    73427749        */
    73437750        int numberViolated = 0;
    7344         if (currentPassNumber_ == 1 && howOftenGlobalScan_ > 0 &&
     7751        if ((currentPassNumber_ == 1 ||!numberNodes_) && howOftenGlobalScan_ > 0 &&
    73457752                (numberNodes_ % howOftenGlobalScan_) == 0 &&
    73467753                (doCutsNow(1) || true)) {
    73477754            // global column cuts now done in node at top of tree
    7348             int numberCuts = globalCuts_.sizeRowCuts() ;
    7349             // possibly extend whichGenerator
    7350             resizeWhichGenerator(numberViolated, numberViolated + numberCuts);
    7351             for (int i = 0; i < numberCuts; i++) {
     7755            int numberCuts = numberCutGenerators_ ? globalCuts_.sizeRowCuts() : 0;
     7756            if (numberCuts) {
     7757              // possibly extend whichGenerator
     7758              resizeWhichGenerator(numberViolated, numberViolated + numberCuts);
     7759              // only add new cuts up to 10% of current elements
     7760              int numberElements = solver_->getNumElements();
     7761              int numberColumns = solver_->getNumCols();
     7762              int maximumAdd = CoinMax(numberElements/10,2*numberColumns)+100;
     7763              double * violations = new double[numberCuts];
     7764              int * which = new int[numberCuts];
     7765              int numberPossible=0;
     7766              for (int i = 0; i < numberCuts; i++) {
    73527767                OsiRowCut * thisCut = globalCuts_.rowCutPtr(i) ;
    7353                 if (thisCut->violated(cbcColSolution_) > primalTolerance ||
    7354                         thisCut->effectiveness() == COIN_DBL_MAX) {
     7768                double violation = thisCut->violated(cbcColSolution_);
     7769                if(thisCut->effectiveness() == COIN_DBL_MAX) {
     7770                  // see if already there
     7771                  int j;
     7772                  for (j = 0; j < currentNumberCuts_; j++) {
     7773                    if (addedCuts_[j]==thisCut)
     7774                      break;
     7775                  }
     7776                  if (j==currentNumberCuts_)
     7777                    violation = COIN_DBL_MAX;
     7778                  //else
     7779                  //printf("already done??\n");
     7780                }
     7781                if (violation > 0.005) {
     7782                  violations[numberPossible]=-violation;
     7783                  which[numberPossible++]=i;
     7784                }
     7785              }
     7786              CoinSort_2(violations,violations+numberPossible,which);
     7787              for (int i = 0; i < numberPossible; i++) {
     7788                int k=which[i];
     7789                OsiRowCut * thisCut = globalCuts_.rowCutPtr(k) ;
     7790                assert (thisCut->violated(cbcColSolution_) > 0.005/*primalTolerance*/ ||
     7791                        thisCut->effectiveness() == COIN_DBL_MAX);
     7792#define CHECK_DEBUGGER
     7793#ifdef CHECK_DEBUGGER
     7794                if ((specialOptions_&1) != 0 ) {
     7795                  const OsiRowCutDebugger * debugger =
     7796                    solver_->getRowCutDebuggerAlways();
     7797                  CoinAssert (!debugger->invalidCut(*thisCut));
     7798                }
     7799#endif
    73557800#if 0 //ndef NDEBUG
    7356                   printf("Global cut added - violation %g\n",
    7357                            thisCut->violated(cbcColSolution_)) ;
    7358 #endif
    7359                     whichGenerator_[numberViolated++] = -1;
     7801                printf("Global cut added - violation %g\n",
     7802                       thisCut->violated(cbcColSolution_)) ;
     7803#endif
     7804                whichGenerator_[numberViolated++] = -1;
    73607805#ifndef GLOBAL_CUTS_JUST_POINTERS
    7361                     theseCuts.insert(*thisCut) ;
     7806                theseCuts.insert(*thisCut) ;
    73627807#else
    7363                     theseCuts.insert(thisCut) ;
    7364 #endif
    7365                 }
    7366             }
    7367             numberGlobalViolations_ += numberViolated;
     7808                theseCuts.insert(thisCut) ;
     7809#endif
     7810                if (violations[i]!=-COIN_DBL_MAX)
     7811                  maximumAdd -= thisCut->row().getNumElements();
     7812                if (maximumAdd<0)
     7813                  break;
     7814              }
     7815              delete [] which;
     7816              delete [] violations;
     7817              numberGlobalViolations_ += numberViolated;
     7818            }
    73687819        }
    73697820        /*
     
    77218172            //solver_->setHintParam(OsiDoDualInResolve,true,OsiHintTry);
    77228173            if ( maximumSecondsReached() ) {
    7723                 numberTries = 0; // exit
     8174                numberTries = -1000; // exit
    77248175                feasible = false;
    77258176                break;
     
    78798330                    // maybe give it one more try
    78808331                    if (numberLastAttempts > 2 || currentDepth_ || experimentBreak < 2)
    7881                         break ;
     8332                        numberTries=0 ;
    78828333                    else
    78838334                        numberLastAttempts++;
     
    79138364            keepGoing=false;
    79148365        }
    7915         if (numberTries <=0 && feasible && !keepGoing && !parentModel_ && !numberNodes_) {
     8366        if (numberTries ==0 && feasible && !keepGoing && !parentModel_ && !numberNodes_) {
    79168367          for (int i = 0; i < numberCutGenerators_; i++) {
    79178368            if (generator_[i]->whetherCallAtEnd()
    79188369                &&!generator_[i]->whetherInMustCallAgainMode()) {
    7919               keepGoing= true;
    7920               break;
     8370              // give it some goes and switch off
     8371              numberTries=(saveNumberTries+4)/5;
     8372              generator_[i]->setWhetherCallAtEnd(false);
    79218373            }
    79228374          }
     
    79888440                }
    79898441                if (!feasible) { //node will be fathomed
     8442                    lockThread();
    79908443                    for (int i = 0; i < currentNumberCuts_; i++) {
    79918444                        // take off node
     
    79968449                        }
    79978450                    }
     8451                    unlockThread();
    79988452                }
    79998453            }
     
    81398593        */
    81408594        if (!numberNodes_) {
     8595          if (!parentModel_) {
     8596            //printf("%d global cuts\n",globalCuts_.sizeRowCuts()) ;
     8597            if ((specialOptions_&1) != 0) {
     8598              //specialOptions_ &= ~1;
     8599              int numberCuts = globalCuts_.sizeRowCuts();
     8600              const OsiRowCutDebugger *debugger =
     8601                continuousSolver_->getRowCutDebugger() ;
     8602              if (debugger) {
     8603                for (int i = 0; i < numberCuts; i++) {
     8604                  OsiRowCut * cut = globalCuts_.rowCutPtr(i) ;
     8605                  if (debugger->invalidCut(*cut)) {
     8606                    continuousSolver_->applyRowCuts(1,cut);
     8607                    continuousSolver_->writeMps("bad");
     8608                    printf("BAD cut\n");
     8609                  }
     8610                  //CoinAssert (!debugger->invalidCut(*cut));
     8611                }
     8612              }
     8613            }
     8614          }
    81418615          //solver_->writeMps("second");
    81428616            if (numberRowsAdded)
     
    82878761                willBeCutsInTree = 0;
    82888762        }
    8289         if (!numberNodes_)
     8763        if (!numberNodes_) {
    82908764            handler_->message(CBC_ROOT, messages_)
    82918765            << numberNewCuts_
     
    82938767            << currentPassNumber_
    82948768            << CoinMessageEol ;
     8769        }
    82958770        /*
    82968771          Count the number of cuts produced by each cut generator on this call. Not
     
    84038878                    howOften = -99; // switch off
    84048879            }
     8880            if (generator_[i]->maximumTries()!=-1)
     8881                howOften = -99; // switch off
    84058882            /*
    84068883              Below -99, this generator is switched off. There's no need to consider
    84078884              further. Then again, there was no point in persisting this far!
    84088885            */
    8409             if (howOften < -99)
    8410                 continue ;
     8886            if (howOften < -99) {
     8887              // may have been switched off - report
     8888              if (!numberNodes_) {
     8889                int n = generator_[i]->numberCutsInTotal();
     8890                if (n) {
     8891                  double average = 0.0;
     8892                  average = generator_[i]->numberElementsInTotal();
     8893                  average /= n;
     8894                  handler_->message(CBC_GENERATOR, messages_)
     8895                    << i
     8896                    << generator_[i]->cutGeneratorName()
     8897                    << n
     8898                    << average
     8899                    << generator_[i]->numberColumnCuts()
     8900                    << generator_[i]->numberCutsActive()
     8901                    + generator_[i]->numberColumnCuts();
     8902                  handler_->printing(generator_[i]->timing())
     8903                    << generator_[i]->timeInCutGenerator();
     8904                  handler_->message()
     8905                    << -100
     8906                    << CoinMessageEol ;
     8907                }
     8908              }
     8909              continue ;
     8910            }
    84118911            /*
    84128912              Adjust, if howOften is adjustable.
     
    87309230        specialOptions_ &= ~256; // mark as full scan done
    87319231    }
    8732 # ifdef COIN_HAS_CLP
    8733     if (!node && !parentModel_ && intParam_[CbcMaxNumNode] == -123456) {
    8734         OsiClpSolverInterface * clpSolver
    8735         = dynamic_cast<OsiClpSolverInterface *> (solver_);
    8736         if (clpSolver) {
    8737             clpSolver->lexSolve();
    8738         }
     9232# if 0 //def COIN_HAS_CLP
     9233    // check basis
     9234    OsiClpSolverInterface * clpSolver
     9235      = dynamic_cast<OsiClpSolverInterface *> (solver_);
     9236    if (clpSolver) {
     9237      ClpSimplex * simplex = clpSolver->getModelPtr();
     9238      int numberTotal=simplex->numberRows()+simplex->numberColumns();
     9239      int superbasic=0;
     9240      for (int i=0;i<numberTotal;i++) {
     9241        if (simplex->getStatus(i)==ClpSimplex::superBasic)
     9242          superbasic++;
     9243      }
     9244      if (superbasic) {
     9245        printf("%d superbasic!\n",superbasic);
     9246        clpSolver->resolve();
     9247        superbasic=0;
     9248        for (int i=0;i<numberTotal;i++) {
     9249          if (simplex->getStatus(i)==ClpSimplex::superBasic)
     9250            superbasic++;
     9251        }
     9252        assert (!superbasic);
     9253      }
    87399254    }
    87409255# endif
     
    87649279            }
    87659280        }
     9281        if (generator_[i]->whetherCallAtEnd())
     9282          generate=false;
    87669283        const OsiRowCutDebugger * debugger = NULL;
    87679284        bool onOptimalPath = false;
     
    88229339            }
    88239340#endif
    8824             if (mustResolve) {
     9341            if (mustResolve || (specialOptions_&1) != 0) {
    88259342                int returnCode = resolve(node ? node->nodeInfo() : NULL, 2);
    88269343                if (returnCode  == 0)
     
    88989415            if (thisCut->lb() > thisCut->ub())
    88999416                status = -1; // sub-problem is infeasible
    8900             if (thisCut->globallyValid()) {
     9417            if (thisCut->globallyValid()||!numberNodes_) {
    89019418                // add to global list
    89029419                OsiRowCut newCut(*thisCut);
     
    92239740        }
    92249741    }
    9225 #ifdef COIN_HAS_CLP
     9742  #ifdef COIN_HAS_CLP
    92269743    OsiClpSolverInterface * clpSolver
    92279744    = dynamic_cast<OsiClpSolverInterface *> (solver_);
     
    950010017#ifdef COIN_HAS_CLP
    950110018    if (clpSolver && !feasible) {
    9502         // make sure marked infeasible
     10019      // make sure marked infeasible
     10020      if (!clpSolver->isProvenDualInfeasible())
    950310021        clpSolver->getModelPtr()->setProblemStatus(1);
    950410022    }
     
    1051411032                int n = CoinMax(obj2->numberTimesDown(),
    1051511033                                obj2->numberTimesUp());
    10516                 if (n >= value)
    10517                     obj2->setNumberBeforeTrust(n + 1);
     11034                if (n >= value) {
     11035                  value = CoinMin(CoinMin(n+1,3*(value+1)/2),5*numberBeforeTrust_);
     11036                  obj2->setNumberBeforeTrust(value);
     11037                }
    1051811038            }
    1051911039        }
     
    1145211972            setCutoff(cutoff);
    1145311973            // change cutoff as constraint if wanted
    11454             if ((moreSpecialOptions_&16777216)!=0) {
    11455               if (solver_->getNumRows()>=numberRowsAtContinuous_) {
     11974            if (cutoffRowNumber_>=0) {
     11975              if (solver_->getNumRows()>cutoffRowNumber_) {
    1145611976                double offset;
    1145711977                solver_->getDblParam(OsiObjOffset, offset);
    11458                 solver_->setRowUpper(numberRowsAtContinuous_-1,cutoff+offset);
     11978                solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
    1145911979              }
    1146011980            }
     
    1163212152                setCutoff(cutoff);
    1163312153                // change cutoff as constraint if wanted
    11634                 if ((moreSpecialOptions_&16777216)!=0) {
    11635                   if (solver_->getNumRows()>=numberRowsAtContinuous_) {
     12154                if (cutoffRowNumber_>=0) {
     12155                  if (solver_->getNumRows()>cutoffRowNumber_) {
    1163612156                    double offset;
    1163712157                    solver_->getDblParam(OsiObjOffset, offset);
    11638                     solver_->setRowUpper(numberRowsAtContinuous_-1,cutoff+offset);
     12158                    solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
    1163912159                  }
    1164012160                }
     
    1235712877// Make partial cut into a global cut and save
    1235812878void
    12359 CbcModel::makePartialCut(const OsiRowCut * partialCut)
     12879CbcModel::makePartialCut(const OsiRowCut * partialCut,
     12880                         const OsiSolverInterface * solver)
    1236012881{
    1236112882  // get greedy cut
    1236212883  double bSum = partialCut->lb();
    1236312884  assert (bSum<0.0);
     12885  if (!solver)
     12886    solver=solver_;
    1236412887  int nConflict = partialCut->row().getNumElements();
    1236512888  const int * column = partialCut->row().getIndices();
    1236612889  const double * element = partialCut->row().getElements();
    1236712890  double * originalLower = topOfTree_->mutableLower();
    12368   const double * columnLower = solver_->getColLower();
     12891  const double * columnLower = solver->getColLower();
    1236912892  double * originalUpper = topOfTree_->mutableUpper();
    12370   const double * columnUpper = solver_->getColUpper();
     12893  const double * columnUpper = solver->getColUpper();
    1237112894  int nC=nConflict;
    1237212895  while (nConflict) {
     
    1240412927  printf("CUTa has %d (started at %d) - final bSum %g\n",nConflict,nC,bSum);
    1240512928  if (nConflict>1) {
     12929    if ((specialOptions_&1) != 0) {
     12930      const OsiRowCutDebugger *debugger = continuousSolver_->getRowCutDebugger() ;
     12931      if (debugger) {
     12932        if (debugger->invalidCut(newCut)) {
     12933          continuousSolver_->applyRowCuts(1,&newCut);
     12934          continuousSolver_->writeMps("bad");
     12935        }
     12936        CoinAssert (!debugger->invalidCut(newCut));
     12937      }
     12938    }
    1240612939    newCut.setGloballyValidAsInteger(2);
    1240712940    newCut.mutableRow().setTestForDuplicateIndex(false);
     
    1314613679            int totalNodes = numberNodes_ + numberExtraNodes_;
    1314713680            int totalIterations = numberIterations_ + numberExtraIterations_;
     13681            bool diving=false;
     13682            if ((moreSpecialOptions_&33554432)!=0) {
     13683              testDepth=COIN_INT_MAX;
     13684              if (oldNode&&(oldNode->depth()==-2||oldNode->depth()==4))
     13685                diving=true;
     13686            }
    1314813687            if (totalNodes*40 < totalIterations || numberNodes_ < 1000) {
    1314913688                doClp = false;
     
    1315313692                //     totalNodes,totalIterations,doClp ? 'Y' : 'N');
    1315413693            }
    13155             if (oldNode && fastNodeDepth_ >= 0 && oldNode->depth() >= testDepth &&/*!parentModel_*/(specialOptions_&2048) == 0
    13156                     && doClp && !cuts.sizeRowCuts()) {
     13694            if (oldNode &&
     13695                ((fastNodeDepth_ >= 0 && oldNode->depth() >= testDepth && doClp)||diving) &&/*!parentModel_*/(specialOptions_&2048) == 0
     13696                && !cuts.sizeRowCuts()) {
    1315713697                OsiClpSolverInterface * clpSolver
    1315813698                = dynamic_cast<OsiClpSolverInterface *> (solver_);
     
    1316513705#endif
    1316613706#ifdef COIN_HAS_CLP
    13167             int save;
     13707            int save=0;
    1316813708            OsiClpSolverInterface * clpSolver
    1316913709              = dynamic_cast<OsiClpSolverInterface *> (solver_);
     
    1334513885                assert (numberProblems);
    1334613886                int nProbMinus1 = numberProblems - 1;
     13887                lockThread();
    1334713888                for (int i = 0; i < currentNumberCuts_; i++) {
    1334813889                    if (addedCuts_[i])
    1334913890                        addedCuts_[i]->increment(nProbMinus1) ;
    1335013891                }
     13892                unlockThread();
    1335113893                for (int i = 0; i < numberProblems; i++) {
    1335213894                    double objectiveValue;
     
    1356714109        setCutoff(cutoff) ;
    1356814110        // change cutoff as constraint if wanted
    13569         if ((moreSpecialOptions_&16777216)!=0) {
    13570           if (solver_->getNumRows()>=numberRowsAtContinuous_) {
     14111        if (cutoffRowNumber_>=0) {
     14112          if (solver_->getNumRows()>cutoffRowNumber_) {
    1357114113            double offset;
    1357214114            solver_->getDblParam(OsiObjOffset, offset);
    13573             solver_->setRowUpper(numberRowsAtContinuous_-1,cutoff+offset);
     14115            solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
    1357414116          }
    1357514117        }
     
    1410314645{
    1410414646    int foundSolution = 0;
     14647    int saveNumberCutGenerators=numberCutGenerators_;
     14648    if ((moreSpecialOptions_&33554432)!=0 && (specialOptions_&2048)==0) {
     14649      if (node&&(node->depth()==-2||node->depth()==4))
     14650        numberCutGenerators_=0; // so can dive and branch
     14651    }
    1410514652    int currentNumberCuts = 0 ;
    1410614653    currentNode_ = node; // so can be accessed elsewhere
     
    1420014747            CbcBranchingObject * branch = static_cast <CbcBranchingObject *>(branch2) ;
    1420114748#endif
     14749#if 1
    1420214750            branch->setModel(this);
    1420314751            branchesLeft = node->branch(NULL); // old way
     14752#else
     14753            branchesLeft = node->branch(solver_);
     14754#endif
    1420414755            if (parallelMode() >= 0)
    1420514756                branch->setModel(baseModel);
     
    1460615157                  solver_->writeMpsNative("infeas2.mps", NULL, NULL, 2);
    1460715158                  solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
    14608                   assert (solver_->getRowCutDebugger()) ;
     15159                  const OsiRowCutDebugger * debugger = solver_->getRowCutDebugger() ;
     15160                  assert (debugger) ;
     15161                  int numberRows0=continuousSolver_->getNumRows();
     15162                  int numberRows=solver_->getNumRows();
     15163                  const CoinPackedMatrix * rowCopy = solver_->getMatrixByRow();
     15164                  const int * rowLength = rowCopy->getVectorLengths();
     15165                  const double * elements = rowCopy->getElements();
     15166                  const int * column = rowCopy->getIndices();
     15167                  const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
     15168                  const double * rowLower = solver_->getRowLower();
     15169                  const double * rowUpper = solver_->getRowUpper();
     15170                  for (int iRow=numberRows0;iRow<numberRows;iRow++) {
     15171                    OsiRowCut rc;
     15172                    rc.setLb(rowLower[iRow]);
     15173                    rc.setUb(rowUpper[iRow]);
     15174                    CoinBigIndex start = rowStart[iRow];
     15175                    rc.setRow(rowLength[iRow],column+start,elements+start,false);
     15176                    CoinAssert (!debugger->invalidCut(rc));
     15177                  }
    1460915178                  assert (feasible);
    1461015179                }
     
    1487715446            if (parallelMode() >= 0)
    1487815447                newNode = new CbcNode() ;
     15448#if 0
     15449            // Try diving
     15450            if (parallelMode() >= 0 && (specialOptions_&2048) == 0) {
     15451              // See if any diving heuristics set to do dive+save
     15452              CbcHeuristicDive * dive=NULL;
     15453              for (int i = 0; i < numberHeuristics_; i++) {
     15454                CbcHeuristicDive * possible = dynamic_cast<CbcHeuristicDive *>(heuristic_[i]);
     15455                if (possible&&possible->maxSimplexIterations()==COIN_INT_MAX) {
     15456                  // if more than one then rotate later?
     15457                  //if (possible->canHeuristicRun()) {
     15458                  if (node->depth()==0||node->depth()==5) {
     15459                    dive=possible;
     15460                    break;
     15461                  }
     15462                }
     15463              }
     15464              if (dive) {
     15465                int numberNodes;
     15466                CbcSubProblem ** nodes=NULL;
     15467                int branchState=dive->fathom(this,numberNodes,nodes);
     15468                if (branchState) {
     15469                  printf("new solution\n");
     15470                }
     15471                if (0) {
     15472                  for (int iNode=0;iNode<numberNodes;iNode++) {
     15473                    //tree_->push(nodes[iNode]) ;
     15474                  }
     15475                  assert (node->nodeInfo());
     15476                  if (node->nodeInfo()->numberBranchesLeft()) {
     15477                    tree_->push(node) ;
     15478                  } else {
     15479                    node->setActive(false);
     15480                  }
     15481                }
     15482                delete [] nodes;
     15483              }
     15484            }
     15485            // end try diving
     15486#endif
    1487915487            // Set objective value (not so obvious if NLP etc)
    1488015488            setObjectiveValue(newNode, node);
     
    1526815876        unlockThread();
    1526915877    }
     15878    numberCutGenerators_=saveNumberCutGenerators;
    1527015879    return foundSolution;
    1527115880}
     
    1552516134    for (int i = 0; i < numberHeuristics_; i++) {
    1552616135        CbcHeuristicDive * heuristic = dynamic_cast<CbcHeuristicDive *> (heuristic_[i]);
    15527         if (heuristic) {
     16136        if (heuristic && heuristic->maxSimplexIterations()!=COIN_INT_MAX) {
    1552816137            heuristic->setMaxSimplexIterations(nTree);
    1552916138            heuristic->setMaxSimplexIterationsAtRoot(nRoot);
     
    1689417503    char general[200];
    1689517504    if (clpSolver) {
    16896       clpSolver->getModelPtr()->dual(); // to get more randomness
     17505      clpSolver->getModelPtr()->dual(); // probably not needed
    1689717506      clpSolver->setWarmStart(NULL);
    16898       sprintf(general,"Starting multiple root solver - %d iterations in initialSolve",
    16899               clpSolver->getIterationCount());
     17507      sprintf(general,"Starting multiple root solver");
    1690017508    } else {
    1690117509#endif
     
    1691617524    return NULL;
    1691717525}
    16918 
    16919 
     17526OsiRowCut *
     17527CbcModel::conflictCut(const OsiSolverInterface * solver, bool & localCuts)
     17528{
     17529  OsiRowCut * cut=NULL;
     17530  localCuts=false;
     17531# ifdef COIN_HAS_CLP
     17532  const OsiClpSolverInterface * clpSolver
     17533    = dynamic_cast<const OsiClpSolverInterface *> (solver);
     17534  if (clpSolver&&topOfTree_) {
     17535    int debugMode=0;
     17536    const double * originalLower = topOfTree_->lower();
     17537    const double * originalUpper = topOfTree_->upper();
     17538    int typeCut = 1;
     17539    ClpSimplex * simplex = clpSolver->getModelPtr();
     17540    assert(simplex->status()==1);
     17541    if(simplex->ray()) {
     17542      {
     17543        int numberRows=simplex->numberRows();
     17544        double * saveRay=CoinCopyOfArray(simplex->ray(),numberRows);
     17545#define SAFE_RAY
     17546#ifdef SAFE_RAY
     17547        ClpSimplex & tempSimplex=*simplex;
     17548#else
     17549        ClpSimplex tempSimplex=*simplex;
     17550#endif
     17551        int logLevel=simplex->logLevel();
     17552        tempSimplex.setLogLevel(63);
     17553        tempSimplex.scaling(0);
     17554        tempSimplex.dual();
     17555        tempSimplex.setLogLevel(logLevel);
     17556        if (!tempSimplex.numberIterations()) {
     17557          double * ray = tempSimplex.ray();
     17558          int nBad=0;
     17559          for (int i=0;i<numberRows;i++) {
     17560            if (fabs(ray[i]-saveRay[i])>1.0e-3) {
     17561              if (debugMode)
     17562                printf("row %d true %g bad %g - diff %g\n",
     17563                       i,ray[i],saveRay[i],ray[i]-saveRay[i]);
     17564              nBad++;
     17565            }
     17566          }
     17567          if (nBad)
     17568            printf("%d mismatch crunch ray values\n",nBad);
     17569        }
     17570        delete [] saveRay;
     17571      }
     17572     // make sure we use non-scaled versions
     17573      ClpPackedMatrix * saveMatrix = simplex->swapScaledMatrix(NULL);
     17574      double * saveScale = simplex->swapRowScale(NULL);
     17575      //printf("Could do normal cut\n");
     17576      // could use existing arrays
     17577      int numberRows=simplex->numberRows();
     17578      int numberColumns=simplex->numberColumns();
     17579      double * farkas = new double [2*numberColumns+numberRows];
     17580      double * bound = farkas + numberColumns;
     17581      double * effectiveRhs = bound + numberColumns;
     17582      // sign as internally for dual - so swap if primal
     17583      /*const*/ double * ray = simplex->ray();
     17584      // have to get rid of local cut rows
     17585      if (whichGenerator_) {
     17586        const int * whichGenerator = whichGenerator_ - numberRowsAtContinuous_;
     17587        int badRows=0;
     17588        for (int iRow=numberRowsAtContinuous_;iRow<numberRows;iRow++) {
     17589          int iType=whichGenerator[iRow];
     17590          if ((iType>=0&&iType<10000)||iType<-1) {
     17591            if (fabs(ray[iRow])>1.0e-10) {
     17592              badRows++;
     17593            } else {
     17594              ray[iRow]=0.0;
     17595            }
     17596          }
     17597        }
     17598        if (badRows) {
     17599          if ((debugMode&1)!=0)
     17600            printf("%d rows from local cuts\n",badRows);
     17601          localCuts=true;
     17602        }
     17603      }
     17604      // get farkas row
     17605      memset(farkas,0,(2*numberColumns+numberRows)*sizeof(double));
     17606      simplex->transposeTimes(-1.0,ray,farkas);
     17607      //const char * integerInformation = simplex->integerType_;
     17608      //assert (integerInformation);
     17609
     17610      int sequenceOut = simplex->sequenceOut();
     17611      // Put nonzero bounds in bound
     17612      const double * columnLower = simplex->columnLower();
     17613      const double * columnUpper = simplex->columnUpper();
     17614      int numberBad=0;
     17615      for (int i=0;i<numberColumns;i++) {
     17616        double value = farkas[i];
     17617        double boundValue=0.0;
     17618        if (simplex->getStatus(i)==ClpSimplex::basic) {
     17619          // treat as zero if small
     17620          if (fabs(value)<1.0e-8) {
     17621            value=0.0;
     17622            farkas[i]=0.0;
     17623          }
     17624          if (value) {
     17625            //printf("basic %d direction %d farkas %g\n",
     17626            //     i,simplex->directionOut(),value);
     17627            if (value<0.0)
     17628              boundValue=columnLower[i];
     17629            else
     17630              boundValue=columnUpper[i];
     17631          }
     17632        } else if (fabs(value)>1.0e-10) {
     17633          if (value<0.0)
     17634            boundValue=columnLower[i];
     17635          else
     17636            boundValue=columnUpper[i];
     17637        }
     17638        bound[i]=boundValue;
     17639        if (fabs(boundValue)>1.0e10)
     17640          numberBad++;
     17641      }
     17642      const double * rowLower = simplex->rowLower();
     17643      const double * rowUpper = simplex->rowUpper();
     17644      //int pivotRow = simplex->spareIntArray_[3];
     17645      //bool badPivot=pivotRow<0;
     17646      for (int i=0;i<numberRows;i++) {
     17647        double value = ray[i];
     17648        double rhsValue=0.0;
     17649        if (simplex->getRowStatus(i)==ClpSimplex::basic) {
     17650          // treat as zero if small
     17651          if (fabs(value)<1.0e-8) {
     17652            value=0.0;
     17653            ray[i]=0.0;
     17654          }
     17655          if (value) {
     17656            //printf("row basic %d direction %d ray %g\n",
     17657            //     i,simplex->directionOut(),value);
     17658            if (value<0.0)
     17659              rhsValue=rowLower[i];
     17660            else
     17661              rhsValue=rowUpper[i];
     17662          }
     17663        } else if (fabs(value)>1.0e-10) {
     17664          if (value<0.0)
     17665            rhsValue=rowLower[i];
     17666          else
     17667              rhsValue=rowUpper[i];
     17668        }
     17669        effectiveRhs[i]=rhsValue;
     17670      }
     17671      simplex->times(-1.0,bound,effectiveRhs);
     17672      simplex->swapRowScale(saveScale);
     17673      simplex->swapScaledMatrix(saveMatrix);
     17674      double bSum=0.0;
     17675      for (int i=0;i<numberRows;i++) {
     17676        bSum += effectiveRhs[i]*ray[i];
     17677      }
     17678      if (numberBad||bSum>-1.0e-4) {
     17679#ifndef NDEBUG
     17680        printf("bad BOUND bSum %g  - %d bad\n",
     17681               bSum,numberBad);
     17682#endif
     17683      } else {
     17684        const char * integerInformation = simplex->integerInformation();
     17685        assert (integerInformation);
     17686        int * conflict = new int[numberColumns];
     17687        double * sort = new double [numberColumns];
     17688        double relax=0.0;
     17689        int nConflict=0;
     17690        int nOriginal=0;
     17691        int nFixed=0;
     17692        for (int iColumn=0;iColumn<numberColumns;iColumn++) {
     17693          if (integerInformation[iColumn]) {
     17694            if ((debugMode&1)!=0)
     17695            printf("%d status %d %g <= %g <=%g (orig %g, %g) farkas %g\n",
     17696                   iColumn,simplex->getStatus(iColumn),columnLower[iColumn],
     17697                   simplex->primalColumnSolution()[iColumn],columnUpper[iColumn],
     17698                   originalLower[iColumn],originalUpper[iColumn],
     17699                   farkas[iColumn]);
     17700            double gap = originalUpper[iColumn]-originalLower[iColumn];
     17701            if (!gap)
     17702              continue;
     17703            if (gap==columnUpper[iColumn]-columnLower[iColumn])
     17704              nOriginal++;
     17705            if (columnUpper[iColumn]==columnLower[iColumn])
     17706              nFixed++;
     17707            if (fabs(farkas[iColumn])<1.0e-15) {
     17708              farkas[iColumn]=0.0;
     17709              continue;
     17710            }
     17711            // temp
     17712            if (gap>=20000.0&&false) {
     17713              // can't use
     17714              if (farkas[iColumn]<0.0) {
     17715                assert(originalLower[iColumn]-columnLower[iColumn]<=0.0);
     17716                // farkas is negative - relax lower bound all way
     17717                relax +=
     17718                  farkas[iColumn]*(originalLower[iColumn]-columnLower[iColumn]);
     17719              } else {
     17720                assert(originalUpper[iColumn]-columnUpper[iColumn]>=0.0);
     17721                // farkas is positive - relax upper bound all way
     17722                relax +=
     17723                  farkas[iColumn]*(originalUpper[iColumn]-columnUpper[iColumn]);
     17724              }
     17725              continue;
     17726            }
     17727            if (originalLower[iColumn]==columnLower[iColumn]) {
     17728              if (farkas[iColumn]>0.0&&(simplex->getStatus(iColumn)==ClpSimplex::atUpperBound
     17729                                        ||simplex->getStatus(iColumn)==ClpSimplex::isFixed
     17730                                        ||iColumn==sequenceOut)) {
     17731                // farkas is positive - add to list
     17732                gap=originalUpper[iColumn]-columnUpper[iColumn];
     17733                if (gap) {
     17734                  sort[nConflict]=-farkas[iColumn]*gap;
     17735                  conflict[nConflict++]=iColumn;
     17736                }
     17737                //assert (gap>columnUpper[iColumn]-columnLower[iColumn]);
     17738              }
     17739            } else if (originalUpper[iColumn]==columnUpper[iColumn]) {
     17740              if (farkas[iColumn]<0.0&&(simplex->getStatus(iColumn)==ClpSimplex::atLowerBound
     17741                                        ||simplex->getStatus(iColumn)==ClpSimplex::isFixed
     17742                                        ||iColumn==sequenceOut)) {
     17743                // farkas is negative - add to list
     17744                gap=columnLower[iColumn]-originalLower[iColumn];
     17745                if (gap) {
     17746                  sort[nConflict]=farkas[iColumn]*gap;
     17747                  conflict[nConflict++]=iColumn;
     17748                }
     17749                //assert (gap>columnUpper[iColumn]-columnLower[iColumn]);
     17750              }
     17751            } else {
     17752              // can't use
     17753              if (farkas[iColumn]<0.0) {
     17754                assert(originalLower[iColumn]-columnLower[iColumn]<=0.0);
     17755                // farkas is negative - relax lower bound all way
     17756                relax +=
     17757                  farkas[iColumn]*(originalLower[iColumn]-columnLower[iColumn]);
     17758              } else {
     17759                assert(originalUpper[iColumn]-columnUpper[iColumn]>=0.0);
     17760                // farkas is positive - relax upper bound all way
     17761                relax +=
     17762                  farkas[iColumn]*(originalUpper[iColumn]-columnUpper[iColumn]);
     17763              }
     17764            }
     17765            assert(relax>=0.0);
     17766          } else {
     17767            // not integer - but may have been got at
     17768            double gap = originalUpper[iColumn]-originalLower[iColumn];
     17769            if (gap>columnUpper[iColumn]-columnLower[iColumn]) {
     17770              // can't use
     17771              if (farkas[iColumn]<0.0) {
     17772                assert(originalLower[iColumn]-columnLower[iColumn]<=0.0);
     17773                // farkas is negative - relax lower bound all way
     17774                relax +=
     17775                  farkas[iColumn]*(originalLower[iColumn]-columnLower[iColumn]);
     17776              } else {
     17777                assert(originalUpper[iColumn]-columnUpper[iColumn]>=0.0);
     17778                // farkas is positive - relax upper bound all way
     17779                relax +=
     17780                  farkas[iColumn]*(originalUpper[iColumn]-columnUpper[iColumn]);
     17781              }
     17782            }
     17783          }
     17784        }
     17785        if (relax+bSum>-1.0e-4||!nConflict) {
     17786          if (relax+bSum>-1.0e-4) {
     17787#ifndef NDEBUG
     17788            printf("General integers relax bSum to %g\n",relax+bSum);
     17789#endif
     17790          } else {
     17791            printf("All variables relaxed and still infeasible - what does this mean?\n");
     17792            int nR=0;
     17793            for (int i=0;i<numberRows;i++) {
     17794              if (fabs(ray[i])>1.0e-10)
     17795                nR++;
     17796              else
     17797                ray[i]=0.0;
     17798            }
     17799            int nC=0;
     17800            for (int i=0;i<numberColumns;i++) {
     17801              if (fabs(farkas[i])>1.0e-10)
     17802                nC++;
     17803              else
     17804                farkas[i]=0.0;
     17805            }
     17806            if (nR<3&&nC<5) {
     17807              printf("BAD %d nonzero rows, %d nonzero columns\n",nR,nC);
     17808            }
     17809          }
     17810        } else {
     17811          printf("BOUNDS violation bSum %g (relaxed %g) - %d at original bounds, %d fixed - %d in conflict\n",bSum,
     17812                 relax+bSum,nOriginal,nFixed,nConflict);
     17813          CoinSort_2(sort,sort+nConflict,conflict);
     17814          int nC=nConflict;
     17815          bSum+=relax;
     17816          double saveBsum = bSum;
     17817          while (nConflict) {
     17818            //int iColumn=conflict[nConflict-1];
     17819            double change=-sort[nConflict-1];
     17820            if (bSum+change>-1.0e-4)
     17821              break;
     17822            nConflict--;
     17823            bSum += change;
     17824          }
     17825          if (!nConflict) {
     17826            int nR=0;
     17827            for (int i=0;i<numberRows;i++) {
     17828              if (fabs(ray[i])>1.0e-10)
     17829                nR++;
     17830              else
     17831                ray[i]=0.0;
     17832            }
     17833            int nC=0;
     17834            for (int i=0;i<numberColumns;i++) {
     17835              if (fabs(farkas[i])>1.0e-10)
     17836                nC++;
     17837              else
     17838                farkas[i]=0.0;
     17839            }
     17840            if (nR<3&&nC<5) {
     17841              printf("BAD2 %d nonzero rows, %d nonzero columns\n",nR,nC);
     17842            }
     17843          }
     17844          // no point doing if no reduction (or big?) ?
     17845          if (nConflict<nC+1&&nConflict<500) {
     17846            cut=new OsiRowCut();
     17847            cut->setUb(COIN_DBL_MAX);
     17848            if (!typeCut) {
     17849              double lo=1.0;
     17850              for (int i=0;i<nConflict;i++) {
     17851                int iColumn = conflict[i];
     17852                if (originalLower[iColumn]==columnLower[iColumn]) {
     17853                  // must be at least one higher
     17854                  sort[i]=1.0;
     17855                  lo += originalLower[iColumn];
     17856                } else {
     17857                  // must be at least one lower
     17858                  sort[i]=-1.0;
     17859                  lo -= originalUpper[iColumn];
     17860                }
     17861              }
     17862              cut->setLb(lo);
     17863              cut->setRow(nConflict,conflict,sort);
     17864              printf("CUT has %d (started at %d) - final bSum %g\n",nConflict,nC,bSum);
     17865            } else {
     17866              // just save for use later
     17867              // first take off small
     17868              int nC2=nC;
     17869              while (nC2) {
     17870                //int iColumn=conflict[nConflict-1];
     17871                double change=-sort[nC2-1];
     17872                if (saveBsum+change>-1.0e-4||change>1.0e-4)
     17873                  break;
     17874                nC2--;
     17875                saveBsum += change;
     17876              }
     17877              cut->setLb(saveBsum);
     17878              for (int i=0;i<nC2;i++) {
     17879                int iColumn = conflict[i];
     17880                sort[i]=farkas[iColumn];
     17881              }
     17882              cut->setRow(nC2,conflict,sort);
     17883              printf("Stem CUT has %d (greedy %d - with small %d) - saved bSum %g final greedy bSum %g\n",
     17884                     nC2,nConflict,nC,saveBsum,bSum);
     17885            }
     17886          }
     17887        }
     17888        delete [] conflict;
     17889        delete [] sort;
     17890      }
     17891      delete [] farkas;
     17892    } else {
     17893      printf("No dual ray\n");
     17894    }
     17895  }
     17896#endif
     17897  return cut;
     17898}
     17899
Note: See TracChangeset for help on using the changeset viewer.