Changeset 44


Ignore:
Timestamp:
Dec 20, 2004 12:13:29 PM (15 years ago)
Author:
forrest
Message:

try and make more robust

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/CbcFathomDynamicProgramming.cpp

    r43 r44  
    176176  // check possible (at present do not allow covering)
    177177  int numberActive=0;
     178  bool infeasible=false;
     179  bool saveBad=bad;
    178180  for (i=0;i<numberRows;i++) {
    179     if (rhs[i]>1.0e5||fabs(rhs[i]-floor(rhs[i]+0.5))>1.0e-7)
     181    if (rhs[i]<0)
     182      infeasible=true;
     183    else if (rhs[i]>1.0e5||fabs(rhs[i]-floor(rhs[i]+0.5))>1.0e-7)
    180184      bad=true;
    181185    else if (rhs[i]>0.0)
    182186      numberActive++;
    183187  }
    184   if (bad) {
     188  if (bad||infeasible) {
    185189    delete [] rhs;
    186     return -1;
     190    if (!saveBad&&infeasible)
     191      return -2;
     192    else
     193      return -1;
    187194  }
    188195  // check size of array needed
     
    440447{
    441448  int returnCode=0;
    442   checkPossible(maximumSizeAllowed_);
     449  int type=checkPossible(maximumSizeAllowed_);
     450  assert (type!=-1);
     451  if (type==-2) {
     452    // infeasible (so complete search done)
     453    return 1;
     454  }
    443455  if (algorithm_>=0) {
    444456    OsiSolverInterface * solver = model_->solver();
     
    475487      tryColumn(columnLength[i],row+start,element+start,cost,gap);
    476488      if (cost_[target_]<bestAtTarget) {
    477         printf("At column %d new best objective of %g\n",i,cost_[target_]);
     489        if (model_->messageHandler()->logLevel()>1)
     490          printf("At column %d new best objective of %g\n",i,cost_[target_]);
    478491        bestAtTarget = cost_[target_];
    479492      }
     
    543556    if (bestValue<FLT_MAX) {
    544557      bestValue += fixedObj;
    545       printf("Can get solution of %g\n",bestValue);
     558      if (model_->messageHandler()->logLevel()>1)
     559        printf("Can get solution of %g\n",bestValue);
    546560      if (bestValue<model_->getMinimizationObjValue()) {
    547561        // set up solution
     
    604618      }
    605619      if (feasible) {
    606         if (model_->messageHandler()->logLevel()>1)
    607           printf("** good solution by dynamic programming\n");
     620        if (model_->messageHandler()->logLevel()>0)
     621          printf("** good solution of %g by dynamic programming\n",bestValue);
    608622      }
    609623      delete [] rowActivity;
     
    870884      assert (value<size);
    871885      maskAdd |= start*value;
    872       int gap = size-rhs_[iRow]-1;
    873       assert (gap>=0);
     886      int gap = size-rhs_[iRow]+value-1;
     887      assert (gap>0&&gap<=size-1);
    874888      maskC |= start*gap;
    875889      maskD |= start*(size-1);
  • trunk/CbcModel.cpp

    r36 r44  
    10401040      else
    10411041      {
    1042         tree_->cleanTree(this,-DBL_MAX) ;
     1042        tree_->cleanTree(this,-COIN_DBL_MAX) ;
    10431043        delete nextRowCut_;
    10441044        // We need to get rid of node if is has already been popped from tree
     
    12491249  howOftenGlobalScan_(1),
    12501250  numberGlobalViolations_(0),
    1251   continuousObjective_(DBL_MAX),
    1252   originalContinuousObjective_(DBL_MAX),
     1251  continuousObjective_(COIN_DBL_MAX),
     1252  originalContinuousObjective_(COIN_DBL_MAX),
    12531253  continuousInfeasibilities_(INT_MAX),
    12541254  maximumCutPassesAtRoot_(20),
     
    13211321  howOftenGlobalScan_(1),
    13221322  numberGlobalViolations_(0),
    1323   continuousObjective_(DBL_MAX),
    1324   originalContinuousObjective_(DBL_MAX),
     1323  continuousObjective_(COIN_DBL_MAX),
     1324  originalContinuousObjective_(COIN_DBL_MAX),
    13251325  continuousInfeasibilities_(INT_MAX),
    13261326  maximumCutPassesAtRoot_(20),
     
    14441444// Copy constructor.
    14451445
    1446 CbcModel::CbcModel(const CbcModel & rhs)
     1446CbcModel::CbcModel(const CbcModel & rhs, bool noTree)
    14471447:
    14481448  continuousSolver_(NULL),
     
    15061506    virginGenerator_=NULL;
    15071507  }
    1508   globalCuts_ = rhs.globalCuts_;
     1508  if (!noTree)
     1509    globalCuts_ = rhs.globalCuts_;
    15091510  numberHeuristics_ = rhs.numberHeuristics_;
    15101511  if (numberHeuristics_) {
     
    15321533    priority_=NULL;
    15331534  }
    1534   solver_ = rhs.solver_->clone();
     1535  if (!noTree||!rhs.continuousSolver_)
     1536    solver_ = rhs.solver_->clone();
     1537  else
     1538    solver_ = rhs.continuousSolver_->clone();
    15351539  if (rhs.originalColumns_) {
    15361540    int numberColumns = solver_->getNumCols();
     
    15541558    integerVariable_ = NULL;
    15551559  }
    1556   if (rhs.bestSolution_) {
     1560  if (rhs.bestSolution_&&!noTree) {
    15571561    int numberColumns = solver_->getNumCols();
    15581562    bestSolution_ = new double[numberColumns];
     
    15611565    bestSolution_=NULL;
    15621566  }
    1563   if (rhs.currentSolution_) {
     1567  if (rhs.currentSolution_&&!noTree) {
    15641568    int numberColumns = solver_->getNumCols();
    15651569    currentSolution_ = new double[numberColumns];
     
    15731577  currentNumberCuts_=rhs.currentNumberCuts_;
    15741578  maximumDepth_= rhs.maximumDepth_;
     1579  if (noTree) {
     1580    bestObjective_ = COIN_DBL_MAX;
     1581    numberSolutions_ =0;
     1582    numberHeuristicSolutions_=0;
     1583    numberNodes_=0;
     1584    numberIterations_=0;
     1585    status_=0;
     1586    subTreeModel_=NULL;
     1587    numberStoppedSubTrees_=0;
     1588    continuousObjective_=COIN_DBL_MAX;
     1589    originalContinuousObjective_=COIN_DBL_MAX;
     1590    continuousInfeasibilities_=INT_MAX;
     1591    maximumNumberCuts_=0;
     1592    tree_->cleanTree(this,-COIN_DBL_MAX);
     1593  }
    15751594  // These are only used as temporary arrays so need not be filled
    15761595  if (maximumNumberCuts_) {
     
    40114030     
    40124031    }
    4013     solver->addRow(newRow,-DBL_MAX,useCutoff);
     4032    solver->addRow(newRow,-COIN_DBL_MAX,useCutoff);
    40144033    // signal no objective
    40154034    delete [] objective;
    40164035    objective=NULL;
    40174036  }
    4018   setCutoff(DBL_MAX);
     4037  setCutoff(COIN_DBL_MAX);
    40194038
    40204039
     
    47594778  return appData_;
    47604779}
     4780/*  create a submodel from partially fixed problem
     4781
     4782The method creates a new clean model with given bounds.
     4783*/
     4784CbcModel * 
     4785CbcModel::cleanModel(const double * lower, const double * upper)
     4786{
     4787  OsiSolverInterface * solver = continuousSolver_->clone();
     4788
     4789  int numberIntegers = numberIntegers_;
     4790  const int * integerVariable = integerVariable_;
     4791 
     4792  int i;
     4793  for (i=0;i<numberIntegers;i++) {
     4794    int iColumn=integerVariable[i];
     4795    const CbcObject * object = object_[i];
     4796    const CbcSimpleInteger * integerObject =
     4797      dynamic_cast<const  CbcSimpleInteger *> (object);
     4798    assert(integerObject);
     4799    // get original bounds
     4800    double originalLower = integerObject->originalLowerBound();
     4801    double originalUpper = integerObject->originalUpperBound();
     4802    solver->setColLower(iColumn,CoinMax(lower[iColumn],originalLower));
     4803    solver->setColUpper(iColumn,CoinMin(upper[iColumn],originalUpper));
     4804  }
     4805  CbcModel * model = new CbcModel(*solver);
     4806  // off some messages
     4807  if (handler_->logLevel()<=1) {
     4808    model->messagesPointer()->setDetailMessage(3,9);
     4809    model->messagesPointer()->setDetailMessage(3,6);
     4810    model->messagesPointer()->setDetailMessage(3,4);
     4811    model->messagesPointer()->setDetailMessage(3,1);
     4812    model->messagesPointer()->setDetailMessage(3,13);
     4813    model->messagesPointer()->setDetailMessage(3,14);
     4814    model->messagesPointer()->setDetailMessage(3,3007);
     4815  }
     4816  // Cuts
     4817  for ( i = 0;i<numberCutGenerators_;i++) {
     4818    int howOften = generator_[i]->howOftenInSub();
     4819    if (howOften>-100) {
     4820      CbcCutGenerator * generator = virginGenerator_[i];
     4821      CglCutGenerator * cglGenerator = generator->generator();
     4822      model->addCutGenerator(cglGenerator,howOften,
     4823                              generator->cutGeneratorName(),
     4824                              generator->normal(),
     4825                              generator->atSolution(),
     4826                              generator->whenInfeasible(),
     4827                              -100, generator->whatDepthInSub(),-1);
     4828    }
     4829  }
     4830  double cutoff = getCutoff();
     4831  model->setCutoff(cutoff);
     4832  return model;
     4833}
     4834/* Invoke the branch & cut algorithm on partially fixed problem
     4835   
     4836   The method uses a subModel created by cleanModel. The search
     4837   ends when the tree is exhausted or maximum nodes is reached.
     4838
     4839   If better solution found then it is saved.
     4840   
     4841   Returns 0 if search completed and solution, 1 if not completed and solution,
     4842   2 if completed and no solution, 3 if not completed and no solution.
     4843   
     4844   Normally okay to do subModel immediately followed by subBranchandBound
     4845   (== other form of subBranchAndBound)
     4846   but may need to get at model for advanced features.
     4847   
     4848   Deletes model
     4849   
     4850*/
     4851 
     4852int
     4853CbcModel::subBranchAndBound(CbcModel * model,
     4854                            CbcModel * presolvedModel,
     4855                            int maximumNodes)
     4856{
     4857  int i;
     4858  double cutoff=model->getCutoff();
     4859  CbcModel * model2;
     4860  if (presolvedModel)
     4861    model2=presolvedModel;
     4862  else
     4863    model2=model;
     4864  // Do complete search
     4865 
     4866  for (i=0;i<numberHeuristics_;i++) {
     4867    model2->addHeuristic(heuristic_[i]);
     4868    model2->heuristic(i)->resetModel(model2);
     4869  }
     4870  // Definition of node choice
     4871  model2->setNodeComparison(nodeCompare_->clone());
     4872  //model2->solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
     4873  model2->messageHandler()->setLogLevel(CoinMax(0,handler_->logLevel()-1));
     4874  //model2->solver()->messageHandler()->setLogLevel(2);
     4875  model2->setMaximumCutPassesAtRoot(maximumCutPassesAtRoot_);
     4876  model2->setPrintFrequency(50);
     4877  model2->setIntParam(CbcModel::CbcMaxNumNode,maximumNodes);
     4878  model2->branchAndBound();
     4879  delete model2->nodeComparison();
     4880  if (model2->getMinimizationObjValue()>cutoff) {
     4881    // no good
     4882    if (model!=model2)
     4883      delete model2;
     4884    delete model;
     4885    return 2;
     4886  }
     4887  if (model!=model2) {
     4888    // get back solution
     4889    model->originalModel(model2,false);
     4890    delete model2;
     4891  }
     4892  int status;
     4893  if (model->getMinimizationObjValue()<cutoff&&model->bestSolution()) {
     4894    double objValue = model->getObjValue();
     4895    const double * solution = model->bestSolution();
     4896    setBestSolution(CBC_TREE_SOL,objValue,solution);
     4897    status = 0;
     4898  } else {
     4899    status=2;
     4900  }
     4901  if (model->status())
     4902    status ++ ; // not finished search
     4903  delete model;
     4904  return status;
     4905}
    47614906/* Invoke the branch & cut algorithm on partially fixed problem
    47624907   
  • trunk/CbcNode.cpp

    r35 r44  
    900900    saveUpper[i] = upper[i];
    901901  }
    902 
    903   // compute current state
    904   int numberIntegerInfeasibilities; // without odd ones
    905   int numberObjectInfeasibilities; // just odd ones
    906   model->feasibleSolution(
    907                            numberIntegerInfeasibilities,
    908                            numberObjectInfeasibilities);
    909   // If forcePriority > 0 then we want best solution
    910   const double * bestSolution = NULL;
    911   int hotstartStrategy=model->getHotstartStrategy();
    912   if (hotstartStrategy>0) {
    913     bestSolution = model->bestSolution();
    914   }
    915 
    916902  // Some objects may compute an estimate of best solution from here
    917903  double estimatedDegradation=0.0;
    918   numberUnsatisfied_ = 0;
    919   int bestPriority=INT_MAX;
    920 /*
    921   Scan for branching objects that indicate infeasibility. Choose the best
    922   maximumStrong candidates, using priority as the first criteria, then
    923   integer infeasibility.
    924 
    925   The algorithm is to fill the choice array with a set of good candidates (by
    926   infeasibility) with priority bestPriority.  Finding a candidate with
    927   priority better (less) than bestPriority flushes the choice array. (This
    928   serves as initialization when the first candidate is found.)
    929 
    930   A new candidate is added to choices only if its infeasibility exceeds the
    931   current max infeasibility (mostAway). When a candidate is added, it
    932   replaces the candidate with the smallest infeasibility (tracked by
    933   iSmallest).
    934 */
    935   int iSmallest = 0;
    936   double mostAway = integerTolerance;
    937   for (i = 0 ; i < maximumStrong ; i++) choice[i].possibleBranch = NULL ;
    938   numberStrong=0;
    939   for (i=0;i<numberObjects;i++) {
    940     const CbcObject * object = model->object(i);
    941     int preferredWay;
    942     double infeasibility = object->infeasibility(preferredWay);
    943     int priorityLevel = model->priority(i);
    944     if (bestSolution) {
    945       // we are doing hot start
    946       const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
    947       if (thisOne) {
    948         int iColumn = thisOne->modelSequence();
    949         if (saveUpper[iColumn]>saveLower[iColumn]) {
    950           double value = saveSolution[iColumn];
    951           double targetValue = bestSolution[iColumn];
    952           //double originalLower = thisOne->originalLower();
    953           //double originalUpper = thisOne->originalUpper();
    954           // switch off if not possible
    955           if (targetValue>=saveLower[iColumn]&&targetValue<=saveUpper[iColumn]) {
    956             /* priority outranks rest always if hotstartStrategy >1
    957                otherwise can be downgraded if at correct level.
    958                Infeasibility may be increased by targetValue to choose 1.0 values first.
    959             */
    960             if (fabs(value-targetValue)>integerTolerance) {
    961               if (value>targetValue) {
    962                 infeasibility += value;
    963                 preferredWay=-1;
    964               } else {
    965                 infeasibility += targetValue;
    966                 preferredWay=1;
    967               }
    968             } else if (hotstartStrategy>1) {
    969               if (targetValue==saveLower[iColumn]) {
    970                 infeasibility += integerTolerance+1.0e-12;
    971                 preferredWay=-1;
    972               } else if (targetValue==saveUpper[iColumn]) {
    973                 infeasibility += integerTolerance+1.0e-12;
    974                 preferredWay=1;
    975               } else {
    976                 infeasibility += integerTolerance+1.0e-12;
    977                 preferredWay=1;
    978               }
    979             } else {
    980               priorityLevel += 10000000;
    981             }
    982           } else {
    983             // switch off if not possible
    984             bestSolution=NULL;
    985             model->setHotstartStrategy(0);
    986           }
    987         }
    988       }
    989     }
    990     if (infeasibility>integerTolerance) {
    991       // Increase estimated degradation to solution
    992       estimatedDegradation += CoinMin(object->upEstimate(),object->downEstimate());
    993       numberUnsatisfied_++;
    994       // Better priority? Flush choices.
    995       if (priorityLevel<bestPriority) {
    996         int j;
    997         iSmallest=0;
    998         for (j=0;j<maximumStrong;j++) {
    999           choice[j].upMovement=0.0;
    1000           delete choice[j].possibleBranch;
    1001           choice[j].possibleBranch=NULL;
    1002         }
    1003         bestPriority = priorityLevel;
    1004         mostAway=integerTolerance;
    1005         numberStrong=0;
    1006       } else if (priorityLevel>bestPriority) {
    1007         continue;
    1008       }
    1009       // Check for suitability based on infeasibility.
    1010       if (infeasibility>mostAway) {
    1011         //add to list
    1012         choice[iSmallest].upMovement=infeasibility;
    1013         delete choice[iSmallest].possibleBranch;
    1014         choice[iSmallest].possibleBranch=object->createBranch(preferredWay);
    1015         numberStrong = CoinMax(numberStrong,iSmallest+1);
    1016         // Save which object it was
    1017         choice[iSmallest].objectNumber=i;
    1018         int j;
    1019         iSmallest=-1;
    1020         mostAway = 1.0e50;
    1021         for (j=0;j<maximumStrong;j++) {
    1022           if (choice[j].upMovement<mostAway) {
    1023             mostAway=choice[j].upMovement;
    1024             iSmallest=j;
    1025           }
    1026         }
     904  int numberIntegerInfeasibilities=0; // without odd ones
     905
     906  // We may go round this loop twice (only if we think we have solution)
     907  for (int iPass=0;iPass<2;iPass++) {
     908
     909    // compute current state
     910    int numberObjectInfeasibilities; // just odd ones
     911    model->feasibleSolution(
     912                            numberIntegerInfeasibilities,
     913                            numberObjectInfeasibilities);
     914    // If forcePriority > 0 then we want best solution
     915    const double * bestSolution = NULL;
     916    int hotstartStrategy=model->getHotstartStrategy();
     917    if (hotstartStrategy>0) {
     918      bestSolution = model->bestSolution();
     919    }
     920   
     921    // Some objects may compute an estimate of best solution from here
     922    estimatedDegradation=0.0;
     923    numberUnsatisfied_ = 0;
     924    int bestPriority=INT_MAX;
     925    /*
     926      Scan for branching objects that indicate infeasibility. Choose the best
     927      maximumStrong candidates, using priority as the first criteria, then
     928      integer infeasibility.
     929     
     930      The algorithm is to fill the choice array with a set of good candidates (by
     931      infeasibility) with priority bestPriority.  Finding a candidate with
     932      priority better (less) than bestPriority flushes the choice array. (This
     933      serves as initialization when the first candidate is found.)
     934     
     935      A new candidate is added to choices only if its infeasibility exceeds the
     936      current max infeasibility (mostAway). When a candidate is added, it
     937      replaces the candidate with the smallest infeasibility (tracked by
     938      iSmallest).
     939    */
     940    int iSmallest = 0;
     941    double mostAway = integerTolerance;
     942    for (i = 0 ; i < maximumStrong ; i++) choice[i].possibleBranch = NULL ;
     943    numberStrong=0;
     944    for (i=0;i<numberObjects;i++) {
     945      const CbcObject * object = model->object(i);
     946      int preferredWay;
     947      double infeasibility = object->infeasibility(preferredWay);
     948      int priorityLevel = model->priority(i);
     949      if (bestSolution) {
     950        // we are doing hot start
     951        const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
     952        if (thisOne) {
     953          int iColumn = thisOne->modelSequence();
     954          if (saveUpper[iColumn]>saveLower[iColumn]) {
     955            double value = saveSolution[iColumn];
     956            double targetValue = bestSolution[iColumn];
     957            //double originalLower = thisOne->originalLower();
     958            //double originalUpper = thisOne->originalUpper();
     959            // switch off if not possible
     960            if (targetValue>=saveLower[iColumn]&&targetValue<=saveUpper[iColumn]) {
     961              /* priority outranks rest always if hotstartStrategy >1
     962                 otherwise can be downgraded if at correct level.
     963                 Infeasibility may be increased by targetValue to choose 1.0 values first.
     964              */
     965              if (fabs(value-targetValue)>integerTolerance) {
     966                if (value>targetValue) {
     967                  infeasibility += value;
     968                  preferredWay=-1;
     969                } else {
     970                  infeasibility += targetValue;
     971                  preferredWay=1;
     972                }
     973              } else if (hotstartStrategy>1) {
     974                if (targetValue==saveLower[iColumn]) {
     975                  infeasibility += integerTolerance+1.0e-12;
     976                  preferredWay=-1;
     977                } else if (targetValue==saveUpper[iColumn]) {
     978                  infeasibility += integerTolerance+1.0e-12;
     979                  preferredWay=1;
     980                } else {
     981                  infeasibility += integerTolerance+1.0e-12;
     982                  preferredWay=1;
     983                }
     984              } else {
     985                priorityLevel += 10000000;
     986              }
     987            } else {
     988              // switch off if not possible
     989              bestSolution=NULL;
     990              model->setHotstartStrategy(0);
     991            }
     992          }
     993        }
     994      }
     995      if (infeasibility>integerTolerance) {
     996        // Increase estimated degradation to solution
     997        estimatedDegradation += CoinMin(object->upEstimate(),object->downEstimate());
     998        numberUnsatisfied_++;
     999        // Better priority? Flush choices.
     1000        if (priorityLevel<bestPriority) {
     1001          int j;
     1002          iSmallest=0;
     1003          for (j=0;j<maximumStrong;j++) {
     1004            choice[j].upMovement=0.0;
     1005            delete choice[j].possibleBranch;
     1006            choice[j].possibleBranch=NULL;
     1007          }
     1008          bestPriority = priorityLevel;
     1009          mostAway=integerTolerance;
     1010          numberStrong=0;
     1011        } else if (priorityLevel>bestPriority) {
     1012          continue;
     1013        }
     1014        // Check for suitability based on infeasibility.
     1015        if (infeasibility>mostAway) {
     1016          //add to list
     1017          choice[iSmallest].upMovement=infeasibility;
     1018          delete choice[iSmallest].possibleBranch;
     1019          choice[iSmallest].possibleBranch=object->createBranch(preferredWay);
     1020          numberStrong = CoinMax(numberStrong,iSmallest+1);
     1021          // Save which object it was
     1022          choice[iSmallest].objectNumber=i;
     1023          int j;
     1024          iSmallest=-1;
     1025          mostAway = 1.0e50;
     1026          for (j=0;j<maximumStrong;j++) {
     1027            if (choice[j].upMovement<mostAway) {
     1028              mostAway=choice[j].upMovement;
     1029              iSmallest=j;
     1030            }
     1031          }
     1032        }
     1033      }
     1034    }
     1035    if (numberUnsatisfied_) {
     1036      // some infeasibilities - go to next steps
     1037      break;
     1038    } else if (!iPass) {
     1039      // looks like a solution - get paranoid
     1040      bool roundAgain=false;
     1041      // get basis
     1042      CoinWarmStartBasis * ws = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
     1043      if (!ws)
     1044        break;
     1045      for (i=0;i<numberColumns;i++) {
     1046        double value = saveSolution[i];
     1047        if (value<lower[i]) {
     1048          saveSolution[i]=lower[i];
     1049          roundAgain=true;
     1050          ws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
     1051        } else if (value>upper[i]) {
     1052          saveSolution[i]=upper[i];
     1053          roundAgain=true;
     1054          ws->setStructStatus(i,CoinWarmStartBasis::atUpperBound);
     1055        }
     1056      }
     1057      if (roundAgain) {
     1058        // restore basis
     1059        solver->setWarmStart(ws);
     1060        delete ws;
     1061        solver->resolve();
     1062        memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
     1063        if (!solver->isProvenOptimal()) {
     1064          // infeasible
     1065          anyAction=-2;
     1066          break;
     1067        }
     1068      } else {
     1069        delete ws;
     1070        break;
    10271071      }
    10281072    }
  • trunk/include/CbcBranchActual.hpp

    r13 r44  
    240240  inline double originalLowerBound() const
    241241  { return originalLower_;};
     242  inline void setOriginalLowerBound(double value)
     243  { originalLower_=value;};
    242244  inline double originalUpperBound() const
    243245  { return originalUpper_;};
     246  inline void setOriginalUpperBound(double value)
     247  { originalUpper_=value;};
    244248  /// Breakeven e.g 0.7 -> >= 0.7 go up first
    245249  inline double breakEven() const
     
    728732  virtual CbcBranchingObject * createBranch(int way) const;
    729733  /// As some computation is needed in more than one place - returns row
    730   int gutsOfFollowOn(int & otherRow, int & preferredWay) const;
     734  virtual int gutsOfFollowOn(int & otherRow, int & preferredWay) const;
    731735
    732736protected:
  • trunk/include/CbcModel.hpp

    r35 r44  
    156156     void branchAndBound();
    157157
     158    /** \brief create a clean model from partially fixed problem
     159
     160      The method creates a new model with given bounds and with no tree.
     161    */
     162     CbcModel *  cleanModel(const double * lower, const double * upper);
     163    /** \brief Invoke the branch \& cut algorithm on partially fixed problem
     164
     165      The method presolves the given model and does branch and cut. The search
     166      ends when the tree is exhausted or maximum nodes is reached.
     167
     168      If better solution found then it is saved.
     169
     170      Returns 0 if search completed and solution, 1 if not completed and solution,
     171      2 if completed and no solution, 3 if not completed and no solution.
     172
     173      Normally okay to do cleanModel immediately followed by subBranchandBound
     174      (== other form of subBranchAndBound)
     175      but may need to get at model for advanced features.
     176
     177      Deletes model2
     178    */
     179     int subBranchAndBound(CbcModel * model2,
     180                           CbcModel * presolvedModel,
     181                           int maximumNodes);
    158182    /** \brief Invoke the branch \& cut algorithm on partially fixed problem
    159183
     
    166190      Returns 0 if search completed and solution, 1 if not completed and solution,
    167191      2 if completed and no solution, 3 if not completed and no solution.
     192
     193      This is just subModel immediately followed by other version of
     194      subBranchandBound.
     195
    168196    */
    169197     int subBranchAndBound(const double * lower, const double * upper,
     
    10531081    void assignSolver(OsiSolverInterface *&solver);
    10541082 
    1055     /// Copy constructor
    1056     CbcModel(const CbcModel &);
     1083    /** Copy constructor .
     1084      If noTree is true then tree and cuts are not copied
     1085    */ 
     1086    CbcModel(const CbcModel & rhs, bool noTree=false);
    10571087 
    10581088    /// Assignment operator
Note: See TracChangeset for help on using the changeset viewer.