Changeset 1656 for trunk/Cbc/src


Ignore:
Timestamp:
May 31, 2011 4:10:30 AM (8 years ago)
Author:
forrest
Message:

allow end cuts and lagomory

Location:
trunk/Cbc/src
Files:
6 edited

Legend:

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

    r1643 r1656  
    276276        if (fullScan < 0)
    277277            info.options |= 128;
     278        if (whetherInMustCallAgainMode())
     279          info.options |= 1024;
    278280        // See if we want alternate set of cuts
    279281        if ((model_->moreSpecialOptions()&16384) != 0)
     
    539541            }
    540542            //if (!solver->basisIsAvailable())
    541             //returnCode=true;
     543            //returnCode=true;
     544            if (!returnCode) {
     545              // bounds changed but still optimal
     546#ifdef COIN_HAS_CLP
     547              OsiClpSolverInterface * clpSolver
     548                = dynamic_cast<OsiClpSolverInterface *> (solver);
     549              if (clpSolver) {
     550                clpSolver->setLastAlgorithm(2);
     551              }
     552#endif
     553            }
    542554#ifdef JJF_ZERO
    543555            // Pass across info to pseudocosts
  • trunk/Cbc/src/CbcCutGenerator.hpp

    r1573 r1656  
    167167    }
    168168
     169    /// Get switches (for debug)
     170    inline int switches() const {
     171        return switches_;
     172    }
    169173    /// Get whether the cut generator should be called in the normal place
    170174    inline bool normal() const {
     
    319323        switches_ &= ~1024;
    320324        switches_ |= yesNo ? 1024 : 0;
     325    }
     326    /// Whether in must call again mode (or after others)
     327    inline bool whetherInMustCallAgainMode() const {
     328        return (switches_&2048) != 0;
     329    }
     330    /// Set whether in must call again mode (or after others)
     331    inline void setWhetherInMustCallAgainMode(bool yesNo) {
     332        switches_ &= ~2048;
     333        switches_ |= yesNo ? 2048 : 0;
     334    }
     335    /// Whether to call at end
     336    inline bool whetherCallAtEnd() const {
     337        return (switches_&4096) != 0;
     338    }
     339    /// Set whether to call at end
     340    inline void setWhetherCallAtEnd(bool yesNo) {
     341        switches_ &= ~4096;
     342        switches_ |= yesNo ? 4096 : 0;
    321343    }
    322344    /// Number of cuts generated at root
  • trunk/Cbc/src/CbcHeuristicRENS.cpp

    r1641 r1656  
    852852        returnCode = smallBranchAndBound(newSolver, numberNodes_, betterSolution, solutionValue,
    853853                                         model_->getCutoff(), "CbcHeuristicRENS");
    854         if (returnCode < 0) {
    855             returnCode = 0; // returned on size
     854        if (returnCode < 0 || returnCode == 0) {
    856855#ifdef RENS_FIX_CONTINUOUS
    857856            if (numberContinuous > numberIntegers && numberFixed >= numberColumns / 5) {
     
    905904                returnCode = smallBranchAndBound(newSolver, numberNodes_, betterSolution, solutionValue,
    906905                                                 model_->getCutoff(), "CbcHeuristicRENS");
    907 #endif
    908             }
     906            }
     907#endif
     908            if (returnCode < 0 || returnCode == 0) {
     909                // Do passes fixing up those >0.9 and
     910                // down those < 0.05
     911#define RENS_PASS 3
     912              //#define KEEP_GOING
     913#ifdef KEEP_GOING
     914                double * saveLower = CoinCopyOfArray(colLower,numberColumns);
     915                double * saveUpper = CoinCopyOfArray(colUpper,numberColumns);
     916                bool badPass=false;
     917                int nSolved=0;
     918#endif
     919                for (int iPass=0;iPass<RENS_PASS;iPass++) {
     920                  int nFixed=0;
     921                  int nFixedAlready=0;
     922                  int nFixedContinuous=0;
     923                  for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
     924                    if (colUpper[iColumn]>colLower[iColumn]) {
     925                      if (newSolver->isInteger(iColumn)) {
     926                        double value = currentSolution[iColumn];
     927                        double fixTo = floor(value+0.1);
     928                        if (fixTo>value || value-fixTo < 0.05) {
     929                          // above 0.9 or below 0.05
     930                          nFixed++;
     931                          newSolver->setColLower(iColumn, fixTo);
     932                          newSolver->setColUpper(iColumn, fixTo);
     933                        }
     934                      }
     935                    } else if (newSolver->isInteger(iColumn)) {
     936                      nFixedAlready++;
     937                    } else {
     938                      nFixedContinuous++;
     939                    }
     940                  }
     941#ifdef CLP_INVESTIGATE2
     942                  printf("%d more integers fixed (total %d) plus %d continuous\n",
     943                         nFixed,nFixed+nFixedAlready,nFixedContinuous);
     944#endif
     945#ifdef KEEP_GOING
     946                  if (nFixed) {
     947                    newSolver->resolve();
     948                    if (!newSolver->isProvenOptimal()) {
     949                      badPass=true;
     950                      break;
     951                    } else {
     952                      nSolved++;
     953                      memcpy(saveLower,colLower,numberColumns*sizeof(double));
     954                      memcpy(saveUpper,colUpper,numberColumns*sizeof(double));
     955                    }
     956                  } else {
     957                    break;
     958                  }
     959#else
     960                  if (nFixed) {
     961                    newSolver->resolve();
     962                    if (!newSolver->isProvenOptimal()) {
     963                      returnCode=0;
     964                      break;
     965                    }
     966                    returnCode = smallBranchAndBound(newSolver, numberNodes_, betterSolution, solutionValue,
     967                                                     model_->getCutoff(), "CbcHeuristicRENS");
     968                  } else {
     969                    returnCode=0;
     970                  }
     971                  if (returnCode>=0)
     972                    break;
     973                }
     974                if (returnCode < 0)
     975                returnCode = 0; // returned on size
     976#endif
     977            }
     978#ifdef KEEP_GOING
     979            if (badPass) {
     980              newSolver->setColLower(saveLower);
     981              newSolver->setColUpper(saveUpper);
     982              newSolver->resolve();
     983            }
     984            delete [] saveLower;
     985            delete [] saveUpper;
     986            if (nSolved)
     987              returnCode =
     988                smallBranchAndBound(newSolver, numberNodes_, betterSolution, solutionValue,
     989                                    model_->getCutoff(), "CbcHeuristicRENS");
     990            else
     991              returnCode=0;
     992        }
     993#endif
    909994        }
    910995        //printf("return code %d",returnCode);
  • trunk/Cbc/src/CbcModel.cpp

    r1654 r1656  
    19811981#endif
    19821982    bool feasible;
     1983    numberSolves_ = 0 ;
    19831984    // If NLP then we assume already solved outside branchAndbound
    19841985    if (!solverCharacteristics_->solverType() || solverCharacteristics_->solverType() == 4) {
     
    22232224        if (clpSolver)
    22242225            clpSolver->setStuff(getIntegerTolerance(), getCutoffIncrement());
     2226#ifdef CLP_RESOLVE
     2227        if ((moreSpecialOptions_&1048576)!=0&&!parentModel_&&clpSolver) {
     2228          resolveClp(clpSolver,0);
     2229        }
     2230#endif
    22252231    }
    22262232#endif
     
    23322338    */
    23332339    numberIterations_ = 0 ;
    2334     numberSolves_ = 0 ;
    23352340    numberNodes_ = 0 ;
    23362341    numberNodes2_ = 0 ;
     
    25612566        feasible = false;
    25622567
     2568#ifdef CLP_RESOLVE
     2569    if ((moreSpecialOptions_&2097152)!=0&&!parentModel_&&feasible) {
     2570      OsiClpSolverInterface * clpSolver
     2571        = dynamic_cast<OsiClpSolverInterface *> (solver_);
     2572      if (clpSolver)
     2573        resolveClp(clpSolver,0);
     2574    }
     2575#endif
    25632576    // make cut generators less aggressive
    25642577    for (iCutGenerator = 0; iCutGenerator < numberCutGenerators_; iCutGenerator++) {
     
    69206933    // Whether to increase minimum drop
    69216934    bool increaseDrop = (moreSpecialOptions_ & 8192) != 0;
     6935    for (int i = 0; i < numberCutGenerators_; i++)
     6936      generator_[i]->setWhetherInMustCallAgainMode(false);
    69226937    /*
    69236938      Begin cut generation loop. Cuts generated during each iteration are
     
    69436958                if (!generator_[i]->mustCallAgain())
    69446959                    generator_[i]->setSwitchedOff(true);
     6960                else
     6961                  generator_[i]->setWhetherInMustCallAgainMode(true);
    69456962            }
    69466963        }
     
    75307547            keepGoing=false;
    75317548        }
     7549        if (numberTries <=0 && feasible && !keepGoing && !parentModel_ && !numberNodes_) {
     7550          for (int i = 0; i < numberCutGenerators_; i++) {
     7551            if (generator_[i]->whetherCallAtEnd()
     7552                &&!generator_[i]->whetherInMustCallAgainMode()) {
     7553              keepGoing= true;
     7554              break;
     7555            }
     7556          }
     7557        }
    75327558    } while (numberTries > 0 || keepGoing) ;
    75337559    /*
     
    83458371        int numberRowCutsAfter = numberRowCutsBefore;
    83468372        int numberColumnCutsAfter = numberColumnCutsBefore;
     8373        /*printf("GEN %d %s switches %d\n",
     8374               i,generator_[i]->cutGeneratorName(),
     8375               generator_[i]->switches());*/
    83478376        bool generate = generator_[i]->normal();
    83488377        // skip if not optimal and should be (maybe a cut generator has fixed variables)
     
    83758404            }
    83768405            if (numberRowCutsBefore < numberRowCutsAfter &&
    8377                     generator_[i]->mustCallAgain() && status >= 0)
     8406                generator_[i]->mustCallAgain() && status >= 0)
     8407              /*printf("%s before %d after %d must %c atend %c off %c endmode %c\n",
     8408                   generator_[i]->cutGeneratorName(),
     8409                   numberRowCutsBefore,numberRowCutsAfter,
     8410                   generator_[i]->mustCallAgain() ? 'Y': 'N',
     8411                   generator_[i]->whetherCallAtEnd() ? 'Y': 'N',
     8412                   generator_[i]->switchedOff() ? 'Y': 'N',
     8413                   generator_[i]->whetherInMustCallAgainMode() ? 'Y': 'N');*/
     8414            if (numberRowCutsBefore < numberRowCutsAfter &&
     8415                generator_[i]->mustCallAgain() && status >= 0)
    83788416                status = 1 ; // say must go round
    83798417            // Check last cut to see if infeasible
     
    1210712145    return solver->isProvenOptimal() ? 1 : 0;
    1210812146}
     12147#ifdef CLP_RESOLVE
     12148// Special purpose resolve
     12149int
     12150CbcModel::resolveClp(OsiClpSolverInterface * clpSolver, int type)
     12151{
     12152    numberSolves_++;
     12153    ClpSimplex * clpSimplex = clpSolver->getModelPtr();
     12154    int save = clpSimplex->specialOptions();
     12155    clpSimplex->setSpecialOptions(save | 0x11000000); // say is Cbc (and in branch and bound)
     12156    int save2 = clpSolver->specialOptions();
     12157    clpSolver->resolve();
     12158    if (!numberNodes_) {
     12159      double error = CoinMax(clpSimplex->largestDualError(),
     12160                             clpSimplex->largestPrimalError());
     12161      if (error > 1.0e-2 || !clpSolver->isProvenOptimal()) {
     12162#ifdef CLP_INVESTIGATE
     12163        printf("Problem was %s largest dual error %g largest primal %g - safer cuts\n",
     12164               clpSolver->isProvenOptimal() ? "optimal" : "!infeasible",
     12165               clpSimplex->largestDualError(),
     12166               clpSimplex->largestPrimalError());
     12167#endif
     12168        if (!clpSolver->isProvenOptimal()) {
     12169          clpSolver->setSpecialOptions(save2 | 2048);
     12170          clpSimplex->allSlackBasis(true);
     12171          clpSolver->resolve();
     12172          if (!clpSolver->isProvenOptimal()) {
     12173            bool takeHint;
     12174            OsiHintStrength strength;
     12175            clpSolver->getHintParam(OsiDoDualInResolve, takeHint, strength);
     12176            clpSolver->setHintParam(OsiDoDualInResolve, false, OsiHintDo);
     12177            clpSolver->resolve();
     12178            clpSolver->setHintParam(OsiDoDualInResolve, takeHint, strength);
     12179          }
     12180        }
     12181        // make cuts safer
     12182        for (int iCutGenerator = 0; iCutGenerator < numberCutGenerators_; iCutGenerator++) {
     12183          CglCutGenerator * generator = generator_[iCutGenerator]->generator();
     12184          CglGomory * cgl1 = dynamic_cast<CglGomory *>(generator);
     12185          if (cgl1) {
     12186            cgl1->setLimitAtRoot(cgl1->getLimit());
     12187          }
     12188          CglTwomir * cgl2 = dynamic_cast<CglTwomir *>(generator);
     12189          if (cgl2) {
     12190            generator_[iCutGenerator]->setHowOften(-100);
     12191          }
     12192        }
     12193      }
     12194    }
     12195    clpSolver->setSpecialOptions(save2);
     12196#ifdef CLP_INVESTIGATE
     12197    if (clpSimplex->numberIterations() > 1000)
     12198      printf("node %d took %d iterations\n", numberNodes_, clpSimplex->numberIterations());
     12199#endif
     12200    if (type==0 && clpSolver->isProvenOptimal()) {
     12201      ClpSimplex newModel(*clpSimplex);
     12202      newModel.primal();
     12203      int numberColumns = newModel.numberColumns();
     12204      int numberRows = newModel.numberRows();
     12205      double * obj = new double [numberColumns];
     12206      int * which = new int [numberColumns];
     12207      const double * solution = clpSimplex->primalColumnSolution();
     12208      double rhs=1.0e-8;
     12209      int numberObj=0;
     12210      double integerTolerance = getDblParam(CbcIntegerTolerance) ;
     12211      double * objective = newModel.objective();
     12212      for (int i=0;i<numberColumns;i++) {
     12213        if (objective[i]) {
     12214          rhs += objective[i]*solution[i];
     12215          obj[numberObj]=objective[i];
     12216          which[numberObj++]=i;
     12217          objective[i]=0.0;
     12218        }
     12219      }
     12220      if (numberObj) {
     12221        newModel.addRow(numberObj,which,obj,-COIN_DBL_MAX,rhs);
     12222      }
     12223      delete [] obj;
     12224      delete [] which;
     12225      double * lower = newModel.columnLower();
     12226      double * upper = newModel.columnUpper();
     12227      int numberInf = 0;
     12228      int numberLb = 0;
     12229      int numberUb = 0;
     12230      int numberInt = 0;
     12231      double sumInf=0.0;
     12232      for (int i=0;i<numberIntegers_;i++) {
     12233        int iSequence = integerVariable_[i];
     12234        double value = solution[iSequence];
     12235        value = CoinMax(value, lower[iSequence]);
     12236        value = CoinMin(value, upper[iSequence]);
     12237        double nearest = floor(value + 0.5);
     12238        if (value<lower[iSequence]+integerTolerance) {
     12239          objective[iSequence]=1.0;
     12240          numberLb++;
     12241        } else if (value>upper[iSequence]-integerTolerance) {
     12242          objective[iSequence]=-1.0;
     12243          numberUb++;
     12244        } else if (fabs(value - nearest) <= integerTolerance) {
     12245          // fix??
     12246          lower[iSequence]=nearest;
     12247          upper[iSequence]=nearest;
     12248          numberInt++;
     12249        } else {
     12250          lower[iSequence]=floor(value);
     12251          upper[iSequence]=ceil(value);
     12252          if (value>nearest) {
     12253            objective[iSequence]=1.0;
     12254            sumInf += value-nearest;
     12255          } else {
     12256            objective[iSequence]=-1.0;
     12257            sumInf -= value-nearest;
     12258          }
     12259          numberInf++;
     12260        }
     12261      }
     12262      printf("XX %d inf (sum %g), %d at lb %d at ub %d other integer\n",
     12263             numberInf,sumInf,numberLb,numberUb,numberInt);
     12264      if (numberInf) {
     12265        newModel.primal(1);
     12266        if (!newModel.isProvenOptimal()) {
     12267          printf("not optimal - scaling issue - switch off\n");
     12268          clpSimplex->setSpecialOptions(save);
     12269          if (clpSimplex->status()==4)
     12270            clpSimplex->setProblemStatus(1);
     12271          return clpSolver->isProvenOptimal() ? 1 : 0;
     12272        }
     12273        //newModel.writeMps("bad.mps");
     12274        //assert (newModel.isProvenOptimal());
     12275        printf("%d iterations\n",newModel.numberIterations());
     12276        int numberInf2 = 0;
     12277        int numberLb2 = 0;
     12278        int numberUb2 = 0;
     12279        int numberInt2 = 0;
     12280        double sumInf2=0.0;
     12281        const double * solution = newModel.primalColumnSolution();
     12282        const double * lower = clpSimplex->columnLower();
     12283        const double * upper = clpSimplex->columnUpper();
     12284        for (int i=0;i<numberIntegers_;i++) {
     12285          int iSequence = integerVariable_[i];
     12286          double value = solution[iSequence];
     12287          value = CoinMax(value, lower[iSequence]);
     12288          value = CoinMin(value, upper[iSequence]);
     12289          double nearest = floor(value + 0.5);
     12290          if (value<lower[iSequence]+integerTolerance) {
     12291            numberLb2++;
     12292          } else if (value>upper[iSequence]-integerTolerance) {
     12293            numberUb2++;
     12294          } else if (fabs(value - nearest) <= integerTolerance) {
     12295            numberInt2++;
     12296          } else {
     12297            if (value>nearest) {
     12298              sumInf2 += value-nearest;
     12299            } else {
     12300              sumInf2 -= value-nearest;
     12301            }
     12302            numberInf2++;
     12303          }
     12304        }
     12305        printf("XXX %d inf (sum %g), %d at lb %d at ub %d other integer\n",
     12306               numberInf2,sumInf2,numberLb2,numberUb2,numberInt2);
     12307        if (sumInf2<sumInf*0.95) {
     12308          printf("XXXX suminf reduced from %g (%d) to %g (%d)\n",
     12309                 sumInf,numberInf,sumInf2,numberInf2);
     12310          if (numberObj) {
     12311            newModel.deleteRows(1,&numberRows);
     12312          }
     12313          memcpy(newModel.objective(),
     12314                 clpSimplex->objective(),
     12315                 numberColumns*sizeof(double));
     12316          memcpy(newModel.columnLower(),
     12317                 clpSimplex->columnLower(),
     12318                 numberColumns*sizeof(double));
     12319          memcpy(newModel.columnUpper(),
     12320                 clpSimplex->columnUpper(),
     12321                 numberColumns*sizeof(double));
     12322          newModel.setClpScaledMatrix(NULL);
     12323          newModel.primal(1);
     12324          printf("%d iterations\n",newModel.numberIterations());
     12325          int numberInf3 = 0;
     12326          int numberLb3 = 0;
     12327          int numberUb3 = 0;
     12328          int numberInt3 = 0;
     12329          double sumInf3=0.0;
     12330          const double * solution = newModel.primalColumnSolution();
     12331          const double * lower = clpSimplex->columnLower();
     12332          const double * upper = clpSimplex->columnUpper();
     12333          for (int i=0;i<numberIntegers_;i++) {
     12334            int iSequence = integerVariable_[i];
     12335            double value = solution[iSequence];
     12336            value = CoinMax(value, lower[iSequence]);
     12337            value = CoinMin(value, upper[iSequence]);
     12338            double nearest = floor(value + 0.5);
     12339            if (value<lower[iSequence]+integerTolerance) {
     12340              numberLb3++;
     12341            } else if (value>upper[iSequence]-integerTolerance) {
     12342              numberUb3++;
     12343            } else if (fabs(value - nearest) <= integerTolerance) {
     12344              numberInt3++;
     12345            } else {
     12346              if (value>nearest) {
     12347                sumInf3 += value-nearest;
     12348              } else {
     12349                sumInf3 -= value-nearest;
     12350              }
     12351              numberInf3++;
     12352            }
     12353          }
     12354          printf("XXXXX %d inf (sum %g), %d at lb %d at ub %d other integer\n",
     12355                 numberInf3,sumInf3,numberLb3,numberUb3,numberInt3);
     12356          if (sumInf3<sumInf*0.95) {
     12357            memcpy(clpSimplex->primalColumnSolution(),
     12358                   newModel.primalColumnSolution(),
     12359                   numberColumns*sizeof(double));
     12360            memcpy(clpSimplex->dualColumnSolution(),
     12361                   newModel.dualColumnSolution(),
     12362                   numberColumns*sizeof(double));
     12363            memcpy(clpSimplex->primalRowSolution(),
     12364                   newModel.primalRowSolution(),
     12365                   numberRows*sizeof(double));
     12366            memcpy(clpSimplex->dualRowSolution(),
     12367                   newModel.dualRowSolution(),
     12368                   numberRows*sizeof(double));
     12369            memcpy(clpSimplex->statusArray(),
     12370                   newModel.statusArray(),
     12371                   (numberColumns+numberRows)*sizeof(unsigned char));
     12372            clpSolver->setWarmStart(NULL);
     12373          }
     12374        }
     12375      }
     12376    }
     12377    clpSimplex->setSpecialOptions(save);
     12378    if (clpSimplex->status()==4)
     12379      clpSimplex->setProblemStatus(1);
     12380    return clpSolver->isProvenOptimal() ? 1 : 0;
     12381}
     12382#endif
    1210912383/*!
    1211012384    \todo It'd be really nice if there were an overload for this method that
  • trunk/Cbc/src/CbcModel.hpp

    r1650 r1656  
    1818#include "ClpDualRowPivot.hpp"
    1919
    20 //class OsiSolverInterface;
    2120
    2221class CbcCutGenerator;
     
    3938class CglPreProcess;
    4039# ifdef COIN_HAS_CLP
     40class OsiClpSolverInterface;
    4141class ClpNodeStuff;
    4242#endif
     
    17161716        16 bit (65536) - Original model had integer bounds
    17171717        17 bit (131072) - Perturbation switched off
     1718        18 bit (262144) - donor CbcModel
     1719        19 bit (524288) - recipient CbcModel
    17181720    */
    17191721    inline void setSpecialOptions(int value) {
     
    17371739        65536 no cuts in preprocessing
    17381740        131072 Time limits elapsed
     1741        18 bit (262144) - Perturb fathom nodes
     1742        19 bit (524288) - No limit on fathom nodes
     1743        20 bit (1048576) - Reduce sum of infeasibilities before cuts
     1744        21 bit (2097152) - Reduce sum of infeasibilities after cuts
    17391745    */
    17401746    inline void setMoreSpecialOptions(int value) {
     
    20042010    /// Encapsulates solver resolve
    20052011    int resolve(OsiSolverInterface * solver);
     2012#ifdef CLP_RESOLVE
     2013    /// Special purpose resolve
     2014    int resolveClp(OsiClpSolverInterface * solver, int type);
     2015#endif
    20062016
    20072017    /** Encapsulates choosing a variable -
     
    24572467        18 bit (262144) - Perturb fathom nodes
    24582468        19 bit (524288) - No limit on fathom nodes
     2469        20 bit (1048576) - Reduce sum of infeasibilities before cuts
     2470        21 bit (2097152) - Reduce sum of infeasibilities after cuts
    24592471    */
    24602472    int moreSpecialOptions_;
  • trunk/Cbc/src/CbcSolver.cpp

    r1650 r1656  
    11301130    int numberParameters_ = numberParameters;
    11311131    CbcModel & model_ = model;
     1132#ifdef CBC_USE_INITIAL_TIME
     1133    if (model_.useElapsedTime())
     1134      model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
     1135    else
     1136      model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
     1137#endif
    11321138    CbcModel * babModel_ = NULL;
    11331139    int returnMode = 1;
     
    17531759                numberGoodCommands++;
    17541760                if (type == CBC_PARAM_ACTION_BAB && goodModel) {
     1761#ifndef CBC_USE_INITIAL_TIME
    17551762                  if (model_.useElapsedTime())
    17561763                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay());
    17571764                  else
    17581765                    model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime());
     1766#endif
    17591767                    // check if any integers
    17601768#ifndef CBC_OTHER_SOLVER
     
    20442052                                pumpChanged = true;
    20452053                            else if (parameters_[iParam].type() == CBC_PARAM_INT_EXPERIMENT) {
     2054                                int addFlags=0;
     2055                                if (value>=10) {
     2056                                  addFlags = 1048576*(value/10);
     2057                                  value = value % 10;
     2058                                  parameters[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters, parameters)].setIntValue(value);
     2059                                }
    20462060                                if (value >= 1) {
    20472061                                    int values[]={24003,280003,792003,24003,24003};
     
    20532067                                      parameters_[iParam].setCurrentOption("on");
    20542068                                    }
    2055                                     int extra4 = values[value-1];
     2069                                    int extra4 = values[value-1]+addFlags;
    20562070                                    parameters[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters, parameters)].setIntValue(extra4);
    20572071                                    if (!noPrinting_) {
     
    40024016                            int bothFlags = CoinMax(CoinMin(experimentFlag, 1), strategyFlag);
    40034017                            // add cut generators if wanted
    4004                             int switches[20];
    4005                             int accuracyFlag[20];
     4018                            int switches[30];
     4019                            int accuracyFlag[30];
     4020                            char doAtEnd[30];
     4021                            memset(doAtEnd,0,30);
    40064022                            int numberGenerators = 0;
    40074023                            int translate[] = { -100, -1, -99, -98, 1, -1098, -999, 1, 1, 1, -1};
     
    40784094                                    }
    40794095                                }
    4080                                 int extra3 = parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].intValue();
    4081                                 if (extra3>=100) {
    4082                                   // replace
    4083                                   gomoryGen.passInOriginalSolver(babModel_->solver());
    4084                                   gomoryGen.setGomoryType(2);
    4085                                   extra3 = -1;
    4086                                   parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].setIntValue(extra3);
    4087                                   babModel_->addCutGenerator(&gomoryGen, translate[gomoryAction], "GomoryL");
    4088                                 } else {
     4096                                int laGomory = parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].currentOptionAsInteger();
     4097                                int gType = translate[gomoryAction];
     4098                                if (!laGomory) {
     4099                                  // Normal
    40894100                                  babModel_->addCutGenerator(&gomoryGen, translate[gomoryAction], "Gomory");
    4090                                 }
    4091                                 accuracyFlag[numberGenerators] = 3;
    4092                                 switches[numberGenerators++] = 0;
    4093                                 if (extra3>=10) {
    4094                                   // just root if 10
    4095                                   int itype=-99;
    4096                                   if (extra3>=20) {
    4097                                     extra3-=10;
    4098                                     itype = translate[gomoryAction];
    4099                                   }
    4100                                   gomoryGen.passInOriginalSolver(babModel_->solver());
    4101                                   babModel_->addCutGenerator(&gomoryGen, itype, "GomoryL2");
    41024101                                  accuracyFlag[numberGenerators] = 3;
    41034102                                  switches[numberGenerators++] = 0;
    4104                                   extra3 -= 10;
    4105                                   parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].setIntValue(extra3);
     4103                                } else {
     4104                                  laGomory--;
     4105                                  int type = (laGomory % 3)+1;
     4106                                  int when = laGomory/3;
     4107                                  char atEnd = (when<2) ? 1 : 0;
     4108                                  int gomoryTypeMajor = 0;
     4109                                  if (when<3) {
     4110                                    // normal as well
     4111                                    babModel_->addCutGenerator(&gomoryGen, gType, "Gomory");
     4112                                    accuracyFlag[numberGenerators] = 3;
     4113                                    switches[numberGenerators++] = 0;
     4114                                    if (when==2)
     4115                                      gomoryTypeMajor=10;
     4116                                  } else {
     4117                                    when--; // so on
     4118                                    gomoryTypeMajor=20;
     4119                                  }
     4120                                  if (!when)
     4121                                    gType=-99; // root
     4122                                  gomoryGen.passInOriginalSolver(babModel_->solver());
     4123                                  if ((type&1) !=0) {
     4124                                    // clean
     4125                                    gomoryGen.setGomoryType(gomoryTypeMajor+1);
     4126                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL1");
     4127                                    accuracyFlag[numberGenerators] = 3;
     4128                                    doAtEnd[numberGenerators]=atEnd;
     4129                                    switches[numberGenerators++] = 0;
     4130                                  }
     4131                                  if ((type&2) !=0) {
     4132                                    // simple
     4133                                    gomoryGen.setGomoryType(gomoryTypeMajor+2);
     4134                                    babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL2");
     4135                                    accuracyFlag[numberGenerators] = 3;
     4136                                    doAtEnd[numberGenerators]=atEnd;
     4137                                    switches[numberGenerators++] = 0;
     4138                                  }
    41064139                                }
    41074140                            }
     
    41904223                                //generator->setWhetherToUse(true);
    41914224                                generator->setInaccuracy(accuracyFlag[iGenerator]);
     4225                                if (doAtEnd[iGenerator]) {
     4226                                  generator->setWhetherCallAtEnd(true);
     4227                                  generator->setMustCallAgain(true);
     4228                                }
    41924229                                generator->setTiming(true);
    41934230                                if (cutDepth >= 0)
Note: See TracChangeset for help on using the changeset viewer.