Ignore:
Timestamp:
Oct 8, 2006 7:33:47 PM (13 years ago)
Author:
forrest
Message:

towards common use with other solvers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/devel/Cbc/src/CbcBranchDynamic.cpp

    r424 r439  
    5757  Loads dynamic upper & lower bounds for the specified variable.
    5858*/
    59 CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int sequence,
     59CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost (CbcModel * model,
    6060                                    int iColumn, double breakEven)
    61   : CbcSimpleInteger(model,sequence,iColumn,breakEven),
     61  : CbcSimpleInteger(model,iColumn,breakEven),
    6262    upDownSeparator_(-1.0),
    6363    sumDownCost_(0.0),
     
    120120  Loads dynamic upper & lower bounds for the specified variable.
    121121*/
    122 CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int sequence,
     122CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost (CbcModel * model,
    123123                                    int iColumn, double downDynamicPseudoCost,
    124124                                                        double upDynamicPseudoCost)
    125   : CbcSimpleInteger(model,sequence,iColumn),
     125  : CbcSimpleInteger(model,iColumn),
    126126    upDownSeparator_(-1.0),
    127127    sumDownCost_(0.0),
     
    175175  numberTimesDown_ = 1;
    176176#endif
     177}
     178/** Useful constructor
     179
     180  Loads dynamic upper & lower bounds for the specified variable.
     181*/
     182CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost (CbcModel * model,
     183                                    int dummy, int iColumn, double downDynamicPseudoCost,
     184                                                        double upDynamicPseudoCost)
     185{
     186  CbcSimpleIntegerDynamicPseudoCost(model,iColumn,downDynamicPseudoCost,upDynamicPseudoCost);
    177187}
    178188
     
    284294  }
    285295  CbcDynamicPseudoCostBranchingObject * newObject =
    286     new CbcDynamicPseudoCostBranchingObject(model_,sequence_,way,
     296    new CbcDynamicPseudoCostBranchingObject(model_,columnNumber_,way,
    287297                                            value,this);
    288298  double up =  upDynamicPseudoCost_*(ceil(value)-value);
     
    441451    return CoinMax(returnValue,1.0e-15);
    442452  }
     453}
     454
     455double
     456CbcSimpleIntegerDynamicPseudoCost::infeasibility(const OsiSolverInterface * solver, const OsiBranchingInformation * info,
     457                         int & preferredWay) const
     458{
     459  double value = info->solution_[columnNumber_];
     460  value = CoinMax(value, info->lower_[columnNumber_]);
     461  value = CoinMin(value, info->upper_[columnNumber_]);
     462  if (info->upper_[columnNumber_]==info->lower_[columnNumber_]) {
     463    // fixed
     464    preferredWay=1;
     465    return 0.0;
     466  }
     467  assert (breakEven_>0.0&&breakEven_<1.0);
     468  double nearest = floor(value+0.5);
     469  double integerTolerance = info->integerTolerance_;
     470  double below = floor(value+integerTolerance);
     471  double above = below+1.0;
     472  if (above>info->upper_[columnNumber_]) {
     473    above=below;
     474    below = above -1;
     475  }
     476#if INFEAS==1
     477  double objectiveValue = info->objectiveValue_;
     478  double distanceToCutoff =  info->cutoff_  - objectiveValue;
     479  if (distanceToCutoff<1.0e20)
     480    distanceToCutoff *= 10.0;
     481  else
     482    distanceToCutoff = 1.0e2 + fabs(objectiveValue);
     483#endif
     484  double sum;
     485  int number;
     486  double downCost = CoinMax(value-below,0.0);
     487  sum = sumDownCost_;
     488  number = numberTimesDown_;
     489#if INFEAS==1
     490  sum += numberTimesDownInfeasible_*(distanceToCutoff/(downCost+1.0e-12));
     491  number += numberTimesDownInfeasible_;
     492#endif
     493  if (number>0)
     494    downCost *= sum / (double) number;
     495  else
     496    downCost  *=  downDynamicPseudoCost_;
     497  double upCost = CoinMax((above-value),0.0);
     498  sum = sumUpCost_;
     499  number = numberTimesUp_;
     500#if INFEAS==1
     501  sum += numberTimesUpInfeasible_*(distanceToCutoff/(upCost+1.0e-12));
     502  number += numberTimesUpInfeasible_;
     503#endif
     504  if (number>0)
     505    upCost *= sum / (double) number;
     506  else
     507    upCost  *=  upDynamicPseudoCost_;
     508  if (downCost>=upCost)
     509    preferredWay=1;
     510  else
     511    preferredWay=-1;
     512  // See if up down choice set
     513  if (upDownSeparator_>0.0) {
     514    preferredWay = (value-below>=upDownSeparator_) ? 1 : -1;
     515  }
     516  if (preferredWay_)
     517    preferredWay=preferredWay_;
     518  // weight at 1.0 is max min
     519#define WEIGHT_BEFORE 0.3
     520  if (fabs(value-nearest)<=integerTolerance) {
     521    return 0.0;
     522  } else {
     523    double returnValue=0.0;
     524    double minValue = CoinMin(downCost,upCost);
     525    double maxValue = CoinMax(downCost,upCost);
     526    if (!info->numberBranchingSolutions_||info->depth_<=10/* was ||maxValue>0.2*distanceToCutoff*/) {
     527      // no solution
     528      returnValue = WEIGHT_BEFORE*minValue + (1.0-WEIGHT_BEFORE)*maxValue;
     529    } else {
     530      // some solution
     531      returnValue = WEIGHT_AFTER*minValue + (1.0-WEIGHT_AFTER)*maxValue;
     532    }
     533    if (numberTimesUp_<numberBeforeTrust_||
     534        numberTimesDown_<numberBeforeTrust_) {
     535      //if (returnValue<1.0e10)
     536      //returnValue += 1.0e12;
     537      //else
     538      returnValue *= 1.0e3;
     539      if (!numberTimesUp_&&!numberTimesDown_)
     540        returnValue=1.0e50;
     541    }
     542    //if (fabs(value-0.5)<1.0e-5) {
     543    //returnValue = 3.0*returnValue + 0.2;
     544    //} else if (value>0.9) {
     545    //returnValue = 2.0*returnValue + 0.1;
     546    //}
     547    if (method_==1) {
     548      // probing
     549      // average
     550      double up=1.0e-15;
     551      double down=1.0e-15;
     552      if (numberTimesProbingTotal_) {
     553        up += numberTimesUpTotalFixed_/((double) numberTimesProbingTotal_);
     554        down += numberTimesDownTotalFixed_/((double) numberTimesProbingTotal_);
     555      }
     556      returnValue = 1 + 10.0*CoinMin(numberTimesDownLocalFixed_,numberTimesUpLocalFixed_) +
     557        CoinMin(down,up);
     558      returnValue *= 1.0e-3;
     559    }
     560    return CoinMax(returnValue,1.0e-15);
     561  }
     562}
     563// Creates a branching object
     564CbcBranchingObject *
     565CbcSimpleIntegerDynamicPseudoCost::createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way)
     566{
     567  double value = info->solution_[columnNumber_];
     568  value = CoinMax(value, info->lower_[columnNumber_]);
     569  value = CoinMin(value, info->upper_[columnNumber_]);
     570  assert (info->upper_[columnNumber_]>info->lower_[columnNumber_]);
     571  if (!info->hotstartSolution_) {
     572#ifndef NDEBUG
     573    double nearest = floor(value+0.5);
     574    assert (fabs(value-nearest)>info->integerTolerance_);
     575#endif
     576  } else {
     577    double targetValue = info->hotstartSolution_[columnNumber_];
     578    if (way>0)
     579      value = targetValue-0.1;
     580    else
     581      value = targetValue+0.1;
     582  }
     583  CbcDynamicPseudoCostBranchingObject * newObject =
     584    new CbcDynamicPseudoCostBranchingObject(model_,columnNumber_,way,
     585                                            value,this);
     586  double up =  upDynamicPseudoCost_*(ceil(value)-value);
     587  double down =  downDynamicPseudoCost_*(value-floor(value));
     588  double changeInGuessed=up-down;
     589  if (way>0)
     590    changeInGuessed = - changeInGuessed;
     591  changeInGuessed=CoinMax(0.0,changeInGuessed);
     592  //if (way>0)
     593  //changeInGuessed += 1.0e8; // bias to stay up
     594  newObject->setChangeInGuessed(changeInGuessed);
     595  newObject->setOriginalObject(this);
     596  return newObject;
    443597}
    444598
     
    653807*/
    654808double
    655 CbcDynamicPseudoCostBranchingObject::branch(bool normalBranch)
    656 {
    657   CbcIntegerBranchingObject::branch(normalBranch);
     809CbcDynamicPseudoCostBranchingObject::branch()
     810{
     811  CbcIntegerBranchingObject::branch();
    658812  return changeInGuessed_;
    659813}
     
    739893      information on object causing branch - after branch */
    740894void
    741 CbcBranchDynamicDecision::saveBranchingObject(CbcBranchingObject * object)
    742 {
    743   object_ = object->clone();
     895CbcBranchDynamicDecision::saveBranchingObject(OsiBranchingObject * object)
     896{
     897  OsiBranchingObject * obj = object->clone();
     898  CbcDynamicPseudoCostBranchingObject * branchingObject =
     899    dynamic_cast<CbcDynamicPseudoCostBranchingObject *>(obj);
     900  assert (branchingObject);
     901  object_=branchingObject;
    744902}
    745903/* Pass in information on branch just done.
Note: See TracChangeset for help on using the changeset viewer.