Ignore:
Timestamp:
Apr 6, 2013 9:33:15 AM (7 years ago)
Author:
stefan
Message:

sync with trunk rev 1882

Location:
stable/2.8/Cbc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • stable/2.8/Cbc

  • stable/2.8/Cbc/src/CbcModel.cpp

    r1879 r1883  
    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).
     
    16741674            // pre-processing done
    16751675            if (strategy_->preProcessState() < 0) {
    1676                 // infeasible
    1677                 handler_->message(CBC_INFEAS, messages_) << CoinMessageEol ;
     1676                // infeasible (or unbounded)
    16781677                status_ = 0 ;
    1679                 secondaryStatus_ = 1;
     1678                if (!solver_->isProvenDualInfeasible()) {
     1679                  handler_->message(CBC_INFEAS, messages_) << CoinMessageEol ;
     1680                  secondaryStatus_ = 1;
     1681                } else {
     1682                  handler_->message(CBC_UNBOUNDED,
     1683                                    messages_) << CoinMessageEol ;
     1684                  secondaryStatus_ = 7;
     1685                }
    16801686                originalContinuousObjective_ = COIN_DBL_MAX;
    16811687                if (flipObjective)
     
    21532159                handler_->message(CBC_HEURISTICS_OFF, messages_) << numberOdd << CoinMessageEol ;
    21542160            }
     2161            // If odd switch off AddIntegers
     2162            specialOptions_ &= ~65536;
    21552163        } else if (numberSOS) {
    21562164            specialOptions_ |= 128; // say can do SOS in dynamic mode
    21572165            // switch off fast nodes for now
    21582166            fastNodeDepth_ = -1;
     2167            moreSpecialOptions_ &= ~33554432; // no diving
    21592168        }
    21602169        if (numberThreads_ > 0) {
     
    22252234
    22262235    // add cutoff as constraint if wanted
    2227     if ((moreSpecialOptions_&16777216)!=0) {
     2236    if (cutoffRowNumber_==-2) {
    22282237      if (!parentModel_) {
    22292238        int numberColumns=solver_->getNumCols();
     
    22392248        if (n) {
    22402249          double cutoff=getCutoff();
     2250          // relax a little bit
     2251          cutoff += 1.0e-4;
    22412252          double offset;
    22422253          solver_->getDblParam(OsiObjOffset, offset);
     2254          cutoffRowNumber_ = solver_->getNumRows();
    22432255          solver_->addRow(n,indices,obj,-COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset);
    22442256        } else {
    22452257          // no objective!
    2246           moreSpecialOptions_ &= ~16777216;
     2258          cutoffRowNumber_ = -1;
    22472259        }
    22482260        delete [] indices;
     
    22502262      } else {
    22512263        // switch off
    2252         moreSpecialOptions_ &= ~16777216;
     2264        cutoffRowNumber_ = -1;
    22532265      }
    22542266    }
     
    24872499      }
    24882500      CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis *> (solver_->getEmptyWarmStart());
     2501      int numberIterations=0;
    24892502      for (int i=0;i<numberModels;i++) {
    24902503        rootModels[i]=new CbcModel(*this);
     
    24962509        // use seed
    24972510        rootModels[i]->setSpecialOptions(specialOptions_ |(4194304|8388608));
     2511        rootModels[i]->setMoreSpecialOptions(moreSpecialOptions_ &
     2512                                             (~134217728));
    24982513        rootModels[i]->solver_->setWarmStart(basis);
    24992514#ifdef COIN_HAS_CLP
     
    25012516          = dynamic_cast<OsiClpSolverInterface *> (rootModels[i]->solver_);
    25022517        if (clpSolver) {
    2503           clpSolver->getModelPtr()->setRandomSeed(newSeed+20000000*i);
    2504           clpSolver->getModelPtr()->allSlackBasis();
     2518          ClpSimplex * simplex = clpSolver->getModelPtr();
     2519          if (defaultHandler_)
     2520            simplex->setDefaultMessageHandler();
     2521          simplex->setRandomSeed(newSeed+20000000*i);
     2522          simplex->allSlackBasis();
     2523          int logLevel=simplex->logLevel();
     2524          if (logLevel==1)
     2525            simplex->setLogLevel(0);
     2526          if (i!=0) {
     2527            double random = simplex->randomNumberGenerator()->randomDouble();
     2528            int bias = static_cast<int>(random*(numberIterations/4));
     2529            simplex->setMaximumIterations(numberIterations/2+bias);
     2530            simplex->primal();
     2531            simplex->setMaximumIterations(COIN_INT_MAX);
     2532            simplex->dual();
     2533          } else {
     2534            simplex->primal();
     2535            numberIterations=simplex->numberIterations();
     2536          }
     2537          simplex->setLogLevel(logLevel);
     2538          clpSolver->setWarmStart(NULL);
    25052539        }
    25062540#endif
     2541        for (int j=0;j<numberHeuristics_;j++)
     2542          rootModels[i]->heuristic_[j]->setSeed(rootModels[i]->heuristic_[j]->getSeed()+100000000*i);
     2543        for (int j=0;j<numberCutGenerators_;j++)
     2544          rootModels[i]->generator_[j]->generator()->refreshSolver(rootModels[i]->solver_);
    25072545      }
    25082546      delete basis;
     
    26612699    }
    26622700    // replace solverType
     2701    double * tightBounds = NULL;
    26632702    if (solverCharacteristics_->tryCuts())  {
    26642703
     
    26672706            if (!eventHappened_ && feasible) {
    26682707                if (rootModels) {
     2708                  // for fixings
     2709                  int numberColumns=solver_->getNumCols();
     2710                  tightBounds = new double [2*numberColumns];
     2711                  {
     2712                    const double * lower = solver_->getColLower();
     2713                    const double * upper = solver_->getColUpper();
     2714                    for (int i=0;i<numberColumns;i++) {
     2715                      tightBounds[2*i+0]=lower[i];
     2716                      tightBounds[2*i+1]=upper[i];
     2717                    }
     2718                  }
    26692719                  int numberModels = multipleRootTries_%100;
    26702720                  const OsiSolverInterface ** solvers = new
     
    26742724                  for (int i=0;i<numberModels;i++) {
    26752725                    solvers[i]=rootModels[i]->solver();
     2726                    const double * lower = solvers[i]->getColLower();
     2727                    const double * upper = solvers[i]->getColUpper();
     2728                    for (int j=0;j<numberColumns;j++) {
     2729                      tightBounds[2*j+0]=CoinMax(lower[j],tightBounds[2*j+0]);
     2730                      tightBounds[2*j+1]=CoinMin(upper[j],tightBounds[2*j+1]);
     2731                    }
    26762732                    int numberRows2=solvers[i]->getNumRows();
    26772733                    assert (numberRows2>=numberRows);
     
    26852741                    generator_[j]->scaleBackStatistics(numberModels);
    26862742                  }
    2687                   CbcRowCuts rowCut(maxCuts);
     2743                  //CbcRowCuts rowCut(maxCuts);
     2744                  const OsiRowCutDebugger *debugger = NULL;
     2745                  if ((specialOptions_&1) != 0)
     2746                    debugger = solver_->getRowCutDebugger() ;
    26882747                  for (int iModel=0;iModel<numberModels;iModel++) {
    26892748                    int numberRows2=solvers[iModel]->getNumRows();
     
    27012760                      CoinBigIndex start = rowStart[iRow];
    27022761                      rc.setRow(rowLength[iRow],column+start,elements+start,false);
    2703                       rowCut.addCutIfNotDuplicate(rc);
     2762                      if (debugger)
     2763                        CoinAssert (!debugger->invalidCut(rc));
     2764                      globalCuts_.addCutIfNotDuplicate(rc);
    27042765                    }
    2705                     //int cutsAdded=rowCut.numberCuts()-numberCuts;
     2766                    //int cutsAdded=globalCuts_.numberCuts()-numberCuts;
    27062767                    //numberCuts += cutsAdded;
    27072768                    //printf("Model %d gave %d cuts (out of %d possible)\n",
    27082769                    //     iModel,cutsAdded,numberRows2-numberRows);
    27092770                  }
    2710                   rowCut.addCuts(cuts);
     2771                  // normally replace global cuts
     2772                  //if (!globalCuts_.())
     2773                  //globalCuts_=rowCutrowCut.addCuts(globalCuts_);
     2774                  //rowCut.addCuts(globalCuts_);
     2775                  int nTightened=0;
     2776                  bool feasible=true;
     2777                  {
     2778                    double tolerance=1.0e-5;
     2779                    const double * lower = solver_->getColLower();
     2780                    const double * upper = solver_->getColUpper();
     2781                    for (int i=0;i<numberColumns;i++) {
     2782                      if (tightBounds[2*i+0]>tightBounds[2*i+1]) {
     2783                        feasible=false;
     2784                        printf("Bad bounds on %d %g,%g was %g,%g\n",
     2785                               i,tightBounds[2*i+0],tightBounds[2*i+1],
     2786                               lower[i],upper[i]);
     2787                      }
     2788                      //int k=0;
     2789                      double oldLower=lower[i];
     2790                      double oldUpper=upper[i];
     2791                      if (tightBounds[2*i+0]>oldLower+tolerance) {
     2792                        nTightened++;
     2793                        //k++;
     2794                        solver_->setColLower(i,tightBounds[2*i+0]);
     2795                      }
     2796                      if (tightBounds[2*i+1]<oldUpper-tolerance) {
     2797                        nTightened++;
     2798                        //k++;
     2799                        solver_->setColUpper(i,tightBounds[2*i+1]);
     2800                      }
     2801                      //if (k)
     2802                      //printf("new bounds on %d %g,%g was %g,%g\n",
     2803                      //       i,tightBounds[2*i+0],tightBounds[2*i+1],
     2804                      //       oldLower,oldUpper);
     2805                    }
     2806                    if (!feasible)
     2807                      abort(); // deal with later
     2808                  }
     2809                  delete [] tightBounds;
     2810                  tightBounds=NULL;
    27112811                  char printBuffer[200];
    27122812                  sprintf(printBuffer,"%d solvers added %d different cuts out of pool of %d",
    2713                           numberModels,cuts.sizeRowCuts(),maxCuts);
     2813                          numberModels,globalCuts_.sizeRowCuts(),maxCuts);
    27142814                  messageHandler()->message(CBC_GENERAL, messages())
    27152815                    << printBuffer << CoinMessageEol ;
     2816                  if (nTightened) {
     2817                    sprintf(printBuffer,"%d bounds were tightened",
     2818                          nTightened);
     2819                    messageHandler()->message(CBC_GENERAL, messages())
     2820                      << printBuffer << CoinMessageEol ;
     2821                  }
    27162822                  delete [] solvers;
     2823                }
     2824                if (!parentModel_&&(moreSpecialOptions_&67108864) != 0) {
     2825                  // load cuts from file
     2826                  FILE * fp = fopen("global.cuts","rb");
     2827                  if (fp) {
     2828                    size_t nRead;
     2829                    int numberColumns=solver_->getNumCols();
     2830                    int numCols;
     2831                    nRead = fread(&numCols, sizeof(int), 1, fp);
     2832                    if (nRead != 1)
     2833                      throw("Error in fread");
     2834                    if (numberColumns!=numCols) {
     2835                      printf("Mismatch on columns %d %d\n",numberColumns,numCols);
     2836                      fclose(fp);
     2837                    } else {
     2838                      // If rootModel just do some
     2839                      double threshold=-1.0;
     2840                      if (!multipleRootTries_)
     2841                        threshold=0.5;
     2842                      int initialCuts=0;
     2843                      int initialGlobal = globalCuts_.sizeRowCuts();
     2844                      double * elements = new double [numberColumns+2];
     2845                      int * indices = new int [numberColumns];
     2846                      int numberEntries=1;
     2847                      while (numberEntries>0) {
     2848                        nRead = fread(&numberEntries, sizeof(int), 1, fp);
     2849                        if (nRead != 1)
     2850                          throw("Error in fread");
     2851                        double randomNumber=randomNumberGenerator_.randomDouble();
     2852                        if (numberEntries>0) {
     2853                          initialCuts++;
     2854                          nRead = fread(elements, sizeof(double), numberEntries+2, fp);
     2855                          if (nRead != static_cast<size_t>(numberEntries+2))
     2856                            throw("Error in fread");
     2857                          nRead = fread(indices, sizeof(int), numberEntries, fp);
     2858                          if (nRead != static_cast<size_t>(numberEntries))
     2859                            throw("Error in fread");
     2860                          if (randomNumber>threshold) {
     2861                            OsiRowCut rc;
     2862                            rc.setLb(elements[numberEntries]);
     2863                            rc.setUb(elements[numberEntries+1]);
     2864                            rc.setRow(numberEntries,indices,elements,
     2865                                      false);
     2866                            rc.setGloballyValidAsInteger(2);
     2867                            globalCuts_.addCutIfNotDuplicate(rc) ;
     2868                          }
     2869                        }
     2870                      }
     2871                      fclose(fp);
     2872                      // fixes
     2873                      int nTightened=0;
     2874                      fp = fopen("global.fix","rb");
     2875                      if (fp) {
     2876                        nRead = fread(indices, sizeof(int), 2, fp);
     2877                        if (nRead != 2)
     2878                          throw("Error in fread");
     2879                        if (numberColumns!=indices[0]) {
     2880                          printf("Mismatch on columns %d %d\n",numberColumns,
     2881                                 indices[0]);
     2882                        } else {
     2883                          indices[0]=1;
     2884                          while (indices[0]>=0) {
     2885                            nRead = fread(indices, sizeof(int), 2, fp);
     2886                            if (nRead != 2)
     2887                              throw("Error in fread");
     2888                            int iColumn=indices[0];
     2889                            if (iColumn>=0) {
     2890                              nTightened++;
     2891                              nRead = fread(elements, sizeof(double), 4, fp);
     2892                              if (nRead != 4)
     2893                                throw("Error in fread");
     2894                              solver_->setColLower(iColumn,elements[0]);
     2895                              solver_->setColUpper(iColumn,elements[1]);
     2896                            }
     2897                          }
     2898                        }
     2899                      }
     2900                      if (fp)
     2901                        fclose(fp);
     2902                      char printBuffer[200];
     2903                      sprintf(printBuffer,"%d cuts read in of which %d were unique, %d bounds tightened",
     2904                             initialCuts,
     2905                             globalCuts_.sizeRowCuts()-initialGlobal,nTightened);
     2906                      messageHandler()->message(CBC_GENERAL, messages())
     2907                        << printBuffer << CoinMessageEol ;
     2908                      delete [] elements;
     2909                      delete [] indices;
     2910                    }
     2911                  }
    27172912                }
    27182913                feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_,
    27192914                                         NULL);
     2915                if (multipleRootTries_&&
     2916                    (moreSpecialOptions_&134217728)!=0) {
     2917                  FILE * fp=NULL;
     2918                  size_t nRead;
     2919                  int numberColumns=solver_->getNumCols();
     2920                  int initialCuts=0;
     2921                  if ((moreSpecialOptions_&134217728)!=0) {
     2922                    // append so go down to end
     2923                    fp = fopen("global.cuts","r+b");
     2924                    if (fp) {
     2925                      int numCols;
     2926                      nRead = fread(&numCols, sizeof(int), 1, fp);
     2927                      if (nRead != 1)
     2928                        throw("Error in fread");
     2929                      if (numberColumns!=numCols) {
     2930                        printf("Mismatch on columns %d %d\n",numberColumns,numCols);
     2931                        fclose(fp);
     2932                        fp=NULL;
     2933                      }
     2934                    }
     2935                  }
     2936                  double * elements = new double [numberColumns+2];
     2937                  int * indices = new int [numberColumns];
     2938                  if (fp) {
     2939                    int numberEntries=1;
     2940                    while (numberEntries>0) {
     2941                      fpos_t position;
     2942                      fgetpos(fp, &position);
     2943                      nRead = fread(&numberEntries, sizeof(int), 1, fp);
     2944                      if (nRead != 1)
     2945                        throw("Error in fread");
     2946                      if (numberEntries>0) {
     2947                        initialCuts++;
     2948                        nRead = fread(elements, sizeof(double), numberEntries+2, fp);
     2949                        if (nRead != static_cast<size_t>(numberEntries+2))
     2950                          throw("Error in fread");
     2951                        nRead = fread(indices, sizeof(int), numberEntries, fp);
     2952                        if (nRead != static_cast<size_t>(numberEntries))
     2953                          throw("Error in fread");
     2954                      } else {
     2955                        // end
     2956                        fsetpos(fp, &position);
     2957                      }
     2958                    }
     2959                  } else {
     2960                    fp = fopen("global.cuts","wb");
     2961                    size_t nWrite;
     2962                    nWrite=fwrite(&numberColumns,sizeof(int),1,fp);
     2963                    if (nWrite != 1)
     2964                      throw("Error in fwrite");
     2965                  }
     2966                  size_t nWrite;
     2967                  // now append binding cuts
     2968                  int numberC=continuousSolver_->getNumRows();
     2969                  int numberRows=solver_->getNumRows();
     2970                  printf("Saving %d cuts (up from %d)\n",
     2971                         initialCuts+numberRows-numberC,initialCuts);
     2972                  const double * rowLower = solver_->getRowLower();
     2973                  const double * rowUpper = solver_->getRowUpper();
     2974                  // Row copy
     2975                  CoinPackedMatrix matrixByRow(*solver_->getMatrixByRow());
     2976                  const double * elementByRow = matrixByRow.getElements();
     2977                  const int * column = matrixByRow.getIndices();
     2978                  const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();
     2979                  const int * rowLength = matrixByRow.getVectorLengths();
     2980                  for (int iRow=numberC;iRow<numberRows;iRow++) {
     2981                    int n=rowLength[iRow];
     2982                    assert (n);
     2983                    CoinBigIndex start=rowStart[iRow];
     2984                    memcpy(elements,elementByRow+start,n*sizeof(double));
     2985                    memcpy(indices,column+start,n*sizeof(int));
     2986                    elements[n]=rowLower[iRow];
     2987                    elements[n+1]=rowUpper[iRow];
     2988                    nWrite=fwrite(&n,sizeof(int),1,fp);
     2989                    if (nWrite != 1)
     2990                      throw("Error in fwrite");
     2991                    nWrite=fwrite(elements,sizeof(double),n+2,fp);
     2992                    if (nWrite != static_cast<size_t>(n+2))
     2993                      throw("Error in fwrite");
     2994                    nWrite=fwrite(indices,sizeof(int),n,fp);
     2995                    if (nWrite != static_cast<size_t>(n))
     2996                      throw("Error in fwrite");
     2997                  }
     2998                  // eof marker
     2999                  int eofMarker=-1;
     3000                  nWrite=fwrite(&eofMarker,sizeof(int),1,fp);
     3001                  if (nWrite != 1)
     3002                    throw("Error in fwrite");
     3003                  fclose(fp);
     3004                  // do tighter bounds (? later extra to original columns)
     3005                  int nTightened=0;
     3006                  const double * lower = solver_->getColLower();
     3007                  const double * upper = solver_->getColUpper();
     3008                  const double * originalLower = continuousSolver_->getColLower();
     3009                  const double * originalUpper = continuousSolver_->getColUpper();
     3010                  double tolerance=1.0e-5;
     3011                  for (int i=0;i<numberColumns;i++) {
     3012                    if (lower[i]>originalLower[i]+tolerance) {
     3013                      nTightened++;
     3014                    }
     3015                    if (upper[i]<originalUpper[i]-tolerance) {
     3016                      nTightened++;
     3017                    }
     3018                  }
     3019                  if (nTightened) {
     3020                    fp = fopen("global.fix","wb");
     3021                    size_t nWrite;
     3022                    indices[0]=numberColumns;
     3023                    if (originalColumns_)
     3024                      indices[1]=COIN_INT_MAX;
     3025                    else
     3026                      indices[1]=-1;
     3027                    nWrite=fwrite(indices,sizeof(int),2,fp);
     3028                    if (nWrite != 2)
     3029                      throw("Error in fwrite");
     3030                    for (int i=0;i<numberColumns;i++) {
     3031                      int nTightened=0;
     3032                      if (lower[i]>originalLower[i]+tolerance) {
     3033                        nTightened++;
     3034                      }
     3035                      if (upper[i]<originalUpper[i]-tolerance) {
     3036                        nTightened++;
     3037                      }
     3038                      if (nTightened) {
     3039                        indices[0]=i;
     3040                        if (originalColumns_)
     3041                          indices[1]=originalColumns_[i];
     3042                        elements[0]=lower[i];
     3043                        elements[1]=upper[i];
     3044                        elements[2]=originalLower[i];
     3045                        elements[3]=originalUpper[i];
     3046                        nWrite=fwrite(indices,sizeof(int),2,fp);
     3047                        if (nWrite != 2)
     3048                          throw("Error in fwrite");
     3049                        nWrite=fwrite(elements,sizeof(double),4,fp);
     3050                        if (nWrite != 4)
     3051                          throw("Error in fwrite");
     3052                      }
     3053                    }
     3054                    // eof marker
     3055                    indices[0]=-1;
     3056                    nWrite=fwrite(indices,sizeof(int),2,fp);
     3057                    if (nWrite != 2)
     3058                      throw("Error in fwrite");
     3059                    fclose(fp);
     3060                  }
     3061                  delete [] elements;
     3062                  delete [] indices;
     3063                }
    27203064                if ((specialOptions_&524288) != 0 && !parentModel_
    27213065                        && storedRowCuts_) {
     
    29743318    }
    29753319#endif
     3320    if (!parentModel_&&(moreSpecialOptions_&268435456) != 0) {
     3321      // try idiotic idea
     3322      CbcObject * obj = new CbcIdiotBranch(this);
     3323      obj->setPriority(1); // temp
     3324      addObjects(1, &obj);
     3325      delete obj;
     3326    }
     3327   
    29763328    /*
    29773329      A hook to use clp to quickly explore some part of the tree.
     
    29833335        obj->setPriority(1);
    29843336        addObjects(1, &obj);
     3337        delete obj;
    29853338    }
    29863339    int saveNumberSolves = numberSolves_;
    29873340    int saveNumberIterations = numberIterations_;
    2988     if (fastNodeDepth_ >= 0 &&/*!parentModel_*/(specialOptions_&2048) == 0) {
     3341    if ((fastNodeDepth_ >= 0||(moreSpecialOptions_&33554432)!=0)
     3342        &&/*!parentModel_*/(specialOptions_&2048) == 0) {
    29893343        // add in a general depth object doClp
    29903344        int type = (fastNodeDepth_ <= 100) ? fastNodeDepth_ : -(fastNodeDepth_ - 100);
     3345        if ((moreSpecialOptions_&33554432)!=0)
     3346          type=12;
     3347        else
     3348          fastNodeDepth_ += 1000000;     // mark as done
    29913349        CbcObject * obj =
    29923350            new CbcGeneralDepth(this, type);
    29933351        addObjects(1, &obj);
    2994         // mark as done
    2995         fastNodeDepth_ += 1000000;
    29963352        delete obj;
    29973353        // fake number of objects
     
    36954051              Decide if we want to do a restart.
    36964052            */
    3697             if (saveSolver) {
     4053            if (saveSolver && (specialOptions_&(512 + 32768)) != 0) {
    36984054                bool tryNewSearch = solverCharacteristics_->reducedCostsAccurate() &&
    36994055                                    (getCutoff() < 1.0e20 && getCutoff() < checkCutoffForRestart);
     
    40504406            if (!node || node->objectiveValue() > cutoff)
    40514407                continue;
    4052             // Do main work of solving node here
    4053             doOneNode(this, node, createdNode);
     4408            // Do main work of solving node here
     4409            doOneNode(this, node, createdNode);
    40544410#ifdef JJF_ZERO
    4055             if (node) {
    4056                 if (createdNode) {
    4057                     printf("Node %d depth %d, created %d depth %d\n",
    4058                            node->nodeNumber(), node->depth(),
    4059                            createdNode->nodeNumber(), createdNode->depth());
    4060                 } else {
    4061                     printf("Node %d depth %d,  no created node\n",
    4062                            node->nodeNumber(), node->depth());
    4063                 }
    4064             } else if (createdNode) {
    4065                 printf("Node exhausted, created %d depth %d\n",
    4066                        createdNode->nodeNumber(), createdNode->depth());
    4067             } else {
    4068                 printf("Node exhausted,  no created node\n");
    4069                 numberConsecutiveInfeasible = 2;
    4070             }
     4411            if (node) {
     4412              if (createdNode) {
     4413                printf("Node %d depth %d, created %d depth %d\n",
     4414                       node->nodeNumber(), node->depth(),
     4415                       createdNode->nodeNumber(), createdNode->depth());
     4416              } else {
     4417                printf("Node %d depth %d,  no created node\n",
     4418                       node->nodeNumber(), node->depth());
     4419              }
     4420            } else if (createdNode) {
     4421              printf("Node exhausted, created %d depth %d\n",
     4422                     createdNode->nodeNumber(), createdNode->depth());
     4423            } else {
     4424              printf("Node exhausted,  no created node\n");
     4425              numberConsecutiveInfeasible = 2;
     4426            }
    40714427#endif
    40724428            //if (createdNode)
     
    44514807        setCutoff(1.0e50) ; // As best solution should be worse than cutoff
    44524808        // change cutoff as constraint if wanted
    4453         if ((moreSpecialOptions_&16777216)!=0) {
    4454           if (solver_->getNumRows()>=numberRowsAtContinuous_)
    4455             solver_->setRowUpper(numberRowsAtContinuous_-1,1.0e50);
     4809        if (cutoffRowNumber_>=0) {
     4810          if (solver_->getNumRows()>cutoffRowNumber_)
     4811            solver_->setRowUpper(cutoffRowNumber_,1.0e50);
    44564812        }
    44574813        // also in continuousSolver_
     
    45164872    delete globalConflictCuts_;
    45174873    globalConflictCuts_=NULL;
    4518     if (!bestSolution_) {
     4874    if (!bestSolution_ && (specialOptions_&8388608)==0) {
    45194875        // make sure lp solver is infeasible
    45204876        int numberColumns = solver_->getNumCols();
     
    45434899    }
    45444900#endif
    4545     if (fastNodeDepth_ >= 1000000 && !parentModel_) {
    4546         // delete object off end
    4547         delete object_[numberObjects_];
     4901    if ((fastNodeDepth_ >= 1000000 || (moreSpecialOptions_&33554432)!=0)
     4902         && !parentModel_) {
     4903      // delete object off end
     4904      delete object_[numberObjects_];
     4905      if ((moreSpecialOptions_&33554432)==0)
    45484906        fastNodeDepth_ -= 1000000;
    45494907    }
     
    47265084        numberIntegers_(0),
    47275085        numberRowsAtContinuous_(0),
     5086        cutoffRowNumber_(-1),
    47285087        maximumNumberCuts_(0),
    47295088        phase_(0),
     
    47735132        ownObjects_(true),
    47745133        originalColumns_(NULL),
    4775         howOftenGlobalScan_(1),
     5134        howOftenGlobalScan_(3),
    47765135        numberGlobalViolations_(0),
    47775136        numberExtraIterations_(0),
     
    48925251        secondaryStatus_(-1),
    48935252        numberRowsAtContinuous_(0),
     5253        cutoffRowNumber_(-1),
    48945254        maximumNumberCuts_(0),
    48955255        phase_(0),
     
    49365296        ownObjects_(true),
    49375297        originalColumns_(NULL),
    4938         howOftenGlobalScan_(1),
     5298        howOftenGlobalScan_(3),
    49395299        numberGlobalViolations_(0),
    49405300        numberExtraIterations_(0),
     
    50635423}
    50645424
     5425static int * resizeInt(int * array,int oldLength, int newLength)
     5426{
     5427  if (!array)
     5428    return NULL;
     5429  assert (newLength>oldLength);
     5430  int * newArray = new int [newLength];
     5431  memcpy(newArray,array,oldLength*sizeof(int));
     5432  delete [] array;
     5433  memset(newArray+oldLength,0,(newLength-oldLength)*sizeof(int));
     5434  return newArray;
     5435}
     5436static double * resizeDouble(double * array,int oldLength, int newLength)
     5437{
     5438  if (!array)
     5439    return NULL;
     5440  assert (newLength>oldLength);
     5441  double * newArray = new double [newLength];
     5442  memcpy(newArray,array,oldLength*sizeof(double));
     5443  delete [] array;
     5444  memset(newArray+oldLength,0,(newLength-oldLength)*sizeof(double));
     5445  return newArray;
     5446}
    50655447/*
    50665448  Assign a solver to the model (model assumes ownership)
     
    50865468
    50875469{
    5088     // resize best solution if exists
    5089     if (bestSolution_ && solver && solver_) {
     5470    // resize stuff if exists
     5471    if (solver && solver_) {
    50905472        int nOld = solver_->getNumCols();
    50915473        int nNew = solver->getNumCols();
    50925474        if (nNew > nOld) {
    5093             double * temp = new double[nNew];
    5094             memcpy(temp, bestSolution_, nOld*sizeof(double));
    5095             memset(temp + nOld, 0, (nNew - nOld)*sizeof(double));
    5096             delete [] bestSolution_;
    5097             bestSolution_ = temp;
     5475          originalColumns_ = resizeInt(originalColumns_,nOld,nNew);
     5476          usedInSolution_ = resizeInt(usedInSolution_,nOld,nNew);
     5477          continuousSolution_ = resizeDouble(continuousSolution_,nOld,nNew);
     5478          hotstartSolution_ = resizeDouble(hotstartSolution_,nOld,nNew);
     5479          bestSolution_ = resizeDouble(bestSolution_,nOld,nNew);
     5480          currentSolution_ = resizeDouble(currentSolution_,nOld,nNew);
     5481          if (savedSolutions_) {
     5482            for (int i = 0; i < maximumSavedSolutions_; i++)
     5483              savedSolutions_[i] = resizeDouble(savedSolutions_[i],nOld,nNew);
     5484          }
    50985485        }
    50995486    }
     
    53865773    testSolution_ = currentSolution_;
    53875774    numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_;
     5775    cutoffRowNumber_ = rhs.cutoffRowNumber_;
    53885776    maximumNumberCuts_ = rhs.maximumNumberCuts_;
    53895777    phase_ = rhs.phase_;
     
    57136101        }
    57146102        numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_;
     6103        cutoffRowNumber_ = rhs.cutoffRowNumber_;
    57156104        maximumNumberCuts_ = rhs.maximumNumberCuts_;
    57166105        phase_ = rhs.phase_;
     
    60056394        int i;
    60066395        for (i = 0; i < numberCutGenerators_; i++) {
    6007             if (mode < 2)
     6396            if (mode < 2) {
    60086397                generator_[i] = new CbcCutGenerator(*rhs.generator_[i]);
    6009             else
     6398            } else {
    60106399                generator_[i] = new CbcCutGenerator(*rhs.virginGenerator_[i]);
     6400                // But copy across maximumTries
     6401                generator_[i]->setMaximumTries(rhs.generator_[i]->maximumTries());
     6402            }
    60116403            virginGenerator_[i] = new CbcCutGenerator(*rhs.virginGenerator_[i]);
    60126404        }
     
    60706462    strongInfo_[6] = rhs.strongInfo_[6];
    60716463    numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_;
     6464    cutoffRowNumber_ = rhs.cutoffRowNumber_;
    60726465    maximumDepth_ = rhs.maximumDepth_;
    60736466}
     
    62596652        heuristic_[where]->setHeuristicName(name) ;
    62606653    heuristic_[where]->setSeed(987654321 + where);
    6261     if (randomSeed_!=-1)
    6262       heuristic_[where]->setSeed(randomSeed_);
    62636654    numberHeuristics_++ ;
    62646655}
     
    62866677{
    62876678    int nNode = 0;
     6679    CbcNodeInfo * nodeInfo = node->nodeInfo();
    62886680    int numberColumns = getNumCols();
    6289     CbcNodeInfo * nodeInfo = node->nodeInfo();
    62906681
    62916682    /*
     
    65436934#         endif
    65446935                    addCuts[numberToAdd++] = addedCuts_[i];
     6936#if 1
     6937                    if ((specialOptions_&1) != 0) {
     6938                      const OsiRowCutDebugger * debugger = solver_->getRowCutDebugger() ;
     6939                      if (debugger)
     6940                        CoinAssert (!debugger->invalidCut(*addedCuts_[i]));
     6941                    }
     6942#endif
    65456943                } else {
    65466944#         ifdef CHECK_CUT_COUNTS
     
    66507048                    delete [] which;
    66517049                }
     7050                //#define CHECK_DEBUGGER
     7051#ifdef CHECK_DEBUGGER
     7052                if ((specialOptions_&1) != 0 ) {
     7053                  const OsiRowCutDebugger * debugger =
     7054                    solver_->getRowCutDebugger();
     7055                  if (debugger) {
     7056                    for (int j=0;j<numberToAdd;j++)
     7057                      CoinAssert (!debugger->invalidCut(*addCuts[j]));
     7058                    //addCuts[j]->print();
     7059                  }
     7060                }
     7061#endif
    66527062                //int n2=solver_->getNumRows();
    66537063                //for (int j=0;j<numberToAdd;j++)
     
    67077117CbcModel::synchronizeHandlers(int /*makeDefault*/)
    67087118{
     7119    bool defaultHandler = defaultHandler_;
    67097120    if (!defaultHandler_) {
    67107121        // Must have clone
     
    67137124    }
    67147125#ifdef COIN_HAS_CLP
    6715     OsiClpSolverInterface * solver;
    6716     solver = dynamic_cast<OsiClpSolverInterface *>(solver_) ;
    6717     if (solver) {
     7126    if (!defaultHandler) {
     7127      OsiClpSolverInterface * solver;
     7128      solver = dynamic_cast<OsiClpSolverInterface *>(solver_) ;
     7129      if (solver) {
    67187130        solver->passInMessageHandler(handler_);
    67197131        solver->getModelPtr()->passInMessageHandler(handler_);
    6720     }
    6721     solver = dynamic_cast<OsiClpSolverInterface *>(continuousSolver_) ;
    6722     if (solver) {
     7132      }
     7133      solver = dynamic_cast<OsiClpSolverInterface *>(continuousSolver_) ;
     7134      if (solver) {
    67237135        solver->passInMessageHandler(handler_);
    67247136        solver->getModelPtr()->passInMessageHandler(handler_);
     7137      }
    67257138    }
    67267139#endif
     
    69857398          if ((specialOptions_&1) != 0) {
    69867399            debugger = continuousSolver_->getRowCutDebugger() ;
    6987             if (debugger)
     7400            if (debugger) {
    69887401              if (debugger->invalidCut(*cut)) {
    69897402                continuousSolver_->applyRowCuts(1,cut);
     
    69917404              }
    69927405              CoinAssert (!debugger->invalidCut(*cut));
     7406            }
    69937407          }
    69947408        } else {
     
    72727686        allowZeroIterations = true;
    72737687    }
     7688    int saveNumberTries=numberTries;
    72747689    /*
    72757690      Is it time to scan the cuts in order to remove redundant cuts? If so, set
     
    72907705    // Really primalIntegerTolerance; relates to an illposed problem with various
    72917706    // integer solutions depending on integer tolerance.
    7292     double primalTolerance = 1.0e-7 ;
     7707    //double primalTolerance = 1.0e-7 ;
    72937708    // We may need to keep going on
    72947709    bool keepGoing = false;
     
    73407755        */
    73417756        int numberViolated = 0;
    7342         if (currentPassNumber_ == 1 && howOftenGlobalScan_ > 0 &&
     7757        if ((currentPassNumber_ == 1 ||!numberNodes_) && howOftenGlobalScan_ > 0 &&
    73437758                (numberNodes_ % howOftenGlobalScan_) == 0 &&
    73447759                (doCutsNow(1) || true)) {
    73457760            // global column cuts now done in node at top of tree
    7346             int numberCuts = globalCuts_.sizeRowCuts() ;
    7347             // possibly extend whichGenerator
    7348             resizeWhichGenerator(numberViolated, numberViolated + numberCuts);
    7349             for (int i = 0; i < numberCuts; i++) {
     7761            int numberCuts = numberCutGenerators_ ? globalCuts_.sizeRowCuts() : 0;
     7762            if (numberCuts) {
     7763              // possibly extend whichGenerator
     7764              resizeWhichGenerator(numberViolated, numberViolated + numberCuts);
     7765              // only add new cuts up to 10% of current elements
     7766              int numberElements = solver_->getNumElements();
     7767              int numberColumns = solver_->getNumCols();
     7768              int maximumAdd = CoinMax(numberElements/10,2*numberColumns)+100;
     7769              double * violations = new double[numberCuts];
     7770              int * which = new int[numberCuts];
     7771              int numberPossible=0;
     7772              for (int i = 0; i < numberCuts; i++) {
    73507773                OsiRowCut * thisCut = globalCuts_.rowCutPtr(i) ;
    7351                 if (thisCut->violated(cbcColSolution_) > primalTolerance ||
    7352                         thisCut->effectiveness() == COIN_DBL_MAX) {
     7774                double violation = thisCut->violated(cbcColSolution_);
     7775                if(thisCut->effectiveness() == COIN_DBL_MAX) {
     7776                  // see if already there
     7777                  int j;
     7778                  for (j = 0; j < currentNumberCuts_; j++) {
     7779                    if (addedCuts_[j]==thisCut)
     7780                      break;
     7781                  }
     7782                  if (j==currentNumberCuts_)
     7783                    violation = COIN_DBL_MAX;
     7784                  //else
     7785                  //printf("already done??\n");
     7786                }
     7787                if (violation > 0.005) {
     7788                  violations[numberPossible]=-violation;
     7789                  which[numberPossible++]=i;
     7790                }
     7791              }
     7792              CoinSort_2(violations,violations+numberPossible,which);
     7793              for (int i = 0; i < numberPossible; i++) {
     7794                int k=which[i];
     7795                OsiRowCut * thisCut = globalCuts_.rowCutPtr(k) ;
     7796                assert (thisCut->violated(cbcColSolution_) > 0.005/*primalTolerance*/ ||
     7797                        thisCut->effectiveness() == COIN_DBL_MAX);
     7798#define CHECK_DEBUGGER
     7799#ifdef CHECK_DEBUGGER
     7800                if ((specialOptions_&1) != 0 ) {
     7801                  const OsiRowCutDebugger * debugger =
     7802                    solver_->getRowCutDebuggerAlways();
     7803                  CoinAssert (!debugger->invalidCut(*thisCut));
     7804                }
     7805#endif
    73537806#if 0 //ndef NDEBUG
    7354                   printf("Global cut added - violation %g\n",
    7355                            thisCut->violated(cbcColSolution_)) ;
    7356 #endif
    7357                     whichGenerator_[numberViolated++] = -1;
     7807                printf("Global cut added - violation %g\n",
     7808                       thisCut->violated(cbcColSolution_)) ;
     7809#endif
     7810                whichGenerator_[numberViolated++] = -1;
    73587811#ifndef GLOBAL_CUTS_JUST_POINTERS
    7359                     theseCuts.insert(*thisCut) ;
     7812                theseCuts.insert(*thisCut) ;
    73607813#else
    7361                     theseCuts.insert(thisCut) ;
    7362 #endif
    7363                 }
    7364             }
    7365             numberGlobalViolations_ += numberViolated;
     7814                theseCuts.insert(thisCut) ;
     7815#endif
     7816                if (violations[i]!=-COIN_DBL_MAX)
     7817                  maximumAdd -= thisCut->row().getNumElements();
     7818                if (maximumAdd<0)
     7819                  break;
     7820              }
     7821              delete [] which;
     7822              delete [] violations;
     7823              numberGlobalViolations_ += numberViolated;
     7824            }
    73667825        }
    73677826        /*
     
    77198178            //solver_->setHintParam(OsiDoDualInResolve,true,OsiHintTry);
    77208179            if ( maximumSecondsReached() ) {
    7721                 numberTries = 0; // exit
     8180                numberTries = -1000; // exit
    77228181                feasible = false;
    77238182                break;
     
    78778336                    // maybe give it one more try
    78788337                    if (numberLastAttempts > 2 || currentDepth_ || experimentBreak < 2)
    7879                         break ;
     8338                        numberTries=0 ;
    78808339                    else
    78818340                        numberLastAttempts++;
     
    79118370            keepGoing=false;
    79128371        }
    7913         if (numberTries <=0 && feasible && !keepGoing && !parentModel_ && !numberNodes_) {
     8372        if (numberTries ==0 && feasible && !keepGoing && !parentModel_ && !numberNodes_) {
    79148373          for (int i = 0; i < numberCutGenerators_; i++) {
    79158374            if (generator_[i]->whetherCallAtEnd()
    79168375                &&!generator_[i]->whetherInMustCallAgainMode()) {
    7917               keepGoing= true;
    7918               break;
     8376              // give it some goes and switch off
     8377              numberTries=(saveNumberTries+4)/5;
     8378              generator_[i]->setWhetherCallAtEnd(false);
    79198379            }
    79208380          }
     
    79868446                }
    79878447                if (!feasible) { //node will be fathomed
     8448                    lockThread();
    79888449                    for (int i = 0; i < currentNumberCuts_; i++) {
    79898450                        // take off node
     
    79948455                        }
    79958456                    }
     8457                    unlockThread();
    79968458                }
    79978459            }
     
    81378599        */
    81388600        if (!numberNodes_) {
     8601          if (!parentModel_) {
     8602            //printf("%d global cuts\n",globalCuts_.sizeRowCuts()) ;
     8603            if ((specialOptions_&1) != 0) {
     8604              //specialOptions_ &= ~1;
     8605              int numberCuts = globalCuts_.sizeRowCuts();
     8606              const OsiRowCutDebugger *debugger =
     8607                continuousSolver_->getRowCutDebugger() ;
     8608              if (debugger) {
     8609                for (int i = 0; i < numberCuts; i++) {
     8610                  OsiRowCut * cut = globalCuts_.rowCutPtr(i) ;
     8611                  if (debugger->invalidCut(*cut)) {
     8612                    continuousSolver_->applyRowCuts(1,cut);
     8613                    continuousSolver_->writeMps("bad");
     8614                    printf("BAD cut\n");
     8615                  }
     8616                  //CoinAssert (!debugger->invalidCut(*cut));
     8617                }
     8618              }
     8619            }
     8620          }
    81398621          //solver_->writeMps("second");
    81408622            if (numberRowsAdded)
     
    82858767                willBeCutsInTree = 0;
    82868768        }
    8287         if (!numberNodes_)
     8769        if (!numberNodes_) {
    82888770            handler_->message(CBC_ROOT, messages_)
    82898771            << numberNewCuts_
     
    82918773            << currentPassNumber_
    82928774            << CoinMessageEol ;
     8775        }
    82938776        /*
    82948777          Count the number of cuts produced by each cut generator on this call. Not
     
    84018884                    howOften = -99; // switch off
    84028885            }
     8886            if (generator_[i]->maximumTries()!=-1)
     8887                howOften = -99; // switch off
    84038888            /*
    84048889              Below -99, this generator is switched off. There's no need to consider
    84058890              further. Then again, there was no point in persisting this far!
    84068891            */
    8407             if (howOften < -99)
    8408                 continue ;
     8892            if (howOften < -99) {
     8893              // may have been switched off - report
     8894              if (!numberNodes_) {
     8895                int n = generator_[i]->numberCutsInTotal();
     8896                if (n) {
     8897                  double average = 0.0;
     8898                  average = generator_[i]->numberElementsInTotal();
     8899                  average /= n;
     8900                  handler_->message(CBC_GENERATOR, messages_)
     8901                    << i
     8902                    << generator_[i]->cutGeneratorName()
     8903                    << n
     8904                    << average
     8905                    << generator_[i]->numberColumnCuts()
     8906                    << generator_[i]->numberCutsActive()
     8907                    + generator_[i]->numberColumnCuts();
     8908                  handler_->printing(generator_[i]->timing())
     8909                    << generator_[i]->timeInCutGenerator();
     8910                  handler_->message()
     8911                    << -100
     8912                    << CoinMessageEol ;
     8913                }
     8914              }
     8915              continue ;
     8916            }
    84098917            /*
    84108918              Adjust, if howOften is adjustable.
     
    87289236        specialOptions_ &= ~256; // mark as full scan done
    87299237    }
    8730 # ifdef COIN_HAS_CLP
    8731     if (!node && !parentModel_ && intParam_[CbcMaxNumNode] == -123456) {
    8732         OsiClpSolverInterface * clpSolver
    8733         = dynamic_cast<OsiClpSolverInterface *> (solver_);
    8734         if (clpSolver) {
    8735             clpSolver->lexSolve();
    8736         }
     9238# if 0 //def COIN_HAS_CLP
     9239    // check basis
     9240    OsiClpSolverInterface * clpSolver
     9241      = dynamic_cast<OsiClpSolverInterface *> (solver_);
     9242    if (clpSolver) {
     9243      ClpSimplex * simplex = clpSolver->getModelPtr();
     9244      int numberTotal=simplex->numberRows()+simplex->numberColumns();
     9245      int superbasic=0;
     9246      for (int i=0;i<numberTotal;i++) {
     9247        if (simplex->getStatus(i)==ClpSimplex::superBasic)
     9248          superbasic++;
     9249      }
     9250      if (superbasic) {
     9251        printf("%d superbasic!\n",superbasic);
     9252        clpSolver->resolve();
     9253        superbasic=0;
     9254        for (int i=0;i<numberTotal;i++) {
     9255          if (simplex->getStatus(i)==ClpSimplex::superBasic)
     9256            superbasic++;
     9257        }
     9258        assert (!superbasic);
     9259      }
    87379260    }
    87389261# endif
     
    87629285            }
    87639286        }
     9287        if (generator_[i]->whetherCallAtEnd())
     9288          generate=false;
    87649289        const OsiRowCutDebugger * debugger = NULL;
    87659290        bool onOptimalPath = false;
     
    88969421            if (thisCut->lb() > thisCut->ub())
    88979422                status = -1; // sub-problem is infeasible
    8898             if (thisCut->globallyValid()) {
     9423            if (thisCut->globallyValid()||!numberNodes_) {
    88999424                // add to global list
    89009425                OsiRowCut newCut(*thisCut);
     
    92219746        }
    92229747    }
    9223 #ifdef COIN_HAS_CLP
     9748  #ifdef COIN_HAS_CLP
    92249749    OsiClpSolverInterface * clpSolver
    92259750    = dynamic_cast<OsiClpSolverInterface *> (solver_);
     
    1051311038                int n = CoinMax(obj2->numberTimesDown(),
    1051411039                                obj2->numberTimesUp());
    10515                 if (n >= value)
    10516                     obj2->setNumberBeforeTrust(n + 1);
     11040                if (n >= value) {
     11041                  value = CoinMin(CoinMin(n+1,3*(value+1)/2),5*numberBeforeTrust_);
     11042                  obj2->setNumberBeforeTrust(value);
     11043                }
    1051711044            }
    1051811045        }
     
    1145111978            setCutoff(cutoff);
    1145211979            // change cutoff as constraint if wanted
    11453             if ((moreSpecialOptions_&16777216)!=0) {
    11454               if (solver_->getNumRows()>=numberRowsAtContinuous_) {
     11980            if (cutoffRowNumber_>=0) {
     11981              if (solver_->getNumRows()>cutoffRowNumber_) {
    1145511982                double offset;
    1145611983                solver_->getDblParam(OsiObjOffset, offset);
    11457                 solver_->setRowUpper(numberRowsAtContinuous_-1,cutoff+offset);
     11984                solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
    1145811985              }
    1145911986            }
     
    1163112158                setCutoff(cutoff);
    1163212159                // change cutoff as constraint if wanted
    11633                 if ((moreSpecialOptions_&16777216)!=0) {
    11634                   if (solver_->getNumRows()>=numberRowsAtContinuous_) {
     12160                if (cutoffRowNumber_>=0) {
     12161                  if (solver_->getNumRows()>cutoffRowNumber_) {
    1163512162                    double offset;
    1163612163                    solver_->getDblParam(OsiObjOffset, offset);
    11637                     solver_->setRowUpper(numberRowsAtContinuous_-1,cutoff+offset);
     12164                    solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
    1163812165                  }
    1163912166                }
     
    1235612883// Make partial cut into a global cut and save
    1235712884void
    12358 CbcModel::makePartialCut(const OsiRowCut * partialCut)
     12885CbcModel::makePartialCut(const OsiRowCut * partialCut,
     12886                         const OsiSolverInterface * solver)
    1235912887{
    1236012888  // get greedy cut
    1236112889  double bSum = partialCut->lb();
    1236212890  assert (bSum<0.0);
     12891  if (!solver)
     12892    solver=solver_;
    1236312893  int nConflict = partialCut->row().getNumElements();
    1236412894  const int * column = partialCut->row().getIndices();
    1236512895  const double * element = partialCut->row().getElements();
    1236612896  double * originalLower = topOfTree_->mutableLower();
    12367   const double * columnLower = solver_->getColLower();
     12897  const double * columnLower = solver->getColLower();
    1236812898  double * originalUpper = topOfTree_->mutableUpper();
    12369   const double * columnUpper = solver_->getColUpper();
     12899  const double * columnUpper = solver->getColUpper();
    1237012900  int nC=nConflict;
    1237112901  while (nConflict) {
     
    1240312933  printf("CUTa has %d (started at %d) - final bSum %g\n",nConflict,nC,bSum);
    1240412934  if (nConflict>1) {
     12935    if ((specialOptions_&1) != 0) {
     12936      const OsiRowCutDebugger *debugger = continuousSolver_->getRowCutDebugger() ;
     12937      if (debugger) {
     12938        if (debugger->invalidCut(newCut)) {
     12939          continuousSolver_->applyRowCuts(1,&newCut);
     12940          continuousSolver_->writeMps("bad");
     12941        }
     12942        CoinAssert (!debugger->invalidCut(newCut));
     12943      }
     12944    }
    1240512945    newCut.setGloballyValidAsInteger(2);
    1240612946    newCut.mutableRow().setTestForDuplicateIndex(false);
     
    1314513685            int totalNodes = numberNodes_ + numberExtraNodes_;
    1314613686            int totalIterations = numberIterations_ + numberExtraIterations_;
     13687            bool diving=false;
     13688            if ((moreSpecialOptions_&33554432)!=0) {
     13689              testDepth=COIN_INT_MAX;
     13690              if (oldNode&&(oldNode->depth()==-2||oldNode->depth()==4))
     13691                diving=true;
     13692            }
    1314713693            if (totalNodes*40 < totalIterations || numberNodes_ < 1000) {
    1314813694                doClp = false;
     
    1315213698                //     totalNodes,totalIterations,doClp ? 'Y' : 'N');
    1315313699            }
    13154             if (oldNode && fastNodeDepth_ >= 0 && oldNode->depth() >= testDepth &&/*!parentModel_*/(specialOptions_&2048) == 0
    13155                     && doClp && !cuts.sizeRowCuts()) {
     13700            if (oldNode &&
     13701                ((fastNodeDepth_ >= 0 && oldNode->depth() >= testDepth && doClp)||diving) &&/*!parentModel_*/(specialOptions_&2048) == 0
     13702                && !cuts.sizeRowCuts()) {
    1315613703                OsiClpSolverInterface * clpSolver
    1315713704                = dynamic_cast<OsiClpSolverInterface *> (solver_);
     
    1316413711#endif
    1316513712#ifdef COIN_HAS_CLP
    13166             int save;
     13713            int save=0;
    1316713714            OsiClpSolverInterface * clpSolver
    1316813715              = dynamic_cast<OsiClpSolverInterface *> (solver_);
     
    1334413891                assert (numberProblems);
    1334513892                int nProbMinus1 = numberProblems - 1;
     13893                lockThread();
    1334613894                for (int i = 0; i < currentNumberCuts_; i++) {
    1334713895                    if (addedCuts_[i])
    1334813896                        addedCuts_[i]->increment(nProbMinus1) ;
    1334913897                }
     13898                unlockThread();
    1335013899                for (int i = 0; i < numberProblems; i++) {
    1335113900                    double objectiveValue;
     
    1356614115        setCutoff(cutoff) ;
    1356714116        // change cutoff as constraint if wanted
    13568         if ((moreSpecialOptions_&16777216)!=0) {
    13569           if (solver_->getNumRows()>=numberRowsAtContinuous_) {
     14117        if (cutoffRowNumber_>=0) {
     14118          if (solver_->getNumRows()>cutoffRowNumber_) {
    1357014119            double offset;
    1357114120            solver_->getDblParam(OsiObjOffset, offset);
    13572             solver_->setRowUpper(numberRowsAtContinuous_-1,cutoff+offset);
     14121            solver_->setRowUpper(cutoffRowNumber_,cutoff+offset);
    1357314122          }
    1357414123        }
     
    1406714616// Set original columns as created by preprocessing
    1406814617void
    14069 CbcModel::setOriginalColumns(const int * originalColumns)
     14618CbcModel::setOriginalColumns(const int * originalColumns,int numberGood)
    1407014619{
    1407114620    int numberColumns = getNumCols();
    1407214621    delete [] originalColumns_;
    14073     originalColumns_ = CoinCopyOfArray(originalColumns, numberColumns);
     14622    originalColumns_ = new int [numberColumns];
     14623    int numberCopy=CoinMin(numberColumns,numberGood);
     14624    memcpy(originalColumns_,originalColumns,numberCopy*sizeof(int));
     14625    for (int i=numberCopy;i<numberColumns;i++)
     14626      originalColumns_[i]=-1;
    1407414627}
    1407514628// Set the cut modifier method
     
    1409814651{
    1409914652    int foundSolution = 0;
     14653    int saveNumberCutGenerators=numberCutGenerators_;
     14654    if ((moreSpecialOptions_&33554432)!=0 && (specialOptions_&2048)==0) {
     14655      if (node&&(node->depth()==-2||node->depth()==4))
     14656        numberCutGenerators_=0; // so can dive and branch
     14657    }
    1410014658    int currentNumberCuts = 0 ;
    1410114659    currentNode_ = node; // so can be accessed elsewhere
     
    1419514753            CbcBranchingObject * branch = static_cast <CbcBranchingObject *>(branch2) ;
    1419614754#endif
     14755#if 1
    1419714756            branch->setModel(this);
    1419814757            branchesLeft = node->branch(NULL); // old way
     14758#else
     14759            branchesLeft = node->branch(solver_);
     14760#endif
    1419914761            if (parallelMode() >= 0)
    1420014762                branch->setModel(baseModel);
     
    1460115163                  solver_->writeMpsNative("infeas2.mps", NULL, NULL, 2);
    1460215164                  solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
    14603                   assert (solver_->getRowCutDebugger()) ;
     15165                  const OsiRowCutDebugger * debugger = solver_->getRowCutDebugger() ;
     15166                  assert (debugger) ;
     15167                  int numberRows0=continuousSolver_->getNumRows();
     15168                  int numberRows=solver_->getNumRows();
     15169                  const CoinPackedMatrix * rowCopy = solver_->getMatrixByRow();
     15170                  const int * rowLength = rowCopy->getVectorLengths();
     15171                  const double * elements = rowCopy->getElements();
     15172                  const int * column = rowCopy->getIndices();
     15173                  const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
     15174                  const double * rowLower = solver_->getRowLower();
     15175                  const double * rowUpper = solver_->getRowUpper();
     15176                  for (int iRow=numberRows0;iRow<numberRows;iRow++) {
     15177                    OsiRowCut rc;
     15178                    rc.setLb(rowLower[iRow]);
     15179                    rc.setUb(rowUpper[iRow]);
     15180                    CoinBigIndex start = rowStart[iRow];
     15181                    rc.setRow(rowLength[iRow],column+start,elements+start,false);
     15182                    CoinAssert (!debugger->invalidCut(rc));
     15183                  }
    1460415184                  assert (feasible);
    1460515185                }
     
    1487215452            if (parallelMode() >= 0)
    1487315453                newNode = new CbcNode() ;
     15454#if 0
     15455            // Try diving
     15456            if (parallelMode() >= 0 && (specialOptions_&2048) == 0) {
     15457              // See if any diving heuristics set to do dive+save
     15458              CbcHeuristicDive * dive=NULL;
     15459              for (int i = 0; i < numberHeuristics_; i++) {
     15460                CbcHeuristicDive * possible = dynamic_cast<CbcHeuristicDive *>(heuristic_[i]);
     15461                if (possible&&possible->maxSimplexIterations()==COIN_INT_MAX) {
     15462                  // if more than one then rotate later?
     15463                  //if (possible->canHeuristicRun()) {
     15464                  if (node->depth()==0||node->depth()==5) {
     15465                    dive=possible;
     15466                    break;
     15467                  }
     15468                }
     15469              }
     15470              if (dive) {
     15471                int numberNodes;
     15472                CbcSubProblem ** nodes=NULL;
     15473                int branchState=dive->fathom(this,numberNodes,nodes);
     15474                if (branchState) {
     15475                  printf("new solution\n");
     15476                }
     15477                if (0) {
     15478                  for (int iNode=0;iNode<numberNodes;iNode++) {
     15479                    //tree_->push(nodes[iNode]) ;
     15480                  }
     15481                  assert (node->nodeInfo());
     15482                  if (node->nodeInfo()->numberBranchesLeft()) {
     15483                    tree_->push(node) ;
     15484                  } else {
     15485                    node->setActive(false);
     15486                  }
     15487                }
     15488                delete [] nodes;
     15489              }
     15490            }
     15491            // end try diving
     15492#endif
    1487415493            // Set objective value (not so obvious if NLP etc)
    1487515494            setObjectiveValue(newNode, node);
     
    1526315882        unlockThread();
    1526415883    }
     15884    numberCutGenerators_=saveNumberCutGenerators;
    1526515885    return foundSolution;
    1526615886}
     
    1552016140    for (int i = 0; i < numberHeuristics_; i++) {
    1552116141        CbcHeuristicDive * heuristic = dynamic_cast<CbcHeuristicDive *> (heuristic_[i]);
    15522         if (heuristic) {
     16142        if (heuristic && heuristic->maxSimplexIterations()!=COIN_INT_MAX) {
    1552316143            heuristic->setMaxSimplexIterations(nTree);
    1552416144            heuristic->setMaxSimplexIterationsAtRoot(nRoot);
     
    1688917509    char general[200];
    1689017510    if (clpSolver) {
    16891       clpSolver->getModelPtr()->dual(); // to get more randomness
     17511      clpSolver->getModelPtr()->dual(); // probably not needed
    1689217512      clpSolver->setWarmStart(NULL);
    16893       sprintf(general,"Starting multiple root solver - %d iterations in initialSolve",
    16894               clpSolver->getIterationCount());
     17513      sprintf(general,"Starting multiple root solver");
    1689517514    } else {
    1689617515#endif
     
    1691117530    return NULL;
    1691217531}
    16913 
    16914 
     17532OsiRowCut *
     17533CbcModel::conflictCut(const OsiSolverInterface * solver, bool & localCuts)
     17534{
     17535  OsiRowCut * cut=NULL;
     17536  localCuts=false;
     17537# ifdef COIN_HAS_CLP
     17538  const OsiClpSolverInterface * clpSolver
     17539    = dynamic_cast<const OsiClpSolverInterface *> (solver);
     17540  if (clpSolver&&topOfTree_) {
     17541    int debugMode=0;
     17542    const double * originalLower = topOfTree_->lower();
     17543    const double * originalUpper = topOfTree_->upper();
     17544    int typeCut = 1;
     17545    ClpSimplex * simplex = clpSolver->getModelPtr();
     17546    assert(simplex->status()==1);
     17547    if(simplex->ray()) {
     17548      {
     17549        int numberRows=simplex->numberRows();
     17550        double * saveRay=CoinCopyOfArray(simplex->ray(),numberRows);
     17551#define SAFE_RAY
     17552#ifdef SAFE_RAY
     17553        ClpSimplex & tempSimplex=*simplex;
     17554#else
     17555        ClpSimplex tempSimplex=*simplex;
     17556#endif
     17557        int logLevel=simplex->logLevel();
     17558        tempSimplex.setLogLevel(63);
     17559        tempSimplex.scaling(0);
     17560        tempSimplex.dual();
     17561        tempSimplex.setLogLevel(logLevel);
     17562        if (!tempSimplex.numberIterations()) {
     17563          double * ray = tempSimplex.ray();
     17564          int nBad=0;
     17565          for (int i=0;i<numberRows;i++) {
     17566            if (fabs(ray[i]-saveRay[i])>1.0e-3) {
     17567              if (debugMode)
     17568                printf("row %d true %g bad %g - diff %g\n",
     17569                       i,ray[i],saveRay[i],ray[i]-saveRay[i]);
     17570              nBad++;
     17571            }
     17572          }
     17573          if (nBad)
     17574            printf("%d mismatch crunch ray values\n",nBad);
     17575        }
     17576        delete [] saveRay;
     17577      }
     17578     // make sure we use non-scaled versions
     17579      ClpPackedMatrix * saveMatrix = simplex->swapScaledMatrix(NULL);
     17580      double * saveScale = simplex->swapRowScale(NULL);
     17581      //printf("Could do normal cut\n");
     17582      // could use existing arrays
     17583      int numberRows=simplex->numberRows();
     17584      int numberColumns=simplex->numberColumns();
     17585      double * farkas = new double [2*numberColumns+numberRows];
     17586      double * bound = farkas + numberColumns;
     17587      double * effectiveRhs = bound + numberColumns;
     17588      // sign as internally for dual - so swap if primal
     17589      /*const*/ double * ray = simplex->ray();
     17590      // have to get rid of local cut rows
     17591      if (whichGenerator_) {
     17592        const int * whichGenerator = whichGenerator_ - numberRowsAtContinuous_;
     17593        int badRows=0;
     17594        for (int iRow=numberRowsAtContinuous_;iRow<numberRows;iRow++) {
     17595          int iType=whichGenerator[iRow];
     17596          if ((iType>=0&&iType<10000)||iType<-1) {
     17597            if (fabs(ray[iRow])>1.0e-10) {
     17598              badRows++;
     17599            } else {
     17600              ray[iRow]=0.0;
     17601            }
     17602          }
     17603        }
     17604        if (badRows) {
     17605          if ((debugMode&1)!=0)
     17606            printf("%d rows from local cuts\n",badRows);
     17607          localCuts=true;
     17608        }
     17609      }
     17610      // get farkas row
     17611      memset(farkas,0,(2*numberColumns+numberRows)*sizeof(double));
     17612      simplex->transposeTimes(-1.0,ray,farkas);
     17613      //const char * integerInformation = simplex->integerType_;
     17614      //assert (integerInformation);
     17615
     17616      int sequenceOut = simplex->sequenceOut();
     17617      // Put nonzero bounds in bound
     17618      const double * columnLower = simplex->columnLower();
     17619      const double * columnUpper = simplex->columnUpper();
     17620      int numberBad=0;
     17621      for (int i=0;i<numberColumns;i++) {
     17622        double value = farkas[i];
     17623        double boundValue=0.0;
     17624        if (simplex->getStatus(i)==ClpSimplex::basic) {
     17625          // treat as zero if small
     17626          if (fabs(value)<1.0e-8) {
     17627            value=0.0;
     17628            farkas[i]=0.0;
     17629          }
     17630          if (value) {
     17631            //printf("basic %d direction %d farkas %g\n",
     17632            //     i,simplex->directionOut(),value);
     17633            if (value<0.0)
     17634              boundValue=columnLower[i];
     17635            else
     17636              boundValue=columnUpper[i];
     17637          }
     17638        } else if (fabs(value)>1.0e-10) {
     17639          if (value<0.0)
     17640            boundValue=columnLower[i];
     17641          else
     17642            boundValue=columnUpper[i];
     17643        }
     17644        bound[i]=boundValue;
     17645        if (fabs(boundValue)>1.0e10)
     17646          numberBad++;
     17647      }
     17648      const double * rowLower = simplex->rowLower();
     17649      const double * rowUpper = simplex->rowUpper();
     17650      //int pivotRow = simplex->spareIntArray_[3];
     17651      //bool badPivot=pivotRow<0;
     17652      for (int i=0;i<numberRows;i++) {
     17653        double value = ray[i];
     17654        double rhsValue=0.0;
     17655        if (simplex->getRowStatus(i)==ClpSimplex::basic) {
     17656          // treat as zero if small
     17657          if (fabs(value)<1.0e-8) {
     17658            value=0.0;
     17659            ray[i]=0.0;
     17660          }
     17661          if (value) {
     17662            //printf("row basic %d direction %d ray %g\n",
     17663            //     i,simplex->directionOut(),value);
     17664            if (value<0.0)
     17665              rhsValue=rowLower[i];
     17666            else
     17667              rhsValue=rowUpper[i];
     17668          }
     17669        } else if (fabs(value)>1.0e-10) {
     17670          if (value<0.0)
     17671            rhsValue=rowLower[i];
     17672          else
     17673              rhsValue=rowUpper[i];
     17674        }
     17675        effectiveRhs[i]=rhsValue;
     17676      }
     17677      simplex->times(-1.0,bound,effectiveRhs);
     17678      simplex->swapRowScale(saveScale);
     17679      simplex->swapScaledMatrix(saveMatrix);
     17680      double bSum=0.0;
     17681      for (int i=0;i<numberRows;i++) {
     17682        bSum += effectiveRhs[i]*ray[i];
     17683      }
     17684      if (numberBad||bSum>-1.0e-4) {
     17685#ifndef NDEBUG
     17686        printf("bad BOUND bSum %g  - %d bad\n",
     17687               bSum,numberBad);
     17688#endif
     17689      } else {
     17690        const char * integerInformation = simplex->integerInformation();
     17691        assert (integerInformation);
     17692        int * conflict = new int[numberColumns];
     17693        double * sort = new double [numberColumns];
     17694        double relax=0.0;
     17695        int nConflict=0;
     17696        int nOriginal=0;
     17697        int nFixed=0;
     17698        for (int iColumn=0;iColumn<numberColumns;iColumn++) {
     17699          if (integerInformation[iColumn]) {
     17700            if ((debugMode&1)!=0)
     17701            printf("%d status %d %g <= %g <=%g (orig %g, %g) farkas %g\n",
     17702                   iColumn,simplex->getStatus(iColumn),columnLower[iColumn],
     17703                   simplex->primalColumnSolution()[iColumn],columnUpper[iColumn],
     17704                   originalLower[iColumn],originalUpper[iColumn],
     17705                   farkas[iColumn]);
     17706            double gap = originalUpper[iColumn]-originalLower[iColumn];
     17707            if (!gap)
     17708              continue;
     17709            if (gap==columnUpper[iColumn]-columnLower[iColumn])
     17710              nOriginal++;
     17711            if (columnUpper[iColumn]==columnLower[iColumn])
     17712              nFixed++;
     17713            if (fabs(farkas[iColumn])<1.0e-15) {
     17714              farkas[iColumn]=0.0;
     17715              continue;
     17716            }
     17717            // temp
     17718            if (gap>=20000.0&&false) {
     17719              // can't use
     17720              if (farkas[iColumn]<0.0) {
     17721                assert(originalLower[iColumn]-columnLower[iColumn]<=0.0);
     17722                // farkas is negative - relax lower bound all way
     17723                relax +=
     17724                  farkas[iColumn]*(originalLower[iColumn]-columnLower[iColumn]);
     17725              } else {
     17726                assert(originalUpper[iColumn]-columnUpper[iColumn]>=0.0);
     17727                // farkas is positive - relax upper bound all way
     17728                relax +=
     17729                  farkas[iColumn]*(originalUpper[iColumn]-columnUpper[iColumn]);
     17730              }
     17731              continue;
     17732            }
     17733            if (originalLower[iColumn]==columnLower[iColumn]) {
     17734              if (farkas[iColumn]>0.0&&(simplex->getStatus(iColumn)==ClpSimplex::atUpperBound
     17735                                        ||simplex->getStatus(iColumn)==ClpSimplex::isFixed
     17736                                        ||iColumn==sequenceOut)) {
     17737                // farkas is positive - add to list
     17738                gap=originalUpper[iColumn]-columnUpper[iColumn];
     17739                if (gap) {
     17740                  sort[nConflict]=-farkas[iColumn]*gap;
     17741                  conflict[nConflict++]=iColumn;
     17742                }
     17743                //assert (gap>columnUpper[iColumn]-columnLower[iColumn]);
     17744              }
     17745            } else if (originalUpper[iColumn]==columnUpper[iColumn]) {
     17746              if (farkas[iColumn]<0.0&&(simplex->getStatus(iColumn)==ClpSimplex::atLowerBound
     17747                                        ||simplex->getStatus(iColumn)==ClpSimplex::isFixed
     17748                                        ||iColumn==sequenceOut)) {
     17749                // farkas is negative - add to list
     17750                gap=columnLower[iColumn]-originalLower[iColumn];
     17751                if (gap) {
     17752                  sort[nConflict]=farkas[iColumn]*gap;
     17753                  conflict[nConflict++]=iColumn;
     17754                }
     17755                //assert (gap>columnUpper[iColumn]-columnLower[iColumn]);
     17756              }
     17757            } else {
     17758              // can't use
     17759              if (farkas[iColumn]<0.0) {
     17760                assert(originalLower[iColumn]-columnLower[iColumn]<=0.0);
     17761                // farkas is negative - relax lower bound all way
     17762                relax +=
     17763                  farkas[iColumn]*(originalLower[iColumn]-columnLower[iColumn]);
     17764              } else {
     17765                assert(originalUpper[iColumn]-columnUpper[iColumn]>=0.0);
     17766                // farkas is positive - relax upper bound all way
     17767                relax +=
     17768                  farkas[iColumn]*(originalUpper[iColumn]-columnUpper[iColumn]);
     17769              }
     17770            }
     17771            assert(relax>=0.0);
     17772          } else {
     17773            // not integer - but may have been got at
     17774            double gap = originalUpper[iColumn]-originalLower[iColumn];
     17775            if (gap>columnUpper[iColumn]-columnLower[iColumn]) {
     17776              // can't use
     17777              if (farkas[iColumn]<0.0) {
     17778                assert(originalLower[iColumn]-columnLower[iColumn]<=0.0);
     17779                // farkas is negative - relax lower bound all way
     17780                relax +=
     17781                  farkas[iColumn]*(originalLower[iColumn]-columnLower[iColumn]);
     17782              } else {
     17783                assert(originalUpper[iColumn]-columnUpper[iColumn]>=0.0);
     17784                // farkas is positive - relax upper bound all way
     17785                relax +=
     17786                  farkas[iColumn]*(originalUpper[iColumn]-columnUpper[iColumn]);
     17787              }
     17788            }
     17789          }
     17790        }
     17791        if (relax+bSum>-1.0e-4||!nConflict) {
     17792          if (relax+bSum>-1.0e-4) {
     17793#ifndef NDEBUG
     17794            printf("General integers relax bSum to %g\n",relax+bSum);
     17795#endif
     17796          } else {
     17797            printf("All variables relaxed and still infeasible - what does this mean?\n");
     17798            int nR=0;
     17799            for (int i=0;i<numberRows;i++) {
     17800              if (fabs(ray[i])>1.0e-10)
     17801                nR++;
     17802              else
     17803                ray[i]=0.0;
     17804            }
     17805            int nC=0;
     17806            for (int i=0;i<numberColumns;i++) {
     17807              if (fabs(farkas[i])>1.0e-10)
     17808                nC++;
     17809              else
     17810                farkas[i]=0.0;
     17811            }
     17812            if (nR<3&&nC<5) {
     17813              printf("BAD %d nonzero rows, %d nonzero columns\n",nR,nC);
     17814            }
     17815          }
     17816        } else {
     17817          printf("BOUNDS violation bSum %g (relaxed %g) - %d at original bounds, %d fixed - %d in conflict\n",bSum,
     17818                 relax+bSum,nOriginal,nFixed,nConflict);
     17819          CoinSort_2(sort,sort+nConflict,conflict);
     17820          int nC=nConflict;
     17821          bSum+=relax;
     17822          double saveBsum = bSum;
     17823          while (nConflict) {
     17824            //int iColumn=conflict[nConflict-1];
     17825            double change=-sort[nConflict-1];
     17826            if (bSum+change>-1.0e-4)
     17827              break;
     17828            nConflict--;
     17829            bSum += change;
     17830          }
     17831          if (!nConflict) {
     17832            int nR=0;
     17833            for (int i=0;i<numberRows;i++) {
     17834              if (fabs(ray[i])>1.0e-10)
     17835                nR++;
     17836              else
     17837                ray[i]=0.0;
     17838            }
     17839            int nC=0;
     17840            for (int i=0;i<numberColumns;i++) {
     17841              if (fabs(farkas[i])>1.0e-10)
     17842                nC++;
     17843              else
     17844                farkas[i]=0.0;
     17845            }
     17846            if (nR<3&&nC<5) {
     17847              printf("BAD2 %d nonzero rows, %d nonzero columns\n",nR,nC);
     17848            }
     17849          }
     17850          // no point doing if no reduction (or big?) ?
     17851          if (nConflict<nC+1&&nConflict<500) {
     17852            cut=new OsiRowCut();
     17853            cut->setUb(COIN_DBL_MAX);
     17854            if (!typeCut) {
     17855              double lo=1.0;
     17856              for (int i=0;i<nConflict;i++) {
     17857                int iColumn = conflict[i];
     17858                if (originalLower[iColumn]==columnLower[iColumn]) {
     17859                  // must be at least one higher
     17860                  sort[i]=1.0;
     17861                  lo += originalLower[iColumn];
     17862                } else {
     17863                  // must be at least one lower
     17864                  sort[i]=-1.0;
     17865                  lo -= originalUpper[iColumn];
     17866                }
     17867              }
     17868              cut->setLb(lo);
     17869              cut->setRow(nConflict,conflict,sort);
     17870              printf("CUT has %d (started at %d) - final bSum %g\n",nConflict,nC,bSum);
     17871            } else {
     17872              // just save for use later
     17873              // first take off small
     17874              int nC2=nC;
     17875              while (nC2) {
     17876                //int iColumn=conflict[nConflict-1];
     17877                double change=-sort[nC2-1];
     17878                if (saveBsum+change>-1.0e-4||change>1.0e-4)
     17879                  break;
     17880                nC2--;
     17881                saveBsum += change;
     17882              }
     17883              cut->setLb(saveBsum);
     17884              for (int i=0;i<nC2;i++) {
     17885                int iColumn = conflict[i];
     17886                sort[i]=farkas[iColumn];
     17887              }
     17888              cut->setRow(nC2,conflict,sort);
     17889              printf("Stem CUT has %d (greedy %d - with small %d) - saved bSum %g final greedy bSum %g\n",
     17890                     nC2,nConflict,nC,saveBsum,bSum);
     17891            }
     17892          }
     17893        }
     17894        delete [] conflict;
     17895        delete [] sort;
     17896      }
     17897      delete [] farkas;
     17898    } else {
     17899      printf("No dual ray\n");
     17900    }
     17901  }
     17902#endif
     17903  return cut;
     17904}
     17905
Note: See TracChangeset for help on using the changeset viewer.