Changeset 202 for trunk


Ignore:
Timestamp:
Oct 31, 2005 9:31:14 AM (14 years ago)
Author:
forrest
Message:

try and improve

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/CbcBranchDynamic.cpp

    r201 r202  
    283283    double minValue = CoinMin(downCost,upCost);
    284284    double maxValue = CoinMax(downCost,upCost);
    285     if (stateOfSearch<=1||model_->currentNode()->depth()<=10) {
     285    if (stateOfSearch<=1||model_->currentNode()->depth()<=10/* was ||maxValue>0.2*distanceToCutoff*/) {
    286286      // no solution
    287287      returnValue = WEIGHT_BEFORE*minValue + (1.0-WEIGHT_BEFORE)*maxValue;
     
    604604  double originalValue=node->objectiveValue();
    605605  int originalUnsatisfied = node->numberUnsatisfied();
    606   double objectiveValue = model->getCurrentMinimizationObjValue();
     606  double objectiveValue = solver->getObjValue()*model->getObjSense();
    607607  int unsatisfied=0;
    608608  int i;
  • trunk/CbcCompareActual.cpp

    r200 r202  
    255255  treeSize_ = model->tree()->size();
    256256  if (treeSize_>10000) {
     257    int n1 = model->solver()->getNumRows()+model->solver()->getNumCols();
     258    int n2 = model->numberObjects();
     259    double size = n1*0.1 + n2*2.0;
    257260    // set weight to reduce size most of time
    258     if (treeSize_>25000)
     261    if (treeSize_*size>5.0e7)
    259262      weight_=-1.0;
    260     else if ((numberNodes1000%4)==0)
     263    else if ((numberNodes1000%4)==0&&treeSize_*size>1.0e6)
    261264      weight_=-1.0;
    262265    else if ((numberNodes1000%4)==1)
  • trunk/CbcCutGenerator.cpp

    r66 r202  
    2222    whenCutGenerator_(-1),
    2323    whenCutGeneratorInSub_(-100),
     24    switchOffIfLessThan_(0),
    2425    depthCutGenerator_(-1),
    2526    depthCutGeneratorInSub_(-1),
     
    4041                                 bool normal, bool atSolution,
    4142                                 bool infeasible, int howOftenInSub,
    42                                  int whatDepth, int whatDepthInSub)
     43                                 int whatDepth, int whatDepthInSub,
     44                                 int switchOffIfLessThan)
    4345  :
    4446    depthCutGenerator_(whatDepth),
     
    5557  whenCutGenerator_=howOften;
    5658  whenCutGeneratorInSub_ = howOftenInSub;
     59  switchOffIfLessThan_=switchOffIfLessThan;
    5760  if (name)
    5861    generatorName_=strdup(name);
     
    7275  whenCutGenerator_=rhs.whenCutGenerator_;
    7376  whenCutGeneratorInSub_ = rhs.whenCutGeneratorInSub_;
     77  switchOffIfLessThan_ = rhs.switchOffIfLessThan_;
    7478  depthCutGenerator_=rhs.depthCutGenerator_;
    7579  depthCutGeneratorInSub_ = rhs.depthCutGeneratorInSub_;
     
    97101    whenCutGenerator_=rhs.whenCutGenerator_;
    98102    whenCutGeneratorInSub_ = rhs.whenCutGeneratorInSub_;
     103    switchOffIfLessThan_ = rhs.switchOffIfLessThan_;
    99104    depthCutGenerator_=rhs.depthCutGenerator_;
    100105    depthCutGeneratorInSub_ = rhs.depthCutGeneratorInSub_;
     
    159164  if (howOften==100)
    160165    doThis=false;
     166  // Switch off if special setting
     167  if (whenCutGeneratorInSub_==-200) {
     168    fullScan=false;
     169    doThis=false;
     170  }
    161171  if (fullScan||doThis) {
    162172    double time1=0.0;
    163173    if (timing_)
    164174      time1 = CoinCpuTime();
     175    int cutsBefore = cs.sizeCuts();
    165176    CglTreeInfo info;
    166177    info.level = depth;
     
    203214    if (timing_)
    204215      timeInCutGenerator_ += CoinCpuTime()-time1;
     216    // switch off if first time and no good
     217    if (node==NULL&&!pass) {
     218      if (cs.sizeCuts()-cutsBefore<switchOffIfLessThan_) {
     219        whenCutGenerator_=-99;
     220        whenCutGeneratorInSub_ = -200;
     221      }
     222    }
    205223  }
    206224  return returnCode;
  • trunk/CbcHeuristic.cpp

    r201 r202  
    9393      model.setMaximumNodes(numberNodes);
    9494      model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
    95       CbcStrategyDefaultSubTree strategy(model_,true,5,5,0);
     95      // Lightweight
     96      CbcStrategyDefaultSubTree strategy(model_,true,5,1,0);
    9697      model.setStrategy(strategy);
    97       // Lightweight
    98       model.setNumberStrong(5);
    99       model.setNumberBeforeTrust(1);
    10098      model.solver()->setIntParam(OsiMaxNumIterationHotStart,10);
    10199      // Do search
  • trunk/CbcHeuristicGreedy.cpp

    r197 r202  
    733733  if (atRoot&&fraction_==1.0) {
    734734    // try quick search
    735     fraction_=0.3;
     735    fraction_=0.4;
    736736    int newCode=this->solution(solutionValue,betterSolution);
    737737    if (newCode)
  • trunk/CbcModel.cpp

    r201 r202  
    424424  findIntegers(false) ;
    425425  // If dynamic pseudo costs then do
    426   if (numberBeforeTrust_>0)
     426  if (numberBeforeTrust_)
    427427    convertToDynamic();
    428428  // Set up char array to say if integer
     
    679679    while (anyAction == -1)
    680680    {
    681       if (numberBeforeTrust_<=0 ) {
     681      if (numberBeforeTrust_==0 ) {
    682682        anyAction = newNode->chooseBranch(this,NULL,numberPassesLeft) ;
    683683      } else {
     
    726726    { bool needValidSolution = (newNode->variable() < 0) ;
    727727      takeOffCuts(cuts,whichGenerator,numberOldActiveCuts,numberNewCuts,
    728                   needValidSolution) ;
     728                  needValidSolution,NULL) ;
    729729#     ifdef CHECK_CUT_COUNTS
    730730      { printf("Number of rows after chooseBranch fix (root)"
     
    10541054          while (anyAction == -1)
    10551055          {
    1056             if (numberBeforeTrust_<=0 ) {
     1056            if (numberBeforeTrust_==0 ) {
    10571057              anyAction = newNode->chooseBranch(this,node,numberPassesLeft) ;
    10581058            } else {
     
    10931093            { bool needValidSolution = (newNode->variable() < 0) ;
    10941094              takeOffCuts(cuts,whichGenerator,numberOldActiveCuts,
    1095                           numberNewCuts,needValidSolution) ;
     1095                          numberNewCuts,needValidSolution,NULL) ;
    10961096#             ifdef CHECK_CUT_COUNTS
    10971097              { printf("Number of rows after chooseBranch fix (node)"
     
    24382438CbcModel::setNumberBeforeTrust(int number)
    24392439{
    2440   if (number<=0) {
     2440  if (number<-1) {
    24412441    numberBeforeTrust_=0;
    24422442  } else {
     
    28392839      onOptimalPath = (debugger->onOptimalPath(*solver_)) ;
    28402840  }
     2841  OsiCuts slackCuts;
    28412842/*
    28422843  Resolve the problem. If we've lost feasibility, might as well bail out right
     
    30953096        }
    30963097      }
     3098      // Add in any violated saved cuts
     3099      if (!theseCuts.sizeRowCuts()&&!theseCuts.sizeColCuts()) {
     3100        int numberCuts = slackCuts.sizeRowCuts() ;
     3101        int i;
     3102        // possibly extend whichGenerator
     3103        whichGenerator = newWhichGenerator(numberViolated, numberViolated+numberCuts,
     3104                                           maximumWhich,  whichGenerator);
     3105        for ( i = 0;i<numberCuts;i++) {
     3106          const OsiRowCut * thisCut = slackCuts.rowCutPtr(i) ;
     3107          if (thisCut->violated(solution)>100.0*primalTolerance) {
     3108            if (messageHandler()->logLevel()>2)
     3109              printf("Old cut added - violation %g\n",
     3110                     thisCut->violated(solution)) ;
     3111            whichGenerator[numberViolated++]=-1;
     3112            theseCuts.insert(*thisCut) ;
     3113          }
     3114        }
     3115      }
    30973116      int numberRowCutsAfter = theseCuts.sizeRowCuts() ;
    30983117      int numberColumnCutsAfter = theseCuts.sizeColCuts() ;
     
    34003419    { int cutIterations = solver_->getIterationCount() ;
    34013420      if (numberOldActiveCuts+numberNewCuts) {
     3421        OsiCuts * saveCuts = node ? NULL : &slackCuts;
    34023422        takeOffCuts(cuts,whichGenerator,numberOldActiveCuts,
    3403                     numberNewCuts,resolveAfterTakeOffCuts_) ;
     3423                    numberNewCuts,resolveAfterTakeOffCuts_,saveCuts) ;
    34043424        if (solver_->isDualObjectiveLimitReached()&&resolveAfterTakeOffCuts_)
    34053425          { feasible = false ;
     
    35313551    for (i = 0;i<numberCutGenerators_;i++) {
    35323552      int howOften = generator_[i]->howOften() ;
    3533       if (thisObjective-startObjective<0.1*fabs(startObjective)+1.0e-5&&howOften==-98)
    3534         howOften=-99; // switch off
     3553      if (howOften==-98) {
     3554        if (thisObjective-startObjective<0.005*fabs(startObjective)+1.0e-5)
     3555          howOften=-99; // switch off
     3556        if (thisObjective-startObjective<0.1*fabs(startObjective)+1.0e-5&&solver_->getNumRows()<500)
     3557          howOften=-99; // switch off
     3558      }
    35353559      if (howOften<-99)
    35363560        continue ;
     
    35523576          } else {
    35533577            howOften = 1+1000000 ;
     3578            if (thisObjective-startObjective<0.1*fabs(startObjective)+1.0e-5)
     3579              generator_[i]->setWhatDepth(5);
    35543580          }
    35553581        }
     
    37153741CbcModel::takeOffCuts (OsiCuts &newCuts, int *whichGenerator,
    37163742                       int &numberOldActiveCuts, int &numberNewCuts,
    3717                        bool allowResolve)
     3743                       bool allowResolve, OsiCuts * saveCuts)
    37183744
    37193745{ // int resolveIterations = 0 ;
     
    37513777          addedCuts_[oldCutIndex]->effectiveness()!=COIN_DBL_MAX)
    37523778      { solverCutIndices[numberOldToDelete++] = i+firstOldCut ;
     3779        if (saveCuts) {
     3780          // send to cut pool
     3781          OsiRowCut * slackCut = addedCuts_[oldCutIndex];
     3782          if (slackCut->effectiveness()!=-1.234) {
     3783            slackCut->setEffectiveness(-1.234);
     3784            saveCuts->insert(*slackCut);
     3785          }
     3786        }
    37533787        if (addedCuts_[oldCutIndex]->decrement() == 0)
    37543788          delete addedCuts_[oldCutIndex] ;
     
    37773811    for (i = numberNewToDelete-1 ; i >= 0 ; i--)
    37783812    { int iCut = newCutIndices[i] ;
     3813      if (saveCuts) {
     3814        // send to cut pool
     3815        OsiRowCut * slackCut = newCuts.rowCutPtr(iCut);
     3816        if (slackCut->effectiveness()!=-1.234) {
     3817          slackCut->setEffectiveness(-1.234);
     3818          saveCuts->insert(*slackCut);
     3819        }
     3820      }
    37793821      newCuts.eraseRowCut(iCut) ; }
    37803822/*
     
    45574599    //solver_->setHintParam(OsiDoScale,saveTakeHint,saveStrength);
    45584600    if (!solver_->isProvenOptimal())
    4559       { printf("checkSolution infeas! Retrying wihout scaling.\n");
     4601      { //printf("checkSolution infeas! Retrying wihout scaling.\n");
    45604602      bool saveTakeHint;
    45614603      OsiHintStrength saveStrength;
  • trunk/CbcNode.cpp

    r201 r202  
    18051805  int kPass=0;
    18061806  int numberColumns = model->getNumCols();
     1807  int numberRows = solver->getNumRows();
    18071808  double * saveUpper = new double[numberColumns];
    18081809  double * saveLower = new double[numberColumns];
     
    18331834  int * whichObject = new int[numberObjects];
    18341835  int * objectMark = new int[2*numberObjects+1];
     1836  // Arrays with movements
     1837  double * upEstimate = new double[numberObjects];
     1838  double * downEstimate = new double[numberObjects];
    18351839  CbcStrongInfo * fixObject = new CbcStrongInfo[numberObjects];
    18361840  double estimatedDegradation=0.0;
     1841  int numberNodes=model->getNodeCount();
    18371842  int numberBeforeTrust = model->numberBeforeTrust();
    18381843  int numberPenalties = model->numberPenalties();
     1844  if (numberBeforeTrust>=1000000) {
     1845    numberBeforeTrust = numberBeforeTrust % 1000000;
     1846    numberPenalties=0;
     1847  } else if (numberBeforeTrust<0) {
     1848    numberPenalties=numberColumns;
     1849    numberBeforeTrust=0;
     1850  }
    18391851  double scaleFactor = model->penaltyScaleFactor();
    18401852  // May go round twice if strong branching fixes all local candidates
     
    18891901      iBestGot=-1;
    18901902      best=0.0;
     1903#define PRINT_STUFF -1
    18911904      for (i=0;i<numberObjects;i++) {
    18921905        CbcObject * object = model->modifiableObject(i);
     
    19141927        }
    19151928        if (infeasibility) {
     1929          if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
     1930            printf("%d down %d %g up %d %g - infeas %g\n",
     1931                   i,numberThisDown,object->downEstimate(),numberThisUp,object->upEstimate(),
     1932                   infeasibility);
    19161933          // Increase estimated degradation to solution
    19171934          estimatedDegradation += CoinMin(object->upEstimate(),object->downEstimate());
     1935          downEstimate[i]=object->downEstimate();
     1936          upEstimate[i]=object->upEstimate();
    19181937          numberUnsatisfied_++;
    19191938          // Better priority? Flush choices.
     
    19511970          }
    19521971          whichObject[numberToDo++]=i;
     1972        } else {
     1973          // for debug
     1974          downEstimate[i]=-1.0;
     1975          upEstimate[i]=-1.0;
    19531976        }
    19541977      }
     
    20092032    if (!numberUnsatisfied_)
    20102033      break;
     2034    bool skipAll = (numberBeforeTrust>20&&numberNodes>20000&&numberNotTrusted==0);
     2035    if ((numberNodes%20)==0)
     2036      skipAll=false;
    20112037    // worth trying if too many times
    20122038    // Save basis
    2013     CoinWarmStart * ws = solver->getWarmStart();
     2039    CoinWarmStart * ws = NULL;
    20142040    // save limit
    2015     int saveLimit;
    2016     solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
    2017     if (!stateOfSearch&&saveLimit<100)
    2018       solver->setIntParam(OsiMaxNumIterationHotStart,100);
    2019    
     2041    int saveLimit=0;
     2042    if (!skipAll) {
     2043      ws = solver->getWarmStart();
     2044      solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
     2045      if (!stateOfSearch&&saveLimit<100)
     2046        solver->setIntParam(OsiMaxNumIterationHotStart,100);
     2047    }
    20202048    // Say which one will be best
    20212049    int whichChoice=0;
     
    20432071      // say do fast
    20442072      int easy=1;
    2045       solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
     2073      if (!skipAll)
     2074        solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
    20462075      if (numberDown)
    20472076        averageDown /= (double) numberDown;
     
    20702099#ifdef RANGING
    20712100      OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
     2101      if (skipAll&&numberBeforeTrust)
     2102        numberPenalties=0;
    20722103      if (osiclp&&numberPenalties) {
    20732104        // just get those not touched and best and not trusted
     
    21052136        // Bug - so switch off for now
    21062137        double distanceToCutoff=COIN_DBL_MAX;
     2138        //printf("numberTodo %d needed %d numberpenalties %d\n",numberToDo,needed,numberPenalties);
    21072139        for ( i=0;i<numberToDo;i++) {
    21082140          int iObject = whichObject[i];
     
    21172149            double value = saveSolution[iSequence];
    21182150            value -= floor(value);
    2119             double upPenalty = upCost[i]*(1.0-value);
    2120             double downPenalty = downCost[i]*value;
     2151            double upPenalty = CoinMin(upCost[i],1.0e110)*(1.0-value);
     2152            double downPenalty = CoinMin(downCost[i],1.0e110)*value;
     2153            if (!numberBeforeTrust) {
     2154              // override
     2155              downEstimate[iObject]=downPenalty;
     2156              upEstimate[iObject]=upPenalty;
     2157            }
     2158            if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
     2159              printf("%d pen down ps %g -> %g up ps %g -> %g\n",
     2160                     iObject,downCost[i],downPenalty,upCost[i],upPenalty);
    21212161            if (upPenalty>distanceToCutoff) {
    21222162              if(downPenalty>distanceToCutoff) {
     
    21762216        numberToDo=put;
    21772217      } else {
    2178         // Mark hot start
    2179         solver->markHotStart();
    2180         if (solver->isProvenPrimalInfeasible())
    2181           printf("**** Hot start says node infeasible\n");
     2218        if (!skipAll) {
     2219          // Mark hot start
     2220          solver->markHotStart();
     2221          if (solver->isProvenPrimalInfeasible())
     2222            printf("**** Hot start says node infeasible\n");
     2223        }
    21822224        // make sure best will be first
    21832225        if (iBestGot>=0)
    2184           sort[iBestGot]=-COIN_DBL_MAX;
     2226          sort[iBestGot]=-1.0e120;
    21852227      }
    21862228#else
     
    22052247      int saveLimit2;
    22062248      solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit2);
    2207       bool doQuickly = numberToDo>2*numberStrong;
     2249      bool doQuickly = false; // numberToDo>2*numberStrong;
    22082250      //printf("todo %d, strong %d\n",numberToDo,numberStrong);
    22092251      int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
     2252      int numberTest2 = CoinMax(2*numberStrong,10)+1000000;
     2253#if 0
     2254      if (numberBeforeTrust>20&&(numberNodes>20000||(numberNodes>200&&numberNotTrusted==0))) {
     2255        if ((numberNodes%20)!=0) {
     2256          numberTest=0;
     2257          doQuickly=true;
     2258        }
     2259      }
     2260#else
     2261      // Try nearly always off
     2262      if ((numberNodes%20)!=0) {
     2263        numberTest=0;
     2264        doQuickly=true;
     2265      } else {
     2266        doQuickly=true;
     2267        numberTest=2*numberStrong;
     2268      }
     2269#endif
     2270      // if too many and big then just do 10 its
     2271      if (!skipAll&&stateOfSearch) {
     2272        if (numberNotTrusted>3*numberStrong&&numberRows>250&&numberColumns>1000)
     2273          solver->setIntParam(OsiMaxNumIterationHotStart,10);
     2274      }
     2275      double distanceToCutoff=model->getCutoff()-objectiveValue_;
     2276      // larger and make negative for test
     2277      distanceToCutoff *= -100.0;
     2278      if (skipAll)
     2279        distanceToCutoff = -COIN_DBL_MAX;
    22102280      for ( iDo=0;iDo<numberToDo;iDo++) {
    22112281        CbcStrongInfo choice;
     
    22142284        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    22152285          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     2286        int iColumn = dynamicObject->columnNumber();
    22162287        int preferredWay;
    22172288        object->infeasibility(preferredWay);
     
    22212292        choice.numIntInfeasUp = numberUnsatisfied_;
    22222293        choice.numIntInfeasDown = numberUnsatisfied_;
     2294        choice.upMovement = upEstimate[iObject];
     2295        choice.downMovement = downEstimate[iObject];
     2296        assert (choice.upMovement>=0.0);
     2297        assert (choice.downMovement>=0.0);
    22232298        choice.fix=0; // say not fixed
    22242299        // see if can skip strong branching
    22252300        int canSkip = choice.possibleBranch->fillStrongInfo(choice);
    2226         if (!doQuickly||numberTest)
     2301        if (!doQuickly||numberTest>0)
    22272302          canSkip=0;
    2228         if (model->messageHandler()->logLevel()>3)
     2303        if (!numberBeforeTrust) {
     2304          choice.upMovement = upEstimate[iObject];
     2305          choice.downMovement = downEstimate[iObject];
     2306          canSkip=1;
     2307        }
     2308        if (sort[iDo]<distanceToCutoff)
     2309          canSkip=0;
     2310        if (numberTest2<=0&&sort[iDo]>distanceToCutoff)
     2311          canSkip=1; // always skip
     2312        if (model->messageHandler()->logLevel()>3&&numberBeforeTrust)
    22292313          dynamicObject->print(1,choice.possibleBranch->value());
    22302314        // was if (!canSkip)
    22312315        if (!canSkip) {
    22322316          numberTest--;
     2317          numberTest2--;
    22332318          // just do a few
    22342319          if (canSkip)
     
    23862471            choice.downMovement = CoinMax(0.0,choice.downMovement);
    23872472            // feasible - see which best
    2388             int iColumn =
    2389               model->integerVariable()[choice.possibleBranch->variable()] ;
    23902473            model->messageHandler()->message(CBC_STRONG,model->messages())
    23912474              << iObject << iColumn
     
    24532536              choice.fix=1;
    24542537              fixObject[numberToFix++]=choice;
     2538#define FIXNOW
     2539#ifdef FIXNOW
     2540              double value = ceil(saveSolution[iColumn]);
     2541              saveLower[iColumn]=value;
     2542              solver->setColLower(iColumn,value);
     2543#endif
    24552544            }
    24562545          }
     
    24712560              choice.fix=-1;
    24722561              fixObject[numberToFix++]=choice;
     2562#ifdef FIXNOW
     2563              double value = floor(saveSolution[iColumn]);
     2564              saveUpper[iColumn]=value;
     2565              solver->setColUpper(iColumn,value);
     2566#endif
    24732567            }
    24742568          } else {
     
    24972591          }
    24982592          numberTest=0;
     2593          distanceToCutoff=-COIN_DBL_MAX;
    24992594        }
    25002595      }
     
    25032598          printf("infeasible\n");
    25042599        else if(anyAction==-1)
    2505           printf("%d fixed\n",numberToFix);
     2600          if (!solveAll)
     2601            printf("%d fixed\n",numberToFix);
     2602          else
     2603            printf("%d fixed AND choosing %d iDo %d iChosenWhen %d numberToDo %d\n",numberToFix,bestChoice,
     2604                   iDo,whichChoice,numberToDo);
    25062605        else
    25072606          printf("choosing %d iDo %d iChosenWhen %d numberToDo %d\n",bestChoice,
    25082607                 iDo,whichChoice,numberToDo);
    25092608      }
    2510       // Delete the snapshot
    2511       solver->unmarkHotStart();
    2512       // back to normal
    2513       solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
    2514       solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
    2515       // restore basis
    2516       solver->setWarmStart(ws);
     2609      if (!skipAll) {
     2610        // Delete the snapshot
     2611        solver->unmarkHotStart();
     2612        // back to normal
     2613        solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
     2614        solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
     2615        // restore basis
     2616        solver->setWarmStart(ws);
     2617      }
    25172618      // Unless infeasible we will carry on
    25182619      // But we could fix anyway
     
    25262627          // apply and take off
    25272628          for (i = 0 ; i < numberToFix ; i++) {
     2629#ifndef FIXNOW
    25282630            fixObject[i].possibleBranch->way(fixObject[i].fix) ;
    25292631            fixObject[i].possibleBranch->branch() ;
     2632#endif
    25302633            delete fixObject[i].possibleBranch;
    25312634          }
     
    25922695  delete [] saveLower;
    25932696  delete [] saveUpper;
     2697  delete [] upEstimate;
     2698  delete [] downEstimate;
    25942699 
    25952700  // restore solution
  • trunk/Test/CoinSolve.cpp

    r199 r202  
    100100int mainTest (int argc, const char *argv[],int algorithm,
    101101              ClpSimplex empty, bool doPresolve,int doIdiot);
    102 // Returns next valid field
    103102int CbcOrClpRead_mode=1;
    104103FILE * CbcOrClpReadCommand=stdin;
    105 static int * analyze(OsiClpSolverInterface * solver, int & numberChanged)
     104static int * analyze(OsiClpSolverInterface * solverMod, int & numberChanged, double & increment,
     105                     bool changeInt)
    106106{
    107   //const double *objective = solver->getObjCoefficients() ;
     107  OsiSolverInterface * solver = solverMod->clone();
     108  {
     109    // just get increment
     110    CbcModel model(*solver);
     111    model.analyzeObjective();
     112    double increment2=model.getCutoffIncrement();
     113    printf("initial cutoff increment %g\n",increment2);
     114  }
     115  const double *objective = solver->getObjCoefficients() ;
    108116  const double *lower = solver->getColLower() ;
    109117  const double *upper = solver->getColUpper() ;
    110118  int numberColumns = solver->getNumCols() ;
    111119  int numberRows = solver->getNumRows();
    112   //double direction = solver->getObjSense();
     120  double direction = solver->getObjSense();
    113121  int iRow,iColumn;
    114122
     
    122130  // Column copy
    123131  CoinPackedMatrix  matrixByCol(*solver->getMatrixByCol());
    124   //const double * element = matrixByCol.getElements();
     132  const double * element = matrixByCol.getElements();
    125133  const int * row = matrixByCol.getIndices();
    126134  const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
     
    132140  char * ignore = new char [numberRows];
    133141  int * changed = new int[numberColumns];
     142  int * which = new int[numberRows];
     143  double * changeRhs = new double[numberRows];
     144  memset(changeRhs,0,numberRows*sizeof(double));
    134145  memset(ignore,0,numberRows);
    135146  numberChanged=0;
     
    139150      numberInteger++;
    140151  }
    141   for (iRow=0;iRow<numberRows;iRow++) {
    142     int numberContinuous=0;
    143     double value1=0.0,value2=0.0;
    144     bool allIntegerCoeff=true;
    145     double sumFixed=0.0;
    146     int jColumn1=-1,jColumn2=-1;
    147     for (CoinBigIndex j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
    148       int jColumn = column[j];
    149       double value = elementByRow[j];
    150       if (upper[jColumn] > lower[jColumn]+1.0e-8) {
    151         if (!solver->isInteger(jColumn)) {
    152           if (numberContinuous==0) {
    153             jColumn1=jColumn;
    154             value1=value;
     152  bool finished=false;
     153  while (!finished) {
     154    int saveNumberChanged = numberChanged;
     155    for (iRow=0;iRow<numberRows;iRow++) {
     156      int numberContinuous=0;
     157      double value1=0.0,value2=0.0;
     158      bool allIntegerCoeff=true;
     159      double sumFixed=0.0;
     160      int jColumn1=-1,jColumn2=-1;
     161      for (CoinBigIndex j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
     162        int jColumn = column[j];
     163        double value = elementByRow[j];
     164        if (upper[jColumn] > lower[jColumn]+1.0e-8) {
     165          if (!solver->isInteger(jColumn)) {
     166            if (numberContinuous==0) {
     167              jColumn1=jColumn;
     168              value1=value;
     169            } else {
     170              jColumn2=jColumn;
     171              value2=value;
     172            }
     173            numberContinuous++;
    155174          } else {
    156             jColumn2=jColumn;
    157             value2=value;
     175            if (fabs(value-floor(value+0.5))>1.0e-12)
     176              allIntegerCoeff=false;
    158177          }
    159           numberContinuous++;
    160178        } else {
    161           if (fabs(value-floor(value+0.5))>1.0e-12)
    162             allIntegerCoeff=false;
     179          sumFixed += lower[jColumn]*value;
    163180        }
    164       } else {
    165         sumFixed += lower[jColumn]*value;
    166181      }
    167     }
    168     double low = rowLower[iRow];
    169     if (low>-1.0e20) {
    170       low -= sumFixed;
    171       if (fabs(low-floor(low+0.5))>1.0e-12)
    172         allIntegerCoeff=false;
    173     }
    174     double up = rowUpper[iRow];
    175     if (up<1.0e20) {
    176       up -= sumFixed;
    177       if (fabs(up-floor(up+0.5))>1.0e-12)
    178         allIntegerCoeff=false;
    179     }
    180     if (numberContinuous==1) {
    181       // see if really integer
    182       // This does not allow for complicated cases
    183       if (low==up) {
    184         if (fabs(value1)>1.0e-3) {
    185           value1 = 1.0/value1;
    186           if (fabs(value1-floor(value1+0.5))<1.0e-12) {
    187             // integer
    188             changed[numberChanged++]=jColumn1;
    189             solver->setInteger(jColumn1);
    190             if (upper[jColumn1]>1.0e20)
    191               solver->setColUpper(jColumn1,1.0e20);
    192             if (lower[jColumn1]<-1.0e20)
    193               solver->setColLower(jColumn1,-1.0e20);
     182      double low = rowLower[iRow];
     183      if (low>-1.0e20) {
     184        low -= sumFixed;
     185        if (fabs(low-floor(low+0.5))>1.0e-12)
     186          allIntegerCoeff=false;
     187      }
     188      double up = rowUpper[iRow];
     189      if (up<1.0e20) {
     190        up -= sumFixed;
     191        if (fabs(up-floor(up+0.5))>1.0e-12)
     192          allIntegerCoeff=false;
     193      }
     194      if (numberContinuous==1) {
     195        // see if really integer
     196        // This does not allow for complicated cases
     197        if (low==up) {
     198          if (fabs(value1)>1.0e-3) {
     199            value1 = 1.0/value1;
     200            if (fabs(value1-floor(value1+0.5))<1.0e-12) {
     201              // integer
     202              changed[numberChanged++]=jColumn1;
     203              solver->setInteger(jColumn1);
     204              if (upper[jColumn1]>1.0e20)
     205                solver->setColUpper(jColumn1,1.0e20);
     206              if (lower[jColumn1]<-1.0e20)
     207                solver->setColLower(jColumn1,-1.0e20);
     208            }
     209          }
     210        } else {
     211          if (fabs(value1)>1.0e-3) {
     212            value1 = 1.0/value1;
     213            if (fabs(value1-floor(value1+0.5))<1.0e-12) {
     214              // This constraint will not stop it being integer
     215              ignore[iRow]=1;
     216            }
    194217          }
    195218        }
    196       } else {
    197         if (fabs(value1)>1.0e-3) {
    198           value1 = 1.0/value1;
    199           if (fabs(value1-floor(value1+0.5))<1.0e-12) {
    200             // This constraint will not stop it being integer
    201             ignore[iRow]=1;
     219      } else if (numberContinuous==2) {
     220        if (low==up) {
     221          /* need general theory - for now just look at 2 cases -
     222             1 - +- 1 one in column and just costs i.e. matching objective
     223             2 - +- 1 two in column but feeds into G/L row which will try and minimize
     224          */
     225          if (fabs(value1)==1.0&&value1*value2==-1.0&&!lower[jColumn1]
     226              &&!lower[jColumn2]) {
     227            int n=0;
     228            int i;
     229            double objChange=direction*(objective[jColumn1]+objective[jColumn2]);
     230            double bound = CoinMin(upper[jColumn1],upper[jColumn2]);
     231            bound = CoinMin(bound,1.0e20);
     232            for ( i=columnStart[jColumn1];i<columnStart[jColumn1]+columnLength[jColumn1];i++) {
     233              int jRow = row[i];
     234              double value = element[i];
     235              if (jRow!=iRow) {
     236                which[n++]=jRow;
     237                changeRhs[jRow]=value;
     238              }
     239            }
     240            for ( i=columnStart[jColumn1];i<columnStart[jColumn1]+columnLength[jColumn1];i++) {
     241              int jRow = row[i];
     242              double value = element[i];
     243              if (jRow!=iRow) {
     244                if (!changeRhs[jRow]) {
     245                  which[n++]=jRow;
     246                  changeRhs[jRow]=value;
     247                } else {
     248                  changeRhs[jRow]+=value;
     249                }
     250              }
     251            }
     252            if (objChange>=0.0) {
     253              // see if all rows OK
     254              bool good=true;
     255              for (i=0;i<n;i++) {
     256                int jRow = which[i];
     257                double value = changeRhs[jRow];
     258                if (value) {
     259                  value *= bound;
     260                  if (rowLength[jRow]==1) {
     261                    if (value>0.0) {
     262                      double rhs = rowLower[jRow];
     263                      if (rhs>0.0) {
     264                        double ratio =rhs/value;
     265                        if (fabs(ratio-floor(ratio+0.5))>1.0e-12)
     266                          good=false;
     267                      }
     268                    } else {
     269                      double rhs = rowUpper[jRow];
     270                      if (rhs<0.0) {
     271                        double ratio =rhs/value;
     272                        if (fabs(ratio-floor(ratio+0.5))>1.0e-12)
     273                          good=false;
     274                      }
     275                    }
     276                  } else if (rowLength[jRow]==2) {
     277                    if (value>0.0) {
     278                      if (rowLower[jRow]>-1.0e20)
     279                        good=false;
     280                    } else {
     281                      if (rowUpper[jRow]<1.0e20)
     282                        good=false;
     283                    }
     284                  } else {
     285                    good=false;
     286                  }
     287                }
     288              }
     289              if (good) {
     290                // both can be integer
     291                changed[numberChanged++]=jColumn1;
     292                solver->setInteger(jColumn1);
     293                if (upper[jColumn1]>1.0e20)
     294                  solver->setColUpper(jColumn1,1.0e20);
     295                if (lower[jColumn1]<-1.0e20)
     296                  solver->setColLower(jColumn1,-1.0e20);
     297                changed[numberChanged++]=jColumn2;
     298                solver->setInteger(jColumn2);
     299                if (upper[jColumn2]>1.0e20)
     300                  solver->setColUpper(jColumn2,1.0e20);
     301                if (lower[jColumn2]<-1.0e20)
     302                  solver->setColLower(jColumn2,-1.0e20);
     303              }
     304            }
     305            // clear
     306            for (i=0;i<n;i++) {
     307              changeRhs[which[i]]=0.0;
     308            }
    202309          }
    203310        }
    204311      }
    205     } else if (numberContinuous==2) {
    206       if (low==up) {
     312    }
     313    for (iColumn=0;iColumn<numberColumns;iColumn++) {
     314      if (upper[iColumn] > lower[iColumn]+1.0e-8&&!solver->isInteger(iColumn)) {
     315        double value;
     316        value = upper[iColumn];
     317        if (value<1.0e20&&fabs(value-floor(value+0.5))>1.0e-12)
     318          continue;
     319        value = lower[iColumn];
     320        if (value>-1.0e20&&fabs(value-floor(value+0.5))>1.0e-12)
     321          continue;
     322        bool integer=true;
     323        for (CoinBigIndex j=columnStart[iColumn];j<columnStart[iColumn]+columnLength[iColumn];j++) {
     324          int iRow = row[j];
     325          if (!ignore[iRow]) {
     326            integer=false;
     327            break;
     328          }
     329        }
     330        if (integer) {
     331          // integer
     332          changed[numberChanged++]=iColumn;
     333          solver->setInteger(iColumn);
     334          if (upper[iColumn]>1.0e20)
     335            solver->setColUpper(iColumn,1.0e20);
     336          if (lower[iColumn]<-1.0e20)
     337            solver->setColLower(iColumn,-1.0e20);
     338        }
    207339      }
    208340    }
     341    finished = numberChanged==saveNumberChanged;
    209342  }
    210   for (iColumn=0;iColumn<numberColumns;iColumn++) {
    211     if (upper[iColumn] > lower[iColumn]+1.0e-8&&!solver->isInteger(iColumn)) {
    212       double value;
    213       value = upper[iColumn];
    214       if (value<1.0e20&&fabs(value-floor(value+0.5))>1.0e-12)
    215         continue;
    216       value = lower[iColumn];
    217       if (value>-1.0e20&&fabs(value-floor(value+0.5))>1.0e-12)
    218         continue;
    219       bool integer=true;
    220       for (CoinBigIndex j=columnStart[iColumn];j<columnStart[iColumn]+columnLength[iColumn];j++) {
    221         int iRow = row[j];
    222         if (!ignore[iRow]) {
    223           integer=false;
    224           break;
    225         }
    226       }
    227       if (integer) {
    228         // integer
    229         changed[numberChanged++]=iColumn;
    230         solver->setInteger(iColumn);
    231         if (upper[iColumn]>1.0e20)
    232           solver->setColUpper(iColumn,1.0e20);
    233         if (lower[iColumn]<-1.0e20)
    234           solver->setColLower(iColumn,-1.0e20);
    235       }
    236     }
    237   }
     343  delete [] which;
     344  delete [] changeRhs;
    238345  if (numberInteger)
    239346    printf("%d integer variables",numberInteger);
    240   if (numberChanged)
    241     printf(" and %d variables made integer\n",numberChanged);
    242   else
    243     printf("\n");
    244   delete [] ignore;
    245   if (!numberChanged) {
    246     delete [] changed;
     347  if (changeInt) {
     348    if (numberChanged)
     349      printf(" and %d variables made integer\n",numberChanged);
     350    else
     351      printf("\n");
     352    delete [] ignore;
     353    //increment=0.0;
     354    if (!numberChanged) {
     355      delete [] changed;
     356      delete solver;
     357      return NULL;
     358    } else {
     359      for (iColumn=0;iColumn<numberColumns;iColumn++) {
     360        if (solver->isInteger(iColumn))
     361          solverMod->setInteger(iColumn);
     362      }
     363      delete solver;
     364      return changed;
     365    }
     366  } else {
     367    if (numberChanged)
     368      printf(" and %d variables could be made integer\n",numberChanged);
     369    else
     370      printf("\n");
     371    // just get increment
     372    CbcModel model(*solver);
     373    model.analyzeObjective();
     374    double increment2=model.getCutoffIncrement();
     375    if (increment2>increment) {
     376      printf("cutoff increment increased from %g to %g\n",increment,increment2);
     377      increment=increment2;
     378    }
     379    delete solver;
     380    numberChanged=0;
    247381    return NULL;
    248   } else {
    249     return changed;
    250382  }
    251383}
     
    265397    CbcModel model(solver1);
    266398    CbcModel * babModel = NULL;
    267     model.setNumberBeforeTrust(5);
     399    model.setNumberBeforeTrust(21);
    268400    int cutPass=-1234567;
    269401    OsiSolverInterface * solver = model.solver();
     
    345477    parameters[whichParam(NUMBERBEFORE,numberParameters,parameters)].setIntValue(5);
    346478    parameters[whichParam(MAXNODES,numberParameters,parameters)].setIntValue(model.getMaximumNodes());
    347     model.setNumberStrong(10);
     479    model.setNumberStrong(5);
    348480    parameters[whichParam(STRONGBRANCHING,numberParameters,parameters)].setIntValue(model.numberStrong());
    349481    parameters[whichParam(INFEASIBILITYWEIGHT,numberParameters,parameters)].setDoubleValue(model.getDblParam(CbcModel::CbcInfeasibilityWeight));
     
    411543    CglTwomir twomirGen;
    412544    // set default action (0=off,1=on,2=root)
    413     int twomirAction=2;
    414     parameters[whichParam(TWOMIRCUTS,numberParameters,parameters)].setCurrentOption("root");
     545    int twomirAction=3;
     546    parameters[whichParam(TWOMIRCUTS,numberParameters,parameters)].setCurrentOption("ifmove");
    415547
    416548    bool useRounding=true;
     
    10601192*/
    10611193          case BAB: // branchAndBound
     1194          case STRENGTHEN:
    10621195            if (goodModel) {
    10631196              // If user made settings then use them
     
    11161249              babModel = new CbcModel(model);
    11171250              OsiSolverInterface * solver3 = clpSolver->clone();
     1251              if (defaultSettings) {
     1252                OsiClpSolverInterface * si =
     1253                  dynamic_cast<OsiClpSolverInterface *>(solver3) ;
     1254                assert (si != NULL);
     1255                // get clp itself
     1256                ClpSimplex * modelC = si->getModelPtr();
     1257                if (modelC->tightenPrimalBounds()!=0) {
     1258                  std::cout<<"Problem is infeasible!"<<std::endl;
     1259                  break;
     1260                }
     1261              }
    11181262              babModel->assignSolver(solver3);
    11191263              OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
    11201264              int numberChanged=0;
    1121               int * changed = analyze( clpSolver2,numberChanged);
    11221265              if (clpSolver2->messageHandler()->logLevel())
    11231266                clpSolver2->messageHandler()->setLogLevel(1);
     
    11491292              time1 = time2;
    11501293              double timeLeft = babModel->getMaximumSeconds();
    1151               if (preProcess) {
     1294              if (preProcess&&type==BAB) {
    11521295                saveSolver=babModel->solver()->clone();
    11531296                /* Do not try and produce equality cliques and
     
    12551398              for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
    12561399                CbcCutGenerator * generator = babModel->cutGenerator(iGenerator);
     1400                if (generator->howOften()<=-98)
     1401                  generator->setSwitchOffIfLessThan(1);
    12571402                generator->setTiming(true);
    12581403                if (cutDepth>=0)
     
    12931438                osiclp->setupForRepeatedUse(0,0);
    12941439              }
     1440              double increment=babModel->getCutoffIncrement();;
     1441              int * changed = analyze( osiclp,numberChanged,increment,false);
     1442              babModel->setCutoffIncrement(CoinMax(babModel->getCutoffIncrement(),increment));
    12951443              // Turn this off if you get problems
    12961444              // Used to be automatically set
     
    13041452                          << value2 << std::endl ;
    13051453              }
     1454              // probably faster to use a basis to get integer solutions
     1455              babModel->setSpecialOptions(2);
    13061456              currentBranchModel = babModel;
    1307               babModel->branchAndBound();
     1457              OsiSolverInterface * strengthenedModel=NULL;
     1458              if (type==BAB) {
     1459                babModel->branchAndBound();
     1460              } else {
     1461                strengthenedModel = babModel->strengthenedModel();
     1462              }
    13081463              currentBranchModel = NULL;
    13091464              osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
     
    13321487              time2 = CoinCpuTime();
    13331488              totalTime += time2-time1;
    1334               if (babModel->getMinimizationObjValue()<1.0e50) {
     1489              if (babModel->getMinimizationObjValue()<1.0e50&&type==BAB) {
    13351490                // post process
    13361491                if (preProcess) {
     
    13401495                }
    13411496              }
    1342               // clpSolver still OK clpSolver = dynamic_cast< OsiClpSolverInterface*> (babModel->solver());
     1497              if (type==STRENGTHEN&&strengthenedModel)
     1498                clpSolver = dynamic_cast< OsiClpSolverInterface*> (strengthenedModel);
    13431499              lpSolver = clpSolver->getModelPtr();
    1344               if (babModel->bestSolution()){
    1345                 //move best solution (should be there -- but ..)
    1346                 int n = lpSolver->getNumCols();
    1347                 memcpy(lpSolver->primalColumnSolution(),babModel->bestSolution(),n*sizeof(double));
    1348               }
    13491500              if (debugFile=="create"&&babModel->bestSolution()) {
    13501501                saveSolution(lpSolver,"debug.file");
     
    13571508                delete [] changed;
    13581509              }
    1359               std::string statusName[]={"Finished","Stopped on ","Difficulties",
    1360                                         "","","User ctrl-c"};
    1361               std::string minor[]={"","","gap","nodes","time","","solutions"};
    1362               int iStat = babModel->status();
    1363               int iStat2 = babModel->secondaryStatus();
    1364               std::cout<<"Result - "<<statusName[iStat]<<minor[iStat2]
    1365                        <<" objective "<<babModel->getObjValue()<<
    1366                 " after "<<babModel->getNodeCount()<<" nodes and "
    1367                 <<babModel->getIterationCount()<<
    1368                 " iterations - took "<<time2-time1<<" seconds"<<std::endl;
     1510              if (type==BAB) {
     1511                std::string statusName[]={"Finished","Stopped on ","Difficulties",
     1512                                          "","","User ctrl-c"};
     1513                std::string minor[]={"","","gap","nodes","time","","solutions"};
     1514                int iStat = babModel->status();
     1515                int iStat2 = babModel->secondaryStatus();
     1516                std::cout<<"Result - "<<statusName[iStat]<<minor[iStat2]
     1517                         <<" objective "<<babModel->getObjValue()<<
     1518                  " after "<<babModel->getNodeCount()<<" nodes and "
     1519                         <<babModel->getIterationCount()<<
     1520                  " iterations - took "<<time2-time1<<" seconds"<<std::endl;
     1521              } else {
     1522                std::cout<<"Model strengthend - now has "<<clpSolver->getNumRows()
     1523                         <<" rows"<<std::endl;
     1524              }
    13691525              time1 = time2;
    13701526              delete babModel;
  • trunk/include/CbcCutGenerator.hpp

    r66 r202  
    7878                  bool normal=true, bool atSolution=false,
    7979                  bool infeasible=false,int howOftenInsub=-100,
    80                   int whatDepth=-1, int whatDepthInSub=-1);
     80                  int whatDepth=-1, int whatDepthInSub=-1,int switchOffIfLessThan=0);
    8181 
    8282  /// Copy constructor
     
    201201  void incrementNumberCutsActive(int value=1)
    202202  { numberCutsActive_ += value;};
     203  inline void setSwitchOffIfLessThan(int value)
     204  { switchOffIfLessThan_ = value;};
     205  inline int switchOffIfLessThan() const
     206  { return switchOffIfLessThan_;};
    203207  //@}
    204208 
     
    218222  */
    219223  int whenCutGeneratorInSub_;
     224  /** If first pass at root produces fewer than this cuts then switch off
     225   */
     226  int switchOffIfLessThan_;
    220227
    221228  /** Depth at which to call the CglCutGenerator::generateCuts
  • trunk/include/CbcModel.hpp

    r197 r202  
    11021102    will not be required, set allowResolve to false to suppress
    11031103    reoptimisation.
     1104    If saveCuts then slack cuts will be saved
    11041105  */
    11051106  void takeOffCuts(OsiCuts &cuts, int *whichGenerator,
    11061107                     int &numberOldActiveCuts, int &numberNewCuts,
    1107                      bool allowResolve) ;
     1108                     bool allowResolve,OsiCuts * saveCuts) ;
    11081109
    11091110  /** Determine and install the active cuts that need to be added for
Note: See TracChangeset for help on using the changeset viewer.