Changeset 1167


Ignore:
Timestamp:
May 23, 2009 3:48:43 AM (11 years ago)
Author:
forrest
Message:

clean up CbcModel? a bit

Location:
trunk/Cbc/src
Files:
3 edited

Legend:

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

    r1165 r1167  
    383383
    384384
    385 static double trueIncrement=0.0;
    386385void
    387386CbcModel::analyzeObjective ()
     
    899898*/
    900899  double maximumCost = 0.0 ;
    901   trueIncrement=0.0;
     900  //double trueIncrement=0.0;
    902901  bool possibleMultiple = continuousMultiplier!=0.0 ;
    903902  int iColumn ;
     
    969968        }
    970969        value /= multiplier ;
    971         trueIncrement=CoinMax(cutoff,value);;
     970        //trueIncrement=CoinMax(cutoff,value);;
    972971        if (value*0.999 > cutoff)
    973972        { messageHandler()->message(CBC_INTEGERINCREMENT,
     
    10571056  OsiObject ** originalObject = NULL;
    10581057  // Set up strategies
    1059 #if 0
    1060   std::string problemName ;
    1061   solver_->getStrParam(OsiProbName,problemName) ;
    1062   if (!strcmp(problemName.c_str(),"EGOUT")) solver_->activateRowCutDebugger(problemName.c_str()) ;
    1063 #endif
    10641058  if (strategy_) {
    10651059    // May do preprocessing
     
    12381232    dupcuts.setMode(2);
    12391233    CglStored * storedCuts = dupcuts.outDuplicates(solver_);
    1240     addCutGenerator(storedCuts,1,"StoredCuts from dominated");
     1234    if (storedCuts) {
     1235      printf("adding dup cuts\n");
     1236      addCutGenerator(storedCuts,1,"StoredCuts from dominated",
     1237                      true,false,false,-200);
     1238    }
    12411239  }
    12421240  if (!nodeCompare_)
     
    81788176    }
    81798177  }
     8178#if 0
    81808179  if (cutModifier_&&feasible&&!solverCharacteristics_->solutionAddsCuts()) {
    81818180    //double increment = getDblParam(CbcModel::CbcCutoffIncrement) ;
     
    82548253    }
    82558254  }
     8255#endif
    82568256
    82578257  setPointers(solver_);
     
    1043810438  return true;
    1043910439}
    10440 /*
    10441    Do Integer Presolve. Returns new model.
    10442    I have to work out cleanest way of getting solution to
    10443    original problem at end.  So this is very preliminary.
    10444 */
    10445 CbcModel *
    10446 CbcModel::integerPresolve(bool weak)
    10447 {
    10448   status_ = 0;
    10449   // solve LP
    10450   //solver_->writeMps("bad");
    10451   bool feasible = (resolve(NULL,3)!=0);
    10452 
    10453   CbcModel * newModel = NULL;
    10454   if (feasible) {
    10455 
    10456     // get a new model
    10457     newModel = new CbcModel(*this);
    10458     newModel->messageHandler()->setLogLevel(messageHandler()->logLevel());
    10459 
    10460     feasible = newModel->integerPresolveThisModel(solver_,weak);
    10461   }
    10462   if (!feasible) {
    10463     handler_->message(CBC_INFEAS,messages_)
    10464     <<CoinMessageEol;
    10465     status_ = 0;
    10466     secondaryStatus_ = 1;
    10467     delete newModel;
    10468     return NULL;
    10469   } else {
    10470     newModel->synchronizeModel(); // make sure everything that needs solver has it
    10471     return newModel;
    10472   }
    10473 }
    10474 /*
    10475    Do Integer Presolve - destroying current model
    10476 */
    10477 bool
    10478 CbcModel::integerPresolveThisModel(OsiSolverInterface * originalSolver,
    10479                                    bool weak)
    10480 {
    10481   printf("DEPRECATED\n");
    10482   status_ = 0;
    10483   // solve LP
    10484   bool feasible = (resolve(NULL,3)!=0);
    10485 
    10486   bestObjective_=1.0e50;
    10487   numberSolutions_=0;
    10488   numberHeuristicSolutions_=0;
    10489   double cutoff = getCutoff() ;
    10490   double direction = solver_->getObjSense();
    10491   if (cutoff < 1.0e20&&direction<0.0)
    10492     messageHandler()->message(CBC_CUTOFF_WARNING1,
    10493                                     messages())
    10494                                       << cutoff << -cutoff << CoinMessageEol ;
    10495   if (cutoff > bestObjective_)
    10496     cutoff = bestObjective_ ;
    10497   setCutoff(cutoff) ;
    10498   int iColumn;
    10499   int numberColumns = getNumCols();
    10500   int originalNumberColumns = numberColumns;
    10501   currentPassNumber_=0;
    10502   synchronizeModel(); // make sure everything that needs solver has it
    10503   if (!solverCharacteristics_) {
    10504     OsiBabSolver * solverCharacteristics = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
    10505     if (solverCharacteristics) {
    10506       solverCharacteristics_ = solverCharacteristics;
    10507     } else {
    10508       // replace in solver
    10509       OsiBabSolver defaultC;
    10510       solver_->setAuxiliaryInfo(&defaultC);
    10511       solverCharacteristics_ = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
    10512     }
    10513   }
    10514   solverCharacteristics_->setSolver(solver_);
    10515   // just point to solver_
    10516   delete continuousSolver_;
    10517   continuousSolver_ = solver_;
    10518   // get a copy of original so we can fix bounds
    10519   OsiSolverInterface * cleanModel = originalSolver->clone();
    10520 #ifdef CBC_DEBUG
    10521   std::string problemName;
    10522   cleanModel->getStrParam(OsiProbName,problemName);
    10523   printf("Problem name - %s\n",problemName.c_str());
    10524   cleanModel->activateRowCutDebugger(problemName.c_str());
    10525   const OsiRowCutDebugger * debugger = cleanModel->getRowCutDebugger();
    10526 #endif
    10527 
    10528   // array which points from original columns to presolved
    10529   int * original = new int[numberColumns];
    10530   // arrays giving bounds - only ones found by probing
    10531   // rest will be found by presolve
    10532   double * originalLower = new double[numberColumns];
    10533   double * originalUpper = new double[numberColumns];
    10534   {
    10535     const double * lower = getColLower();
    10536     const double * upper = getColUpper();
    10537     for (iColumn=0;iColumn<numberColumns;iColumn++) {
    10538       original[iColumn]=iColumn;
    10539       originalLower[iColumn] = lower[iColumn];
    10540       originalUpper[iColumn] = upper[iColumn];
    10541     }
    10542   }
    10543   findIntegers(true);
    10544   // save original integers
    10545   int * originalIntegers = new int[numberIntegers_];
    10546   int originalNumberIntegers = numberIntegers_;
    10547   memcpy(originalIntegers,integerVariable_,numberIntegers_*sizeof(int));
    10548 
    10549   int todo=20;
    10550   if (weak)
    10551     todo=1;
    10552   while (currentPassNumber_<todo) {
    10553    
    10554     currentPassNumber_++;
    10555     numberSolutions_=0;
    10556     // this will be set false to break out of loop with presolved problem
    10557     bool doIntegerPresolve=(currentPassNumber_!=20);
    10558    
    10559     // Current number of free integer variables
    10560     // Get increment in solutions
    10561     {
    10562       const double * objective = cleanModel->getObjCoefficients();
    10563       const double * lower = cleanModel->getColLower();
    10564       const double * upper = cleanModel->getColUpper();
    10565       double maximumCost=0.0;
    10566       bool possibleMultiple=true;
    10567       int numberChanged=0;
    10568       for (iColumn=0;iColumn<originalNumberColumns;iColumn++) {
    10569         if (originalUpper[iColumn]>originalLower[iColumn]) {
    10570           if( cleanModel->isInteger(iColumn)) {
    10571             maximumCost = CoinMax(maximumCost,fabs(objective[iColumn]));
    10572           } else if (objective[iColumn]) {
    10573             possibleMultiple=false;
    10574           }
    10575         }
    10576         if (originalUpper[iColumn]<upper[iColumn]) {
    10577 #ifdef CBC_DEBUG
    10578           printf("Changing upper bound on %d from %g to %g\n",
    10579                  iColumn,upper[iColumn],originalUpper[iColumn]);
    10580 #endif
    10581           cleanModel->setColUpper(iColumn,originalUpper[iColumn]);
    10582           numberChanged++;
    10583         }
    10584         if (originalLower[iColumn]>lower[iColumn]) {
    10585 #ifdef CBC_DEBUG
    10586           printf("Changing lower bound on %d from %g to %g\n",
    10587                  iColumn,lower[iColumn],originalLower[iColumn]);
    10588 #endif
    10589           cleanModel->setColLower(iColumn,originalLower[iColumn]);
    10590           numberChanged++;
    10591         }
    10592       }
    10593       // if first pass - always try
    10594       if (currentPassNumber_==1)
    10595         numberChanged += 1;
    10596       if (possibleMultiple&&maximumCost) {
    10597         int increment=0;
    10598         double multiplier = 2520.0;
    10599         while (10.0*multiplier*maximumCost<1.0e8)
    10600           multiplier *= 10.0;
    10601         for (int j =0;j<originalNumberIntegers;j++) {
    10602           iColumn = originalIntegers[j];
    10603           if (originalUpper[iColumn]>originalLower[iColumn]) {
    10604             if(objective[iColumn]) {
    10605               double value = fabs(objective[iColumn])*multiplier;
    10606               int nearest = static_cast<int> (floor(value+0.5));
    10607               if (fabs(value-floor(value+0.5))>1.0e-8||value>2.1e9) {
    10608                 increment=0;
    10609                 break; // no good
    10610               } else if (!increment) {
    10611                 // first
    10612                 increment=nearest;
    10613               } else {
    10614                 increment = gcd(increment,nearest);
    10615               }
    10616             }
    10617           }
    10618         }
    10619         if (increment) {
    10620           double value = increment;
    10621           value /= multiplier;
    10622           if (value*0.999>dblParam_[CbcCutoffIncrement]) {
    10623             messageHandler()->message(CBC_INTEGERINCREMENT,messages())
    10624               <<value
    10625               <<CoinMessageEol;
    10626             dblParam_[CbcCutoffIncrement]=value*0.999;
    10627           }
    10628         }
    10629       }
    10630       if (!numberChanged) {
    10631         doIntegerPresolve=false; // not doing any better
    10632       }
    10633     }
    10634 #ifdef CBC_DEBUG
    10635     if (debugger)
    10636       assert(debugger->onOptimalPath(*cleanModel));
    10637 #endif
    10638 #ifdef COIN_HAS_CLP
    10639     // do presolve - for now just clp but easy to get osi interface
    10640     OsiClpSolverInterface * clpSolver
    10641       = dynamic_cast<OsiClpSolverInterface *> (cleanModel);
    10642     if (clpSolver) {
    10643       ClpSimplex * clp = clpSolver->getModelPtr();
    10644       clp->messageHandler()->setLogLevel(cleanModel->messageHandler()->logLevel());
    10645       ClpPresolve pinfo;
    10646       //printf("integerPresolve - temp switch off doubletons\n");
    10647       //pinfo.setPresolveActions(4);
    10648       ClpSimplex * model2 = pinfo.presolvedModel(*clp,1.0e-8);
    10649       if (!model2) {
    10650         // presolve found to be infeasible
    10651         feasible=false;
    10652       } else {
    10653         // update original array
    10654         const int * originalColumns = pinfo.originalColumns();
    10655         // just slot in new solver
    10656         OsiClpSolverInterface * temp = new OsiClpSolverInterface(model2,true);
    10657         numberColumns = temp->getNumCols();
    10658         for (iColumn=0;iColumn<originalNumberColumns;iColumn++)
    10659           original[iColumn]=-1;
    10660         for (iColumn=0;iColumn<numberColumns;iColumn++)
    10661           original[originalColumns[iColumn]]=iColumn;
    10662         // copy parameters
    10663         temp->copyParameters(*solver_);
    10664         // and specialized ones
    10665         temp->setSpecialOptions(clpSolver->specialOptions());
    10666         delete solver_;
    10667         solver_ = temp;
    10668         setCutoff(cutoff);
    10669         deleteObjects();
    10670         if (!numberObjects_) {
    10671           // Nothing left
    10672           doIntegerPresolve=false;
    10673           weak=true;
    10674           break;
    10675         }
    10676         synchronizeModel(); // make sure everything that needs solver has it
    10677         // just point to solver_
    10678         continuousSolver_ = solver_;
    10679         feasible=(resolve(NULL,3)!=0);
    10680         if (!feasible||!doIntegerPresolve||weak) break;
    10681         // see if we can get solution by heuristics
    10682         int found=-1;
    10683         int iHeuristic;
    10684         double * newSolution = new double [numberColumns];
    10685         double heuristicValue=getCutoff();
    10686         for (iHeuristic=0;iHeuristic<numberHeuristics_;iHeuristic++) {
    10687           // skip if can't run here
    10688           if (!heuristic_[iHeuristic]->shouldHeurRun())
    10689             continue;
    10690           double saveValue=heuristicValue;
    10691           int ifSol = heuristic_[iHeuristic]->solution(heuristicValue,
    10692                                                        newSolution);
    10693           if (ifSol>0) {
    10694             // better solution found
    10695             heuristic_[iHeuristic]->incrementNumberSolutionsFound();
    10696             found=iHeuristic;
    10697             incrementUsed(newSolution);
    10698           } else if (ifSol<0) {
    10699             heuristicValue = saveValue;
    10700           }
    10701         }
    10702         if (found >= 0) {
    10703           // We probably already have a current solution, but just in case ...
    10704           int numberColumns = getNumCols() ;
    10705           if (!currentSolution_)
    10706             currentSolution_ = new double[numberColumns] ;
    10707           testSolution_=currentSolution_;
    10708           // better solution save
    10709           lastHeuristic_ = heuristic_[found];
    10710           setBestSolution(CBC_ROUNDING,heuristicValue,
    10711                           newSolution);
    10712           // update cutoff
    10713           cutoff = getCutoff();
    10714         }
    10715         delete [] newSolution;
    10716         // Space for type of cuts
    10717         maximumWhich_=1000;
    10718         delete [] whichGenerator_ ;
    10719         whichGenerator_ = new int[maximumWhich_];
    10720         // save number of rows
    10721         numberRowsAtContinuous_ = getNumRows();
    10722         maximumNumberCuts_=0;
    10723         currentNumberCuts_=0;
    10724         delete [] addedCuts_;
    10725         addedCuts_ = NULL;
    10726        
    10727         // maximum depth for tree walkback
    10728         maximumDepth_=10;
    10729         delete [] walkback_;
    10730         walkback_ = new CbcNodeInfo * [maximumDepth_];
    10731         lastDepth_=0;
    10732         delete [] lastNodeInfo_ ;
    10733         lastNodeInfo_ = new CbcNodeInfo * [maximumDepth_] ;
    10734         delete [] lastNumberCuts_ ;
    10735         lastNumberCuts_ = new int [maximumDepth_] ;
    10736         maximumCuts_ = 100;
    10737         delete [] lastCut_;
    10738         lastCut_ = new const OsiRowCut * [maximumCuts_];
    10739        
    10740         OsiCuts cuts;
    10741         numberOldActiveCuts_=0;
    10742         numberNewCuts_ = 0;
    10743         feasible = solveWithCuts(cuts,maximumCutPassesAtRoot_,NULL);
    10744         currentNumberCuts_=numberNewCuts_;
    10745         delete [] whichGenerator_;
    10746         whichGenerator_=NULL;
    10747         delete [] walkback_;
    10748         walkback_ = NULL;
    10749         delete [] addedCuts_;
    10750         addedCuts_=NULL;
    10751         if (feasible) {
    10752           // fix anything in original which integer presolve fixed
    10753           // for now just integers
    10754           const double * lower = solver_->getColLower();
    10755           const double * upper = solver_->getColUpper();
    10756           int i;
    10757           for (i=0;i<originalNumberIntegers;i++) {
    10758             iColumn = originalIntegers[i];
    10759             int jColumn = original[iColumn];
    10760             if (jColumn >= 0) {
    10761               if (upper[jColumn]<originalUpper[iColumn])
    10762                 originalUpper[iColumn]  = upper[jColumn];
    10763               if (lower[jColumn]>originalLower[iColumn])
    10764                 originalLower[iColumn]  = lower[jColumn];
    10765             }
    10766           }
    10767         }
    10768       }
    10769     }
    10770 #endif
    10771     if (!feasible||!doIntegerPresolve) {
    10772       break;
    10773     }
    10774   }
    10775   //solver_->writeMps("xx");
    10776   delete cleanModel;
    10777   delete [] originalIntegers;
    10778   numberColumns = getNumCols();
    10779   delete [] originalColumns_;
    10780   originalColumns_ = new int[numberColumns];
    10781   numberColumns=0;
    10782   for (iColumn=0;iColumn<originalNumberColumns;iColumn++) {
    10783     int jColumn = original[iColumn];
    10784     if (jColumn >= 0)
    10785       originalColumns_[numberColumns++]=iColumn;
    10786   }
    10787   delete [] original;
    10788   delete [] originalLower;
    10789   delete [] originalUpper;
    10790  
    10791   deleteObjects();
    10792   synchronizeModel(); // make sure everything that needs solver has it
    10793   continuousSolver_=NULL;
    10794   currentNumberCuts_=0;
    10795   return feasible;
    10796 }
    10797 // Put back information into original model - after integerpresolve
    10798 void
    10799 CbcModel::originalModel(CbcModel * presolvedModel,bool weak)
    10800 {
    10801   solver_->copyParameters(*(presolvedModel->solver_));
    10802   bestObjective_ = presolvedModel->bestObjective_;
    10803   delete [] bestSolution_;
    10804   findIntegers(true);
    10805   if (presolvedModel->bestSolution_) {
    10806     int numberColumns = getNumCols();
    10807     int numberOtherColumns = presolvedModel->getNumCols();
    10808     //bestSolution_ = new double[numberColumns];
    10809     // set up map
    10810     int * back = new int[numberColumns];
    10811     int i;
    10812     for (i=0;i<numberColumns;i++)
    10813       back[i]=-1;
    10814     for (i=0;i<numberOtherColumns;i++)
    10815       back[presolvedModel->originalColumns_[i]]=i;
    10816     int iColumn;
    10817     // set ones in presolved model to values
    10818     double * otherSolution = presolvedModel->bestSolution_;
    10819     //const double * lower = getColLower();
    10820     for (i=0;i<numberIntegers_;i++) {
    10821       iColumn = integerVariable_[i];
    10822       int jColumn = back[iColumn];
    10823       //bestSolution_[iColumn]=lower[iColumn];
    10824       if (jColumn >= 0) {
    10825         double value=floor(otherSolution[jColumn]+0.5);
    10826         solver_->setColLower(iColumn,value);
    10827         solver_->setColUpper(iColumn,value);
    10828         //bestSolution_[iColumn]=value;
    10829       }
    10830     }
    10831     delete [] back;
    10832 #if 0
    10833     // ** looks as if presolve needs more intelligence
    10834     // do presolve - for now just clp but easy to get osi interface
    10835     OsiClpSolverInterface * clpSolver
    10836       = dynamic_cast<OsiClpSolverInterface *> (solver_);
    10837     assert (clpSolver);
    10838     ClpSimplex * clp = clpSolver->getModelPtr();
    10839     Presolve pinfo;
    10840     ClpSimplex * model2 = pinfo.presolvedModel(*clp,1.0e-8);
    10841     model2->primal(1);
    10842     pinfo.postsolve(true);
    10843     const double * solution = solver_->getColSolution();
    10844     for (i=0;i<numberIntegers_;i++) {
    10845       iColumn = integerVariable_[i];
    10846       double value=floor(solution[iColumn]+0.5);
    10847       solver_->setColLower(iColumn,value);
    10848       solver_->setColUpper(iColumn,value);
    10849     }
    10850 #else
    10851     if (!weak) {
    10852       // for now give up
    10853       int save = numberCutGenerators_;
    10854       numberCutGenerators_=0;
    10855       bestObjective_=1.0e100;
    10856       branchAndBound();
    10857       numberCutGenerators_=save;
    10858     }
    10859 #endif
    10860     if (bestSolution_) {
    10861       // solve problem
    10862       resolve(NULL,3);
    10863       // should be feasible
    10864       if (!currentSolution_)
    10865         currentSolution_ = new double[numberColumns] ;
    10866       testSolution_ = currentSolution_;
    10867 #ifndef NDEBUG
    10868       int numberIntegerInfeasibilities;
    10869       int numberObjectInfeasibilities;
    10870       assert(feasibleSolution(numberIntegerInfeasibilities,
    10871                               numberObjectInfeasibilities));
    10872 #endif
    10873     }
    10874   } else {
    10875     bestSolution_=NULL;
    10876   }
    10877   numberSolutions_=presolvedModel->numberSolutions_;
    10878   numberHeuristicSolutions_=presolvedModel->numberHeuristicSolutions_;
    10879   numberNodes_ = presolvedModel->numberNodes_;
    10880   numberIterations_ = presolvedModel->numberIterations_;
    10881   status_ = presolvedModel->status_;
    10882   secondaryStatus_ = presolvedModel->secondaryStatus_;
    10883   synchronizeModel();
    10884 }
    1088510440// Pass in Message handler (not deleted at end)
    1088610441void
     
    1095410509  return appData_;
    1095510510}
    10956 /*  create a submodel from partially fixed problem
    10957 
    10958 The method creates a new clean model with given bounds.
    10959 */
    10960 CbcModel * 
    10961 CbcModel::cleanModel(const double * lower, const double * upper)
    10962 {
    10963   OsiSolverInterface * solver = continuousSolver_->clone();
    10964 
    10965   int numberIntegers = numberIntegers_;
    10966   const int * integerVariable = integerVariable_;
    10967  
    10968   int i;
    10969   for (i=0;i<numberIntegers;i++) {
    10970     int iColumn=integerVariable[i];
    10971     const OsiObject * object = object_[i];
    10972 #ifndef NDEBUG
    10973     const CbcSimpleInteger * integerObject =
    10974       dynamic_cast<const  CbcSimpleInteger *> (object);
    10975     assert(integerObject);
    10976 #else
    10977     const CbcSimpleInteger * integerObject =
    10978       static_cast<const  CbcSimpleInteger *> (object);
    10979 #endif
    10980     // get original bounds
    10981     double originalLower = integerObject->originalLowerBound();
    10982     double originalUpper = integerObject->originalUpperBound();
    10983     solver->setColLower(iColumn,CoinMax(lower[iColumn],originalLower));
    10984     solver->setColUpper(iColumn,CoinMin(upper[iColumn],originalUpper));
    10985   }
    10986   CbcModel * model = new CbcModel(*solver);
    10987   // off some messages
    10988   if (handler_->logLevel()<=1) {
    10989     model->messagesPointer()->setDetailMessage(3,9);
    10990     model->messagesPointer()->setDetailMessage(3,6);
    10991     model->messagesPointer()->setDetailMessage(3,4);
    10992     model->messagesPointer()->setDetailMessage(3,1);
    10993     model->messagesPointer()->setDetailMessage(3,13);
    10994     model->messagesPointer()->setDetailMessage(3,14);
    10995     model->messagesPointer()->setDetailMessage(3,3007);
    10996   }
    10997   // Cuts
    10998   for ( i = 0;i<numberCutGenerators_;i++) {
    10999     int howOften = generator_[i]->howOftenInSub();
    11000     if (howOften>-100) {
    11001       CbcCutGenerator * generator = virginGenerator_[i];
    11002       CglCutGenerator * cglGenerator = generator->generator();
    11003       model->addCutGenerator(cglGenerator,howOften,
    11004                               generator->cutGeneratorName(),
    11005                               generator->normal(),
    11006                               generator->atSolution(),
    11007                               generator->whenInfeasible(),
    11008                               -100, generator->whatDepthInSub(),-1);
    11009     }
    11010   }
    11011   double cutoff = getCutoff();
    11012   model->setCutoff(cutoff);
    11013   return model;
    11014 }
    11015 /* Invoke the branch & cut algorithm on partially fixed problem
    11016    
    11017    The method uses a subModel created by cleanModel. The search
    11018    ends when the tree is exhausted or maximum nodes is reached.
    11019 
    11020    If better solution found then it is saved.
    11021    
    11022    Returns 0 if search completed and solution, 1 if not completed and solution,
    11023    2 if completed and no solution, 3 if not completed and no solution.
    11024    
    11025    Normally okay to do subModel immediately followed by subBranchandBound
    11026    (== other form of subBranchAndBound)
    11027    but may need to get at model for advanced features.
    11028    
    11029    Deletes model
    11030    
    11031 */
    11032  
    11033 int
    11034 CbcModel::subBranchAndBound(CbcModel * model,
    11035                             CbcModel * presolvedModel,
    11036                             int maximumNodes)
    11037 {
    11038   int i;
    11039   double cutoff=model->getCutoff();
    11040   CbcModel * model2;
    11041   if (presolvedModel)
    11042     model2=presolvedModel;
    11043   else
    11044     model2=model;
    11045   // Do complete search
    11046  
    11047   for (i=0;i<numberHeuristics_;i++) {
    11048     model2->addHeuristic(heuristic_[i]);
    11049     model2->heuristic(i)->resetModel(model2);
    11050   }
    11051   // Definition of node choice
    11052   model2->setNodeComparison(nodeCompare_->clone());
    11053   //model2->solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
    11054   model2->messageHandler()->setLogLevel(CoinMax(0,handler_->logLevel()-1));
    11055   //model2->solver()->messageHandler()->setLogLevel(2);
    11056   model2->setMaximumCutPassesAtRoot(maximumCutPassesAtRoot_);
    11057   model2->setPrintFrequency(50);
    11058   model2->setIntParam(CbcModel::CbcMaxNumNode,maximumNodes);
    11059   model2->branchAndBound();
    11060   delete model2->nodeComparison();
    11061   if (model2->getMinimizationObjValue()>cutoff) {
    11062     // no good
    11063     if (model!=model2)
    11064       delete model2;
    11065     delete model;
    11066     return 2;
    11067   }
    11068   if (model!=model2) {
    11069     // get back solution
    11070     model->originalModel(model2,false);
    11071     delete model2;
    11072   }
    11073   int status;
    11074   if (model->getMinimizationObjValue()<cutoff&&model->bestSolution()) {
    11075     double objValue = model->getObjValue();
    11076     const double * solution = model->bestSolution();
    11077     setBestSolution(CBC_TREE_SOL,objValue,solution);
    11078     status = 0;
    11079   } else {
    11080     status=2;
    11081   }
    11082   if (model->status())
    11083     status ++ ; // not finished search
    11084   delete model;
    11085   return status;
    11086 }
    11087 /* Invoke the branch & cut algorithm on partially fixed problem
    11088    
    11089 The method creates a new model with given bounds, presolves it
    11090 then proceeds to explore the branch & cut search tree. The search
    11091 ends when the tree is exhausted or maximum nodes is reached.
    11092 Returns 0 if search completed and solution, 1 if not completed and solution,
    11093 2 if completed and no solution, 3 if not completed and no solution.
    11094 */
    11095 int
    11096 CbcModel::subBranchAndBound(const double * lower, const double * upper,
    11097                             int maximumNodes)
    11098 {
    11099   OsiSolverInterface * solver = continuousSolver_->clone();
    11100 
    11101   int numberIntegers = numberIntegers_;
    11102   const int * integerVariable = integerVariable_;
    11103  
    11104   int i;
    11105   for (i=0;i<numberIntegers;i++) {
    11106     int iColumn=integerVariable[i];
    11107     const OsiObject * object = object_[i];
    11108 #ifndef NDEBUG
    11109     const CbcSimpleInteger * integerObject =
    11110       dynamic_cast<const  CbcSimpleInteger *> (object);
    11111     assert(integerObject);
    11112 #else
    11113     const CbcSimpleInteger * integerObject =
    11114       static_cast<const  CbcSimpleInteger *> (object);
    11115 #endif
    11116     // get original bounds
    11117     double originalLower = integerObject->originalLowerBound();
    11118     double originalUpper = integerObject->originalUpperBound();
    11119     solver->setColLower(iColumn,CoinMax(lower[iColumn],originalLower));
    11120     solver->setColUpper(iColumn,CoinMin(upper[iColumn],originalUpper));
    11121   }
    11122   CbcModel model(*solver);
    11123   // off some messages
    11124   if (handler_->logLevel()<=1) {
    11125     model.messagesPointer()->setDetailMessage(3,9);
    11126     model.messagesPointer()->setDetailMessage(3,6);
    11127     model.messagesPointer()->setDetailMessage(3,4);
    11128     model.messagesPointer()->setDetailMessage(3,1);
    11129     model.messagesPointer()->setDetailMessage(3,3007);
    11130   }
    11131   double cutoff = getCutoff();
    11132   model.setCutoff(cutoff);
    11133   // integer presolve
    11134   CbcModel * model2 = model.integerPresolve(false);
    11135   if (!model2||!model2->getNumRows()) {
    11136     delete model2;
    11137     delete solver;
    11138     return 2;
    11139   }
    11140   if (handler_->logLevel()>1)
    11141     printf("Reduced model has %d rows and %d columns\n",
    11142            model2->getNumRows(),model2->getNumCols());
    11143   // Do complete search
    11144  
    11145   // Cuts
    11146   for ( i = 0;i<numberCutGenerators_;i++) {
    11147     int howOften = generator_[i]->howOftenInSub();
    11148     if (howOften>-100) {
    11149       CbcCutGenerator * generator = virginGenerator_[i];
    11150       CglCutGenerator * cglGenerator = generator->generator();
    11151       model2->addCutGenerator(cglGenerator,howOften,
    11152                               generator->cutGeneratorName(),
    11153                               generator->normal(),
    11154                               generator->atSolution(),
    11155                               generator->whenInfeasible(),
    11156                               -100, generator->whatDepthInSub(),-1);
    11157     }
    11158   }
    11159   for (i=0;i<numberHeuristics_;i++) {
    11160     model2->addHeuristic(heuristic_[i]);
    11161     model2->heuristic(i)->resetModel(model2);
    11162   }
    11163   // Definition of node choice
    11164   model2->setNodeComparison(nodeCompare_->clone());
    11165   //model2->solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
    11166   model2->messageHandler()->setLogLevel(CoinMax(0,handler_->logLevel()-1));
    11167   //model2->solver()->messageHandler()->setLogLevel(2);
    11168   model2->setMaximumCutPassesAtRoot(maximumCutPassesAtRoot_);
    11169   model2->setPrintFrequency(50);
    11170   model2->setIntParam(CbcModel::CbcMaxNumNode,maximumNodes);
    11171   model2->branchAndBound();
    11172   delete model2->nodeComparison();
    11173   if (model2->getMinimizationObjValue()>cutoff) {
    11174     // no good
    11175     delete model2;
    11176     delete solver;
    11177     return 2;
    11178   }
    11179   // get back solution
    11180   model.originalModel(model2,false);
    11181   delete model2;
    11182   int status;
    11183   if (model.getMinimizationObjValue()<cutoff&&model.bestSolution()) {
    11184     double objValue = model.getObjValue();
    11185     const double * solution = model.bestSolution();
    11186     setBestSolution(CBC_TREE_SOL,objValue,solution);
    11187     status = 0;
    11188   } else {
    11189     status=2;
    11190   }
    11191   if (model.status())
    11192     status ++ ; // not finished search
    11193   delete solver;
    11194   return status;
    11195 }
    1119610511// Set a pointer to a row cut which will be added instead of normal branching.
    1119710512void
     
    1120010515  nextRowCut_=new OsiRowCut(cut);
    1120110516  nextRowCut_->setEffectiveness(COIN_DBL_MAX); // mark so will always stay
    11202 }
    11203 /* Process root node and return a strengthened model
    11204    
    11205 The method assumes that initialSolve() has been called to solve the
    11206 LP relaxation. It processes the root node and then returns a pointer
    11207 to the strengthened model (or NULL if infeasible)
    11208 */
    11209 OsiSolverInterface * 
    11210 CbcModel::strengthenedModel()
    11211 {
    11212 /*
    11213   Switch off heuristics
    11214 */
    11215   int saveNumberHeuristics=numberHeuristics_;
    11216   numberHeuristics_=0;
    11217 /*
    11218   Scan the variables, noting the integer variables. Create an
    11219   CbcSimpleInteger object for each integer variable.
    11220 */
    11221   findIntegers(false) ;
    11222 /*
    11223   Ensure that objects on the lists of OsiObjects, heuristics, and cut
    11224   generators attached to this model all refer to this model.
    11225 */
    11226   synchronizeModel() ;
    11227 
    11228   if (!solverCharacteristics_) {
    11229     OsiBabSolver * solverCharacteristics = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
    11230     if (solverCharacteristics) {
    11231       solverCharacteristics_ = solverCharacteristics;
    11232     } else {
    11233       // replace in solver
    11234       OsiBabSolver defaultC;
    11235       solver_->setAuxiliaryInfo(&defaultC);
    11236       solverCharacteristics_ = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
    11237     }
    11238   }
    11239 
    11240   solverCharacteristics_->setSolver(solver_);
    11241   // Set so we can tell we are in initial phase in resolve
    11242   continuousObjective_ = -COIN_DBL_MAX ;
    11243 /*
    11244   Solve the relaxation.
    11245 
    11246   Apparently there are circumstances where this will be non-trivial --- i.e.,
    11247   we've done something since initialSolve that's trashed the solution to the
    11248   continuous relaxation.
    11249 */
    11250   bool feasible = resolve(NULL,0) != 0 ;
    11251 /*
    11252   If the linear relaxation of the root is infeasible, bail out now. Otherwise,
    11253   continue with processing the root node.
    11254 */
    11255   if (!feasible)
    11256   { handler_->message(CBC_INFEAS,messages_)<< CoinMessageEol ;
    11257     return NULL; }
    11258   // Save objective (just so user can access it)
    11259   originalContinuousObjective_ = solver_->getObjValue();
    11260 
    11261 /*
    11262   Begin setup to process a feasible root node.
    11263 */
    11264   bestObjective_ = CoinMin(bestObjective_,1.0e50) ;
    11265   numberSolutions_ = 0 ;
    11266   numberHeuristicSolutions_ = 0 ;
    11267   // Everything is minimization
    11268   double cutoff=getCutoff() ;
    11269   double direction = solver_->getObjSense() ;
    11270   if (cutoff < 1.0e20&&direction<0.0)
    11271     messageHandler()->message(CBC_CUTOFF_WARNING1,
    11272                                     messages())
    11273                                       << cutoff << -cutoff << CoinMessageEol ;
    11274   if (cutoff > bestObjective_)
    11275     cutoff = bestObjective_ ;
    11276   setCutoff(cutoff) ;
    11277 /*
    11278   We probably already have a current solution, but just in case ...
    11279 */
    11280   int numberColumns = getNumCols() ;
    11281   if (!currentSolution_)
    11282     currentSolution_ = new double[numberColumns] ;
    11283   testSolution_=currentSolution_;
    11284 /*
    11285   Create a copy of the solver, thus capturing the original (root node)
    11286   constraint system (aka the continuous system).
    11287 */
    11288   continuousSolver_ = solver_->clone() ;
    11289   numberRowsAtContinuous_ = getNumRows() ;
    11290 /*
    11291   Check the objective to see if we can deduce a nontrivial increment. If
    11292   it's better than the current value for CbcCutoffIncrement, it'll be
    11293   installed.
    11294 */
    11295   analyzeObjective() ;
    11296 /*
    11297   Set up for cut generation. addedCuts_ holds the cuts which are relevant for
    11298   the active subproblem. whichGenerator will be used to record the generator
    11299   that produced a given cut.
    11300 */
    11301   maximumWhich_ = 1000 ;
    11302   delete [] whichGenerator_ ;
    11303   whichGenerator_ = new int[maximumWhich_] ;
    11304   maximumNumberCuts_ = 0 ;
    11305   currentNumberCuts_ = 0 ;
    11306   delete [] addedCuts_ ;
    11307   addedCuts_ = NULL ;
    11308   /* 
    11309   Generate cuts at the root node and reoptimise. solveWithCuts does the heavy
    11310   lifting. It will iterate a generate/reoptimise loop (including reduced cost
    11311   fixing) until no cuts are generated, the change in objective falls off,  or
    11312   the limit on the number of rounds of cut generation is exceeded.
    11313 
    11314   At the end of all this, any cuts will be recorded in cuts and also
    11315   installed in the solver's constraint system. We'll have reoptimised, and
    11316   removed any slack cuts (numberOldActiveCuts_ and numberNewCuts_ have been
    11317   adjusted accordingly).
    11318 
    11319   Tell cut generators they can be a bit more aggressive at root node
    11320 
    11321 */
    11322   int iCutGenerator;
    11323   for (iCutGenerator = 0;iCutGenerator<numberCutGenerators_;iCutGenerator++) {
    11324     CglCutGenerator * generator = generator_[iCutGenerator]->generator();
    11325     generator->setAggressiveness(generator->getAggressiveness()+100);
    11326   }
    11327   OsiCuts cuts ;
    11328   numberOldActiveCuts_ = 0 ;
    11329   numberNewCuts_ = 0 ;
    11330   { int iObject ;
    11331     int preferredWay ;
    11332     int numberUnsatisfied = 0 ;
    11333     memcpy(currentSolution_,solver_->getColSolution(),
    11334            numberColumns*sizeof(double)) ;
    11335 
    11336     // point to useful information
    11337     OsiBranchingInformation usefulInfo=usefulInformation();
    11338     for (iObject = 0 ; iObject < numberObjects_ ; iObject++)
    11339     { double infeasibility =
    11340           object_[iObject]->infeasibility(&usefulInfo,preferredWay) ;
    11341       if (infeasibility) numberUnsatisfied++ ; }
    11342     if (numberUnsatisfied)
    11343     { feasible = solveWithCuts(cuts,maximumCutPassesAtRoot_,
    11344                                NULL) ; } }
    11345 /*
    11346   We've taken the continuous relaxation as far as we can.
    11347 */
    11348 
    11349   OsiSolverInterface * newSolver=NULL;
    11350   if (feasible) {
    11351     // make copy of current solver
    11352     newSolver = solver_->clone();
    11353   }
    11354 /*
    11355   Clean up dangling objects. continuousSolver_ may already be toast.
    11356 */
    11357   delete [] whichGenerator_ ;
    11358   whichGenerator_ = NULL;
    11359   delete [] walkback_ ;
    11360   walkback_ = NULL ;
    11361   delete [] lastNodeInfo_ ;
    11362   lastNodeInfo_ = NULL;
    11363   delete [] lastNumberCuts_ ;
    11364   lastNumberCuts_ = NULL;
    11365   delete [] lastCut_;
    11366   lastCut_ = NULL;
    11367   delete [] addedCuts_ ;
    11368   addedCuts_ = NULL ;
    11369   if (continuousSolver_)
    11370   { delete continuousSolver_ ;
    11371     continuousSolver_ = NULL ; }
    11372 /*
    11373   Destroy global cuts by replacing with an empty OsiCuts object.
    11374 */
    11375   globalCuts_= OsiCuts() ;
    11376   numberHeuristics_ = saveNumberHeuristics;
    11377  
    11378   return newSolver;
    1137910517}
    1138010518// Just update objectiveValue
     
    1208311221  solverCharacteristics_ = solverCharacteristics;
    1208411222}
    12085 /* preProcess problem - replacing solver
    12086    If makeEquality true then <= cliques converted to ==.
    12087    Presolve will be done numberPasses times.
    12088    
    12089    Returns NULL if infeasible
    12090    
    12091    If makeEquality is 1 add slacks to get cliques,
    12092    if 2 add slacks to get sos (but only if looks plausible) and keep sos info
    12093 */
    12094 CglPreProcess *
    12095 CbcModel::preProcess( int makeEquality, int numberPasses, int tuning)
    12096 {
    12097   CglPreProcess * process = new CglPreProcess();
    12098   // Default set of cut generators
    12099   CglProbing generator1;
    12100   generator1.setUsingObjective(true);
    12101   generator1.setMaxPass(3);
    12102   generator1.setMaxProbeRoot(solver_->getNumCols());
    12103   generator1.setMaxElements(100);
    12104   generator1.setMaxLookRoot(50);
    12105   generator1.setRowCuts(3);
    12106   // Add in generators
    12107   process->addCutGenerator(&generator1);
    12108   process->messageHandler()->setLogLevel(this->logLevel());
    12109   /* model may not have created objects
    12110      If none then create
    12111   */
    12112   if (!numberIntegers_||!numberObjects_) {
    12113     this->findIntegers(true,1);
    12114   }
    12115   // Do SOS
    12116   int i;
    12117   int numberSOS2=0;
    12118   for (i=0;i<numberObjects_;i++) {
    12119     CbcSOS * objSOS =
    12120       dynamic_cast <CbcSOS *>(object_[i]) ;
    12121     if (objSOS) {
    12122       int type = objSOS->sosType();
    12123       if (type==2)
    12124         numberSOS2++;
    12125     }
    12126   }
    12127   if (numberSOS2) {
    12128     // SOS
    12129     int numberColumns = solver_->getNumCols();
    12130     char * prohibited = new char[numberColumns];
    12131     memset(prohibited,0,numberColumns);
    12132     for (i=0;i<numberObjects_;i++) {
    12133       CbcSOS * objSOS =
    12134         dynamic_cast <CbcSOS *>(object_[i]) ;
    12135       if (objSOS) {
    12136         int type = objSOS->sosType();
    12137         if (type==2) {
    12138           int n=objSOS->numberMembers();
    12139           const int * which = objSOS->members();
    12140           for (int j=0;j<n;j++) {
    12141             int iColumn = which[j];
    12142             prohibited[iColumn]=1;
    12143           }
    12144         }
    12145       }
    12146     }
    12147     process->passInProhibited(prohibited,numberColumns);
    12148     delete [] prohibited;
    12149   }
    12150   // Tell solver we are not in Branch and Cut
    12151   solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;
    12152   OsiSolverInterface * newSolver = process->preProcessNonDefault(*solver_, makeEquality,
    12153                                                                 numberPasses, tuning);
    12154   // Tell solver we are not in Branch and Cut
    12155   solver_->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
    12156   if (newSolver) {
    12157     int numberOriginalObjects=numberObjects_;
    12158     OsiSolverInterface * originalSolver = solver_;
    12159     solver_=newSolver->clone(); // clone as process owns solver
    12160     // redo sequence
    12161     numberIntegers_=0;
    12162     int numberColumns = solver_->getNumCols();
    12163     int nOrig = originalSolver->getNumCols();
    12164     const int * originalColumns = process->originalColumns();
    12165     // allow for cliques etc
    12166     nOrig = CoinMax(nOrig,originalColumns[numberColumns-1]+1);
    12167     OsiObject ** originalObject = object_;
    12168     // object number or -1
    12169     int * temp = new int[nOrig];
    12170     int iColumn;
    12171     for (iColumn=0;iColumn<nOrig;iColumn++)
    12172       temp[iColumn]=-1;
    12173     int iObject;
    12174     numberObjects_=0;
    12175     int nNonInt=0;
    12176     for (iObject=0;iObject<numberOriginalObjects;iObject++) {
    12177       iColumn = originalObject[iObject]->columnNumber();
    12178       if (iColumn<0) {
    12179         nNonInt++;
    12180       } else {
    12181         temp[iColumn]=iObject;
    12182       }
    12183     }
    12184     int numberNewIntegers=0;
    12185     int numberOldIntegers=0;
    12186     int numberOldOther=0;
    12187     for (iColumn=0;iColumn<numberColumns;iColumn++) {
    12188       int jColumn = originalColumns[iColumn];
    12189       if (temp[jColumn]>=0) {
    12190         int iObject= temp[jColumn];
    12191         CbcSimpleInteger * obj =
    12192           dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ;
    12193         if (obj)
    12194           numberOldIntegers++;
    12195         else
    12196           numberOldOther++;
    12197       } else if (isInteger(iColumn)) {
    12198         numberNewIntegers++;
    12199       }
    12200     }
    12201     /*
    12202       Allocate an array to hold the indices of the integer variables.
    12203       Make a large enough array for all objects
    12204     */
    12205     numberObjects_= numberNewIntegers+numberOldIntegers+numberOldOther+nNonInt;
    12206     object_ = new OsiObject * [numberObjects_];
    12207     delete [] integerVariable_;
    12208     integerVariable_ = new int [numberNewIntegers+numberOldIntegers];
    12209     /*
    12210       Walk the variables again, filling in the indices and creating objects for
    12211       the integer variables. Initially, the objects hold the index and upper &
    12212       lower bounds.
    12213     */
    12214     numberIntegers_=0;
    12215     int n=originalColumns[numberColumns-1]+1;
    12216     int * backward = new int[n];
    12217     int i;
    12218     for ( i=0;i<n;i++)
    12219       backward[i]=-1;
    12220     for (i=0;i<numberColumns;i++)
    12221       backward[originalColumns[i]]=i;
    12222     for (iColumn=0;iColumn<numberColumns;iColumn++) {
    12223       int jColumn = originalColumns[iColumn];
    12224       if (temp[jColumn]>=0) {
    12225         int iObject= temp[jColumn];
    12226         CbcSimpleInteger * obj =
    12227           dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ;
    12228         if (obj) {
    12229           object_[numberIntegers_] = originalObject[iObject]->clone();
    12230           // redo ids etc
    12231           //object_[numberIntegers_]->resetSequenceEtc(numberColumns,originalColumns);
    12232           object_[numberIntegers_]->resetSequenceEtc(numberColumns,backward);
    12233           integerVariable_[numberIntegers_++]=iColumn;
    12234         }
    12235       } else if (isInteger(iColumn)) {
    12236         object_[numberIntegers_] =
    12237           new CbcSimpleInteger(this,iColumn);
    12238         integerVariable_[numberIntegers_++]=iColumn;
    12239       }
    12240     }
    12241     delete [] backward;
    12242     numberObjects_=numberIntegers_;
    12243     // Now append other column stuff
    12244     for (iColumn=0;iColumn<numberColumns;iColumn++) {
    12245       int jColumn = originalColumns[iColumn];
    12246       if (temp[jColumn]>=0) {
    12247         int iObject= temp[jColumn];
    12248         CbcSimpleInteger * obj =
    12249           dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ;
    12250         if (!obj) {
    12251           object_[numberObjects_] = originalObject[iObject]->clone();
    12252           // redo ids etc
    12253           CbcObject * obj =
    12254             dynamic_cast <CbcObject *>(object_[numberObjects_]) ;
    12255           assert (obj);
    12256           obj->redoSequenceEtc(this,numberColumns,originalColumns);
    12257           numberObjects_++;
    12258         }
    12259       }
    12260     }
    12261     // now append non column stuff
    12262     for (iObject=0;iObject<numberOriginalObjects;iObject++) {
    12263       iColumn = originalObject[iObject]->columnNumber();
    12264       if (iColumn<0) {
    12265         object_[numberObjects_] = originalObject[iObject]->clone();
    12266         // redo ids etc
    12267         CbcObject * obj =
    12268           static_cast <CbcObject *>(object_[numberObjects_]) ;
    12269         assert (obj);
    12270         obj->redoSequenceEtc(this,numberColumns,originalColumns);
    12271         numberObjects_++;
    12272       }
    12273       delete originalObject[iObject];
    12274     }
    12275     delete [] originalObject;
    12276     delete [] temp;
    12277     if (!numberObjects_)
    12278       handler_->message(CBC_NOINT,messages_) << CoinMessageEol ;
    12279     return process;
    12280   } else {
    12281     // infeasible
    12282     delete process;
    12283     return NULL;
    12284   }
    12285    
    12286 }
    1228711223// Generate an OsiBranchingInformation object
    1228811224OsiBranchingInformation
     
    1229811234  usefulInfo.depth_=-1;
    1229911235  return usefulInfo;
    12300 }
    12301 /* Does postprocessing - original solver back.
    12302    User has to delete process */
    12303 void
    12304 CbcModel::postProcess(CglPreProcess * process)
    12305 {
    12306   process->postProcess(*solver_);
    12307   delete solver_;
    12308   solver_ = process->originalModel();
    1230911236}
    1231011237void
     
    1471413641  }
    1471513642}
     13643// Below this is deprecated or at least fairly deprecated
     13644/*
     13645   Do Integer Presolve. Returns new model.
     13646   I have to work out cleanest way of getting solution to
     13647   original problem at end.  So this is very preliminary.
     13648*/
     13649CbcModel *
     13650CbcModel::integerPresolve(bool weak)
     13651{
     13652  status_ = 0;
     13653  // solve LP
     13654  //solver_->writeMps("bad");
     13655  bool feasible = (resolve(NULL,3)!=0);
     13656
     13657  CbcModel * newModel = NULL;
     13658  if (feasible) {
     13659
     13660    // get a new model
     13661    newModel = new CbcModel(*this);
     13662    newModel->messageHandler()->setLogLevel(messageHandler()->logLevel());
     13663
     13664    feasible = newModel->integerPresolveThisModel(solver_,weak);
     13665  }
     13666  if (!feasible) {
     13667    handler_->message(CBC_INFEAS,messages_)
     13668    <<CoinMessageEol;
     13669    status_ = 0;
     13670    secondaryStatus_ = 1;
     13671    delete newModel;
     13672    return NULL;
     13673  } else {
     13674    newModel->synchronizeModel(); // make sure everything that needs solver has it
     13675    return newModel;
     13676  }
     13677}
     13678/*
     13679   Do Integer Presolve - destroying current model
     13680*/
     13681bool
     13682CbcModel::integerPresolveThisModel(OsiSolverInterface * originalSolver,
     13683                                   bool weak)
     13684{
     13685  printf("DEPRECATED\n");
     13686  status_ = 0;
     13687  // solve LP
     13688  bool feasible = (resolve(NULL,3)!=0);
     13689
     13690  bestObjective_=1.0e50;
     13691  numberSolutions_=0;
     13692  numberHeuristicSolutions_=0;
     13693  double cutoff = getCutoff() ;
     13694  double direction = solver_->getObjSense();
     13695  if (cutoff < 1.0e20&&direction<0.0)
     13696    messageHandler()->message(CBC_CUTOFF_WARNING1,
     13697                                    messages())
     13698                                      << cutoff << -cutoff << CoinMessageEol ;
     13699  if (cutoff > bestObjective_)
     13700    cutoff = bestObjective_ ;
     13701  setCutoff(cutoff) ;
     13702  int iColumn;
     13703  int numberColumns = getNumCols();
     13704  int originalNumberColumns = numberColumns;
     13705  currentPassNumber_=0;
     13706  synchronizeModel(); // make sure everything that needs solver has it
     13707  if (!solverCharacteristics_) {
     13708    OsiBabSolver * solverCharacteristics = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
     13709    if (solverCharacteristics) {
     13710      solverCharacteristics_ = solverCharacteristics;
     13711    } else {
     13712      // replace in solver
     13713      OsiBabSolver defaultC;
     13714      solver_->setAuxiliaryInfo(&defaultC);
     13715      solverCharacteristics_ = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
     13716    }
     13717  }
     13718  solverCharacteristics_->setSolver(solver_);
     13719  // just point to solver_
     13720  delete continuousSolver_;
     13721  continuousSolver_ = solver_;
     13722  // get a copy of original so we can fix bounds
     13723  OsiSolverInterface * cleanModel = originalSolver->clone();
     13724#ifdef CBC_DEBUG
     13725  std::string problemName;
     13726  cleanModel->getStrParam(OsiProbName,problemName);
     13727  printf("Problem name - %s\n",problemName.c_str());
     13728  cleanModel->activateRowCutDebugger(problemName.c_str());
     13729  const OsiRowCutDebugger * debugger = cleanModel->getRowCutDebugger();
     13730#endif
     13731
     13732  // array which points from original columns to presolved
     13733  int * original = new int[numberColumns];
     13734  // arrays giving bounds - only ones found by probing
     13735  // rest will be found by presolve
     13736  double * originalLower = new double[numberColumns];
     13737  double * originalUpper = new double[numberColumns];
     13738  {
     13739    const double * lower = getColLower();
     13740    const double * upper = getColUpper();
     13741    for (iColumn=0;iColumn<numberColumns;iColumn++) {
     13742      original[iColumn]=iColumn;
     13743      originalLower[iColumn] = lower[iColumn];
     13744      originalUpper[iColumn] = upper[iColumn];
     13745    }
     13746  }
     13747  findIntegers(true);
     13748  // save original integers
     13749  int * originalIntegers = new int[numberIntegers_];
     13750  int originalNumberIntegers = numberIntegers_;
     13751  memcpy(originalIntegers,integerVariable_,numberIntegers_*sizeof(int));
     13752
     13753  int todo=20;
     13754  if (weak)
     13755    todo=1;
     13756  while (currentPassNumber_<todo) {
     13757   
     13758    currentPassNumber_++;
     13759    numberSolutions_=0;
     13760    // this will be set false to break out of loop with presolved problem
     13761    bool doIntegerPresolve=(currentPassNumber_!=20);
     13762   
     13763    // Current number of free integer variables
     13764    // Get increment in solutions
     13765    {
     13766      const double * objective = cleanModel->getObjCoefficients();
     13767      const double * lower = cleanModel->getColLower();
     13768      const double * upper = cleanModel->getColUpper();
     13769      double maximumCost=0.0;
     13770      bool possibleMultiple=true;
     13771      int numberChanged=0;
     13772      for (iColumn=0;iColumn<originalNumberColumns;iColumn++) {
     13773        if (originalUpper[iColumn]>originalLower[iColumn]) {
     13774          if( cleanModel->isInteger(iColumn)) {
     13775            maximumCost = CoinMax(maximumCost,fabs(objective[iColumn]));
     13776          } else if (objective[iColumn]) {
     13777            possibleMultiple=false;
     13778          }
     13779        }
     13780        if (originalUpper[iColumn]<upper[iColumn]) {
     13781#ifdef CBC_DEBUG
     13782          printf("Changing upper bound on %d from %g to %g\n",
     13783                 iColumn,upper[iColumn],originalUpper[iColumn]);
     13784#endif
     13785          cleanModel->setColUpper(iColumn,originalUpper[iColumn]);
     13786          numberChanged++;
     13787        }
     13788        if (originalLower[iColumn]>lower[iColumn]) {
     13789#ifdef CBC_DEBUG
     13790          printf("Changing lower bound on %d from %g to %g\n",
     13791                 iColumn,lower[iColumn],originalLower[iColumn]);
     13792#endif
     13793          cleanModel->setColLower(iColumn,originalLower[iColumn]);
     13794          numberChanged++;
     13795        }
     13796      }
     13797      // if first pass - always try
     13798      if (currentPassNumber_==1)
     13799        numberChanged += 1;
     13800      if (possibleMultiple&&maximumCost) {
     13801        int increment=0;
     13802        double multiplier = 2520.0;
     13803        while (10.0*multiplier*maximumCost<1.0e8)
     13804          multiplier *= 10.0;
     13805        for (int j =0;j<originalNumberIntegers;j++) {
     13806          iColumn = originalIntegers[j];
     13807          if (originalUpper[iColumn]>originalLower[iColumn]) {
     13808            if(objective[iColumn]) {
     13809              double value = fabs(objective[iColumn])*multiplier;
     13810              int nearest = static_cast<int> (floor(value+0.5));
     13811              if (fabs(value-floor(value+0.5))>1.0e-8||value>2.1e9) {
     13812                increment=0;
     13813                break; // no good
     13814              } else if (!increment) {
     13815                // first
     13816                increment=nearest;
     13817              } else {
     13818                increment = gcd(increment,nearest);
     13819              }
     13820            }
     13821          }
     13822        }
     13823        if (increment) {
     13824          double value = increment;
     13825          value /= multiplier;
     13826          if (value*0.999>dblParam_[CbcCutoffIncrement]) {
     13827            messageHandler()->message(CBC_INTEGERINCREMENT,messages())
     13828              <<value
     13829              <<CoinMessageEol;
     13830            dblParam_[CbcCutoffIncrement]=value*0.999;
     13831          }
     13832        }
     13833      }
     13834      if (!numberChanged) {
     13835        doIntegerPresolve=false; // not doing any better
     13836      }
     13837    }
     13838#ifdef CBC_DEBUG
     13839    if (debugger)
     13840      assert(debugger->onOptimalPath(*cleanModel));
     13841#endif
     13842#ifdef COIN_HAS_CLP
     13843    // do presolve - for now just clp but easy to get osi interface
     13844    OsiClpSolverInterface * clpSolver
     13845      = dynamic_cast<OsiClpSolverInterface *> (cleanModel);
     13846    if (clpSolver) {
     13847      ClpSimplex * clp = clpSolver->getModelPtr();
     13848      clp->messageHandler()->setLogLevel(cleanModel->messageHandler()->logLevel());
     13849      ClpPresolve pinfo;
     13850      //printf("integerPresolve - temp switch off doubletons\n");
     13851      //pinfo.setPresolveActions(4);
     13852      ClpSimplex * model2 = pinfo.presolvedModel(*clp,1.0e-8);
     13853      if (!model2) {
     13854        // presolve found to be infeasible
     13855        feasible=false;
     13856      } else {
     13857        // update original array
     13858        const int * originalColumns = pinfo.originalColumns();
     13859        // just slot in new solver
     13860        OsiClpSolverInterface * temp = new OsiClpSolverInterface(model2,true);
     13861        numberColumns = temp->getNumCols();
     13862        for (iColumn=0;iColumn<originalNumberColumns;iColumn++)
     13863          original[iColumn]=-1;
     13864        for (iColumn=0;iColumn<numberColumns;iColumn++)
     13865          original[originalColumns[iColumn]]=iColumn;
     13866        // copy parameters
     13867        temp->copyParameters(*solver_);
     13868        // and specialized ones
     13869        temp->setSpecialOptions(clpSolver->specialOptions());
     13870        delete solver_;
     13871        solver_ = temp;
     13872        setCutoff(cutoff);
     13873        deleteObjects();
     13874        if (!numberObjects_) {
     13875          // Nothing left
     13876          doIntegerPresolve=false;
     13877          weak=true;
     13878          break;
     13879        }
     13880        synchronizeModel(); // make sure everything that needs solver has it
     13881        // just point to solver_
     13882        continuousSolver_ = solver_;
     13883        feasible=(resolve(NULL,3)!=0);
     13884        if (!feasible||!doIntegerPresolve||weak) break;
     13885        // see if we can get solution by heuristics
     13886        int found=-1;
     13887        int iHeuristic;
     13888        double * newSolution = new double [numberColumns];
     13889        double heuristicValue=getCutoff();
     13890        for (iHeuristic=0;iHeuristic<numberHeuristics_;iHeuristic++) {
     13891          // skip if can't run here
     13892          if (!heuristic_[iHeuristic]->shouldHeurRun())
     13893            continue;
     13894          double saveValue=heuristicValue;
     13895          int ifSol = heuristic_[iHeuristic]->solution(heuristicValue,
     13896                                                       newSolution);
     13897          if (ifSol>0) {
     13898            // better solution found
     13899            heuristic_[iHeuristic]->incrementNumberSolutionsFound();
     13900            found=iHeuristic;
     13901            incrementUsed(newSolution);
     13902          } else if (ifSol<0) {
     13903            heuristicValue = saveValue;
     13904          }
     13905        }
     13906        if (found >= 0) {
     13907          // We probably already have a current solution, but just in case ...
     13908          int numberColumns = getNumCols() ;
     13909          if (!currentSolution_)
     13910            currentSolution_ = new double[numberColumns] ;
     13911          testSolution_=currentSolution_;
     13912          // better solution save
     13913          lastHeuristic_ = heuristic_[found];
     13914          setBestSolution(CBC_ROUNDING,heuristicValue,
     13915                          newSolution);
     13916          // update cutoff
     13917          cutoff = getCutoff();
     13918        }
     13919        delete [] newSolution;
     13920        // Space for type of cuts
     13921        maximumWhich_=1000;
     13922        delete [] whichGenerator_ ;
     13923        whichGenerator_ = new int[maximumWhich_];
     13924        // save number of rows
     13925        numberRowsAtContinuous_ = getNumRows();
     13926        maximumNumberCuts_=0;
     13927        currentNumberCuts_=0;
     13928        delete [] addedCuts_;
     13929        addedCuts_ = NULL;
     13930       
     13931        // maximum depth for tree walkback
     13932        maximumDepth_=10;
     13933        delete [] walkback_;
     13934        walkback_ = new CbcNodeInfo * [maximumDepth_];
     13935        lastDepth_=0;
     13936        delete [] lastNodeInfo_ ;
     13937        lastNodeInfo_ = new CbcNodeInfo * [maximumDepth_] ;
     13938        delete [] lastNumberCuts_ ;
     13939        lastNumberCuts_ = new int [maximumDepth_] ;
     13940        maximumCuts_ = 100;
     13941        delete [] lastCut_;
     13942        lastCut_ = new const OsiRowCut * [maximumCuts_];
     13943       
     13944        OsiCuts cuts;
     13945        numberOldActiveCuts_=0;
     13946        numberNewCuts_ = 0;
     13947        feasible = solveWithCuts(cuts,maximumCutPassesAtRoot_,NULL);
     13948        currentNumberCuts_=numberNewCuts_;
     13949        delete [] whichGenerator_;
     13950        whichGenerator_=NULL;
     13951        delete [] walkback_;
     13952        walkback_ = NULL;
     13953        delete [] addedCuts_;
     13954        addedCuts_=NULL;
     13955        if (feasible) {
     13956          // fix anything in original which integer presolve fixed
     13957          // for now just integers
     13958          const double * lower = solver_->getColLower();
     13959          const double * upper = solver_->getColUpper();
     13960          int i;
     13961          for (i=0;i<originalNumberIntegers;i++) {
     13962            iColumn = originalIntegers[i];
     13963            int jColumn = original[iColumn];
     13964            if (jColumn >= 0) {
     13965              if (upper[jColumn]<originalUpper[iColumn])
     13966                originalUpper[iColumn]  = upper[jColumn];
     13967              if (lower[jColumn]>originalLower[iColumn])
     13968                originalLower[iColumn]  = lower[jColumn];
     13969            }
     13970          }
     13971        }
     13972      }
     13973    }
     13974#endif
     13975    if (!feasible||!doIntegerPresolve) {
     13976      break;
     13977    }
     13978  }
     13979  //solver_->writeMps("xx");
     13980  delete cleanModel;
     13981  delete [] originalIntegers;
     13982  numberColumns = getNumCols();
     13983  delete [] originalColumns_;
     13984  originalColumns_ = new int[numberColumns];
     13985  numberColumns=0;
     13986  for (iColumn=0;iColumn<originalNumberColumns;iColumn++) {
     13987    int jColumn = original[iColumn];
     13988    if (jColumn >= 0)
     13989      originalColumns_[numberColumns++]=iColumn;
     13990  }
     13991  delete [] original;
     13992  delete [] originalLower;
     13993  delete [] originalUpper;
     13994 
     13995  deleteObjects();
     13996  synchronizeModel(); // make sure everything that needs solver has it
     13997  continuousSolver_=NULL;
     13998  currentNumberCuts_=0;
     13999  return feasible;
     14000}
     14001// Put back information into original model - after integerpresolve
     14002void
     14003CbcModel::originalModel(CbcModel * presolvedModel,bool weak)
     14004{
     14005  solver_->copyParameters(*(presolvedModel->solver_));
     14006  bestObjective_ = presolvedModel->bestObjective_;
     14007  delete [] bestSolution_;
     14008  findIntegers(true);
     14009  if (presolvedModel->bestSolution_) {
     14010    int numberColumns = getNumCols();
     14011    int numberOtherColumns = presolvedModel->getNumCols();
     14012    //bestSolution_ = new double[numberColumns];
     14013    // set up map
     14014    int * back = new int[numberColumns];
     14015    int i;
     14016    for (i=0;i<numberColumns;i++)
     14017      back[i]=-1;
     14018    for (i=0;i<numberOtherColumns;i++)
     14019      back[presolvedModel->originalColumns_[i]]=i;
     14020    int iColumn;
     14021    // set ones in presolved model to values
     14022    double * otherSolution = presolvedModel->bestSolution_;
     14023    //const double * lower = getColLower();
     14024    for (i=0;i<numberIntegers_;i++) {
     14025      iColumn = integerVariable_[i];
     14026      int jColumn = back[iColumn];
     14027      //bestSolution_[iColumn]=lower[iColumn];
     14028      if (jColumn >= 0) {
     14029        double value=floor(otherSolution[jColumn]+0.5);
     14030        solver_->setColLower(iColumn,value);
     14031        solver_->setColUpper(iColumn,value);
     14032        //bestSolution_[iColumn]=value;
     14033      }
     14034    }
     14035    delete [] back;
     14036#if 0
     14037    // ** looks as if presolve needs more intelligence
     14038    // do presolve - for now just clp but easy to get osi interface
     14039    OsiClpSolverInterface * clpSolver
     14040      = dynamic_cast<OsiClpSolverInterface *> (solver_);
     14041    assert (clpSolver);
     14042    ClpSimplex * clp = clpSolver->getModelPtr();
     14043    Presolve pinfo;
     14044    ClpSimplex * model2 = pinfo.presolvedModel(*clp,1.0e-8);
     14045    model2->primal(1);
     14046    pinfo.postsolve(true);
     14047    const double * solution = solver_->getColSolution();
     14048    for (i=0;i<numberIntegers_;i++) {
     14049      iColumn = integerVariable_[i];
     14050      double value=floor(solution[iColumn]+0.5);
     14051      solver_->setColLower(iColumn,value);
     14052      solver_->setColUpper(iColumn,value);
     14053    }
     14054#else
     14055    if (!weak) {
     14056      // for now give up
     14057      int save = numberCutGenerators_;
     14058      numberCutGenerators_=0;
     14059      bestObjective_=1.0e100;
     14060      branchAndBound();
     14061      numberCutGenerators_=save;
     14062    }
     14063#endif
     14064    if (bestSolution_) {
     14065      // solve problem
     14066      resolve(NULL,3);
     14067      // should be feasible
     14068      if (!currentSolution_)
     14069        currentSolution_ = new double[numberColumns] ;
     14070      testSolution_ = currentSolution_;
     14071#ifndef NDEBUG
     14072      int numberIntegerInfeasibilities;
     14073      int numberObjectInfeasibilities;
     14074      assert(feasibleSolution(numberIntegerInfeasibilities,
     14075                              numberObjectInfeasibilities));
     14076#endif
     14077    }
     14078  } else {
     14079    bestSolution_=NULL;
     14080  }
     14081  numberSolutions_=presolvedModel->numberSolutions_;
     14082  numberHeuristicSolutions_=presolvedModel->numberHeuristicSolutions_;
     14083  numberNodes_ = presolvedModel->numberNodes_;
     14084  numberIterations_ = presolvedModel->numberIterations_;
     14085  status_ = presolvedModel->status_;
     14086  secondaryStatus_ = presolvedModel->secondaryStatus_;
     14087  synchronizeModel();
     14088}
     14089#ifdef CBC_KEEP_DEPRECATED
     14090/* preProcess problem - replacing solver
     14091   If makeEquality true then <= cliques converted to ==.
     14092   Presolve will be done numberPasses times.
     14093   
     14094   Returns NULL if infeasible
     14095   
     14096   If makeEquality is 1 add slacks to get cliques,
     14097   if 2 add slacks to get sos (but only if looks plausible) and keep sos info
     14098*/
     14099CglPreProcess *
     14100CbcModel::preProcess( int makeEquality, int numberPasses, int tuning)
     14101{
     14102  CglPreProcess * process = new CglPreProcess();
     14103  // Default set of cut generators
     14104  CglProbing generator1;
     14105  generator1.setUsingObjective(true);
     14106  generator1.setMaxPass(3);
     14107  generator1.setMaxProbeRoot(solver_->getNumCols());
     14108  generator1.setMaxElements(100);
     14109  generator1.setMaxLookRoot(50);
     14110  generator1.setRowCuts(3);
     14111  // Add in generators
     14112  process->addCutGenerator(&generator1);
     14113  process->messageHandler()->setLogLevel(this->logLevel());
     14114  /* model may not have created objects
     14115     If none then create
     14116  */
     14117  if (!numberIntegers_||!numberObjects_) {
     14118    this->findIntegers(true,1);
     14119  }
     14120  // Do SOS
     14121  int i;
     14122  int numberSOS2=0;
     14123  for (i=0;i<numberObjects_;i++) {
     14124    CbcSOS * objSOS =
     14125      dynamic_cast <CbcSOS *>(object_[i]) ;
     14126    if (objSOS) {
     14127      int type = objSOS->sosType();
     14128      if (type==2)
     14129        numberSOS2++;
     14130    }
     14131  }
     14132  if (numberSOS2) {
     14133    // SOS
     14134    int numberColumns = solver_->getNumCols();
     14135    char * prohibited = new char[numberColumns];
     14136    memset(prohibited,0,numberColumns);
     14137    for (i=0;i<numberObjects_;i++) {
     14138      CbcSOS * objSOS =
     14139        dynamic_cast <CbcSOS *>(object_[i]) ;
     14140      if (objSOS) {
     14141        int type = objSOS->sosType();
     14142        if (type==2) {
     14143          int n=objSOS->numberMembers();
     14144          const int * which = objSOS->members();
     14145          for (int j=0;j<n;j++) {
     14146            int iColumn = which[j];
     14147            prohibited[iColumn]=1;
     14148          }
     14149        }
     14150      }
     14151    }
     14152    process->passInProhibited(prohibited,numberColumns);
     14153    delete [] prohibited;
     14154  }
     14155  // Tell solver we are not in Branch and Cut
     14156  solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;
     14157  OsiSolverInterface * newSolver = process->preProcessNonDefault(*solver_, makeEquality,
     14158                                                                numberPasses, tuning);
     14159  // Tell solver we are not in Branch and Cut
     14160  solver_->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
     14161  if (newSolver) {
     14162    int numberOriginalObjects=numberObjects_;
     14163    OsiSolverInterface * originalSolver = solver_;
     14164    solver_=newSolver->clone(); // clone as process owns solver
     14165    // redo sequence
     14166    numberIntegers_=0;
     14167    int numberColumns = solver_->getNumCols();
     14168    int nOrig = originalSolver->getNumCols();
     14169    const int * originalColumns = process->originalColumns();
     14170    // allow for cliques etc
     14171    nOrig = CoinMax(nOrig,originalColumns[numberColumns-1]+1);
     14172    OsiObject ** originalObject = object_;
     14173    // object number or -1
     14174    int * temp = new int[nOrig];
     14175    int iColumn;
     14176    for (iColumn=0;iColumn<nOrig;iColumn++)
     14177      temp[iColumn]=-1;
     14178    int iObject;
     14179    numberObjects_=0;
     14180    int nNonInt=0;
     14181    for (iObject=0;iObject<numberOriginalObjects;iObject++) {
     14182      iColumn = originalObject[iObject]->columnNumber();
     14183      if (iColumn<0) {
     14184        nNonInt++;
     14185      } else {
     14186        temp[iColumn]=iObject;
     14187      }
     14188    }
     14189    int numberNewIntegers=0;
     14190    int numberOldIntegers=0;
     14191    int numberOldOther=0;
     14192    for (iColumn=0;iColumn<numberColumns;iColumn++) {
     14193      int jColumn = originalColumns[iColumn];
     14194      if (temp[jColumn]>=0) {
     14195        int iObject= temp[jColumn];
     14196        CbcSimpleInteger * obj =
     14197          dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ;
     14198        if (obj)
     14199          numberOldIntegers++;
     14200        else
     14201          numberOldOther++;
     14202      } else if (isInteger(iColumn)) {
     14203        numberNewIntegers++;
     14204      }
     14205    }
     14206    /*
     14207      Allocate an array to hold the indices of the integer variables.
     14208      Make a large enough array for all objects
     14209    */
     14210    numberObjects_= numberNewIntegers+numberOldIntegers+numberOldOther+nNonInt;
     14211    object_ = new OsiObject * [numberObjects_];
     14212    delete [] integerVariable_;
     14213    integerVariable_ = new int [numberNewIntegers+numberOldIntegers];
     14214    /*
     14215      Walk the variables again, filling in the indices and creating objects for
     14216      the integer variables. Initially, the objects hold the index and upper &
     14217      lower bounds.
     14218    */
     14219    numberIntegers_=0;
     14220    int n=originalColumns[numberColumns-1]+1;
     14221    int * backward = new int[n];
     14222    int i;
     14223    for ( i=0;i<n;i++)
     14224      backward[i]=-1;
     14225    for (i=0;i<numberColumns;i++)
     14226      backward[originalColumns[i]]=i;
     14227    for (iColumn=0;iColumn<numberColumns;iColumn++) {
     14228      int jColumn = originalColumns[iColumn];
     14229      if (temp[jColumn]>=0) {
     14230        int iObject= temp[jColumn];
     14231        CbcSimpleInteger * obj =
     14232          dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ;
     14233        if (obj) {
     14234          object_[numberIntegers_] = originalObject[iObject]->clone();
     14235          // redo ids etc
     14236          //object_[numberIntegers_]->resetSequenceEtc(numberColumns,originalColumns);
     14237          object_[numberIntegers_]->resetSequenceEtc(numberColumns,backward);
     14238          integerVariable_[numberIntegers_++]=iColumn;
     14239        }
     14240      } else if (isInteger(iColumn)) {
     14241        object_[numberIntegers_] =
     14242          new CbcSimpleInteger(this,iColumn);
     14243        integerVariable_[numberIntegers_++]=iColumn;
     14244      }
     14245    }
     14246    delete [] backward;
     14247    numberObjects_=numberIntegers_;
     14248    // Now append other column stuff
     14249    for (iColumn=0;iColumn<numberColumns;iColumn++) {
     14250      int jColumn = originalColumns[iColumn];
     14251      if (temp[jColumn]>=0) {
     14252        int iObject= temp[jColumn];
     14253        CbcSimpleInteger * obj =
     14254          dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ;
     14255        if (!obj) {
     14256          object_[numberObjects_] = originalObject[iObject]->clone();
     14257          // redo ids etc
     14258          CbcObject * obj =
     14259            dynamic_cast <CbcObject *>(object_[numberObjects_]) ;
     14260          assert (obj);
     14261          obj->redoSequenceEtc(this,numberColumns,originalColumns);
     14262          numberObjects_++;
     14263        }
     14264      }
     14265    }
     14266    // now append non column stuff
     14267    for (iObject=0;iObject<numberOriginalObjects;iObject++) {
     14268      iColumn = originalObject[iObject]->columnNumber();
     14269      if (iColumn<0) {
     14270        object_[numberObjects_] = originalObject[iObject]->clone();
     14271        // redo ids etc
     14272        CbcObject * obj =
     14273          static_cast <CbcObject *>(object_[numberObjects_]) ;
     14274        assert (obj);
     14275        obj->redoSequenceEtc(this,numberColumns,originalColumns);
     14276        numberObjects_++;
     14277      }
     14278      delete originalObject[iObject];
     14279    }
     14280    delete [] originalObject;
     14281    delete [] temp;
     14282    if (!numberObjects_)
     14283      handler_->message(CBC_NOINT,messages_) << CoinMessageEol ;
     14284    return process;
     14285  } else {
     14286    // infeasible
     14287    delete process;
     14288    return NULL;
     14289  }
     14290   
     14291}
     14292/* Does postprocessing - original solver back.
     14293   User has to delete process */
     14294void
     14295CbcModel::postProcess(CglPreProcess * process)
     14296{
     14297  process->postProcess(*solver_);
     14298  delete solver_;
     14299  solver_ = process->originalModel();
     14300}
     14301/* Process root node and return a strengthened model
     14302   
     14303The method assumes that initialSolve() has been called to solve the
     14304LP relaxation. It processes the root node and then returns a pointer
     14305to the strengthened model (or NULL if infeasible)
     14306*/
     14307OsiSolverInterface * 
     14308CbcModel::strengthenedModel()
     14309{
     14310/*
     14311  Switch off heuristics
     14312*/
     14313  int saveNumberHeuristics=numberHeuristics_;
     14314  numberHeuristics_=0;
     14315/*
     14316  Scan the variables, noting the integer variables. Create an
     14317  CbcSimpleInteger object for each integer variable.
     14318*/
     14319  findIntegers(false) ;
     14320/*
     14321  Ensure that objects on the lists of OsiObjects, heuristics, and cut
     14322  generators attached to this model all refer to this model.
     14323*/
     14324  synchronizeModel() ;
     14325
     14326  if (!solverCharacteristics_) {
     14327    OsiBabSolver * solverCharacteristics = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
     14328    if (solverCharacteristics) {
     14329      solverCharacteristics_ = solverCharacteristics;
     14330    } else {
     14331      // replace in solver
     14332      OsiBabSolver defaultC;
     14333      solver_->setAuxiliaryInfo(&defaultC);
     14334      solverCharacteristics_ = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
     14335    }
     14336  }
     14337
     14338  solverCharacteristics_->setSolver(solver_);
     14339  // Set so we can tell we are in initial phase in resolve
     14340  continuousObjective_ = -COIN_DBL_MAX ;
     14341/*
     14342  Solve the relaxation.
     14343
     14344  Apparently there are circumstances where this will be non-trivial --- i.e.,
     14345  we've done something since initialSolve that's trashed the solution to the
     14346  continuous relaxation.
     14347*/
     14348  bool feasible = resolve(NULL,0) != 0 ;
     14349/*
     14350  If the linear relaxation of the root is infeasible, bail out now. Otherwise,
     14351  continue with processing the root node.
     14352*/
     14353  if (!feasible)
     14354  { handler_->message(CBC_INFEAS,messages_)<< CoinMessageEol ;
     14355    return NULL; }
     14356  // Save objective (just so user can access it)
     14357  originalContinuousObjective_ = solver_->getObjValue();
     14358
     14359/*
     14360  Begin setup to process a feasible root node.
     14361*/
     14362  bestObjective_ = CoinMin(bestObjective_,1.0e50) ;
     14363  numberSolutions_ = 0 ;
     14364  numberHeuristicSolutions_ = 0 ;
     14365  // Everything is minimization
     14366  double cutoff=getCutoff() ;
     14367  double direction = solver_->getObjSense() ;
     14368  if (cutoff < 1.0e20&&direction<0.0)
     14369    messageHandler()->message(CBC_CUTOFF_WARNING1,
     14370                                    messages())
     14371                                      << cutoff << -cutoff << CoinMessageEol ;
     14372  if (cutoff > bestObjective_)
     14373    cutoff = bestObjective_ ;
     14374  setCutoff(cutoff) ;
     14375/*
     14376  We probably already have a current solution, but just in case ...
     14377*/
     14378  int numberColumns = getNumCols() ;
     14379  if (!currentSolution_)
     14380    currentSolution_ = new double[numberColumns] ;
     14381  testSolution_=currentSolution_;
     14382/*
     14383  Create a copy of the solver, thus capturing the original (root node)
     14384  constraint system (aka the continuous system).
     14385*/
     14386  continuousSolver_ = solver_->clone() ;
     14387  numberRowsAtContinuous_ = getNumRows() ;
     14388/*
     14389  Check the objective to see if we can deduce a nontrivial increment. If
     14390  it's better than the current value for CbcCutoffIncrement, it'll be
     14391  installed.
     14392*/
     14393  analyzeObjective() ;
     14394/*
     14395  Set up for cut generation. addedCuts_ holds the cuts which are relevant for
     14396  the active subproblem. whichGenerator will be used to record the generator
     14397  that produced a given cut.
     14398*/
     14399  maximumWhich_ = 1000 ;
     14400  delete [] whichGenerator_ ;
     14401  whichGenerator_ = new int[maximumWhich_] ;
     14402  maximumNumberCuts_ = 0 ;
     14403  currentNumberCuts_ = 0 ;
     14404  delete [] addedCuts_ ;
     14405  addedCuts_ = NULL ;
     14406  /* 
     14407  Generate cuts at the root node and reoptimise. solveWithCuts does the heavy
     14408  lifting. It will iterate a generate/reoptimise loop (including reduced cost
     14409  fixing) until no cuts are generated, the change in objective falls off,  or
     14410  the limit on the number of rounds of cut generation is exceeded.
     14411
     14412  At the end of all this, any cuts will be recorded in cuts and also
     14413  installed in the solver's constraint system. We'll have reoptimised, and
     14414  removed any slack cuts (numberOldActiveCuts_ and numberNewCuts_ have been
     14415  adjusted accordingly).
     14416
     14417  Tell cut generators they can be a bit more aggressive at root node
     14418
     14419*/
     14420  int iCutGenerator;
     14421  for (iCutGenerator = 0;iCutGenerator<numberCutGenerators_;iCutGenerator++) {
     14422    CglCutGenerator * generator = generator_[iCutGenerator]->generator();
     14423    generator->setAggressiveness(generator->getAggressiveness()+100);
     14424  }
     14425  OsiCuts cuts ;
     14426  numberOldActiveCuts_ = 0 ;
     14427  numberNewCuts_ = 0 ;
     14428  { int iObject ;
     14429    int preferredWay ;
     14430    int numberUnsatisfied = 0 ;
     14431    memcpy(currentSolution_,solver_->getColSolution(),
     14432           numberColumns*sizeof(double)) ;
     14433
     14434    // point to useful information
     14435    OsiBranchingInformation usefulInfo=usefulInformation();
     14436    for (iObject = 0 ; iObject < numberObjects_ ; iObject++)
     14437    { double infeasibility =
     14438          object_[iObject]->infeasibility(&usefulInfo,preferredWay) ;
     14439      if (infeasibility) numberUnsatisfied++ ; }
     14440    if (numberUnsatisfied)
     14441    { feasible = solveWithCuts(cuts,maximumCutPassesAtRoot_,
     14442                               NULL) ; } }
     14443/*
     14444  We've taken the continuous relaxation as far as we can.
     14445*/
     14446
     14447  OsiSolverInterface * newSolver=NULL;
     14448  if (feasible) {
     14449    // make copy of current solver
     14450    newSolver = solver_->clone();
     14451  }
     14452/*
     14453  Clean up dangling objects. continuousSolver_ may already be toast.
     14454*/
     14455  delete [] whichGenerator_ ;
     14456  whichGenerator_ = NULL;
     14457  delete [] walkback_ ;
     14458  walkback_ = NULL ;
     14459  delete [] lastNodeInfo_ ;
     14460  lastNodeInfo_ = NULL;
     14461  delete [] lastNumberCuts_ ;
     14462  lastNumberCuts_ = NULL;
     14463  delete [] lastCut_;
     14464  lastCut_ = NULL;
     14465  delete [] addedCuts_ ;
     14466  addedCuts_ = NULL ;
     14467  if (continuousSolver_)
     14468  { delete continuousSolver_ ;
     14469    continuousSolver_ = NULL ; }
     14470/*
     14471  Destroy global cuts by replacing with an empty OsiCuts object.
     14472*/
     14473  globalCuts_= OsiCuts() ;
     14474  numberHeuristics_ = saveNumberHeuristics;
     14475 
     14476  return newSolver;
     14477}
     14478/*  create a submodel from partially fixed problem
     14479
     14480The method creates a new clean model with given bounds.
     14481*/
     14482CbcModel * 
     14483CbcModel::cleanModel(const double * lower, const double * upper)
     14484{
     14485  OsiSolverInterface * solver = continuousSolver_->clone();
     14486
     14487  int numberIntegers = numberIntegers_;
     14488  const int * integerVariable = integerVariable_;
     14489 
     14490  int i;
     14491  for (i=0;i<numberIntegers;i++) {
     14492    int iColumn=integerVariable[i];
     14493    const OsiObject * object = object_[i];
     14494#ifndef NDEBUG
     14495    const CbcSimpleInteger * integerObject =
     14496      dynamic_cast<const  CbcSimpleInteger *> (object);
     14497    assert(integerObject);
     14498#else
     14499    const CbcSimpleInteger * integerObject =
     14500      static_cast<const  CbcSimpleInteger *> (object);
     14501#endif
     14502    // get original bounds
     14503    double originalLower = integerObject->originalLowerBound();
     14504    double originalUpper = integerObject->originalUpperBound();
     14505    solver->setColLower(iColumn,CoinMax(lower[iColumn],originalLower));
     14506    solver->setColUpper(iColumn,CoinMin(upper[iColumn],originalUpper));
     14507  }
     14508  CbcModel * model = new CbcModel(*solver);
     14509  // off some messages
     14510  if (handler_->logLevel()<=1) {
     14511    model->messagesPointer()->setDetailMessage(3,9);
     14512    model->messagesPointer()->setDetailMessage(3,6);
     14513    model->messagesPointer()->setDetailMessage(3,4);
     14514    model->messagesPointer()->setDetailMessage(3,1);
     14515    model->messagesPointer()->setDetailMessage(3,13);
     14516    model->messagesPointer()->setDetailMessage(3,14);
     14517    model->messagesPointer()->setDetailMessage(3,3007);
     14518  }
     14519  // Cuts
     14520  for ( i = 0;i<numberCutGenerators_;i++) {
     14521    int howOften = generator_[i]->howOftenInSub();
     14522    if (howOften>-100) {
     14523      CbcCutGenerator * generator = virginGenerator_[i];
     14524      CglCutGenerator * cglGenerator = generator->generator();
     14525      model->addCutGenerator(cglGenerator,howOften,
     14526                              generator->cutGeneratorName(),
     14527                              generator->normal(),
     14528                              generator->atSolution(),
     14529                              generator->whenInfeasible(),
     14530                              -100, generator->whatDepthInSub(),-1);
     14531    }
     14532  }
     14533  double cutoff = getCutoff();
     14534  model->setCutoff(cutoff);
     14535  return model;
     14536}
     14537/* Invoke the branch & cut algorithm on partially fixed problem
     14538   
     14539   The method uses a subModel created by cleanModel. The search
     14540   ends when the tree is exhausted or maximum nodes is reached.
     14541
     14542   If better solution found then it is saved.
     14543   
     14544   Returns 0 if search completed and solution, 1 if not completed and solution,
     14545   2 if completed and no solution, 3 if not completed and no solution.
     14546   
     14547   Normally okay to do subModel immediately followed by subBranchandBound
     14548   (== other form of subBranchAndBound)
     14549   but may need to get at model for advanced features.
     14550   
     14551   Deletes model
     14552   
     14553*/
     14554 
     14555int
     14556CbcModel::subBranchAndBound(CbcModel * model,
     14557                            CbcModel * presolvedModel,
     14558                            int maximumNodes)
     14559{
     14560  int i;
     14561  double cutoff=model->getCutoff();
     14562  CbcModel * model2;
     14563  if (presolvedModel)
     14564    model2=presolvedModel;
     14565  else
     14566    model2=model;
     14567  // Do complete search
     14568 
     14569  for (i=0;i<numberHeuristics_;i++) {
     14570    model2->addHeuristic(heuristic_[i]);
     14571    model2->heuristic(i)->resetModel(model2);
     14572  }
     14573  // Definition of node choice
     14574  model2->setNodeComparison(nodeCompare_->clone());
     14575  //model2->solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
     14576  model2->messageHandler()->setLogLevel(CoinMax(0,handler_->logLevel()-1));
     14577  //model2->solver()->messageHandler()->setLogLevel(2);
     14578  model2->setMaximumCutPassesAtRoot(maximumCutPassesAtRoot_);
     14579  model2->setPrintFrequency(50);
     14580  model2->setIntParam(CbcModel::CbcMaxNumNode,maximumNodes);
     14581  model2->branchAndBound();
     14582  delete model2->nodeComparison();
     14583  if (model2->getMinimizationObjValue()>cutoff) {
     14584    // no good
     14585    if (model!=model2)
     14586      delete model2;
     14587    delete model;
     14588    return 2;
     14589  }
     14590  if (model!=model2) {
     14591    // get back solution
     14592    model->originalModel(model2,false);
     14593    delete model2;
     14594  }
     14595  int status;
     14596  if (model->getMinimizationObjValue()<cutoff&&model->bestSolution()) {
     14597    double objValue = model->getObjValue();
     14598    const double * solution = model->bestSolution();
     14599    setBestSolution(CBC_TREE_SOL,objValue,solution);
     14600    status = 0;
     14601  } else {
     14602    status=2;
     14603  }
     14604  if (model->status())
     14605    status ++ ; // not finished search
     14606  delete model;
     14607  return status;
     14608}
     14609/* Invoke the branch & cut algorithm on partially fixed problem
     14610   
     14611The method creates a new model with given bounds, presolves it
     14612then proceeds to explore the branch & cut search tree. The search
     14613ends when the tree is exhausted or maximum nodes is reached.
     14614Returns 0 if search completed and solution, 1 if not completed and solution,
     146152 if completed and no solution, 3 if not completed and no solution.
     14616*/
     14617int
     14618CbcModel::subBranchAndBound(const double * lower, const double * upper,
     14619                            int maximumNodes)
     14620{
     14621  OsiSolverInterface * solver = continuousSolver_->clone();
     14622
     14623  int numberIntegers = numberIntegers_;
     14624  const int * integerVariable = integerVariable_;
     14625 
     14626  int i;
     14627  for (i=0;i<numberIntegers;i++) {
     14628    int iColumn=integerVariable[i];
     14629    const OsiObject * object = object_[i];
     14630#ifndef NDEBUG
     14631    const CbcSimpleInteger * integerObject =
     14632      dynamic_cast<const  CbcSimpleInteger *> (object);
     14633    assert(integerObject);
     14634#else
     14635    const CbcSimpleInteger * integerObject =
     14636      static_cast<const  CbcSimpleInteger *> (object);
     14637#endif
     14638    // get original bounds
     14639    double originalLower = integerObject->originalLowerBound();
     14640    double originalUpper = integerObject->originalUpperBound();
     14641    solver->setColLower(iColumn,CoinMax(lower[iColumn],originalLower));
     14642    solver->setColUpper(iColumn,CoinMin(upper[iColumn],originalUpper));
     14643  }
     14644  CbcModel model(*solver);
     14645  // off some messages
     14646  if (handler_->logLevel()<=1) {
     14647    model.messagesPointer()->setDetailMessage(3,9);
     14648    model.messagesPointer()->setDetailMessage(3,6);
     14649    model.messagesPointer()->setDetailMessage(3,4);
     14650    model.messagesPointer()->setDetailMessage(3,1);
     14651    model.messagesPointer()->setDetailMessage(3,3007);
     14652  }
     14653  double cutoff = getCutoff();
     14654  model.setCutoff(cutoff);
     14655  // integer presolve
     14656  CbcModel * model2 = model.integerPresolve(false);
     14657  if (!model2||!model2->getNumRows()) {
     14658    delete model2;
     14659    delete solver;
     14660    return 2;
     14661  }
     14662  if (handler_->logLevel()>1)
     14663    printf("Reduced model has %d rows and %d columns\n",
     14664           model2->getNumRows(),model2->getNumCols());
     14665  // Do complete search
     14666 
     14667  // Cuts
     14668  for ( i = 0;i<numberCutGenerators_;i++) {
     14669    int howOften = generator_[i]->howOftenInSub();
     14670    if (howOften>-100) {
     14671      CbcCutGenerator * generator = virginGenerator_[i];
     14672      CglCutGenerator * cglGenerator = generator->generator();
     14673      model2->addCutGenerator(cglGenerator,howOften,
     14674                              generator->cutGeneratorName(),
     14675                              generator->normal(),
     14676                              generator->atSolution(),
     14677                              generator->whenInfeasible(),
     14678                              -100, generator->whatDepthInSub(),-1);
     14679    }
     14680  }
     14681  for (i=0;i<numberHeuristics_;i++) {
     14682    model2->addHeuristic(heuristic_[i]);
     14683    model2->heuristic(i)->resetModel(model2);
     14684  }
     14685  // Definition of node choice
     14686  model2->setNodeComparison(nodeCompare_->clone());
     14687  //model2->solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
     14688  model2->messageHandler()->setLogLevel(CoinMax(0,handler_->logLevel()-1));
     14689  //model2->solver()->messageHandler()->setLogLevel(2);
     14690  model2->setMaximumCutPassesAtRoot(maximumCutPassesAtRoot_);
     14691  model2->setPrintFrequency(50);
     14692  model2->setIntParam(CbcModel::CbcMaxNumNode,maximumNodes);
     14693  model2->branchAndBound();
     14694  delete model2->nodeComparison();
     14695  if (model2->getMinimizationObjValue()>cutoff) {
     14696    // no good
     14697    delete model2;
     14698    delete solver;
     14699    return 2;
     14700  }
     14701  // get back solution
     14702  model.originalModel(model2,false);
     14703  delete model2;
     14704  int status;
     14705  if (model.getMinimizationObjValue()<cutoff&&model.bestSolution()) {
     14706    double objValue = model.getObjValue();
     14707    const double * solution = model.bestSolution();
     14708    setBestSolution(CBC_TREE_SOL,objValue,solution);
     14709    status = 0;
     14710  } else {
     14711    status=2;
     14712  }
     14713  if (model.status())
     14714    status ++ ; // not finished search
     14715  delete solver;
     14716  return status;
     14717}
     14718#endif
  • trunk/Cbc/src/CbcModel.hpp

    r1165 r1167  
    197197    */
    198198     void branchAndBound(int doStatistics=0);
    199 
    200     /** \brief create a clean model from partially fixed problem
    201 
    202       The method creates a new model with given bounds and with no tree.
    203     */
    204      CbcModel *  cleanModel(const double * lower, const double * upper);
    205     /** \brief Invoke the branch \& cut algorithm on partially fixed problem
    206 
    207       The method presolves the given model and does branch and cut. The search
    208       ends when the tree is exhausted or maximum nodes is reached.
    209 
    210       If better solution found then it is saved.
    211 
    212       Returns 0 if search completed and solution, 1 if not completed and solution,
    213       2 if completed and no solution, 3 if not completed and no solution.
    214 
    215       Normally okay to do cleanModel immediately followed by subBranchandBound
    216       (== other form of subBranchAndBound)
    217       but may need to get at model for advanced features.
    218 
    219       Deletes model2
    220     */
    221      int subBranchAndBound(CbcModel * model2,
    222                            CbcModel * presolvedModel,
    223                            int maximumNodes);
    224     /** \brief Invoke the branch \& cut algorithm on partially fixed problem
    225 
    226       The method creates a new model with given bounds, presolves it
    227       then proceeds to explore the branch & cut search tree. The search
    228       ends when the tree is exhausted or maximum nodes is reached.
    229 
    230       If better solution found then it is saved.
    231 
    232       Returns 0 if search completed and solution, 1 if not completed and solution,
    233       2 if completed and no solution, 3 if not completed and no solution.
    234 
    235       This is just subModel immediately followed by other version of
    236       subBranchandBound.
    237 
    238     */
    239      int subBranchAndBound(const double * lower, const double * upper,
    240                             int maximumNodes);
    241 
    242     /** \brief Process root node and return a strengthened model
    243 
    244       The method assumes that initialSolve() has been called to solve the
    245       LP relaxation. It processes the root node and then returns a pointer
    246       to the strengthened model (or NULL if infeasible)
    247     */
    248      OsiSolverInterface *  strengthenedModel();
    249   /** preProcess problem - replacing solver
    250       If makeEquality true then <= cliques converted to ==.
    251       Presolve will be done numberPasses times.
    252 
    253       Returns NULL if infeasible
    254 
    255       If makeEquality is 1 add slacks to get cliques,
    256       if 2 add slacks to get sos (but only if looks plausible) and keep sos info
    257   */
    258   CglPreProcess * preProcess( int makeEquality=0, int numberPasses=5,
    259                   int tuning=5);
    260   /** Does postprocessing - original solver back.
    261       User has to delete process */
    262   void postProcess(CglPreProcess * process);
    263199private:
    264200    /** \brief Evaluate a subproblem using cutting planes and heuristics
     
    281217  void resizeWhichGenerator(int numberNow, int numberAfter);
    282218public:
     219#ifdef CBC_KEEP_DEPRECATED
     220  // See if anyone is using these any more!!
     221    /** \brief create a clean model from partially fixed problem
     222
     223      The method creates a new model with given bounds and with no tree.
     224    */
     225     CbcModel *  cleanModel(const double * lower, const double * upper);
     226    /** \brief Invoke the branch \& cut algorithm on partially fixed problem
     227
     228      The method presolves the given model and does branch and cut. The search
     229      ends when the tree is exhausted or maximum nodes is reached.
     230
     231      If better solution found then it is saved.
     232
     233      Returns 0 if search completed and solution, 1 if not completed and solution,
     234      2 if completed and no solution, 3 if not completed and no solution.
     235
     236      Normally okay to do cleanModel immediately followed by subBranchandBound
     237      (== other form of subBranchAndBound)
     238      but may need to get at model for advanced features.
     239
     240      Deletes model2
     241    */
     242     int subBranchAndBound(CbcModel * model2,
     243                           CbcModel * presolvedModel,
     244                           int maximumNodes);
     245    /** \brief Invoke the branch \& cut algorithm on partially fixed problem
     246
     247      The method creates a new model with given bounds, presolves it
     248      then proceeds to explore the branch & cut search tree. The search
     249      ends when the tree is exhausted or maximum nodes is reached.
     250
     251      If better solution found then it is saved.
     252
     253      Returns 0 if search completed and solution, 1 if not completed and solution,
     254      2 if completed and no solution, 3 if not completed and no solution.
     255
     256      This is just subModel immediately followed by other version of
     257      subBranchandBound.
     258
     259    */
     260     int subBranchAndBound(const double * lower, const double * upper,
     261                            int maximumNodes);
     262
     263    /** \brief Process root node and return a strengthened model
     264
     265      The method assumes that initialSolve() has been called to solve the
     266      LP relaxation. It processes the root node and then returns a pointer
     267      to the strengthened model (or NULL if infeasible)
     268    */
     269     OsiSolverInterface *  strengthenedModel();
     270  /** preProcess problem - replacing solver
     271      If makeEquality true then <= cliques converted to ==.
     272      Presolve will be done numberPasses times.
     273
     274      Returns NULL if infeasible
     275
     276      If makeEquality is 1 add slacks to get cliques,
     277      if 2 add slacks to get sos (but only if looks plausible) and keep sos info
     278  */
     279  CglPreProcess * preProcess( int makeEquality=0, int numberPasses=5,
     280                  int tuning=5);
     281  /** Does postprocessing - original solver back.
     282      User has to delete process */
     283  void postProcess(CglPreProcess * process);
     284#endif
    283285  /// Adds an update information object
    284286  void addUpdateInformation(const CbcObjectUpdateData & data);
     
    906908  /// Whether or not integer
    907909  inline char integerType(int i) const
    908   { return integerInfo_[i];}
     910  { assert (integerInfo_); assert (integerInfo_[i]==0||integerInfo_[i]==1);return integerInfo_[i];}
    909911  /// Whether or not integer
    910912  inline const char * integerType() const
  • trunk/Cbc/src/CbcSolver.cpp

    r1165 r1167  
    41264126    // Set up likely cut generators and defaults
    41274127    int nodeStrategy=0;
     4128    bool dominatedCuts=false;
    41284129    int doSOS=1;
    41294130    int verbose=0;
     
    42024203
    42034204    // Stored cuts
    4204     bool storedCuts = false;
     4205    //bool storedCuts = false;
    42054206
    42064207    int useCosts=0;
     
    54345435            break;
    54355436          case OUTDUPROWS:
     5437            dominatedCuts=true;
     5438#if 0
    54365439            if (goodModel) {
    54375440              int numberRows = clpSolver->getNumRows();
     
    54505453#endif
    54515454            }
     5455#endif
    54525456            break;
    54535457          case NETWORK:
     
    55765580*/
    55775581          case BAB: // branchAndBound
    5578           case STRENGTHEN:
     5582            // obsolete case STRENGTHEN:
    55795583            if (goodModel) {
    55805584              bool miplib = type==MIPLIB;
     
    66486652              }
    66496653#endif
    6650               if (storedCuts)
     6654              if (dominatedCuts)
    66516655                babModel_->setSpecialOptions(babModel_->specialOptions()|64);
    66526656              // Say we want timings
     
    67986802              babModel_->setSpecialOptions(babModel_->specialOptions()|2);
    67996803              currentBranchModel = babModel_;
    6800               OsiSolverInterface * strengthenedModel=NULL;
     6804              //OsiSolverInterface * strengthenedModel=NULL;
    68016805              if (type==BAB||type==MIPLIB) {
    68026806                if (experimentFlag==2||strategyFlag==1) {
     
    80528056                stuff[9]=doVector;
    80538057                stuff[10] = parameters_[whichParam(SMALLFACT,numberParameters_,parameters_)].intValue();
     8058                if ( dominatedCuts)
     8059                  model_.setSpecialOptions(model_.specialOptions()|64);
    80548060                if (parameters_[whichParam(CPX,numberParameters_,parameters_)].currentOptionAsInteger()) {
    80558061                  model_.setSpecialOptions(model_.specialOptions()|16384);
     
    80858091                return returnCode;
    80868092              } else {
    8087                 strengthenedModel = babModel_->strengthenedModel();
     8093                abort(); // can't get here
     8094                //strengthenedModel = babModel_->strengthenedModel();
    80888095              }
    80898096              currentBranchModel = NULL;
     
    83598366              }
    83608367#ifndef CBC_OTHER_SOLVER
    8361               if (type==STRENGTHEN&&strengthenedModel)
    8362                 clpSolver = dynamic_cast< OsiClpSolverInterface*> (strengthenedModel);
     8368              //if (type==STRENGTHEN&&strengthenedModel)
     8369              //clpSolver = dynamic_cast< OsiClpSolverInterface*> (strengthenedModel);
    83638370#ifdef COIN_HAS_ASL
    83648371              else if (statusUserFunction_[0])
Note: See TracChangeset for help on using the changeset viewer.