Changeset 439 for branches/devel


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

towards common use with other solvers

Location:
branches/devel/Cbc/src
Files:
2 deleted
31 edited

Legend:

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

    r436 r439  
    694694CbcSimpleInteger::CbcSimpleInteger ()
    695695  : CbcObject(),
    696     sequence_(-1),
    697     columnNumber_(-1),
    698696    originalLower_(0.0),
    699697    originalUpper_(1.0),
    700     breakEven_(0.5)
     698    breakEven_(0.5),
     699    columnNumber_(-1),
     700    preferredWay_(0)
    701701{
    702702}
     
    706706  Loads actual upper & lower bounds for the specified variable.
    707707*/
    708 CbcSimpleInteger::CbcSimpleInteger (CbcModel * model, int sequence,
    709                                     int iColumn, double breakEven)
     708CbcSimpleInteger::CbcSimpleInteger ( CbcModel * model, int iColumn, double breakEven)
    710709  : CbcObject(model)
    711710{
    712   sequence_ = sequence ;
    713   id_ = iColumn; // set as well
    714711  columnNumber_ = iColumn ;
    715   originalLower_ = model_->solver()->getColLower()[columnNumber_] ;
    716   originalUpper_ = model_->solver()->getColUpper()[columnNumber_] ;
     712  originalLower_ = model->solver()->getColLower()[columnNumber_] ;
     713  originalUpper_ = model->solver()->getColUpper()[columnNumber_] ;
    717714  breakEven_ = breakEven;
    718715  assert (breakEven_>0.0&&breakEven_<1.0);
    719 }
     716  preferredWay_ = 0;
     717}
     718
    720719
    721720// Copy constructor
     
    724723
    725724{
    726   sequence_ = rhs.sequence_;
    727725  columnNumber_ = rhs.columnNumber_;
    728726  originalLower_ = rhs.originalLower_;
    729727  originalUpper_ = rhs.originalUpper_;
    730728  breakEven_ = rhs.breakEven_;
     729  preferredWay_ = rhs.preferredWay_;
    731730}
    732731
     
    748747    originalUpper_ = rhs.originalUpper_;
    749748    breakEven_ = rhs.breakEven_;
     749    preferredWay_ = rhs.preferredWay_;
    750750  }
    751751  return *this;
     
    756756{
    757757}
    758 
    759 // Infeasibility - large is 0.5
    760 double
    761 CbcSimpleInteger::infeasibility(int & preferredWay) const
    762 {
    763   OsiSolverInterface * solver = model_->solver();
    764   const double * solution = model_->testSolution();
    765   const double * lower = solver->getColLower();
    766   const double * upper = solver->getColUpper();
    767   double value = solution[columnNumber_];
    768   value = CoinMax(value, lower[columnNumber_]);
    769   value = CoinMin(value, upper[columnNumber_]);
    770   /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
    771     solution[columnNumber_],upper[columnNumber_]);*/
     758// Construct an OsiSimpleInteger object
     759OsiSimpleInteger *
     760CbcSimpleInteger::osiObject() const
     761{
     762  OsiSimpleInteger * obj = new OsiSimpleInteger(columnNumber_,
     763                                                originalLower_,originalUpper_);
     764  obj->setPriority(priority());
     765  return obj;
     766}
     767
     768double
     769CbcSimpleInteger::infeasibility(const OsiSolverInterface * solver, const OsiBranchingInformation * info,
     770                         int & preferredWay) const
     771{
     772  double value = info->solution_[columnNumber_];
     773  value = CoinMax(value, info->lower_[columnNumber_]);
     774  value = CoinMin(value, info->upper_[columnNumber_]);
    772775  double nearest = floor(value+(1.0-breakEven_));
    773776  assert (breakEven_>0.0&&breakEven_<1.0);
    774   double integerTolerance =
    775     model_->getDblParam(CbcModel::CbcIntegerTolerance);
    776777  if (nearest>value)
    777778    preferredWay=1;
     
    786787  else
    787788    weight = (0.5/(1.0-breakEven_))*weight;
    788   if (fabs(value-nearest)<=integerTolerance)
     789  if (fabs(value-nearest)<=info->integerTolerance_)
    789790    return 0.0;
    790791  else
    791792    return weight;
     793}
     794double
     795CbcSimpleInteger::feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const
     796{
     797  double value = info->solution_[columnNumber_];
     798  double newValue = CoinMax(value, info->lower_[columnNumber_]);
     799  newValue = CoinMin(newValue, info->upper_[columnNumber_]);
     800  newValue = floor(newValue+0.5);
     801  solver->setColLower(columnNumber_,newValue);
     802  solver->setColUpper(columnNumber_,newValue);
     803  return fabs(value-newValue);
     804}
     805
     806/* Create an OsiSolverBranch object
     807   
     808This returns NULL if branch not represented by bound changes
     809*/
     810OsiSolverBranch *
     811CbcSimpleInteger::solverBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info) const
     812{
     813  double value = info->solution_[columnNumber_];
     814  value = CoinMax(value, info->lower_[columnNumber_]);
     815  value = CoinMin(value, info->upper_[columnNumber_]);
     816  assert (info->upper_[columnNumber_]>info->lower_[columnNumber_]);
     817#ifndef NDEBUG
     818  double nearest = floor(value+0.5);
     819  assert (fabs(value-nearest)>info->integerTolerance_);
     820#endif
     821  OsiSolverBranch * branch = new OsiSolverBranch();
     822  branch->addBranch(columnNumber_,value);
     823  return branch;
     824}
     825// Creates a branching object
     826CbcBranchingObject *
     827CbcSimpleInteger::createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way)
     828{
     829  double value = info->solution_[columnNumber_];
     830  value = CoinMax(value, info->lower_[columnNumber_]);
     831  value = CoinMin(value, info->upper_[columnNumber_]);
     832  assert (info->upper_[columnNumber_]>info->lower_[columnNumber_]);
     833  if (!info->hotstartSolution_) {
     834#ifndef NDEBUG
     835    double nearest = floor(value+0.5);
     836    assert (fabs(value-nearest)>info->integerTolerance_);
     837#endif
     838  } else {
     839    double targetValue = info->hotstartSolution_[columnNumber_];
     840    if (way>0)
     841      value = targetValue-0.1;
     842    else
     843      value = targetValue+0.1;
     844  }
     845  CbcBranchingObject * branch = new CbcIntegerBranchingObject(model_,columnNumber_,way,
     846                                             value);
     847  branch->setOriginalObject(this);
     848  return branch;
     849}
     850/* Column number if single column object -1 otherwise,
     851   so returns >= 0
     852   Used by heuristics
     853*/
     854int
     855CbcSimpleInteger::columnNumber() const
     856{
     857  return columnNumber_;
     858}
     859
     860// Infeasibility - large is 0.5
     861double
     862CbcSimpleInteger::infeasibility(int & preferredWay) const
     863{
     864  abort();
     865  return 0.0;
    792866}
    793867
     
    800874CbcSimpleInteger::feasibleRegion()
    801875{
    802   OsiSolverInterface * solver = model_->solver();
    803   const double * lower = solver->getColLower();
    804   const double * upper = solver->getColUpper();
    805   const double * solution = model_->testSolution();
    806   double value = solution[columnNumber_];
    807   value = CoinMax(value, lower[columnNumber_]);
    808   value = CoinMin(value, upper[columnNumber_]);
    809 
    810   double nearest = floor(value+0.5);
    811   //double integerTolerance =
    812   //model_->getDblParam(CbcModel::CbcIntegerTolerance);
    813   // Scaling may have moved it a bit
    814   //assert (fabs(value-nearest)<=100.0*integerTolerance);
    815   assert (fabs(value-nearest)<=0.01);
    816   solver->setColLower(columnNumber_,nearest);
    817   solver->setColUpper(columnNumber_,nearest);
    818 }
    819 // Redoes data when sequence numbers change
    820 void
    821 CbcSimpleInteger::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
    822 {
    823   model_=model;
    824   int i;
    825   for (i=0;i<numberColumns;i++) {
    826     if (originalColumns[i]==columnNumber_)
    827       break;
    828   }
    829   if (i<numberColumns)
    830     columnNumber_=i;
    831   else
    832     abort(); // should never happen
    833 }
    834 /* Column number if single column object -1 otherwise,
    835    so returns >= 0
    836    Used by heuristics
    837 */
    838 int
    839 CbcSimpleInteger::columnNumber() const
    840 {
    841   return columnNumber_;
    842 }
    843 
    844 // Creates a branching object
     876  abort();
     877}
    845878CbcBranchingObject *
    846 CbcSimpleInteger::createBranch(int way)
    847 {
    848   OsiSolverInterface * solver = model_->solver();
    849   const double * solution = model_->testSolution();
    850   const double * lower = solver->getColLower();
    851   const double * upper = solver->getColUpper();
    852   double value = solution[columnNumber_];
    853   value = CoinMax(value, lower[columnNumber_]);
    854   value = CoinMin(value, upper[columnNumber_]);
    855   assert (upper[columnNumber_]>lower[columnNumber_]);
    856   if (!model_->hotstartSolution()) {
    857 #ifndef NDEBUG
    858     double nearest = floor(value+0.5);
    859     double integerTolerance =
    860     model_->getDblParam(CbcModel::CbcIntegerTolerance);
    861     assert (fabs(value-nearest)>integerTolerance);
    862 #endif
    863   } else {
    864     const double * hotstartSolution = model_->hotstartSolution();
    865     double targetValue = hotstartSolution[columnNumber_];
    866     if (way>0)
    867       value = targetValue-0.1;
    868     else
    869       value = targetValue+0.1;
    870   }
    871   CbcBranchingObject * branch = new CbcIntegerBranchingObject(model_,sequence_,way,
    872                                              value);
    873   branch->setOriginalObject(this);
    874   return branch;
    875 }
    876 
    877 /* Create an OsiSolverBranch object
    878    
    879 This returns NULL if branch not represented by bound changes
    880 */
    881 OsiSolverBranch *
    882 CbcSimpleInteger::solverBranch() const
    883 {
    884   OsiSolverInterface * solver = model_->solver();
    885   const double * solution = model_->testSolution();
    886   const double * lower = solver->getColLower();
    887   const double * upper = solver->getColUpper();
    888   double value = solution[columnNumber_];
    889   value = CoinMax(value, lower[columnNumber_]);
    890   value = CoinMin(value, upper[columnNumber_]);
    891   assert (upper[columnNumber_]>lower[columnNumber_]);
    892 #ifndef NDEBUG
    893   double nearest = floor(value+0.5);
    894   double integerTolerance =
    895     model_->getDblParam(CbcModel::CbcIntegerTolerance);
    896   assert (fabs(value-nearest)>integerTolerance);
    897 #endif
    898   OsiSolverBranch * branch = new OsiSolverBranch();
    899   branch->addBranch(columnNumber_,value);
    900   return branch;
    901 }
    902  
    903 
    904 /* Given valid solution (i.e. satisfied) and reduced costs etc
    905    returns a branching object which would give a new feasible
    906    point in direction reduced cost says would be cheaper.
    907    If no feasible point returns null
    908 */
    909 CbcBranchingObject *
    910 CbcSimpleInteger::preferredNewFeasible() const
    911 {
    912   OsiSolverInterface * solver = model_->solver();
    913   double value = model_->testSolution()[columnNumber_];
    914 
    915   double nearest = floor(value+0.5);
    916 #ifndef NDEBUG
    917   double integerTolerance =
    918     model_->getDblParam(CbcModel::CbcIntegerTolerance);
    919   assert (fabs(value-nearest)<=integerTolerance);
    920 #endif
    921   double dj = solver->getObjSense()*solver->getReducedCost()[columnNumber_];
    922   CbcIntegerBranchingObject * object = NULL;
    923   if (dj>=0.0) {
    924     // can we go down
    925     if (nearest>originalLower_+0.5) {
    926       // yes
    927       object = new CbcIntegerBranchingObject(model_,sequence_,-1,
    928                                              nearest-1.0,nearest-1.0);
    929     }
    930   } else {
    931     // can we go up
    932     if (nearest<originalUpper_-0.5) {
    933       // yes
    934       object = new CbcIntegerBranchingObject(model_,sequence_,-1,
    935                                              nearest+1.0,nearest+1.0);
    936     }
    937   }
    938   return object;
    939 }
    940  
    941 /* Given valid solution (i.e. satisfied) and reduced costs etc
    942    returns a branching object which would give a new feasible
    943    point in direction opposite to one reduced cost says would be cheaper.
    944    If no feasible point returns null
    945 */
    946 CbcBranchingObject *
    947 CbcSimpleInteger::notPreferredNewFeasible() const
    948 {
    949   OsiSolverInterface * solver = model_->solver();
    950   double value = model_->testSolution()[columnNumber_];
    951 
    952   double nearest = floor(value+0.5);
    953 #ifndef NDEBUG
    954   double integerTolerance =
    955     model_->getDblParam(CbcModel::CbcIntegerTolerance);
    956   assert (fabs(value-nearest)<=integerTolerance);
    957 #endif
    958   double dj = solver->getObjSense()*solver->getReducedCost()[columnNumber_];
    959   CbcIntegerBranchingObject * object = NULL;
    960   if (dj<=0.0) {
    961     // can we go down
    962     if (nearest>originalLower_+0.5) {
    963       // yes
    964       object = new CbcIntegerBranchingObject(model_,sequence_,-1,
    965                                              nearest-1.0,nearest-1.0);
    966     }
    967   } else {
    968     // can we go up
    969     if (nearest<originalUpper_-0.5) {
    970       // yes
    971       object = new CbcIntegerBranchingObject(model_,sequence_,-1,
    972                                              nearest+1.0,nearest+1.0);
    973     }
    974   }
    975   return object;
    976 }
    977  
    978 /*
    979   Bounds may be tightened, so it may be good to be able to refresh the local
    980   copy of the original bounds.
    981  */
    982 void
    983 CbcSimpleInteger::resetBounds()
    984 {
    985   originalLower_ = model_->solver()->getColLower()[columnNumber_];
    986   originalUpper_ = model_->solver()->getColUpper()[columnNumber_];
    987 }
    988 
    989 
     879CbcSimpleInteger::createBranch( int way)
     880{
     881  abort();
     882  return NULL;
     883}
    990884// Default Constructor
    991885CbcIntegerBranchingObject::CbcIntegerBranchingObject()
     
    1003897  :CbcBranchingObject(model,variable,way,value)
    1004898{
    1005   int iColumn = model_->integerVariable()[variable_];
     899  int iColumn = variable;
    1006900  down_[0] = model_->solver()->getColLower()[iColumn];
    1007901  down_[1] = floor(value_);
     
    1016910  :CbcBranchingObject(model,variable,way,lowerValue)
    1017911{
    1018   numberBranchesLeft_=1;
     912  setNumberBranchesLeft(1);
    1019913  down_[0] = lowerValue;
    1020914  down_[1] = upperValue;
     
    1069963*/
    1070964double
    1071 CbcIntegerBranchingObject::branch(bool normalBranch)
    1072 {
    1073   if (model_->messageHandler()->logLevel()>2&&normalBranch)
    1074     print(normalBranch);
    1075   numberBranchesLeft_--;
    1076   int iColumn = model_->integerVariable()[variable_];
     965CbcIntegerBranchingObject::branch()
     966{
     967  decrementNumberBranchesLeft();
     968  int iColumn = originalCbcObject_->columnNumber();
     969  assert (variable_==iColumn);
    1077970  if (way_<0) {
    1078971#ifdef CBC_DEBUG
     
    1102995// Print what would happen 
    1103996void
    1104 CbcIntegerBranchingObject::print(bool normalBranch)
    1105 {
    1106   int iColumn = model_->integerVariable()[variable_];
     997CbcIntegerBranchingObject::print()
     998{
     999  int iColumn = originalCbcObject_->columnNumber();
     1000  assert (variable_==iColumn);
    11071001  if (way_<0) {
    11081002  { double olb,oub ;
     
    11381032  Loads actual upper & lower bounds for the specified variable.
    11391033*/
    1140 CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, int sequence,
     1034CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model,
    11411035                                    int iColumn, double breakEven)
    1142   : CbcSimpleInteger(model,sequence,iColumn,breakEven)
     1036  : CbcSimpleInteger(model,iColumn,breakEven)
    11431037{
    11441038  const double * cost = model->getObjCoefficients();
     
    11561050  Loads actual upper & lower bounds for the specified variable.
    11571051*/
    1158 CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, int sequence,
     1052CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model,
    11591053                                    int iColumn, double downPseudoCost,
    11601054                                                        double upPseudoCost)
    1161   : CbcSimpleInteger(model,sequence,iColumn)
     1055  : CbcSimpleInteger(model,iColumn)
    11621056{
    11631057  downPseudoCost_ = CoinMax(1.0e-10,downPseudoCost);
     
    11661060  upDownSeparator_ = -1.0;
    11671061  method_=0;
     1062}
     1063// Useful constructor - passed and model index and pseudo costs
     1064CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, int dummy,int iColumn,
     1065                                                        double downPseudoCost, double upPseudoCost)
     1066{
     1067  CbcSimpleIntegerPseudoCost(model,iColumn,downPseudoCost,upPseudoCost);
    11681068}
    11691069
     
    12321132  }
    12331133  CbcIntegerPseudoCostBranchingObject * newObject =
    1234     new CbcIntegerPseudoCostBranchingObject(model_,sequence_,way,
     1134    new CbcIntegerPseudoCostBranchingObject(model_,columnNumber_,way,
    12351135                                            value);
    12361136  double up =  upPseudoCost_*(ceil(value)-value);
     
    14151315*/
    14161316double
    1417 CbcIntegerPseudoCostBranchingObject::branch(bool normalBranch)
    1418 {
    1419   CbcIntegerBranchingObject::branch(normalBranch);
     1317CbcIntegerPseudoCostBranchingObject::branch()
     1318{
     1319  CbcIntegerBranchingObject::branch();
    14201320  return changeInGuessed_;
    14211321}
     
    14991399}
    15001400double
    1501 CbcCliqueBranchingObject::branch(bool normalBranch)
    1502 {
    1503   if (model_->messageHandler()->logLevel()>2&&normalBranch)
    1504     print(normalBranch);
    1505   numberBranchesLeft_--;
     1401CbcCliqueBranchingObject::branch()
     1402{
     1403  decrementNumberBranchesLeft();
    15061404  int iWord;
    15071405  int numberMembers = clique_->numberMembers();
     
    15621460// Print what would happen 
    15631461void
    1564 CbcCliqueBranchingObject::print(bool normalBranch)
     1462CbcCliqueBranchingObject::print()
    15651463{
    15661464  int iWord;
     
    16931591}
    16941592double
    1695 CbcLongCliqueBranchingObject::branch(bool normalBranch)
    1696 {
    1697   if (model_->messageHandler()->logLevel()>2&&normalBranch)
    1698     print(normalBranch);
    1699   numberBranchesLeft_--;
     1593CbcLongCliqueBranchingObject::branch()
     1594{
     1595  decrementNumberBranchesLeft();
    17001596  int iWord;
    17011597  int numberMembers = clique_->numberMembers();
     
    17551651}
    17561652void
    1757 CbcLongCliqueBranchingObject::print(bool normalBranch)
     1653CbcLongCliqueBranchingObject::print()
    17581654{
    17591655  int iWord;
     
    18391735}
    18401736double
    1841 CbcSOSBranchingObject::branch(bool normalBranch)
    1842 {
    1843   if (model_->messageHandler()->logLevel()>2&&normalBranch)
    1844     print(normalBranch);
    1845   numberBranchesLeft_--;
     1737CbcSOSBranchingObject::branch()
     1738{
     1739  decrementNumberBranchesLeft();
    18461740  int numberMembers = set_->numberMembers();
    18471741  const int * which = set_->members();
     
    18761770// Print what would happen 
    18771771void
    1878 CbcSOSBranchingObject::print(bool normalBranch)
     1772CbcSOSBranchingObject::print()
    18791773{
    18801774  int numberMembers = set_->numberMembers();
     
    19401834  bestNumberUp_ = 0;
    19411835  bestChangeDown_ = 0.0;
     1836  bestObject_ = NULL;
    19421837  bestNumberDown_ = 0;
    1943   bestObject_ = NULL;
    19441838}
    19451839
     
    19471841CbcBranchDefaultDecision::CbcBranchDefaultDecision (
    19481842                                    const CbcBranchDefaultDecision & rhs)
    1949   :CbcBranchDecision()
     1843  :CbcBranchDecision(rhs)
    19501844{
    19511845  bestCriterion_ = rhs.bestCriterion_;
     
    19551849  bestNumberDown_ = rhs.bestNumberDown_;
    19561850  bestObject_ = rhs.bestObject_;
     1851  model_ = rhs.model_;
    19571852}
    19581853
     
    19781873  bestNumberDown_ = 0;
    19791874  bestObject_ = NULL;
     1875  model_ = model;
    19801876}
    19811877
     
    19941890                            double changeDn, int numInfDn)
    19951891{
    1996   bool beforeSolution = thisOne->model()->getSolutionCount()==
    1997     thisOne->model()->getNumberHeuristicSolutions();;
     1892  bool beforeSolution = cbcModel()->getSolutionCount()==
     1893    cbcModel()->getNumberHeuristicSolutions();;
    19981894  int betterWay=0;
    19991895  if (beforeSolution) {
     
    20911987  int whichObject = -1;
    20921988  if (numberObjects) {
    2093     CbcModel * model = objects[0]->model();
     1989    CbcModel * model = cbcModel();
    20941990    // at continuous
    20951991    //double continuousObjective = model->getContinuousObjective();
     
    27392635}
    27402636double
    2741 CbcFixingBranchingObject::branch(bool normalBranch)
    2742 {
    2743   if (model_->messageHandler()->logLevel()>2&&normalBranch)
    2744     print(normalBranch);
    2745   numberBranchesLeft_--;
     2637CbcFixingBranchingObject::branch()
     2638{
     2639  decrementNumberBranchesLeft();
    27462640  OsiSolverInterface * solver = model_->solver();
    27472641  const double * columnLower = solver->getColLower();
     
    27812675}
    27822676void
    2783 CbcFixingBranchingObject::print(bool normalBranch)
     2677CbcFixingBranchingObject::print()
    27842678{
    27852679  int i;
     
    30322926    value = CoinMin(value, upper[iColumn]);
    30332927    if (upper[iColumn]>lower[iColumn]) {
    3034       double distance = CoinMin(value-lower[iColumn],upper[iColumn]-value);
     2928      double distance = upper[iColumn]-value;
    30352929      list[numberFree]=j;
    30362930      sort[numberFree++]=distance;
     
    30652959  :CbcBranchingObject(model,nway->id(),-1,0.5)
    30662960{
     2961  numberBranches_ = number;
    30672962  order_ = new int [number];
    30682963  object_=nway;
    30692964  numberInSet_=number;
    30702965  memcpy(order_,order,number*sizeof(int));
    3071   numberBranchesLeft_=number;
    30722966}
    30732967
     
    31163010}
    31173011double
    3118 CbcNWayBranchingObject::branch(bool normalBranch)
    3119 {
    3120   if (model_->messageHandler()->logLevel()>2&&normalBranch)
    3121     print(normalBranch);
    3122   numberBranchesLeft_--;
    3123   assert (numberBranchesLeft_>=0);
    3124   int which = numberBranchesLeft_;
    3125   if (numberBranchesLeft_==numberInSet_) {
     3012CbcNWayBranchingObject::branch()
     3013{
     3014  int which = branchIndex_;
     3015  branchIndex_++;
     3016  assert (numberBranchesLeft()>=0);
     3017  if (which==0) {
    31263018    // first branch so way_ may mean something
    31273019    assert (way_==-1||way_==1);
    3128     if (way_==1)
    3129       which--;
    3130   } else if (numberBranchesLeft_+1==numberInSet_) {
     3020    if (way_==-1)
     3021      which++;
     3022  } else if (which==1) {
    31313023    // second branch so way_ may mean something
    31323024    assert (way_==-1||way_==1);
    31333025    if (way_==-1)
    3134       which++;
     3026      which--;
    31353027    // switch way off
    31363028    way_=0;
     
    31423034    int iSequence = order_[j];
    31433035    int iColumn = members[iSequence];
    3144     if (j!=numberBranchesLeft_) {
     3036    if (j!=which) {
    31453037      model_->solver()->setColUpper(iColumn,lower[iColumn]);
    31463038      //model_->solver()->setColLower(iColumn,lower[iColumn]);
     
    31623054}
    31633055void
    3164 CbcNWayBranchingObject::print(bool normalBranch)
     3056CbcNWayBranchingObject::print()
    31653057{
    31663058  printf("NWay - Up Fix ");
     
    33433235  :CbcBranchingObject(model,0,0,0.5)
    33443236{
    3345   numberBranchesLeft_=1;
     3237  setNumberBranchesLeft(1);
    33463238}
    33473239
     
    33773269*/
    33783270double
    3379 CbcDummyBranchingObject::branch(bool normalBranch)
    3380 {
    3381   if (model_->messageHandler()->logLevel()>2&&normalBranch)
    3382     print(normalBranch);
    3383   numberBranchesLeft_=0;
     3271CbcDummyBranchingObject::branch()
     3272{
     3273  decrementNumberBranchesLeft();
    33843274  return 0.0;
    33853275}
    33863276// Print what would happen 
    33873277void
    3388 CbcDummyBranchingObject::print(bool normalBranch)
     3278CbcDummyBranchingObject::print()
    33893279{
    33903280  printf("Dummy branch\n");
  • branches/devel/Cbc/src/CbcBranchActual.hpp

    r424 r439  
    187187  CbcSimpleInteger ();
    188188
    189   // Useful constructor - passed integer index and model index
    190   CbcSimpleInteger (CbcModel * model, int sequence, int iColumn, double breakEven=0.5);
     189  // Useful constructor - passed model and index
     190  CbcSimpleInteger (CbcModel * model,  int iColumn, double breakEven=0.5);
     191 
     192  // Useful constructor - passed model and Osi object
     193  CbcSimpleInteger (CbcModel * model,  const OsiSimpleInteger * object);
    191194 
    192195  // Copy constructor
     
    201204  // Destructor
    202205  ~CbcSimpleInteger ();
    203  
     206  /// Construct an OsiSimpleInteger object
     207  OsiSimpleInteger * osiObject() const;
     208  /// Infeasibility - large is 0.5
     209  virtual double infeasibility(const OsiSolverInterface * solver,
     210                               const OsiBranchingInformation * info, int & preferredWay) const;
     211
     212  /** Set bounds to fix the variable at the current (integer) value.
     213
     214    Given an integer value, set the lower and upper bounds to fix the
     215    variable. Returns amount it had to move variable.
     216  */
     217  virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
     218
     219  /** Create a branching object and indicate which way to branch first.
     220     
     221      The branching object has to know how to create branches (fix
     222      variables, etc.)
     223  */
     224  virtual CbcBranchingObject * createBranch(OsiSolverInterface * solver,
     225                                            const OsiBranchingInformation * info, int way) ;
     226  /** Create an OsiSolverBranch object
     227
     228      This returns NULL if branch not represented by bound changes
     229  */
     230  virtual OsiSolverBranch * solverBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
    204231  /// Infeasibility - large is 0.5
    205232  virtual double infeasibility(int & preferredWay) const;
     
    218245  */
    219246  virtual CbcBranchingObject * createBranch(int way) ;
    220 
    221   /** Create an OsiSolverBranch object
    222 
    223       This returns NULL if branch not represented by bound changes
    224   */
    225   virtual OsiSolverBranch * solverBranch() const;
    226   /// Redoes data when sequence numbers change
    227   virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns);
    228  
    229   /** \brief Given a valid solution (with reduced costs, etc.),
    230       return a branching object which would give a new feasible
    231       point in the good direction.
    232 
    233     The preferred branching object will force the variable to be either the
    234     floor or ceiling of its current value, depending on the reduced cost and
    235     objective sense. If movement in the direction which improves the
    236     objective is impossible due to bounds on the variable, the branching
    237     object will move in the other direction.  If no movement is possible, the
    238     method returns NULL.
    239 
    240     Only the bounds on this variable are considered when determining if the new
    241     point is feasible.
    242   */
    243   virtual CbcBranchingObject * preferredNewFeasible() const;
    244  
    245   /** \brief Given a valid solution (with reduced costs, etc.),
    246       return a branching object which would give a new feasible
    247       point in a bad direction.
    248 
    249     As for preferredNewFeasible(), but the preferred branching object will
    250     force movement in a direction that degrades the objective.
    251   */
    252   virtual CbcBranchingObject * notPreferredNewFeasible() const ;
    253  
    254   /** Reset original upper and lower bound values from the solver.
    255  
    256     Handy for updating bounds held in this object after bounds held in the
    257     solver have been tightened.
    258    */
    259   virtual void resetBounds();
    260  
    261   /// Sequence number
    262   inline int sequence() const
    263   {return sequence_;};
    264 
    265   /// Model column number
    266   inline int modelSequence() const
    267   {return columnNumber_;};
    268   /// Set model column number
    269   inline void setColumnNumber(int value)
    270   {columnNumber_=value;};
    271  
    272247  /** Column number if single column object -1 otherwise,
    273248      so returns >= 0
     
    296271  /// data
    297272
    298   /// Sequence
    299   int sequence_;
    300   /// Column number in model
    301   int columnNumber_;
    302273  /// Original lower bound
    303274  double originalLower_;
     
    306277  /// Breakeven i.e. >= this preferred is up
    307278  double breakEven_;
    308 };
    309 
     279  /// Column number in model
     280  int columnNumber_;
     281  /// If -1 down always chosen first, +1 up always, 0 normal
     282  int preferredWay_;
     283};
    310284/** Define an n-way class for variables.
    311285    Only valid value is one at UB others at LB
     
    425399             Returns change in guessed objective on next branch
    426400  */
    427   virtual double branch(bool normalBranch=false);
     401  virtual double branch();
    428402
    429403  /** \brief Print something about branch - only if log level high
    430404  */
    431   virtual void print(bool normalBranch);
     405  virtual void print();
    432406
    433407protected:
     
    449423  CbcSimpleIntegerPseudoCost ();
    450424
    451   // Useful constructor - passed integer index and model index
    452   CbcSimpleIntegerPseudoCost (CbcModel * model, int sequence, int iColumn, double breakEven=0.5);
    453  
    454   // Useful constructor - passed integer index and model index and pseudo costs
    455   CbcSimpleIntegerPseudoCost (CbcModel * model, int sequence, int iColumn,
     425  // Useful constructor - passed model index
     426  CbcSimpleIntegerPseudoCost (CbcModel * model, int iColumn, double breakEven=0.5);
     427 
     428  // Useful constructor - passed and model index and pseudo costs
     429  CbcSimpleIntegerPseudoCost (CbcModel * model, int iColumn,
     430                              double downPseudoCost, double upPseudoCost);
     431  // Useful constructor - passed and model index and pseudo costs
     432  CbcSimpleIntegerPseudoCost (CbcModel * model, int dummy,int iColumn,
    456433                              double downPseudoCost, double upPseudoCost);
    457434 
     
    582559             This version also changes guessed objective value
    583560  */
    584   virtual double branch(bool normalBranch=false);
     561  virtual double branch();
    585562
    586563  /// Change in guessed
     
    630607 
    631608  /// Does next branch and updates state
    632   virtual double branch(bool normalBranch=false);
     609  virtual double branch();
    633610
    634611  /** \brief Print something about branch - only if log level high
    635612  */
    636   virtual void print(bool normalBranch);
     613  virtual void print();
    637614private:
    638615  /// data
     
    675652 
    676653  /// Does next branch and updates state
    677   virtual double branch(bool normalBranch=false);
     654  virtual double branch();
    678655
    679656  /** \brief Print something about branch - only if log level high
    680657  */
    681   virtual void print(bool normalBranch);
     658  virtual void print();
    682659private:
    683660  /// data
     
    719696 
    720697  /// Does next branch and updates state
    721   virtual double branch(bool normalBranch=false);
     698  virtual double branch();
    722699
    723700  /** \brief Print something about branch - only if log level high
    724701  */
    725   virtual void print(bool normalBranch);
     702  virtual void print();
    726703private:
    727704  /// data
     
    761738 
    762739  /// Does next branch and updates state
    763   virtual double branch(bool normalBranch=false);
     740  virtual double branch();
    764741
    765742  /** \brief Print something about branch - only if log level high
    766743  */
    767   virtual void print(bool normalBranch);
     744  virtual void print();
    768745  /** The number of branch arms created for this branching object
    769746  */
     
    861838  double bestChangeDown_;
    862839
     840  /// Pointer to best branching object
     841  CbcBranchingObject * bestObject_;
     842
    863843  /// Number of infeasibilities for down
    864844  int bestNumberDown_;
    865 
    866   /// Pointer to best branching object
    867   CbcBranchingObject * bestObject_;
    868845
    869846};
     
    951928 
    952929  /// Does next branch and updates state
    953   virtual double branch(bool normalBranch=false);
     930  virtual double branch();
    954931
    955932  /** \brief Print something about branch - only if log level high
    956933  */
    957   virtual void print(bool normalBranch);
     934  virtual void print();
    958935private:
    959936  /// data
     
    10471024  /** \brief Dummy branch
    10481025  */
    1049   virtual double branch(bool normalBranch=false);
     1026  virtual double branch();
    10501027
    10511028  /** \brief Print something about branch - only if log level high
    10521029  */
    1053   virtual void print(bool normalBranch);
     1030  virtual void print();
    10541031
    10551032};
  • branches/devel/Cbc/src/CbcBranchBase.cpp

    r310 r439  
    1111#include "OsiSolverInterface.hpp"
    1212#include "OsiSolverBranch.hpp"
     13#include "OsiChooseVariable.hpp"
    1314#include "CbcModel.hpp"
    1415#include "CbcMessage.hpp"
     
    1819// Default Constructor
    1920CbcObject::CbcObject()
    20   :model_(NULL),
     21  : OsiObject(),
     22    model_(NULL),
    2123   id_(-1),
    22    priority_(1000),
    2324   preferredWay_(0)
    2425{
     
    2728// Constructor from model
    2829CbcObject::CbcObject(CbcModel * model)
    29 :
    30   model_(model),
    31   id_(-1),
    32   priority_(1000),
    33   preferredWay_(0)
     30  : OsiObject(),
     31    model_(model),
     32    id_(-1),
     33    preferredWay_(0)
    3434{
    3535}
     
    4343// Copy constructor
    4444CbcObject::CbcObject ( const CbcObject & rhs)
     45  : OsiObject(rhs)
    4546{
    4647  model_ = rhs.model_;
    4748  id_ = rhs.id_;
    48   priority_ = rhs.priority_;
    4949  preferredWay_ = rhs.preferredWay_;
    5050}
     
    5555{
    5656  if (this!=&rhs) {
     57    OsiObject::operator=(rhs);
    5758    model_ = rhs.model_;
    5859    id_ = rhs.id_;
    59     priority_ = rhs.priority_;
    6060    preferredWay_ = rhs.preferredWay_;
    6161  }
     
    7676  ceilingValue = floorValue+1.0;
    7777}
    78 // Return "up" estimate (default 1.0e-5)
     78/* Infeasibility of the object
     79     
     80    This is some measure of the infeasibility of the object. 0.0
     81    indicates that the object is satisfied.
     82 
     83    The preferred branching direction is returned in way,
     84 
     85    This is used to prepare for strong branching but should also think of
     86    case when no strong branching
     87 
     88    The object may also compute an estimate of cost of going "up" or "down".
     89    This will probably be based on pseudo-cost ideas
     90
     91    This should also set mutable infeasibility_ and whichWay_
     92    This is for instant re-use for speed
     93*/
    7994double
    80 CbcObject::upEstimate() const
    81 {
    82   return 1.0e-5;
    83 }
    84 // Return "down" estimate (default 1.0e-5)
     95CbcObject::infeasibility(const OsiSolverInterface * solver,int &preferredWay) const
     96{
     97  assert (solver==model_->solver());
     98  return infeasibility(preferredWay);
     99}
     100 
     101/* For the variable(s) referenced by the object,
     102      look at the current solution and set bounds to match the solution.
     103      Returns measure of how much it had to move solution to make feasible
     104*/
    85105double
    86 CbcObject::downEstimate() const
    87 {
    88   return 1.0e-5;
    89 }
    90 // Column number if single column object -1 otherwise
    91 int
    92 CbcObject::columnNumber() const
    93 {
    94   // Say not as at present only used by heuristics
    95   return -1;
     106CbcObject::feasibleRegion(OsiSolverInterface * solver) const
     107{
     108  assert (solver==model_->solver());
     109  CbcObject * fudge = const_cast<CbcObject *>(this);
     110  fudge->feasibleRegion();
     111  return 0.0;
     112}
     113/* Infeasibility of the object
     114     
     115    This is some measure of the infeasibility of the object. 0.0
     116    indicates that the object is satisfied.
     117 
     118    The preferred branching direction is returned in way,
     119 
     120    This is used to prepare for strong branching but should also think of
     121    case when no strong branching
     122 
     123    The object may also compute an estimate of cost of going "up" or "down".
     124    This will probably be based on pseudo-cost ideas
     125
     126    This should also set mutable infeasibility_ and whichWay_
     127    This is for instant re-use for speed
     128*/
     129double
     130CbcObject::infeasibility(const OsiBranchingInformation * info,
     131                         int &preferredWay) const
     132{
     133  return infeasibility(preferredWay);
     134}
     135 
     136/* For the variable(s) referenced by the object,
     137      look at the current solution and set bounds to match the solution.
     138      Returns measure of how much it had to move solution to make feasible
     139*/
     140double
     141CbcObject::feasibleRegion(OsiSolverInterface * solver,const OsiBranchingInformation * info) const
     142{
     143  assert (solver==model_->solver());
     144  CbcObject * fudge = const_cast<CbcObject *>(this);
     145  fudge->feasibleRegion();
     146  return 0.0;
     147}
     148 
     149/* Create a branching object and indicate which way to branch first.
     150     
     151      The branching object has to know how to create branches (fix
     152      variables, etc.)
     153*/
     154OsiBranchingObject *
     155CbcObject::createBranch(OsiSolverInterface * solver, int way) const
     156{
     157  assert (solver==model_->solver());
     158  CbcObject * fudge = const_cast<CbcObject *>(this);
     159  return fudge->createBranch(way);
    96160}
    97161/* Create an OsiSolverBranch object
     
    107171// Default Constructor
    108172CbcBranchingObject::CbcBranchingObject()
     173  : OsiBranchingObject()
    109174{
    110175  model_=NULL;
    111   originalObject_=NULL;
     176  originalCbcObject_=NULL;
    112177  variable_=-1;
    113178  way_=0;
    114   value_=0.0;
    115   numberBranchesLeft_=2;
    116179}
    117180
    118181// Useful constructor
    119182CbcBranchingObject::CbcBranchingObject (CbcModel * model, int variable, int way , double value)
     183  : OsiBranchingObject(model->solver(),value)
    120184{
    121185  model_= model;
    122   originalObject_=NULL;
     186  originalCbcObject_=NULL;
    123187  variable_=variable;
    124188  way_=way;
    125   value_=value;
    126   numberBranchesLeft_=2;
    127189}
    128190
    129191// Copy constructor
    130192CbcBranchingObject::CbcBranchingObject ( const CbcBranchingObject & rhs)
     193  : OsiBranchingObject(rhs)
    131194{
    132195  model_=rhs.model_;
    133   originalObject_=rhs.originalObject_;
     196  originalCbcObject_=rhs.originalCbcObject_;
    134197  variable_=rhs.variable_;
    135198  way_=rhs.way_;
    136199  value_=rhs.value_;
    137   numberBranchesLeft_=rhs.numberBranchesLeft_;
    138200}
    139201
     
    143205{
    144206  if (this != &rhs) {
     207    OsiBranchingObject::operator=(rhs);
    145208    model_=rhs.model_;
    146     originalObject_=rhs.originalObject_;
     209    originalCbcObject_=rhs.originalCbcObject_;
    147210    variable_=rhs.variable_;
    148211    way_=rhs.way_;
    149     value_=rhs.value_;
    150     numberBranchesLeft_=rhs.numberBranchesLeft_;
    151212  }
    152213  return *this;
     
    159220// Default Constructor
    160221CbcBranchDecision::CbcBranchDecision ()
    161   : object_(NULL)
    162 {
     222  : object_(NULL),model_(NULL),chooseMethod_(NULL)
     223{
     224}
     225
     226// Copy Constructor
     227CbcBranchDecision::CbcBranchDecision (const CbcBranchDecision &rhs)
     228  : object_(NULL),model_(rhs.model_),chooseMethod_(NULL)
     229{
     230  if (rhs.chooseMethod_)
     231    chooseMethod_ = rhs.chooseMethod_->clone();
    163232}
    164233
     
    166235{
    167236  delete object_;
     237  delete chooseMethod_;
    168238}
    169239/* Compare N branching objects. Return index of best
     
    205275  return whichObject;
    206276}
    207 
     277// Set (clone) chooseMethod
     278void
     279CbcBranchDecision::setChooseMethod(const OsiChooseVariable & method)
     280{
     281  delete chooseMethod_;
     282  chooseMethod_ = method.clone();
     283}
    208284// Default constructor
    209285CbcConsequence::CbcConsequence()
  • branches/devel/Cbc/src/CbcBranchBase.hpp

    r424 r439  
    66#include <string>
    77#include <vector>
    8 
     8#include "OsiBranchingObject.hpp"
    99class OsiSolverInterface;
    1010class OsiSolverBranch;
     
    1414class CbcNodeInfo;
    1515class CbcBranchingObject;
     16class OsiChooseVariable;
    1617
    1718//#############################################################################
    1819
    1920/** Abstract base class for `objects'.
     21    It now just has stuff that OsiObject does not have
    2022
    2123  The branching model used in Cbc is based on the idea of an <i>object</i>.
     
    5860  } CbcStrongInfo;
    5961
    60 class CbcObject {
     62class CbcObject : public OsiObject {
    6163
    6264public:
     
    9597  */
    9698  virtual double infeasibility(int &preferredWay) const = 0;
     99  /// Dummy one for compatibility
     100  virtual double infeasibility(const OsiBranchingInformation * info,
     101                               int &preferredWay) const;
    97102
    98103  /** For the variable(s) referenced by the object,
     
    100105  */
    101106  virtual void feasibleRegion() = 0;
     107  /// Dummy one for compatibility
     108  virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
    102109
    103110  /** Create a branching object and indicate which way to branch first.
     
    108115  virtual CbcBranchingObject * createBranch(int way) = 0;
    109116 
     117  /** Infeasibility of the object
     118     
     119    This is some measure of the infeasibility of the object. 0.0
     120    indicates that the object is satisfied.
     121 
     122    The preferred branching direction is returned in way,
     123 
     124    This is used to prepare for strong branching but should also think of
     125    case when no strong branching
     126 
     127    The object may also compute an estimate of cost of going "up" or "down".
     128    This will probably be based on pseudo-cost ideas
     129
     130    This should also set mutable infeasibility_ and whichWay_
     131    This is for instant re-use for speed
     132  */
     133  virtual double infeasibility(const OsiSolverInterface * solver,int &preferredWay) const;
     134 
     135  /** For the variable(s) referenced by the object,
     136      look at the current solution and set bounds to match the solution.
     137      Returns measure of how much it had to move solution to make feasible
     138  */
     139  virtual double feasibleRegion(OsiSolverInterface * solver) const ;
     140 
     141  /** Create a branching object and indicate which way to branch first.
     142     
     143      The branching object has to know how to create branches (fix
     144      variables, etc.)
     145  */
     146  virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, int way) const;
    110147  /** Create an OsiSolverBranch object
    111148
     
    141178    their original values.
    142179   */
    143   virtual void resetBounds() {};
    144  
    145   /** \brief Return true if branch created by object should fix variables
    146   */
    147   virtual bool boundBranch() const
    148   {return true;};
    149   /** \brief Return true if object can take part in normal heuristics
    150   */
    151   virtual bool canDoHeuristics() const
    152   {return true;};
     180  virtual void resetBounds(const OsiSolverInterface * solver) {};
     181 
    153182  /** Returns floor and ceiling i.e. closest valid points
    154183  */
     
    159188  inline int id() const
    160189  { return id_;};
    161   /// Return Priority
    162   inline int priority() const
    163   { return priority_;};
    164   /// Set priority
    165   inline void setPriority(int priority)
    166   { priority_ = priority;};
    167  
    168   /// Column number if single column object -1 otherwise
    169   virtual int columnNumber() const;
    170 
    171190 
    172191   /// update model
     
    178197  {return  model_;};
    179198
    180   /// Return "up" estimate (default 1.0e-5)
    181   virtual double upEstimate() const;
    182   /// Return "down" estimate (default 1.0e-5)
    183   virtual double downEstimate() const;
    184199  /// If -1 down always chosen first, +1 up always, 0 normal
    185200  inline int preferredWay() const
     
    198213  /// Identifier (normally column number in matrix)
    199214  int id_;
    200   /// Priority
    201   int priority_;
    202215  /// If -1 down always chosen first, +1 up always, 0 normal
    203216  int preferredWay_;
     
    206219
    207220/** \brief Abstract branching object base class
     221    Now just difference with OsiBranchingObject
    208222
    209223  In the abstract, an CbcBranchingObject contains instructions for how to
     
    222236*/
    223237
    224 class CbcBranchingObject {
     238class CbcBranchingObject : public OsiBranchingObject {
    225239
    226240public:
     
    249263      Returns nonzero if skip is wanted */
    250264  virtual int fillStrongInfo( CbcStrongInfo & info) {return 0;};
    251   /** The number of branch arms created for this branching object
    252 
    253     \todo The hardwired `2' has to be changed before cbc can do branches with
    254           more than two arms.
    255   */
    256   virtual int numberBranches() const
    257   {return 2;};
    258 
    259   /// The number of branch arms left to be evaluated
    260   virtual int numberBranchesLeft() const
    261   {return numberBranchesLeft_;};
    262265  /// Reset number of branches left to original
    263266  inline void resetNumberBranchesLeft()
    264   { numberBranchesLeft_ = numberBranches();};
     267  { branchIndex_=0;};
    265268
    266269  /** \brief Execute the actions required to branch, as specified by the
     
    270273             Returns change in guessed objective on next branch
    271274  */
    272   virtual double branch(bool normalBranch=false)=0;
     275  virtual double branch()=0;
    273276
    274277  /** \brief Print something about branch - only if log level high
    275278  */
    276   virtual void print(bool normalBranch) {};
    277 
    278   /** \brief Return true if branch should fix variables
    279   */
    280   virtual bool boundBranch() const
    281   {return true;};
     279  virtual void print() const {};
    282280
    283281  /** \brief Index identifying the associated CbcObject within its class.
     
    312310  {way_=way;};
    313311
    314   /// Current value
    315   inline double value() const
    316   {return value_;};
    317  
    318312  /// Return model
    319313  inline CbcModel * model() const
     
    322316  /// Return pointer back to object which created
    323317  inline CbcObject * object() const
    324   {return  originalObject_;};
     318  {return  originalCbcObject_;};
    325319  /// Set pointer back to object which created
    326320  inline void setOriginalObject(CbcObject * object)
    327   {originalObject_=object;};
     321  {originalCbcObject_=object;};
    328322
    329323protected:
     
    332326  CbcModel * model_;
    333327  /// Pointer back to object which created
    334   CbcObject * originalObject_;
     328  CbcObject * originalCbcObject_;
    335329
    336330  /// Branching variable (0 is first integer)
     
    346340  int way_;
    347341
    348   /// Current value
    349   double value_;
    350 
    351   /** Number of arms remaining to be evaluated
    352 
    353     \todo Compare with CbcNodeInfo::numberBranchesLeft_, and check for
    354           redundancy.
    355   */
    356   int numberBranchesLeft_;
    357 
    358342};
    359343
     
    377361  CbcBranchDecision ();
    378362
     363  // Copy constructor
     364  CbcBranchDecision ( const CbcBranchDecision &);
     365   
    379366  /// Destructor
    380367  virtual ~CbcBranchDecision();
     
    419406  /** Saves a clone of current branching object.  Can be used to update
    420407      information on object causing branch - after branch */
    421   virtual void saveBranchingObject(CbcBranchingObject * object) {};
     408  virtual void saveBranchingObject(OsiBranchingObject * object) {};
    422409  /** Pass in information on branch just done.
    423410      assumes object can get information from solver */
     
    429416  /// Create C++ lines to get to current state
    430417  virtual void generateCpp( FILE * fp) {};
     418  /// Model
     419  inline CbcModel * cbcModel() const
     420  { return model_;}
     421  /* If chooseMethod_ id non-null then the rest is fairly pointless
     422     as choosemethod_ will be doing all work
     423  */
     424  OsiChooseVariable * chooseMethod() const
     425  { return chooseMethod_;};
     426  /// Set (clone) chooseMethod
     427  void setChooseMethod(const OsiChooseVariable & method);
    431428
    432429protected:
     
    434431  // Clone of branching object
    435432  CbcBranchingObject * object_;
     433  /// Pointer to model
     434  CbcModel * model_;
     435  /* If chooseMethod_ id non-null then the rest is fairly pointless
     436     as choosemethod_ will be doing all work
     437  */
     438  OsiChooseVariable * chooseMethod_;
    436439private:
    437440  /// Assignment is illegal
  • branches/devel/Cbc/src/CbcBranchCut.cpp

    r310 r439  
    186186*/
    187187double
    188 CbcCutBranchingObject::branch(bool normalBranch)
    189 {
    190   if (model_->messageHandler()->logLevel()>2&&normalBranch)
    191     print(normalBranch);
    192   numberBranchesLeft_--;
     188CbcCutBranchingObject::branch()
     189{
     190  decrementNumberBranchesLeft();
    193191  OsiRowCut * cut;
    194192  if (way_<0) {
     
    252250// Print what would happen 
    253251void
    254 CbcCutBranchingObject::print(bool normalBranch)
     252CbcCutBranchingObject::print()
    255253{
    256254  OsiRowCut * cut;
  • branches/devel/Cbc/src/CbcBranchCut.hpp

    r216 r439  
    131131             Returns change in guessed objective on next branch
    132132  */
    133   virtual double branch(bool normalBranch=false);
     133  virtual double branch();
    134134
    135135  /** \brief Print something about branch - only if log level high
    136136  */
    137   virtual void print(bool normalBranch);
     137  virtual void print();
    138138
    139139  /** \brief Return true if branch should fix variables
  • 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.
  • branches/devel/Cbc/src/CbcBranchDynamic.hpp

    r424 r439  
    2424  CbcSimpleIntegerDynamicPseudoCost ();
    2525
    26   // Useful constructor - passed integer index and model index
    27   CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int sequence, int iColumn, double breakEven=0.5);
    28  
    29   // Useful constructor - passed integer index and model index and pseudo costs
    30   CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int sequence, int iColumn,
     26  // Useful constructor - passed  model index
     27  CbcSimpleIntegerDynamicPseudoCost (CbcModel * model,  int iColumn, double breakEven=0.5);
     28 
     29  // Useful constructor - passed  model index and pseudo costs
     30  CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int iColumn,
     31                              double downDynamicPseudoCost, double upDynamicPseudoCost);
     32 
     33  // Useful constructor - passed  model index and pseudo costs
     34  CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int dummy, int iColumn,
    3135                              double downDynamicPseudoCost, double upDynamicPseudoCost);
    3236 
     
    4852  /// Creates a branching object
    4953  virtual CbcBranchingObject * createBranch(int way) ;
     54  /// Infeasibility - large is 0.5
     55  virtual double infeasibility(const OsiSolverInterface * solver,
     56                               const OsiBranchingInformation * info, int & preferredWay) const;
     57
     58
     59  /** Create a branching object and indicate which way to branch first.
     60     
     61      The branching object has to know how to create branches (fix
     62      variables, etc.)
     63  */
     64  virtual CbcBranchingObject * createBranch(OsiSolverInterface * solver,
     65                                            const OsiBranchingInformation * info, int way) ;
    5066
    5167  /** Create an OsiSolverBranch object
     
    322338             This version also changes guessed objective value
    323339  */
    324   virtual double branch(bool normalBranch=false);
     340  virtual double branch();
    325341  /** Some branchingObjects may claim to be able to skip
    326342      strong branching.  If so they have to fill in CbcStrongInfo.
     
    399415  /** Saves a clone of current branching object.  Can be used to update
    400416      information on object causing branch - after branch */
    401   virtual void saveBranchingObject(CbcBranchingObject * object) ;
     417  virtual void saveBranchingObject(OsiBranchingObject * object) ;
    402418  /** Pass in information on branch just done.
    403419      assumes object can get information from solver */
  • branches/devel/Cbc/src/CbcBranchLotsize.cpp

    r356 r439  
    642642 */
    643643void
    644 CbcLotsize::resetBounds()
    645 {
    646   //printf("resetBounds needs coding for CbcLotSize\n");
     644CbcLotsize::resetBounds(const OsiSolverInterface * solver)
     645{
    647646}
    648647
     
    679678  :CbcBranchingObject(model,variable,way,lowerValue)
    680679{
    681   numberBranchesLeft_=1;
     680  setNumberBranchesLeft(1);
    682681  down_[0] = lowerValue;
    683682  down_[1] = upperValue;
     
    731730*/
    732731double
    733 CbcLotsizeBranchingObject::branch(bool normalBranch)
    734 {
    735   if (model_->messageHandler()->logLevel()>2&&normalBranch)
    736     print(normalBranch);
    737   numberBranchesLeft_--;
     732CbcLotsizeBranchingObject::branch()
     733{
     734  decrementNumberBranchesLeft();
    738735  int iColumn = variable_;
    739736  if (way_<0) {
     
    764761// Print
    765762void
    766 CbcLotsizeBranchingObject::print(bool normalBranch)
     763CbcLotsizeBranchingObject::print()
    767764{
    768765  int iColumn = variable_;
  • branches/devel/Cbc/src/CbcBranchLotsize.hpp

    r424 r439  
    7878    solver have been tightened.
    7979   */
    80   virtual void resetBounds();
     80  virtual void resetBounds(const OsiSolverInterface * solver);
    8181
    8282  /** Finds range of interest so value is feasible in range range_ or infeasible
     
    191191             of the branch and advances the object state to the next arm.
    192192  */
    193   virtual double branch(bool normalBranch=false);
     193  virtual double branch();
    194194
    195195  /** \brief Print something about branch - only if log level high
    196196  */
    197   virtual void print(bool normalBranch);
     197  virtual void print();
    198198
    199199protected:
  • branches/devel/Cbc/src/CbcCompareActual.cpp

    r424 r439  
    219219  }
    220220#else
    221   if (weight_==-1.0&&(y->depth()>7||x->depth()>7)) {
     221  if ((weight_==-1.0&&(y->depth()>7||x->depth()>7))||weight_==-3.0) {
     222    int adjust =  (weight_==-3.0) ? 10000 : 0;
    222223    // before solution
    223     /* printf("x %d %d %g, y %d %d %g\n",
     224    /*printf("x %d %d %g, y %d %d %g\n",
    224225       x->numberUnsatisfied(),x->depth(),x->objectiveValue(),
    225226       y->numberUnsatisfied(),y->depth(),y->objectiveValue()); */
    226     if (x->numberUnsatisfied() > y->numberUnsatisfied()) {
     227    if (x->numberUnsatisfied() > y->numberUnsatisfied()+adjust) {
    227228      return true;
    228     } else if (x->numberUnsatisfied() < y->numberUnsatisfied()) {
     229    } else if (x->numberUnsatisfied() < y->numberUnsatisfied()-adjust) {
    229230      return false;
    230231    } else {
  • branches/devel/Cbc/src/CbcCompareActual.hpp

    r356 r439  
    9494  virtual bool every1000Nodes(CbcModel * model,int numberNodes);
    9595
    96   /* if weight == -1.0 then depth first (before solution)
     96  /* if weight == -1.0 then fewest infeasibilities (before solution)
    9797     if -2.0 then do breadth first just for first 1000 nodes
     98     if -3.0 then depth first before solution
    9899  */
    99100  inline double getWeight() const
  • branches/devel/Cbc/src/CbcHeuristic.cpp

    r356 r439  
    118118          << name
    119119          <<CoinMessageEol;
    120       if (model.getMinimizationObjValue()<cutoff) {
     120      if (model.getMinimizationObjValue()<CoinMin(cutoff,1.0e30)) {
    121121        // solution
    122122        returnCode=1;
  • branches/devel/Cbc/src/CbcHeuristic.hpp

    r356 r439  
    8686 
    8787};
    88 
    8988/** Rounding class
    9089 */
  • branches/devel/Cbc/src/CbcHeuristicFPump.cpp

    r435 r439  
    2323   startTime_(0.0),
    2424   maximumTime_(0.0),
     25   downValue_(0.5),
     26   fakeCutoff_(COIN_DBL_MAX),
     27   absoluteIncrement_(0.0),
     28   relativeIncrement_(0.0),
    2529   maximumPasses_(100),
    26    downValue_(0.5),
     30   maximumRetries_(1),
    2731   roundExpensive_(false)
    2832{
     
    3640   startTime_(0.0),
    3741   maximumTime_(0.0),
     42   downValue_(downValue),
     43   fakeCutoff_(COIN_DBL_MAX),
     44   absoluteIncrement_(0.0),
     45   relativeIncrement_(0.0),
    3846   maximumPasses_(100),
    39    downValue_(downValue),
     47   maximumRetries_(1),
    4048   roundExpensive_(roundExpensive)
    4149{
     
    6573  else
    6674    fprintf(fp,"4  heuristicFPump.setMaximumPasses(%d);\n",maximumPasses_);
     75  if (maximumRetries_!=other.maximumRetries_)
     76    fprintf(fp,"3  heuristicFPump.setMaximumRetries(%d);\n",maximumRetries_);
     77  else
     78    fprintf(fp,"4  heuristicFPump.setMaximumRetries(%d);\n",maximumRetries_);
    6779  if (maximumTime_!=other.maximumTime_)
    6880    fprintf(fp,"3  heuristicFPump.setMaximumTime(%g);\n",maximumTime_);
    6981  else
    7082    fprintf(fp,"4  heuristicFPump.setMaximumTime(%g);\n",maximumTime_);
     83  if (fakeCutoff_!=other.fakeCutoff_)
     84    fprintf(fp,"3  heuristicFPump.setFakeCutoff(%g);\n",fakeCutoff_);
     85  else
     86    fprintf(fp,"4  heuristicFPump.setFakeCutoff(%g);\n",fakeCutoff_);
     87  if (absoluteIncrement_!=other.absoluteIncrement_)
     88    fprintf(fp,"3  heuristicFPump.setAbsoluteIncrement(%g);\n",absoluteIncrement_);
     89  else
     90    fprintf(fp,"4  heuristicFPump.setAbsoluteIncrement(%g);\n",absoluteIncrement_);
     91  if (relativeIncrement_!=other.relativeIncrement_)
     92    fprintf(fp,"3  heuristicFPump.setRelativeIncrement(%g);\n",relativeIncrement_);
     93  else
     94    fprintf(fp,"4  heuristicFPump.setRelativeIncrement(%g);\n",relativeIncrement_);
    7195  fprintf(fp,"3  cbcModel->addHeuristic(&heuristicFPump);\n");
    7296}
     
    78102  startTime_(rhs.startTime_),
    79103  maximumTime_(rhs.maximumTime_),
     104  downValue_(rhs.downValue_),
     105  fakeCutoff_(rhs.fakeCutoff_),
     106  absoluteIncrement_(rhs.absoluteIncrement_),
     107  relativeIncrement_(rhs.relativeIncrement_),
    80108  maximumPasses_(rhs.maximumPasses_),
    81   downValue_(rhs.downValue_),
     109  maximumRetries_(rhs.maximumRetries_),
    82110  roundExpensive_(rhs.roundExpensive_)
    83111{
     
    109137  // probably a good idea
    110138  if (model_->getSolutionCount()) return 0;
    111   // Clone solver - otherwise annoys root node computations
    112   OsiSolverInterface * solver = model_->solver()->clone();
    113   solver->setDblParam(OsiDualObjectiveLimit,1.0e50);
    114   solver->resolve();
    115   const double * lower = solver->getColLower();
    116   const double * upper = solver->getColUpper();
    117   const double * solution = solver->getColSolution();
    118   double primalTolerance;
    119   solver->getDblParam(OsiPrimalTolerance,primalTolerance);
    120  
     139  // loop round doing repeated pumps
     140  double cutoff;
     141  model_->solver()->getDblParam(OsiDualObjectiveLimit,cutoff);
     142  double direction = model_->solver()->getObjSense();
     143  cutoff *= direction;
     144  cutoff = CoinMin(cutoff,solutionValue);
     145  // space for rounded solution
    121146  int numberColumns = model_->getNumCols();
     147  double * newSolution = new double [numberColumns];
     148  double newSolutionValue=COIN_DBL_MAX;
     149  bool solutionFound=false;
    122150  char * usedColumn = NULL;
    123151  double * lastSolution=NULL;
     
    130158    usedColumn = new char [numberColumns];
    131159    memset(usedColumn,0,numberColumns);
    132     lastSolution = CoinCopyOfArray(solver->getColSolution(),numberColumns);
     160    model_->solver()->resolve();
     161    assert (model_->solver()->isProvenOptimal());
     162    lastSolution = CoinCopyOfArray(model_->solver()->getColSolution(),numberColumns);
    133163  }
    134   int numberIntegers = model_->numberIntegers();
    135   const int * integerVariable = model_->integerVariable();
    136 
    137 // 1. initially check 0-1
    138   int i,j;
    139   int general=0;
    140   for (i=0;i<numberIntegers;i++) {
    141     int iColumn = integerVariable[i];
     164  int finalReturnCode=0;
     165  int totalNumberPasses=0;
     166  int numberTries=0;
     167  while (true) {
     168    int numberPasses=0;
     169    numberTries++;
     170    // Clone solver - otherwise annoys root node computations
     171    OsiSolverInterface * solver = model_->solver()->clone();
     172    // if cutoff exists then add constraint
     173    if (fabs(cutoff)<1.0e20&&(fakeCutoff_!=COIN_DBL_MAX||numberTries>1)) {
     174      cutoff = CoinMin(cutoff,fakeCutoff_);
     175      const double * objective = solver->getObjCoefficients();
     176      int numberColumns = solver->getNumCols();
     177      int * which = new int[numberColumns];
     178      double * els = new double[numberColumns];
     179      int nel=0;
     180      for (int i=0;i<numberColumns;i++) {
     181        double value = objective[i];
     182        if (value) {
     183          which[nel]=i;
     184          els[nel++] = direction*value;
     185        }
     186      }
     187      solver->addRow(nel,which,els,-COIN_DBL_MAX,cutoff);
     188      delete [] which;
     189      delete [] els;
     190    }
     191    solver->setDblParam(OsiDualObjectiveLimit,1.0e50);
     192    solver->resolve();
     193    // Solver may not be feasible
     194    if (!solver->isProvenOptimal()) {
     195      break;
     196    }
     197    const double * lower = solver->getColLower();
     198    const double * upper = solver->getColUpper();
     199    const double * solution = solver->getColSolution();
     200    if (lastSolution)
     201      memcpy(lastSolution,solution,numberColumns*sizeof(double));
     202    double primalTolerance;
     203    solver->getDblParam(OsiPrimalTolerance,primalTolerance);
     204   
     205    int numberIntegers = model_->numberIntegers();
     206    const int * integerVariable = model_->integerVariable();
     207
     208    // 1. initially check 0-1
     209    int i,j;
     210    int general=0;
     211    for (i=0;i<numberIntegers;i++) {
     212      int iColumn = integerVariable[i];
    142213#ifndef NDEBUG
    143     const CbcObject * object = model_->object(i);
    144     const CbcSimpleInteger * integerObject =
    145       dynamic_cast<const  CbcSimpleInteger *> (object);
    146     assert(integerObject);
     214      const OsiObject * object = model_->object(i);
     215      const CbcSimpleInteger * integerObject =
     216        dynamic_cast<const  CbcSimpleInteger *> (object);
     217      const OsiSimpleInteger * integerObject2 =
     218        dynamic_cast<const  OsiSimpleInteger *> (object);
     219      assert(integerObject||integerObject2);
    147220#endif
    148     if (upper[iColumn]-lower[iColumn]>1.000001) {
    149       general++;
    150       break;
    151     }
    152   }
    153   if (general*3>numberIntegers) {
    154     delete solver;
    155     return 0;
    156   }
    157 
    158 // 2. space for rounded solution
    159   double * newSolution = new double [numberColumns];
    160   // space for last rounded solutions
     221      if (upper[iColumn]-lower[iColumn]>1.000001) {
     222        general++;
     223        break;
     224      }
     225    }
     226    if (general*3>numberIntegers) {
     227      delete solver;
     228      return 0;
     229    }
     230   
     231    // 2 space for last rounded solutions
    161232#define NUMBER_OLD 4
    162   double ** oldSolution = new double * [NUMBER_OLD];
    163   for (j=0;j<NUMBER_OLD;j++) {
    164     oldSolution[j]= new double[numberColumns];
    165     for (i=0;i<numberColumns;i++) oldSolution[j][i]=-COIN_DBL_MAX;
    166   }
    167 
    168 // 3. Replace objective with an initial 0-valued objective
    169   double * saveObjective = new double [numberColumns];
    170   memcpy(saveObjective,solver->getObjCoefficients(),numberColumns*sizeof(double));
    171   for (i=0;i<numberColumns;i++) {
    172     solver->setObjCoeff(i,0.0);
    173   }
    174   bool finished=false;
    175   double direction = solver->getObjSense();
    176   int returnCode=0;
    177   bool takeHint;
    178   OsiHintStrength strength;
    179   solver->getHintParam(OsiDoDualInResolve,takeHint,strength);
    180   solver->setHintParam(OsiDoDualInResolve,false);
    181   solver->messageHandler()->setLogLevel(0);
    182 
    183 // 4. Save objective offset so we can see progress
    184   double saveOffset;
    185   solver->getDblParam(OsiObjOffset,saveOffset);
    186 
    187 // 5. MAIN WHILE LOOP
    188   int numberPasses=0;
    189   double newSolutionValue=COIN_DBL_MAX;
    190   bool newLineNeeded=false;
    191   while (!finished) {
    192     returnCode=0;
    193     // see what changed
    194     if (usedColumn) {
    195       const double * solution = solver->getColSolution();
    196       for (i=0;i<numberColumns;i++) {
    197         if (fabs(solution[i]-lastSolution[i])>1.0e-8)
    198           usedColumn[i]=1;
    199         lastSolution[i]=solution[i];
    200       }
    201     }
    202     if (numberPasses>=maximumPasses_) {
    203       break;
    204     }
    205     if (maximumTime_>0.0&&CoinCpuTime()>=startTime_+maximumTime_) break;
    206     numberPasses++;
    207     memcpy(newSolution,solution,numberColumns*sizeof(double));
    208     int flip;
    209     returnCode = rounds(newSolution,saveObjective,roundExpensive_,downValue_,&flip);
    210     if (returnCode) {
    211       // SOLUTION IS INTEGER
    212       // Put back correct objective
    213       for (i=0;i<numberColumns;i++)
    214         solver->setObjCoeff(i,saveObjective[i]);
    215       // solution - but may not be better
    216       // Compute using dot product
    217       solver->setDblParam(OsiObjOffset,saveOffset);
    218       newSolutionValue = direction*solver->OsiSolverInterface::getObjValue();
    219       if (model_->logLevel())
    220         printf(" - solution found\n");
    221       newLineNeeded=false;
    222       if (newSolutionValue<solutionValue) {
    223         if (general) {
    224           int numberLeft=0;
    225           for (i=0;i<numberIntegers;i++) {
    226             int iColumn = integerVariable[i];
    227             double value = floor(newSolution[iColumn]+0.5);
    228             if(solver->isBinary(iColumn)) {
    229               solver->setColLower(iColumn,value);
    230               solver->setColUpper(iColumn,value);
    231             } else {
    232               if (fabs(value-newSolution[iColumn])>1.0e-7)
    233                 numberLeft++;
    234             }
    235           }
    236           if (numberLeft) {
    237             returnCode = smallBranchAndBound(solver,200,newSolution,newSolutionValue,
    238                                          solutionValue,"CbcHeuristicFpump");
    239           }
    240         }
    241         if (returnCode) {
    242           memcpy(betterSolution,newSolution,numberColumns*sizeof(double));
    243           solutionValue=newSolutionValue;
    244         }
     233    double ** oldSolution = new double * [NUMBER_OLD];
     234    for (j=0;j<NUMBER_OLD;j++) {
     235      oldSolution[j]= new double[numberColumns];
     236      for (i=0;i<numberColumns;i++) oldSolution[j][i]=-COIN_DBL_MAX;
     237    }
     238   
     239    // 3. Replace objective with an initial 0-valued objective
     240    double * saveObjective = new double [numberColumns];
     241    memcpy(saveObjective,solver->getObjCoefficients(),numberColumns*sizeof(double));
     242    for (i=0;i<numberColumns;i++) {
     243      solver->setObjCoeff(i,0.0);
     244    }
     245    bool finished=false;
     246    double direction = solver->getObjSense();
     247    int returnCode=0;
     248    bool takeHint;
     249    OsiHintStrength strength;
     250    solver->getHintParam(OsiDoDualInResolve,takeHint,strength);
     251    solver->setHintParam(OsiDoDualInResolve,false);
     252    solver->messageHandler()->setLogLevel(0);
     253   
     254    // 4. Save objective offset so we can see progress
     255    double saveOffset;
     256    solver->getDblParam(OsiObjOffset,saveOffset);
     257   
     258    // 5. MAIN WHILE LOOP
     259    bool newLineNeeded=false;
     260    while (!finished) {
     261      returnCode=0;
     262      // see what changed
     263      if (usedColumn) {
     264        for (i=0;i<numberColumns;i++) {
     265          if (fabs(solution[i]-lastSolution[i])>1.0e-8)
     266            usedColumn[i]=1;
     267          lastSolution[i]=solution[i];
     268        }
     269      }
     270      if (numberPasses>=maximumPasses_) {
     271        break;
     272      }
     273      if (maximumTime_>0.0&&CoinCpuTime()>=startTime_+maximumTime_) break;
     274      numberPasses++;
     275      memcpy(newSolution,solution,numberColumns*sizeof(double));
     276      int flip;
     277      returnCode = rounds(newSolution,saveObjective,roundExpensive_,downValue_,&flip);
     278      if (returnCode) {
     279        // SOLUTION IS INTEGER
     280        // Put back correct objective
     281        for (i=0;i<numberColumns;i++)
     282          solver->setObjCoeff(i,saveObjective[i]);
     283
     284        // solution - but may not be better
     285        // Compute using dot product
     286        solver->setDblParam(OsiObjOffset,saveOffset);
     287        newSolutionValue = -saveOffset;
     288        for (  i=0 ; i<numberColumns ; i++ )
     289          newSolutionValue += saveObjective[i]*newSolution[i];
     290        newSolutionValue *= direction;
     291        if (model_->logLevel())
     292          printf(" - solution found of %g",newSolutionValue);
     293        newLineNeeded=false;
     294        if (newSolutionValue<solutionValue) {
     295          double saveValue = newSolutionValue;
     296          if (general) {
     297            int numberLeft=0;
     298            for (i=0;i<numberIntegers;i++) {
     299              int iColumn = integerVariable[i];
     300              double value = floor(newSolution[iColumn]+0.5);
     301              if(solver->isBinary(iColumn)) {
     302                solver->setColLower(iColumn,value);
     303                solver->setColUpper(iColumn,value);
     304              } else {
     305                if (fabs(value-newSolution[iColumn])>1.0e-7)
     306                  numberLeft++;
     307              }
     308            }
     309            if (numberLeft) {
     310              returnCode = smallBranchAndBound(solver,200,newSolution,newSolutionValue,
     311                                               solutionValue,"CbcHeuristicFpump");
     312            }
     313          }
     314          if (returnCode) {
     315            memcpy(betterSolution,newSolution,numberColumns*sizeof(double));
     316            solutionValue=newSolutionValue;
     317            solutionFound=true;
     318            if (general&&saveValue!=newSolutionValue)
     319              printf(" - cleaned solution of %g\n",solutionValue);
     320            else
     321              printf("\n");
     322          } else {
     323          if (model_->logLevel())
     324            printf(" - not good enough after small branch and bound\n");
     325          }
     326        } else {
     327          if (model_->logLevel())
     328            printf(" - not good enough\n");
     329          newLineNeeded=false;
     330          returnCode=0;
     331        }     
     332        break;
    245333      } else {
    246         returnCode=0;
    247       }     
    248       break;
    249     } else {
    250       // SOLUTION IS not INTEGER
    251       // 1. check for loop
    252       bool matched;
    253       for (int k = NUMBER_OLD-1; k > 0; k--) {
     334        // SOLUTION IS not INTEGER
     335        // 1. check for loop
     336        bool matched;
     337        for (int k = NUMBER_OLD-1; k > 0; k--) {
    254338          double * b = oldSolution[k];
    255339          matched = true;
    256340          for (i = 0; i <numberIntegers; i++) {
    257               int iColumn = integerVariable[i];
    258               if(!solver->isBinary(iColumn))
    259                 continue;
    260               if (newSolution[iColumn]!=b[iColumn]) {
    261                 matched=false;
    262                 break;
    263               }
     341            int iColumn = integerVariable[i];
     342            if(!solver->isBinary(iColumn))
     343              continue;
     344            if (newSolution[iColumn]!=b[iColumn]) {
     345              matched=false;
     346              break;
     347            }
    264348          }
    265349          if (matched) break;
    266       }
    267       if (matched || numberPasses%100 == 0) {
    268          // perturbation
    269         if (model_->logLevel())
    270           printf("Perturbation applied");
    271          newLineNeeded=true;
    272          for (i=0;i<numberIntegers;i++) {
    273              int iColumn = integerVariable[i];
    274              if(!solver->isBinary(iColumn))
    275                continue;
    276              double value = max(0.0,CoinDrand48()-0.3);
    277              double difference = fabs(solution[iColumn]-newSolution[iColumn]);
    278              if (difference+value>0.5) {
    279                 if (newSolution[iColumn]<lower[iColumn]+primalTolerance) newSolution[iColumn] += 1.0;
    280              else if (newSolution[iColumn]>upper[iColumn]-primalTolerance) newSolution[iColumn] -= 1.0;
    281                   else abort();
    282              }
    283          }
    284       } else {
    285          for (j=NUMBER_OLD-1;j>0;j--) {
    286              for (i = 0; i < numberColumns; i++) oldSolution[j][i]=oldSolution[j-1][i];
    287          }
    288          for (j = 0; j < numberColumns; j++) oldSolution[0][j] = newSolution[j];
    289       }
    290 
    291       // 2. update the objective function based on the new rounded solution
    292       double offset=0.0;
     350        }
     351        if (matched || numberPasses%100 == 0) {
     352          // perturbation
     353          if (model_->logLevel())
     354            printf("Perturbation applied");
     355          newLineNeeded=true;
     356          for (i=0;i<numberIntegers;i++) {
     357            int iColumn = integerVariable[i];
     358            if(!solver->isBinary(iColumn))
     359              continue;
     360            double value = max(0.0,CoinDrand48()-0.3);
     361            double difference = fabs(solution[iColumn]-newSolution[iColumn]);
     362            if (difference+value>0.5) {
     363              if (newSolution[iColumn]<lower[iColumn]+primalTolerance) newSolution[iColumn] += 1.0;
     364              else if (newSolution[iColumn]>upper[iColumn]-primalTolerance) newSolution[iColumn] -= 1.0;
     365              else abort();
     366            }
     367          }
     368        } else {
     369          for (j=NUMBER_OLD-1;j>0;j--) {
     370            for (i = 0; i < numberColumns; i++) oldSolution[j][i]=oldSolution[j-1][i];
     371          }
     372          for (j = 0; j < numberColumns; j++) oldSolution[0][j] = newSolution[j];
     373        }
     374       
     375        // 2. update the objective function based on the new rounded solution
     376        double offset=0.0;
     377        for (i=0;i<numberIntegers;i++) {
     378          int iColumn = integerVariable[i];
     379          if(!solver->isBinary(iColumn))
     380            continue;
     381          double costValue = 1.0;
     382          // deal with fixed variables (i.e., upper=lower)
     383          if (fabs(lower[iColumn]-upper[iColumn]) < primalTolerance) {
     384            if (lower[iColumn] > 1. - primalTolerance) solver->setObjCoeff(iColumn,-costValue);
     385            else                                       solver->setObjCoeff(iColumn,costValue);
     386            continue;
     387          }
     388          if (newSolution[iColumn]<lower[iColumn]+primalTolerance) {
     389            solver->setObjCoeff(iColumn,costValue);
     390          } else {
     391            if (newSolution[iColumn]>upper[iColumn]-primalTolerance) {
     392              solver->setObjCoeff(iColumn,-costValue);
     393            } else {
     394              abort();
     395            }
     396          }
     397          offset += costValue*newSolution[iColumn];
     398        }
     399        solver->setDblParam(OsiObjOffset,-offset);
     400        if (!general&false) {
     401          // Solve in two goes - first keep satisfied ones fixed
     402          double * saveLower = new double [numberIntegers];
     403          double * saveUpper = new double [numberIntegers];
     404          for (i=0;i<numberIntegers;i++) {
     405            int iColumn = integerVariable[i];
     406            saveLower[i]=COIN_DBL_MAX;
     407            saveUpper[i]=-COIN_DBL_MAX;
     408            if (solution[iColumn]<lower[iColumn]+primalTolerance) {
     409              saveUpper[i]=upper[iColumn];
     410              solver->setColUpper(iColumn,lower[iColumn]);
     411            } else if (solution[iColumn]>upper[iColumn]-primalTolerance) {
     412              saveLower[i]=lower[iColumn];
     413              solver->setColLower(iColumn,upper[iColumn]);
     414            }
     415          }
     416          solver->resolve();
     417          assert (solver->isProvenOptimal());
     418          for (i=0;i<numberIntegers;i++) {
     419            int iColumn = integerVariable[i];
     420            if (saveLower[i]!=COIN_DBL_MAX)
     421              solver->setColLower(iColumn,saveLower[i]);
     422            if (saveUpper[i]!=-COIN_DBL_MAX)
     423              solver->setColUpper(iColumn,saveUpper[i]);
     424            saveUpper[i]=-COIN_DBL_MAX;
     425          }
     426          memcpy(newSolution,solution,numberColumns*sizeof(double));
     427          int flip;
     428          returnCode = rounds(newSolution,saveObjective,roundExpensive_,downValue_,&flip);
     429          if (returnCode) {
     430            // solution - but may not be better
     431            // Compute using dot product
     432            double newSolutionValue = -saveOffset;
     433            for (  i=0 ; i<numberColumns ; i++ )
     434              newSolutionValue += saveObjective[i]*newSolution[i];
     435            newSolutionValue *= direction;
     436            if (model_->logLevel())
     437              printf(" - intermediate solution found of %g",newSolutionValue);
     438            if (newSolutionValue<solutionValue) {
     439              memcpy(betterSolution,newSolution,numberColumns*sizeof(double));
     440              solutionValue=newSolutionValue;
     441              solutionFound=true;
     442            } else {
     443              returnCode=0;
     444            }
     445          }     
     446        }
     447        solver->resolve();
     448        assert (solver->isProvenOptimal());
     449        if (model_->logLevel())
     450          printf("\npass %3d: obj. %10.5f --> ", numberPasses+totalNumberPasses,solver->getObjValue());
     451        newLineNeeded=true;
     452       
     453      }
     454    } // END WHILE
     455    if (newLineNeeded&&model_->logLevel())
     456      printf(" - no solution found\n");
     457    delete solver;
     458    for ( j=0;j<NUMBER_OLD;j++)
     459      delete [] oldSolution[j];
     460    delete [] oldSolution;
     461    delete [] saveObjective;
     462    if (usedColumn) {
     463      OsiSolverInterface * newSolver = model_->continuousSolver()->clone();
     464      const double * colLower = newSolver->getColLower();
     465      const double * colUpper = newSolver->getColUpper();
     466      int i;
     467      int nFix=0;
     468      int nFixI=0;
     469      int nFixC=0;
    293470      for (i=0;i<numberIntegers;i++) {
    294         int iColumn = integerVariable[i];
    295         if(!solver->isBinary(iColumn))
    296           continue;
    297         double costValue = 1.0;
    298         // deal with fixed variables (i.e., upper=lower)
    299         if (fabs(lower[iColumn]-upper[iColumn]) < primalTolerance) {
    300            if (lower[iColumn] > 1. - primalTolerance) solver->setObjCoeff(iColumn,-costValue);
    301            else                                       solver->setObjCoeff(iColumn,costValue);
    302            continue;
    303         }
    304         if (newSolution[iColumn]<lower[iColumn]+primalTolerance) {
    305           solver->setObjCoeff(iColumn,costValue);
    306         } else {
    307           if (newSolution[iColumn]>upper[iColumn]-primalTolerance) {
    308             solver->setObjCoeff(iColumn,-costValue);
    309           } else {
    310             abort();
    311           }
    312         }
    313         offset += costValue*newSolution[iColumn];
    314       }
    315       solver->setDblParam(OsiObjOffset,-offset);
    316       solver->resolve();
    317       if (model_->logLevel())
    318         printf("\npass %3d: obj. %10.5f --> ", numberPasses,solver->getObjValue());
    319       newLineNeeded=true;
    320 
    321     }
    322   } // END WHILE
    323   if (newLineNeeded&&model_->logLevel())
    324     printf(" - no solution found\n");
    325   delete solver;
    326   for ( j=0;j<NUMBER_OLD;j++)
    327     delete [] oldSolution[j];
    328   delete [] oldSolution;
    329   delete [] saveObjective;
    330   if (usedColumn) {
    331     OsiSolverInterface * newSolver = model_->continuousSolver()->clone();
    332     const double * colLower = newSolver->getColLower();
    333     const double * colUpper = newSolver->getColUpper();
    334     int i;
    335     int nFix=0;
    336     int nFixI=0;
    337     int nFixC=0;
    338     for (i=0;i<numberIntegers;i++) {
    339       int iColumn=integerVariable[i];
    340       const CbcObject * object = model_->object(i);
    341       const CbcSimpleInteger * integerObject =
    342         dynamic_cast<const  CbcSimpleInteger *> (object);
    343       assert(integerObject);
    344       // get original bounds
    345       double originalLower = integerObject->originalLowerBound();
    346       assert(colLower[iColumn]==originalLower);
    347       newSolver->setColLower(iColumn,CoinMax(colLower[iColumn],originalLower));
    348       double originalUpper = integerObject->originalUpperBound();
    349       assert(colUpper[iColumn]==originalUpper);
    350       newSolver->setColUpper(iColumn,CoinMin(colUpper[iColumn],originalUpper));
    351       if (!usedColumn[iColumn]) {
    352         double value=lastSolution[iColumn];
    353         double nearest = floor(value+0.5);
    354         if (fabs(value-nearest)<1.0e-7) {
    355           if (nearest==colLower[iColumn]) {
    356             newSolver->setColUpper(iColumn,colLower[iColumn]);
    357             nFix++;
    358           } else if (nearest==colUpper[iColumn]) {
    359             newSolver->setColLower(iColumn,colUpper[iColumn]);
    360             nFix++;
    361           } else if (fixInternal) {
    362             newSolver->setColLower(iColumn,nearest);
    363             newSolver->setColUpper(iColumn,nearest);
    364             nFix++;
    365             nFixI++;
    366           }
    367         }
    368       }
    369     }
    370     if (fixContinuous) {
    371       for (int iColumn=0;iColumn<numberColumns;iColumn++) {
    372         if (!newSolver->isInteger(iColumn)&&!usedColumn[iColumn]) {
     471        int iColumn=integerVariable[i];
     472        const OsiObject * object = model_->object(i);
     473        double originalLower;
     474        double originalUpper;
     475        getIntegerInformation( object,originalLower, originalUpper);
     476        assert(colLower[iColumn]==originalLower);
     477        newSolver->setColLower(iColumn,CoinMax(colLower[iColumn],originalLower));
     478        assert(colUpper[iColumn]==originalUpper);
     479        newSolver->setColUpper(iColumn,CoinMin(colUpper[iColumn],originalUpper));
     480        if (!usedColumn[iColumn]) {
    373481          double value=lastSolution[iColumn];
    374           if (value<colLower[iColumn]+1.0e-8) {
    375             newSolver->setColUpper(iColumn,colLower[iColumn]);
    376             nFix++;
    377             nFixC++;
    378           } else if (value>colUpper[iColumn]-1.0e-8) {
    379             newSolver->setColLower(iColumn,colUpper[iColumn]);
    380             nFix++;
    381             nFixC++;
    382           }
    383         }
    384       }
    385     }
    386     newSolver->initialSolve();
    387     assert (newSolver->isProvenOptimal());
    388     printf("%d integers at bound fixed, %d internal and %d continuous\n",
    389            nFix,nFixI,nFixC);
    390     double saveValue = newSolutionValue;
    391     returnCode = smallBranchAndBound(newSolver,200,newSolution,newSolutionValue,
    392                                      newSolutionValue,"CbcHeuristicLocalAfterFPump");
    393     if (returnCode) {
    394       printf("old sol of %g new of %g\n",saveValue,newSolutionValue);
    395       memcpy(betterSolution,newSolution,numberColumns*sizeof(double));
    396       solutionValue=newSolutionValue;
    397     }
    398     delete newSolver;
    399     delete [] usedColumn;
    400     delete [] lastSolution;
     482          double nearest = floor(value+0.5);
     483          if (fabs(value-nearest)<1.0e-7) {
     484            if (nearest==colLower[iColumn]) {
     485              newSolver->setColUpper(iColumn,colLower[iColumn]);
     486              nFix++;
     487            } else if (nearest==colUpper[iColumn]) {
     488              newSolver->setColLower(iColumn,colUpper[iColumn]);
     489              nFix++;
     490            } else if (fixInternal) {
     491              newSolver->setColLower(iColumn,nearest);
     492              newSolver->setColUpper(iColumn,nearest);
     493              nFix++;
     494              nFixI++;
     495            }
     496          }
     497        }
     498      }
     499      if (fixContinuous) {
     500        for (int iColumn=0;iColumn<numberColumns;iColumn++) {
     501          if (!newSolver->isInteger(iColumn)&&!usedColumn[iColumn]) {
     502            double value=lastSolution[iColumn];
     503            if (value<colLower[iColumn]+1.0e-8) {
     504              newSolver->setColUpper(iColumn,colLower[iColumn]);
     505              nFixC++;
     506            } else if (value>colUpper[iColumn]-1.0e-8) {
     507              newSolver->setColLower(iColumn,colUpper[iColumn]);
     508              nFixC++;
     509            }
     510          }
     511        }
     512      }
     513      newSolver->initialSolve();
     514      if (!newSolver->isProvenOptimal()) {
     515        newSolver->writeMps("bad.mps");
     516        assert (newSolver->isProvenOptimal());
     517        break;
     518      }
     519      printf("%d integers at bound fixed (of which %d were internal) and %d continuous\n",
     520             nFix,nFixI,nFixC);
     521      double saveValue = newSolutionValue;
     522      returnCode = smallBranchAndBound(newSolver,200,newSolution,newSolutionValue,
     523                                       newSolutionValue,"CbcHeuristicLocalAfterFPump");
     524      if (returnCode) {
     525        printf("old sol of %g new of %g\n",saveValue,newSolutionValue);
     526        memcpy(betterSolution,newSolution,numberColumns*sizeof(double));
     527        solutionValue=newSolutionValue;
     528        solutionFound=true;
     529      }
     530      delete newSolver;
     531    }
     532    if (solutionFound) finalReturnCode=1;
     533    cutoff = CoinMin(cutoff,solutionValue);
     534    if (numberTries>=CoinAbs(maximumRetries_)||!solutionFound) {
     535      break;
     536    } else if (absoluteIncrement_>0.0||relativeIncrement_>0.0) {
     537      solutionFound=false;
     538      double gap = relativeIncrement_*fabs(solutionValue);
     539      cutoff -= CoinMax(CoinMax(gap,absoluteIncrement_),model_->getCutoffIncrement());
     540      printf("round again with cutoff of %g\n",cutoff);
     541      if (maximumRetries_<0)
     542        memset(usedColumn,0,numberColumns);
     543      totalNumberPasses += numberPasses;
     544    } else {
     545      break;
     546    }
    401547  }
     548  delete [] usedColumn;
     549  delete [] lastSolution;
    402550  delete [] newSolution;
    403   return returnCode;
     551  return finalReturnCode;
    404552}
    405553
     
    449597      continue;
    450598#ifndef NDEBUG
    451     const CbcObject * object = model_->object(i);
    452     const CbcSimpleInteger * integerObject =
    453       dynamic_cast<const  CbcSimpleInteger *> (object);
    454     assert(integerObject);
     599      const OsiObject * object = model_->object(i);
     600      const CbcSimpleInteger * integerObject =
     601        dynamic_cast<const  CbcSimpleInteger *> (object);
     602      const OsiSimpleInteger * integerObject2 =
     603        dynamic_cast<const  OsiSimpleInteger *> (object);
     604      assert(integerObject||integerObject2);
    455605#endif
    456606    double value=solution[iColumn];
  • branches/devel/Cbc/src/CbcHeuristicFPump.hpp

    r356 r439  
    4747                       double * newSolution);
    4848
     49  /// Set maximum Time (default off) - also sets starttime to current
     50  void setMaximumTime(double value);
     51  /// Get maximum Time (default 0.0 == time limit off)
     52  inline double maximumTime() const
     53  { return maximumTime_;};
     54  /// Set fake cutoff (default COIN_DBL_MAX == off)
     55  inline void setFakeCutoff(double value)
     56  { fakeCutoff_ = value;};
     57  /// Get fake cutoff (default 0.0 == off)
     58  inline double fakeCutoff() const
     59  { return fakeCutoff_;};
     60  /// Set absolute increment (default 0.0 == off)
     61  inline void setAbsoluteIncrement(double value)
     62  { absoluteIncrement_ = value;};
     63  /// Get absolute increment (default 0.0 == off)
     64  inline double absoluteIncrement() const
     65  { return absoluteIncrement_;};
     66  /// Set relative increment (default 0.0 == off)
     67  inline void setRelativeIncrement(double value)
     68  { relativeIncrement_ = value;};
     69  /// Get relative increment (default 0.0 == off)
     70  inline double relativeIncrement() const
     71  { return relativeIncrement_;};
    4972  /// Set maximum passes (default 100)
    5073  inline void setMaximumPasses(int value)
     
    5376  inline int maximumPasses() const
    5477  { return maximumPasses_;};
    55   /// Set maximum Time (default off) - also sets starttime to current
    56   void setMaximumTime(double value);
    57   /// Get maximum Time (default 0.0 == time limit off)
    58   inline double maximumTime() const
    59   { return maximumTime_;};
     78  /// Set maximum retries (default 1)
     79  inline void setMaximumRetries(int value)
     80  { maximumRetries_=value;};
     81  /// Get maximum retries (default 1)
     82  inline int maximumRetries() const
     83  { return maximumRetries_;};
    6084
    6185protected:
     
    6589  /// Maximum Cpu seconds
    6690  double maximumTime_;
     91  /// If less than this round down
     92  double downValue_;
     93  /** Fake cutoff value.
     94      If set then better of real cutoff and this used to add a constraint
     95  */
     96  double fakeCutoff_;
     97  /// If positive carry on after solution expecting gain of at least this
     98  double absoluteIncrement_;
     99  /// If positive carry on after solution expecting gain of at least this times objective
     100  double relativeIncrement_;
    67101  /// Maximum number of passes
    68102  int maximumPasses_;
    69   /// If less than this round down
    70   double downValue_;
     103  /** Maximum number of retries if we find a solution.
     104      If negative we clean out used array
     105  */
     106  int maximumRetries_;
    71107  /// If true round to expensive
    72108  bool roundExpensive_;
     
    82118             bool roundExpensive=false,
    83119             double downValue=0.5, int *flip=0);
     120  /* note for eagle eyed readers.
     121     when_ can now be exotic -
     122     <=10 normal
     123  */
    84124};
    85125
  • branches/devel/Cbc/src/CbcHeuristicLocal.cpp

    r356 r439  
    121121  for (i=0;i<numberIntegers;i++) {
    122122    int iColumn=integerVariable[i];
    123     const CbcObject * object = model_->object(i);
    124     const CbcSimpleInteger * integerObject =
    125       dynamic_cast<const  CbcSimpleInteger *> (object);
    126     assert(integerObject);
     123    const OsiObject * object = model_->object(i);
    127124    // get original bounds
    128     double originalLower = integerObject->originalLowerBound();
     125    double originalLower;
     126    double originalUpper;
     127    getIntegerInformation( object,originalLower, originalUpper);
    129128    newSolver->setColLower(iColumn,CoinMax(colLower[iColumn],originalLower));
    130129    if (!used_[iColumn]) {
     
    200199  for (i=0;i<numberIntegers;i++) {
    201200    int iColumn = integerVariable[i];
    202     const CbcObject * object = model_->object(i);
    203     const CbcSimpleInteger * integerObject =
    204       dynamic_cast<const  CbcSimpleInteger *> (object);
    205     assert(integerObject);
     201    const OsiObject * object = model_->object(i);
    206202    // get original bounds
    207     double originalLower = integerObject->originalLowerBound();
    208     double originalUpper = integerObject->originalUpperBound();
    209 
     203    double originalLower;
     204    double originalUpper;
     205    getIntegerInformation( object,originalLower, originalUpper);
    210206    double value=newSolution[iColumn];
    211207    if (value<originalLower) {
     
    463459        newSolution[kColumn] += wayK;
    464460        // See if k can go further ?
    465         const CbcObject * object = model_->object(goodK);
    466         const CbcSimpleInteger * integerObject =
    467           dynamic_cast<const  CbcSimpleInteger *> (object);
     461        const OsiObject * object = model_->object(goodK);
    468462        // get original bounds
    469         double originalLower = integerObject->originalLowerBound();
    470         double originalUpper = integerObject->originalUpperBound();
     463        double originalLower;
     464        double originalUpper;
     465        getIntegerInformation( object,originalLower, originalUpper);
    471466       
    472467        double value=newSolution[kColumn];
     
    512507        for (i=0;i<numberIntegers;i++) {
    513508          int iColumn = integerVariable[i];
    514           const CbcObject * object = model_->object(i);
    515           const CbcSimpleInteger * integerObject =
    516             dynamic_cast<const  CbcSimpleInteger *> (object);
     509          const OsiObject * object = model_->object(i);
    517510          // get original bounds
    518           double originalLower = integerObject->originalLowerBound();
    519           //double originalUpper = integerObject->originalUpperBound();
     511          double originalLower;
     512          double originalUpper;
     513          getIntegerInformation( object,originalLower, originalUpper);
    520514         
    521515          double value=newSolution[iColumn];
  • branches/devel/Cbc/src/CbcMessage.cpp

    r424 r439  
    5555  {CBC_OTHER_STATS,35,1,"Maximum depth %d, %g variables fixed on reduced cost"},
    5656  {CBC_HEURISTICS_OFF,36,1,"Heuristics switched off as %d branching objects are of wrong type"},
     57  {CBC_STATUS2,37,1,"%d nodes, %d on tree, best %g - possible %g depth %d unsat %d its %d (%.2f seconds)"},
    5758  {CBC_DUMMY_END,999999,0,""}
    5859};
  • branches/devel/Cbc/src/CbcMessage.hpp

    r424 r439  
    6060  CBC_OTHER_STATS,
    6161  CBC_HEURISTICS_OFF,
     62  CBC_STATUS2,
    6263  CBC_DUMMY_END
    6364};
  • branches/devel/Cbc/src/CbcModel.cpp

    r435 r439  
    2828#include "OsiAuxInfo.hpp"
    2929#include "OsiSolverBranch.hpp"
     30#include "OsiChooseVariable.hpp"
    3031#include "CoinWarmStartBasis.hpp"
    3132#include "CoinPackedMatrix.hpp"
     
    228229    int change = node->nodeInfo()->numberBranchesLeft() ;
    229230    printf("Node %d %x (info %x) var %d way %d obj %g",j,node,
    230            node->nodeInfo(),node->variable(),node->way(),
     231           node->nodeInfo(),node->columnNumber(),node->way(),
    231232           node->objectiveValue()) ;
    232233
     
    405406  OsiSolverInterface * originalSolver=NULL;
    406407  int numberOriginalObjects=numberObjects_;
    407   CbcObject ** originalObject = NULL;
     408  OsiObject ** originalObject = NULL;
    408409  // Set up strategies
    409410  if (strategy_) {
     
    473474        */
    474475        numberObjects_= numberNewIntegers+numberOldIntegers+numberOldOther+nNonInt;
    475         object_ = new CbcObject * [numberObjects_];
     476        object_ = new OsiObject * [numberObjects_];
    476477        integerVariable_ = new int [numberNewIntegers+numberOldIntegers];
    477478        /*
     
    490491              object_[numberIntegers_] = originalObject[iObject]->clone();
    491492              // redo ids etc
    492               object_[numberIntegers_]->redoSequenceEtc(this,numberColumns,originalColumns);
     493              object_[numberIntegers_]->resetSequenceEtc(numberColumns,originalColumns);
    493494              integerVariable_[numberIntegers_++]=iColumn;
    494495            }
     
    510511              object_[numberObjects_] = originalObject[iObject]->clone();
    511512              // redo ids etc
    512               object_[numberObjects_]->redoSequenceEtc(this,numberColumns,originalColumns);
     513              CbcObject * obj =
     514              dynamic_cast <CbcObject *>(object_[numberObjects_]) ;
     515              assert (obj);
     516              obj->redoSequenceEtc(this,numberColumns,originalColumns);
    513517              numberObjects_++;
    514518            }
     
    521525            object_[numberObjects_] = originalObject[iObject]->clone();
    522526            // redo ids etc
    523             object_[numberObjects_]->redoSequenceEtc(this,numberColumns,originalColumns);
     527            CbcObject * obj =
     528              dynamic_cast <CbcObject *>(object_[numberObjects_]) ;
     529            assert (obj);
     530            obj->redoSequenceEtc(this,numberColumns,originalColumns);
    524531            numberObjects_++;
    525532          }
     
    641648    }
    642649  }
    643    
    644 /*
    645   Ensure that objects on the lists of CbcObjects, heuristics, and cut
     650  if (preferredWay_) {
     651    // set all unset ones
     652    for (int iObject = 0 ; iObject < numberObjects_ ; iObject++) {
     653      CbcObject * obj =
     654        dynamic_cast <CbcObject *>(object_[iObject]) ;
     655      if (obj&&!obj->preferredWay())
     656        obj->setPreferredWay(preferredWay_);
     657    }
     658  } 
     659/*
     660  Ensure that objects on the lists of OsiObjects, heuristics, and cut
    646661  generators attached to this model all refer to this model.
    647662*/
     
    696711    solverCharacteristics_ = NULL;
    697712    return ;
     713  }
     714  // Convert to Osi if wanted
     715  OsiBranchingInformation * persistentInfo = NULL;
     716  if (branchingMethod_&&branchingMethod_->chooseMethod()) {
     717    persistentInfo = new OsiBranchingInformation(solver_);
     718    for (int iObject = 0 ; iObject < numberObjects_ ; iObject++) {
     719      CbcObject * obj =
     720        dynamic_cast <CbcObject *>(object_[iObject]) ;
     721      if (obj) {
     722        CbcSimpleInteger * obj2 =
     723          dynamic_cast <CbcSimpleInteger *>(obj) ;
     724        if (obj2) {
     725          // back to Osi land
     726          object_[iObject]=obj2->osiObject();
     727          delete obj;
     728        } else {
     729          printf("Code up CbcObject type in Osi land\n");
     730          abort();
     731        }
     732      }
     733    }
     734    // and add to solver if none
     735    if (!solver_->numberObjects()) {
     736      solver_->addObjects(numberObjects_,object_);
     737    } else {
     738      printf("should have trapped that solver has objects before\n");
     739      abort();
     740    }
     741    branchingMethod_->chooseMethod()->setSolver(solver_);
    698742  }
    699743  // Save objective (just so user can access it)
     
    867911    memcpy(currentSolution_,solver_->getColSolution(),
    868912           numberColumns*sizeof(double)) ;
     913    // point to useful information
     914    OsiBranchingInformation usefulInfo=usefulInformation();
    869915
    870916    for (iObject = 0 ; iObject < numberObjects_ ; iObject++)
    871917    { double infeasibility =
    872           object_[iObject]->infeasibility(preferredWay) ;
     918          object_[iObject]->infeasibility(&usefulInfo,preferredWay) ;
    873919      if (infeasibility ) numberUnsatisfied++ ; }
    874920    // replace solverType
     
    9561002      }
    9571003    }
     1004#if 0
    9581005    while (anyAction == -1)
    9591006    {
     
    9891036      { delete newNode ;
    9901037        newNode = NULL ;
    991         feasible = false ; } } }
     1038        feasible = false ; } }
     1039#else
     1040  OsiSolverBranch * branches = NULL;
     1041  anyAction = chooseBranch(newNode, numberPassesLeft, NULL, cuts,resolved,
     1042                           NULL,NULL,NULL,branches,persistentInfo);
     1043  if (anyAction == -2||newNode->objectiveValue() >= cutoff) {
     1044    delete newNode ;
     1045    newNode = NULL ;
     1046    feasible = false ;
     1047  }
     1048#endif
     1049  }
    9921050/*
    9931051  At this point, the root subproblem is infeasible or fathomed by bound
     
    9981056  // Save address of root node as we don't want to delete it
    9991057  CbcNode * rootNode = newNode;
     1058  // initialize for print out
     1059  int lastDepth=0;
     1060  int lastUnsatisfied=0;
     1061  if (newNode)
     1062    lastUnsatisfied=newNode->numberUnsatisfied();
    10001063/*
    10011064  The common case is that the lp relaxation is feasible but doesn't satisfy
    1002   integrality (i.e., newNode->variable() >= 0, indicating we've been able to
     1065  integrality (i.e., newNode->branchingObject(), indicating we've been able to
    10031066  select a branching variable). Remove any cuts that have gone slack due to
    10041067  forcing monotone variables. Then tack on an CbcFullNodeInfo object and full
    10051068  basis (via createInfo()) and stash the new cuts in the nodeInfo (via
    10061069  addCuts()). If, by some miracle, we have an integral solution at the root
    1007   (newNode->variable() < 0), takeOffCuts() will ensure that the solver holds
     1070  (newNode->branchingObject() is NULL), takeOffCuts() will ensure that the solver holds
    10081071  a valid solution for use by setBestSolution().
    10091072*/
    10101073  CoinWarmStartBasis *lastws = 0 ;
    1011   if (feasible && newNode->variable() >= 0)
     1074  if (feasible && newNode->branchingObject())
    10121075  { if (resolved)
    1013     { bool needValidSolution = (newNode->variable() < 0) ;
    1014       takeOffCuts(cuts,needValidSolution,NULL) ;
     1076    { takeOffCuts(cuts,false,NULL) ;
    10151077#     ifdef CHECK_CUT_COUNTS
    10161078      { printf("Number of rows after chooseBranch fix (root)"
     
    10231085#     endif
    10241086    }
    1025     newNode->createInfo(this,NULL,NULL,NULL,NULL,0,0) ;
     1087  //newNode->createInfo(this,NULL,NULL,NULL,NULL,0,0) ;
    10261088    newNode->nodeInfo()->addCuts(cuts,
    10271089                                 newNode->numberBranches(),whichGenerator_) ;
     
    10451107  { int i ;
    10461108    for (i = 0;i < numberObjects_;i++)
    1047       object_[i]->resetBounds() ; }
     1109      object_[i]->resetBounds(solver_) ; }
    10481110  stoppedOnGap_ = false ;
    10491111/*
     
    10581120  if (newNode) {
    10591121    bestValue = newNode->objectiveValue();
    1060     if (newNode->variable() >= 0) {
     1122    if (newNode->branchingObject()) {
    10611123      newNode->initializeInfo() ;
    10621124      tree_->push(newNode) ;
     
    11821244          bestPossibleObjective_ = node->objectiveValue() ;
    11831245      }
    1184       messageHandler()->message(CBC_STATUS,messages())
    1185         << numberNodes_<< nNodes<< bestObjective_<< bestPossibleObjective_
    1186         <<getCurrentSeconds()
    1187         << CoinMessageEol ;
     1246      if (!intParam_[CbcPrinting]) {
     1247        messageHandler()->message(CBC_STATUS,messages())
     1248          << numberNodes_<< nNodes<< bestObjective_<< bestPossibleObjective_
     1249          <<getCurrentSeconds()
     1250          << CoinMessageEol ;
     1251      } else {
     1252        messageHandler()->message(CBC_STATUS2,messages())
     1253          << numberNodes_<< nNodes<< bestObjective_<< bestPossibleObjective_
     1254          <<lastDepth<<lastUnsatisfied<<numberIterations_
     1255          <<getCurrentSeconds()
     1256          << CoinMessageEol ;
     1257      }
    11881258      if (!eventHandler->event(CbcEventHandler::treeStatus)) {
    11891259        eventHappened_=true; // exit
     
    12311301    bool onOptimalPath=false;
    12321302#   ifdef CHECK_NODE
    1233 /*
    1234   WARNING: The use of integerVariable_[*] here will break as soon as the
    1235            branching object is something other than an integer variable.
    1236            This needs some thought.
    1237 */
    12381303    printf("Node %x popped from tree - %d left, %d count\n",node,
    12391304           node->nodeInfo()->numberBranchesLeft(),
     
    12421307           node->depth(),node->objectiveValue(),
    12431308           node->numberUnsatisfied(),
    1244            integerVariable_[node->variable()]) ;
     1309           node->columnNumber()) ;
    12451310#   endif
     1311    lastDepth=node->depth();
     1312    lastUnsatisfied=node->numberUnsatisfied();
    12461313
    12471314/*
     
    12661333        upperBefore[i]= upper[i] ; }
    12671334      bool deleteNode ;
     1335      if (messageHandler()->logLevel()>2)
     1336        node->modifiableBranchingObject()->print();
    12681337      if (node->branch())
    12691338      {
     
    13291398          memcpy(currentSolution_,solver_->getColSolution(),
    13301399                 numberColumns*sizeof(double)) ;
     1400          // point to useful information
     1401          OsiBranchingInformation usefulInfo=usefulInformation();
    13311402         
    13321403          for (iObject = 0 ; iObject < numberObjects_ ; iObject++) {
    13331404            double infeasibility =
    1334               object_[iObject]->infeasibility(preferredWay) ;
     1405              object_[iObject]->infeasibility(&usefulInfo,preferredWay) ;
    13351406            if (infeasibility ) numberUnsatisfied++ ;
    13361407          }
     
    14211492          int numberPassesLeft=20;
    14221493          checkingNode=true;
     1494#if 0
    14231495          while (anyAction == -1)
    14241496          {
     
    15061578          if (anyAction >= 0)
    15071579          { if (resolved)
    1508             { bool needValidSolution = (newNode->variable() < 0) ;
     1580            { bool needValidSolution = (newNode->branchingObject() == NULL) ;
    15091581              takeOffCuts(cuts,needValidSolution,NULL) ;
    15101582#             ifdef CHECK_CUT_COUNTS
     
    15621634          setSpecialOptions(specialOptions_&~8);
    15631635        }
     1636#else
     1637        OsiSolverBranch * branches=NULL;
     1638        anyAction = chooseBranch(newNode, numberPassesLeft,node, cuts,resolved,
     1639                                 lastws, lowerBefore, upperBefore, branches,persistentInfo);
     1640/*
     1641  If we end up infeasible, we can delete the new node immediately. Since this
     1642  node won't be needing the cuts we collected, decrement the reference counts.
     1643  If we are feasible, then we'll be placing this node into the live set, so
     1644  increment the reference count in the current (parent) nodeInfo.
     1645*/
     1646        if (anyAction == -2)
     1647          { delete newNode ;
     1648          newNode = NULL ;
     1649          // say strong doing well
     1650          if (checkingNode)
     1651            setSpecialOptions(specialOptions_|8);
     1652          for (i = 0 ; i < currentNumberCuts_ ; i++)
     1653            { if (addedCuts_[i])
     1654              { if (!addedCuts_[i]->decrement(1))
     1655                delete addedCuts_[i] ; } } }
     1656        else
     1657          { nodeInfo->increment() ;
     1658          if ((numberNodes_%20)==0) {
     1659            // say strong not doing as well
     1660            setSpecialOptions(specialOptions_&~8);
     1661          }
     1662        }
     1663#endif
    15641664        }
    15651665/*
     
    15901690        }
    15911691        if (newNode) {
    1592           if (newNode->variable() < 0&&solverCharacteristics_->solverType()==4) {
     1692          if (newNode->branchingObject() == NULL&&solverCharacteristics_->solverType()==4) {
    15931693            // need to check if any cuts would do anything
    15941694            OsiCuts theseCuts;
     
    16151715            }
    16161716          }
    1617           if (newNode->variable() >= 0)
     1717          if (newNode->branchingObject())
    16181718          { handler_->message(CBC_BRANCH,messages_)
    16191719               << numberNodes_<< newNode->objectiveValue()
     
    18051905    bool goodIds=true;
    18061906    for (i=0;i<numberObjects_;i++) {
    1807       int id = object_[i]->id();
    18081907      int iColumn = object_[i]->columnNumber();
    1809       if (iColumn<0)
    1810         iColumn = id+numberColumns;
    1811       if(id>=0&&id<numberObjects_) {
    1812         if (lookup[id]==-1) {
    1813           lookup[id]=iColumn;
     1908      if(iColumn>=0&&iColumn<numberColumns) {
     1909        if (lookup[i]==-1) {
     1910          lookup[i]=iColumn;
    18141911        } else {
    18151912          goodIds=false;
     
    20082105  delete [] addedCuts_ ;
    20092106  addedCuts_ = NULL ;
     2107  delete persistentInfo;
    20102108  // Get rid of characteristics
    20112109  solverCharacteristics_=NULL;
     
    22122310  maximumCutPassesAtRoot_(20),
    22132311  maximumCutPasses_(10),
     2312  preferredWay_(0),
    22142313  currentPassNumber_(0),
    22152314  maximumWhich_(1000),
     
    22322331  resolveAfterTakeOffCuts_(true)
    22332332{
     2333  memset(intParam_,0,sizeof(intParam_));
    22342334  intParam_[CbcMaxNumNode] = 2147483647;
    22352335  intParam_[CbcMaxNumSol] = 9999999;
     
    23382438  maximumCutPassesAtRoot_(20),
    23392439  maximumCutPasses_(10),
     2440  preferredWay_(0),
    23402441  currentPassNumber_(0),
    23412442  maximumWhich_(1000),
     
    23582459  resolveAfterTakeOffCuts_(true)
    23592460{
     2461  memset(intParam_,0,sizeof(intParam_));
    23602462  intParam_[CbcMaxNumNode] = 2147483647;
    23612463  intParam_[CbcMaxNumSol] = 9999999;
     
    25492651  maximumCutPassesAtRoot_(rhs.maximumCutPassesAtRoot_),
    25502652  maximumCutPasses_( rhs.maximumCutPasses_),
     2653  preferredWay_(rhs.preferredWay_),
    25512654  currentPassNumber_(rhs.currentPassNumber_),
    25522655  maximumWhich_(rhs.maximumWhich_),
     
    25692672  resolveAfterTakeOffCuts_(rhs.resolveAfterTakeOffCuts_)
    25702673{
    2571   intParam_[CbcMaxNumNode] = rhs.intParam_[CbcMaxNumNode];
    2572   intParam_[CbcMaxNumSol] = rhs.intParam_[CbcMaxNumSol];
    2573   intParam_[CbcFathomDiscipline] = rhs.intParam_[CbcFathomDiscipline];
    2574   dblParam_[CbcIntegerTolerance] = rhs.dblParam_[CbcIntegerTolerance];
    2575   dblParam_[CbcInfeasibilityWeight] = rhs.dblParam_[CbcInfeasibilityWeight];
    2576   dblParam_[CbcCutoffIncrement] = rhs.dblParam_[CbcCutoffIncrement];
    2577   dblParam_[CbcAllowableGap] = rhs.dblParam_[CbcAllowableGap];
    2578   dblParam_[CbcAllowableFractionGap] = rhs.dblParam_[CbcAllowableFractionGap];
    2579   dblParam_[CbcMaximumSeconds] = rhs.dblParam_[CbcMaximumSeconds];
    2580   dblParam_[CbcCurrentCutoff] = rhs.dblParam_[CbcCurrentCutoff];
    2581   dblParam_[CbcOptimizationDirection] = rhs.dblParam_[CbcOptimizationDirection];
    2582   dblParam_[CbcCurrentObjectiveValue] = rhs.dblParam_[CbcCurrentObjectiveValue];
    2583   dblParam_[CbcCurrentMinimizationObjectiveValue] = rhs.dblParam_[CbcCurrentMinimizationObjectiveValue];
    2584   dblParam_[CbcStartSeconds] = dblParam_[CbcStartSeconds]; // will be overwritten hopefully
     2674  memcpy(intParam_,rhs.intParam_,sizeof(intParam_));
     2675  memcpy(dblParam_,rhs.dblParam_,sizeof(dblParam_));
    25852676  strongInfo_[0]=rhs.strongInfo_[0];
    25862677  strongInfo_[1]=rhs.strongInfo_[1];
     
    26272718  numberObjects_=rhs.numberObjects_;
    26282719  if (numberObjects_) {
    2629     object_ = new CbcObject * [numberObjects_];
     2720    object_ = new OsiObject * [numberObjects_];
    26302721    int i;
    26312722    for (i=0;i<numberObjects_;i++)
     
    28362927    maximumCutPassesAtRoot_ = rhs.maximumCutPassesAtRoot_;
    28372928    maximumCutPasses_ = rhs.maximumCutPasses_;
     2929    preferredWay_ = rhs.preferredWay_;
    28382930    currentPassNumber_ = rhs.currentPassNumber_;
    2839     intParam_[CbcMaxNumNode] = rhs.intParam_[CbcMaxNumNode];
    2840     intParam_[CbcMaxNumSol] = rhs.intParam_[CbcMaxNumSol];
    2841     intParam_[CbcFathomDiscipline] = rhs.intParam_[CbcFathomDiscipline];
    2842     dblParam_[CbcIntegerTolerance] = rhs.dblParam_[CbcIntegerTolerance];
    2843     dblParam_[CbcInfeasibilityWeight] = rhs.dblParam_[CbcInfeasibilityWeight];
    2844     dblParam_[CbcCutoffIncrement] = rhs.dblParam_[CbcCutoffIncrement];
    2845     dblParam_[CbcAllowableGap] = rhs.dblParam_[CbcAllowableGap];
    2846     dblParam_[CbcAllowableFractionGap] = rhs.dblParam_[CbcAllowableFractionGap];
    2847     dblParam_[CbcMaximumSeconds] = rhs.dblParam_[CbcMaximumSeconds];
    2848     dblParam_[CbcCurrentCutoff] = rhs.dblParam_[CbcCurrentCutoff];
    2849     dblParam_[CbcOptimizationDirection] = rhs.dblParam_[CbcOptimizationDirection];
    2850     dblParam_[CbcCurrentObjectiveValue] = rhs.dblParam_[CbcCurrentObjectiveValue];
    2851     dblParam_[CbcCurrentMinimizationObjectiveValue] = rhs.dblParam_[CbcCurrentMinimizationObjectiveValue];
    2852     dblParam_[CbcStartSeconds] = dblParam_[CbcStartSeconds]; // will be overwritten hopefully
     2931    memcpy(intParam_,rhs.intParam_,sizeof(intParam_));
     2932    memcpy(dblParam_,rhs.dblParam_,sizeof(dblParam_));
    28532933    globalCuts_ = rhs.globalCuts_;
    28542934    int i;
     
    29213001    numberObjects_=rhs.numberObjects_;
    29223002    if (numberObjects_) {
    2923       object_ = new CbcObject * [numberObjects_];
     3003      object_ = new OsiObject * [numberObjects_];
    29243004      int i;
    29253005      for (i=0;i<numberObjects_;i++)
     
    44004480    const double * save = testSolution_;
    44014481    testSolution_ = solver_->getColSolution();
     4482    // point to useful information
     4483    OsiBranchingInformation usefulInfo=usefulInformation();
    44024484    for (int i=0;i<numberObjects_ && integerFeasible;i++)
    44034485    {
    44044486      int preferredWay;
    4405       double infeasibility = object_[i]->infeasibility(preferredWay);
     4487      double infeasibility = object_[i]->infeasibility(&usefulInfo,preferredWay);
    44064488      if(infeasibility)
    44074489        integerFeasible = false;
     
    51295211
    51305212  int numberCliques=0;
    5131   CbcObject ** object = new CbcObject * [numberRows];
     5213  OsiObject ** object = new OsiObject * [numberRows];
    51325214  int * which = new int[numberIntegers_];
    51335215  char * type = new char[numberIntegers_];
     
    55185600
    55195601/*!
    5520   Ensure all attached objects (CbcObjects, heuristics, and cut
     5602  Ensure all attached objects (OsiObjects, heuristics, and cut
    55215603  generators) point to this model.
    55225604*/
     
    55265608  for (i=0;i<numberHeuristics_;i++)
    55275609    heuristic_[i]->setModel(this);
    5528   for (i=0;i<numberObjects_;i++)
    5529     object_[i]->setModel(this);
     5610  for (i=0;i<numberObjects_;i++) {
     5611    CbcObject * obj =
     5612      dynamic_cast <CbcObject *>(object_[i]) ;
     5613    if (obj)
     5614      obj->setModel(this);
     5615  }
    55305616  for (i=0;i<numberCutGenerators_;i++)
    55315617    generator_[i]->refreshModel(this);
     
    55785664  // Find out how many old non-integer objects there are
    55795665  int nObjects=0;
    5580   CbcObject ** oldObject = object_;
     5666  OsiObject ** oldObject = object_;
    55815667  int iObject;
    55825668  for (iObject = 0;iObject<numberObjects_;iObject++) {
     
    55995685      nObjects=0;
    56005686      delete [] oldObject;
    5601       oldObject = new CbcObject * [numberSOS];
     5687      oldObject = new OsiObject * [numberSOS];
    56025688      for (int i=0;i<numberSOS;i++) {
    56035689        int type = setInfo[i].setType();
     
    56165702*/
    56175703  delete [] integerVariable_;
    5618   object_ = new CbcObject * [numberIntegers_+nObjects];
     5704  object_ = new OsiObject * [numberIntegers_+nObjects];
    56195705  numberObjects_=numberIntegers_+nObjects;
    56205706  integerVariable_ = new int [numberIntegers_];
     
    56295715      if (!type)
    56305716        object_[numberIntegers_] =
    5631           new CbcSimpleInteger(this,numberIntegers_,iColumn);
     5717          new CbcSimpleInteger(this,iColumn);
    56325718      else if (type==1)
    56335719        object_[numberIntegers_] =
     
    56375723  }
    56385724  // Now append other objects
    5639   memcpy(object_+numberIntegers_,oldObject,nObjects*sizeof(CbcObject *));
     5725  memcpy(object_+numberIntegers_,oldObject,nObjects*sizeof(OsiObject *));
    56405726  // Delete old array (just array)
    56415727  delete [] oldObject;
     
    56765762      }
    56775763      CbcSimpleIntegerDynamicPseudoCost * newObject =
    5678         new CbcSimpleIntegerDynamicPseudoCost(this,iObject,iColumn,1.0e0*downCost,1.0e0*upCost);
     5764        new CbcSimpleIntegerDynamicPseudoCost(this,iColumn,1.0e0*downCost,1.0e0*upCost);
    56795765      newObject->setNumberBeforeTrust(numberBeforeTrust_);
    56805766      newObject->setPriority(priority);
     
    56855771    }
    56865772  }
    5687   if (branchingMethod_&&(branchingMethod_->whichMethod()&1)==0) {
    5688     // Need a method which can do better
    5689     delete branchingMethod_;
    5690     branchingMethod_=NULL;
     5773  if (branchingMethod_) {
     5774    if ((branchingMethod_->whichMethod()&1)==0&&!branchingMethod_->chooseMethod()) {
     5775      // Need a method which can do better
     5776      delete branchingMethod_;
     5777      branchingMethod_=NULL;
     5778    }
    56915779  }
    56925780  if (!branchingMethod_&&allDynamic) {
     
    57005788void
    57015789CbcModel::addObjects(int numberObjects, CbcObject ** objects)
     5790{
     5791 // If integers but not enough objects fudge
     5792  if (numberIntegers_>numberObjects_)
     5793    findIntegers(true);
     5794  /* But if incoming objects inherit from simple integer we just want
     5795     to replace */
     5796  int numberColumns = solver_->getNumCols();
     5797  /** mark is -1 if not integer, >=0 if using existing simple integer and
     5798      >=numberColumns if using new integer */
     5799  int * mark = new int[numberColumns];
     5800  int i;
     5801  for (i=0;i<numberColumns;i++)
     5802    mark[i]=-1;
     5803  int newNumberObjects = numberObjects;
     5804  int newIntegers=0;
     5805  for (i=0;i<numberObjects;i++) {
     5806    CbcSimpleInteger * obj =
     5807      dynamic_cast <CbcSimpleInteger *>(objects[i]) ;
     5808    if (obj) {
     5809      int iColumn = obj->columnNumber();
     5810      mark[iColumn]=i+numberColumns;
     5811      newIntegers++;
     5812    }
     5813  }
     5814  // and existing
     5815  for (i=0;i<numberObjects_;i++) {
     5816    CbcSimpleInteger * obj =
     5817      dynamic_cast <CbcSimpleInteger *>(object_[i]) ;
     5818    if (obj) {
     5819      int iColumn = obj->columnNumber();
     5820      if (mark[iColumn]<0) {
     5821        newIntegers++;
     5822        newNumberObjects++;
     5823        mark[iColumn]=i;
     5824      }
     5825    }
     5826  }
     5827  delete [] integerVariable_;
     5828  integerVariable_=NULL;
     5829  if (newIntegers!=numberIntegers_)
     5830    printf("changing number of integers from %d to %d\n",
     5831           numberIntegers_,newIntegers);
     5832  numberIntegers_ = newIntegers;
     5833  integerVariable_ = new int [numberIntegers_];
     5834  OsiObject ** temp  = new OsiObject * [newNumberObjects];
     5835  // Put integers first
     5836  newIntegers=0;
     5837  numberIntegers_=0;
     5838  for (i=0;i<numberColumns;i++) {
     5839    int which = mark[i];
     5840    if (which>=0) {
     5841      if (!isInteger(i)) {
     5842        newIntegers++;
     5843        solver_->setInteger(i);
     5844      }
     5845      if (which<numberColumns) {
     5846        temp[numberIntegers_]=object_[which];
     5847        object_[which]=NULL;
     5848      } else {
     5849        temp[numberIntegers_]=objects[which-numberColumns]->clone();
     5850      }
     5851      integerVariable_[numberIntegers_++]=i;
     5852    }
     5853  }
     5854  if (newIntegers)
     5855    printf("%d variables were declared integer\n",newIntegers);
     5856  int n=numberIntegers_;
     5857  // Now rest of old
     5858  for (i=0;i<numberObjects_;i++) {
     5859    if (object_[i]) {
     5860      CbcSimpleInteger * obj =
     5861        dynamic_cast <CbcSimpleInteger *>(object_[i]) ;
     5862      if (obj) {
     5863        delete object_[i];
     5864      } else {
     5865        temp[n++]=object_[i];
     5866      }
     5867    }
     5868  }
     5869  // and rest of new
     5870  for (i=0;i<numberObjects;i++) {
     5871    CbcSimpleInteger * obj =
     5872      dynamic_cast <CbcSimpleInteger *>(objects[i]) ;
     5873    if (!obj) {
     5874      temp[n]=objects[i]->clone();
     5875      CbcObject * obj =
     5876        dynamic_cast <CbcObject *>(temp[n]) ;
     5877      if (obj)
     5878        obj->setModel(this);
     5879      n++;
     5880    }
     5881  }
     5882  delete [] mark;
     5883  delete [] object_;
     5884  object_ = temp;
     5885  assert (n==newNumberObjects);
     5886  numberObjects_ = newNumberObjects;
     5887}
     5888/* Add in any object information (objects are cloned - owner can delete
     5889   originals */
     5890void
     5891CbcModel::addObjects(int numberObjects, OsiObject ** objects)
    57025892{
    57035893  // If integers but not enough objects fudge
     
    57445934  numberIntegers_ = newIntegers;
    57455935  integerVariable_ = new int [numberIntegers_];
    5746   CbcObject ** temp  = new CbcObject * [newNumberObjects];
     5936  OsiObject ** temp  = new OsiObject * [newNumberObjects];
    57475937  // Put integers first
    57485938  newIntegers=0;
     
    57605950      } else {
    57615951        temp[numberIntegers_]=objects[which-numberColumns]->clone();
    5762         temp[numberIntegers_]->setModel(this);
    57635952      }
    57645953      integerVariable_[numberIntegers_++]=i;
     
    57865975    if (!obj) {
    57875976      temp[n]=objects[i]->clone();
    5788       temp[n++]->setModel(this);
     5977      CbcObject * obj =
     5978        dynamic_cast <CbcObject *>(temp[n]) ;
     5979      if (obj)
     5980        obj->setModel(this);
     5981      n++;
    57895982    }
    57905983  }
     
    58836076    memcpy(saveUpper,getColUpper(),numberColumns*sizeof(double));
    58846077    memcpy(saveLower,getColLower(),numberColumns*sizeof(double));
     6078    // point to useful information
     6079    OsiBranchingInformation usefulInfo=usefulInformation();
    58856080   
    58866081    /*
     
    58926087    int i;
    58936088    for (i=0;i<numberObjects_;i++)
    5894       object_[i]->feasibleRegion();
     6089      object_[i]->feasibleRegion(solver_,&usefulInfo);
    58956090    // We can switch off check
    58966091    if ((specialOptions_&4)==0) {
     
    60386233            const double * save = testSolution_;
    60396234            testSolution_ = solution;
     6235            // point to useful information
     6236            OsiBranchingInformation usefulInfo=usefulInformation();
    60406237            for (int i=0;i<numberObjects_;i++)
    6041               object_[i]->feasibleRegion();
     6238              object_[i]->feasibleRegion(solver_,&usefulInfo);
    60426239            testSolution_ = save;
    60436240            resolve(solver_);
     
    63836580  //memcpy(currentSolution_,solver_->getColSolution(),
    63846581  // solver_->getNumCols()*sizeof(double));
     6582  // point to useful information
     6583  OsiBranchingInformation usefulInfo=usefulInformation();
    63856584  for (j=0;j<numberIntegers_;j++) {
    6386     const CbcObject * object = object_[j];
    6387     double infeasibility = object->infeasibility(preferredWay);
     6585    const OsiObject * object = object_[j];
     6586    double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    63886587    if (infeasibility) {
    63896588      assert (infeasibility>0);
     
    63946593  numberIntegerInfeasibilities = numberUnsatisfied;
    63956594  for (;j<numberObjects_;j++) {
    6396     const CbcObject * object = object_[j];
    6397     double infeasibility = object->infeasibility(preferredWay);
     6595    const OsiObject * object = object_[j];
     6596    double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    63986597    if (infeasibility) {
    63996598      assert (infeasibility>0);
     
    72967495  for (i=0;i<numberIntegers;i++) {
    72977496    int iColumn=integerVariable[i];
    7298     const CbcObject * object = object_[i];
     7497    const OsiObject * object = object_[i];
    72997498    const CbcSimpleInteger * integerObject =
    73007499      dynamic_cast<const  CbcSimpleInteger *> (object);
     
    74277626  for (i=0;i<numberIntegers;i++) {
    74287627    int iColumn=integerVariable[i];
    7429     const CbcObject * object = object_[i];
     7628    const OsiObject * object = object_[i];
    74307629    const CbcSimpleInteger * integerObject =
    74317630      dynamic_cast<const  CbcSimpleInteger *> (object);
     
    75387737  findIntegers(false) ;
    75397738/*
    7540   Ensure that objects on the lists of CbcObjects, heuristics, and cut
     7739  Ensure that objects on the lists of OsiObjects, heuristics, and cut
    75417740  generators attached to this model all refer to this model.
    75427741*/
     
    76387837           numberColumns*sizeof(double)) ;
    76397838
     7839    // point to useful information
     7840    OsiBranchingInformation usefulInfo=usefulInformation();
    76407841    for (iObject = 0 ; iObject < numberObjects_ ; iObject++)
    76417842    { double infeasibility =
    7642           object_[iObject]->infeasibility(preferredWay) ;
     7843          object_[iObject]->infeasibility(&usefulInfo,preferredWay) ;
    76437844      if (infeasibility) numberUnsatisfied++ ; }
    76447845    if (numberUnsatisfied)
     
    79718172  return CoinCpuTime()-getDblParam(CbcStartSeconds);
    79728173}
     8174/* Encapsulates choosing a variable -
     8175   anyAction -2, infeasible (-1 round again), 0 done
     8176*/
     8177int
     8178CbcModel::chooseBranch(CbcNode * newNode, int numberPassesLeft,
     8179                       CbcNode * oldNode, OsiCuts & cuts,
     8180                       bool & resolved, CoinWarmStartBasis *lastws,
     8181                       const double * lowerBefore,const double * upperBefore,
     8182                       OsiSolverBranch * & branches,
     8183                       OsiBranchingInformation * usefulInfo)
     8184{
     8185  int anyAction =-1 ;
     8186  resolved = false ;
     8187  if (newNode->objectiveValue() >= getCutoff())
     8188    anyAction=-2;
     8189  branches=NULL;
     8190  bool feasible=true;
     8191  int branchingState=-1;
     8192  while (anyAction == -1) {
     8193    // Set objective value (not so obvious if NLP etc)
     8194    setObjectiveValue(newNode,oldNode);
     8195    if (numberPassesLeft<=0)
     8196      branchingState=1;
     8197    if (!branchingMethod_||!branchingMethod_->chooseMethod()) {
     8198      if (numberBeforeTrust_==0 ) {
     8199        anyAction = newNode->chooseBranch(this,oldNode,numberPassesLeft) ;
     8200      } else {
     8201        anyAction = newNode->chooseDynamicBranch(this,oldNode,branches,numberPassesLeft) ;
     8202      if (anyAction==-3)
     8203        anyAction = newNode->chooseBranch(this,oldNode,numberPassesLeft) ; // dynamic did nothing
     8204      }
     8205    } else {
     8206      anyAction = newNode->chooseOsiBranch(this,oldNode,usefulInfo,branchingState) ;; // Osi method
     8207      branchingState=0;
     8208    }
     8209    if (solverCharacteristics_ &&
     8210        solverCharacteristics_->solutionAddsCuts() && // we are in some OA based bab
     8211        feasible && (newNode->numberUnsatisfied()==0) //solution has become integer feasible during strong branching
     8212        ) {
     8213      //in the present case we need to check here integer infeasibility if the node is not fathomed we will have to do the loop
     8214      // again
     8215      //std::cout<<solver_<<std::endl;
     8216      resolve(solver_);
     8217      double objval = solver_->getObjValue();
     8218      setBestSolution(CBC_SOLUTION, objval,
     8219                      solver_->getColSolution()) ;
     8220      lastHeuristic_ = NULL;
     8221      int easy=2;
     8222      if (!solverCharacteristics_->mipFeasible())//did we prove that the node could be pruned?
     8223        feasible = false;
     8224      // Reset the bound now
     8225      solverCharacteristics_->setMipBound(-COIN_DBL_MAX);
     8226     
     8227     
     8228      solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
     8229      feasible &= resolve(oldNode ? oldNode->nodeInfo() : NULL,11) != 0 ;
     8230      solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
     8231      resolved = true ;
     8232      if (problemFeasibility_->feasible(this,0)<0) {
     8233        feasible=false; // pretend infeasible
     8234      }
     8235      if(feasible)
     8236        anyAction = -1;
     8237      else
     8238        anyAction = -2;
     8239    }
     8240    /*
     8241      Yep, false positives for sure. And no easy way to distinguish honest
     8242      infeasibility from `found a solution and tightened objective target.'
     8243     
     8244      if (onOptimalPath)
     8245      assert (anyAction!=-2); // can be useful but gives false positives on strong
     8246    */
     8247    numberPassesLeft--;
     8248    if (numberPassesLeft<=-1) {
     8249      if (!numberLongStrong_)
     8250        messageHandler()->message(CBC_WARNING_STRONG,
     8251                                  messages()) << CoinMessageEol ;
     8252      numberLongStrong_++;
     8253    }
     8254    if (anyAction == -1) {
     8255      // can do quick optimality check
     8256      int easy=2;
     8257      solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
     8258      feasible = resolve(oldNode ? oldNode->nodeInfo() : NULL,11) != 0 ;
     8259      solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
     8260      resolved = true ;
     8261      if (problemFeasibility_->feasible(this,0)<0) {
     8262        feasible=false; // pretend infeasible
     8263      }
     8264      if (feasible) {
     8265        // Set objective value (not so obvious if NLP etc)
     8266        setObjectiveValue(newNode,oldNode);
     8267        reducedCostFix() ;
     8268        if (newNode->objectiveValue() >= getCutoff())
     8269          anyAction=-2;
     8270      } else {
     8271        anyAction = -2 ;
     8272      }
     8273    }
     8274  }
     8275  if (anyAction >= 0) {
     8276    if (resolved) {
     8277      bool needValidSolution = (newNode->branchingObject() == NULL) ;
     8278      takeOffCuts(cuts,needValidSolution,NULL) ;
     8279#             ifdef CHECK_CUT_COUNTS
     8280      {
     8281        printf("Number of rows after chooseBranch fix (node)"
     8282               "(active only) %d\n",
     8283               numberRowsAtContinuous_+numberNewCuts_+
     8284               numberOldActiveCuts_) ;
     8285        const CoinWarmStartBasis* debugws =
     8286          dynamic_cast<const CoinWarmStartBasis*>
     8287          (solver_->getWarmStart()) ;
     8288        debugws->print() ;
     8289        delete debugws ;
     8290      }
     8291#             endif
     8292    }
     8293    newNode->createInfo(this,oldNode,lastws,lowerBefore,upperBefore,
     8294                          numberOldActiveCuts_,numberNewCuts_) ;
     8295    if (newNode->numberUnsatisfied()) {
     8296      maximumDepthActual_ = CoinMax(maximumDepthActual_,newNode->depth());
     8297      newNode->initializeInfo() ;
     8298      newNode->nodeInfo()->addCuts(cuts,newNode->numberBranches(),
     8299                                   whichGenerator_) ;
     8300    }
     8301  } else {
     8302    anyAction = -2 ;
     8303    // Reset bound anyway (no harm if not odd)
     8304    solverCharacteristics_->setMipBound(-COIN_DBL_MAX);
     8305  }
     8306  // May have slipped through i.e. anyAction == 0 and objective above cutoff
     8307  // I think this will screw up cut reference counts if executed.
     8308  // We executed addCuts just above. (lh)
     8309  if ( anyAction >=0 ) {
     8310    assert (newNode);
     8311    if (newNode->objectiveValue() >= getCutoff())
     8312      anyAction = -2; // say bad after all
     8313  }
     8314  return anyAction;
     8315}
     8316
    79738317/*
    79748318   For advanced applications you may wish to modify the behavior of Cbc
     
    80698413    // allow for cliques etc
    80708414    nOrig = CoinMax(nOrig,originalColumns[numberColumns-1]+1);
    8071     CbcObject ** originalObject = object_;
     8415    OsiObject ** originalObject = object_;
    80728416    // object number or -1
    80738417    int * temp = new int[nOrig];
     
    81088452    */
    81098453    numberObjects_= numberNewIntegers+numberOldIntegers+numberOldOther+nNonInt;
    8110     object_ = new CbcObject * [numberObjects_];
     8454    object_ = new OsiObject * [numberObjects_];
    81118455    delete [] integerVariable_;
    81128456    integerVariable_ = new int [numberNewIntegers+numberOldIntegers];
     
    81268470          object_[numberIntegers_] = originalObject[iObject]->clone();
    81278471          // redo ids etc
    8128           object_[numberIntegers_]->redoSequenceEtc(this,numberColumns,originalColumns);
     8472          object_[numberIntegers_]->resetSequenceEtc(numberColumns,originalColumns);
    81298473          integerVariable_[numberIntegers_++]=iColumn;
    81308474        }
     
    81468490          object_[numberObjects_] = originalObject[iObject]->clone();
    81478491          // redo ids etc
    8148           object_[numberObjects_]->redoSequenceEtc(this,numberColumns,originalColumns);
     8492          CbcObject * obj =
     8493            dynamic_cast <CbcObject *>(object_[numberObjects_]) ;
     8494          assert (obj);
     8495          obj->redoSequenceEtc(this,numberColumns,originalColumns);
    81498496          numberObjects_++;
    81508497        }
     
    81578504        object_[numberObjects_] = originalObject[iObject]->clone();
    81588505        // redo ids etc
    8159         object_[numberObjects_]->redoSequenceEtc(this,numberColumns,originalColumns);
     8506        CbcObject * obj =
     8507          dynamic_cast <CbcObject *>(object_[numberObjects_]) ;
     8508        assert (obj);
     8509        obj->redoSequenceEtc(this,numberColumns,originalColumns);
    81608510        numberObjects_++;
    81618511      }
     
    81738523  }
    81748524   
     8525}
     8526// Generate an OsiBranchingInformation object
     8527OsiBranchingInformation
     8528CbcModel::usefulInformation() const
     8529{
     8530  OsiBranchingInformation usefulInfo(solver_);
     8531  // and modify
     8532  usefulInfo.solution_=testSolution_;
     8533  usefulInfo.integerTolerance_= dblParam_[CbcIntegerTolerance] ;
     8534  usefulInfo.hotstartSolution_=hotstartSolution_;
     8535  usefulInfo.numberSolutions_=numberSolutions_;
     8536  usefulInfo.numberBranchingSolutions_=numberSolutions_-numberHeuristicSolutions_;
     8537  usefulInfo.depth_=-1;
     8538  return usefulInfo;
    81758539}
    81768540/* Does postprocessing - original solver back.
     
    82848648  fprintf(fp,"%d  cbcModel->setMaximumCutPasses(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
    82858649  fprintf(fp,"%d  cbcModel->setMaximumCutPasses(save_getMaximumCutPasses);\n",iValue1==iValue2 ? 7 : 6);
     8650  iValue1 = this->getPreferredWay();
     8651  iValue2 = other->getPreferredWay();
     8652  fprintf(fp,"%d  int save_getPreferredWay = cbcModel->getPreferredWay();\n",iValue1==iValue2 ? 2 : 1);
     8653  fprintf(fp,"%d  cbcModel->setPreferredWay(%d);\n",iValue1==iValue2 ? 4 : 3,iValue1);
     8654  fprintf(fp,"%d  cbcModel->setPreferredWay(save_getPreferredWay);\n",iValue1==iValue2 ? 7 : 6);
    82868655  dValue1 = this->getMinimumDrop();
    82878656  dValue2 = other->getMinimumDrop();
     
    83208689  fprintf(fp,"%d  cbcModel->setMaximumSeconds(save_cbcMaximumSeconds);\n",dValue1==dValue2 ? 7 : 6);
    83218690}
     8691// So we can use osiObject or CbcObject during transition
     8692void getIntegerInformation(const OsiObject * object, double & originalLower,
     8693                           double & originalUpper)
     8694{
     8695  const CbcSimpleInteger * integerObject =
     8696    dynamic_cast<const  CbcSimpleInteger *> (object);
     8697  if (integerObject) {
     8698    // get original bounds
     8699    originalLower = integerObject->originalLowerBound();
     8700    originalUpper = integerObject->originalUpperBound();
     8701  } else {
     8702    const OsiSimpleInteger * integerObject =
     8703      dynamic_cast<const  OsiSimpleInteger *> (object);
     8704    assert (integerObject);
     8705    // get original bounds
     8706    originalLower = integerObject->originalLowerBound();
     8707    originalUpper = integerObject->originalUpperBound();
     8708  }
     8709}
  • branches/devel/Cbc/src/CbcModel.hpp

    r426 r439  
    88#include "CoinMessageHandler.hpp"
    99#include "OsiSolverInterface.hpp"
     10#include "OsiBranchingObject.hpp"
    1011#include "OsiCuts.hpp"
    1112#include "CoinWarmStartBasis.hpp"
     
    2223class CglTreeProbingInfo;
    2324class CbcHeuristic;
    24 class CbcObject;
     25class OsiObject;
    2526class CbcTree;
    2627class CbcStrategy;
     
    103104  */
    104105  CbcFathomDiscipline,
     106  /** Adjusts printout
     107      1 does different node message with number unsatisfied on last branch
     108  */
     109  CbcPrinting,
    105110  /** Just a marker, so that a static sized array can store parameters. */
    106111  CbcLastIntParam
     
    350355  /** \name Object manipulation routines
    351356 
    352     See CbcObject for an explanation of `object' in the context of CbcModel.
     357    See OsiObject for an explanation of `object' in the context of CbcModel.
    353358  */
    354359  //@{
     
    361366
    362367  /// Get the array of objects
    363   inline CbcObject ** objects() const { return object_;};
     368  inline OsiObject ** objects() const { return object_;};
    364369
    365370  /// Get the specified object
    366   const inline CbcObject * object(int which) const { return object_[which];};
     371  const inline OsiObject * object(int which) const { return object_[which];};
    367372  /// Get the specified object
    368   inline CbcObject * modifiableObject(int which) const { return object_[which];};
     373  inline OsiObject * modifiableObject(int which) const { return object_[which];};
    369374
    370375  /// Delete all object information
    371376  void deleteObjects();
     377
     378  /** Add in object information.
     379 
     380    Objects are cloned; the owner can delete the originals.
     381  */
     382  void addObjects(int numberObjects, OsiObject ** objects);
    372383
    373384  /** Add in object information.
     
    459470    return getIntParam(CbcMaxNumSol);
    460471  }
     472  /// Set the printing mode
     473  inline bool setPrintingMode( int value)
     474  { return setIntParam(CbcPrinting,value); }
     475
     476  /// Get the printing mode
     477  inline int getPrintingMode() const
     478  { return getIntParam(CbcPrinting); }
    461479
    462480  /** Set the
     
    601619  inline int numberStrong() const
    602620  { return numberStrong_;};
     621  /** Set global preferred way to branch
     622      -1 down, +1 up, 0 no preference */
     623  inline void setPreferredWay(int value)
     624  {preferredWay_=value;};
     625  /** Get the preferred way to branch (default 0) */
     626  inline int getPreferredWay() const
     627  { return preferredWay_;};
    603628  /** Set size of mini - tree.  If > 1 then does total enumeration of
    604629      tree given by this best variables to branch on
     
    712737    inline int status() const
    713738    { return status_;};
     739    inline void setProblemStatus(int value)
     740    { status_=value;};
    714741    /** Secondary status of problem
    715742        -1 unset (status_ will also be -1)
     
    725752    inline int secondaryStatus() const
    726753    { return secondaryStatus_;};
     754    inline void setSecondaryStatus(int value)
     755    { secondaryStatus_=value;};
    727756    /// Are there numerical difficulties (for initialSolve) ?
    728757    bool isInitialSolveAbandoned() const ;
     
    11211150  /// Set the branching decision method.
    11221151  inline void setBranchingMethod(CbcBranchDecision * method)
    1123   { branchingMethod_ = method->clone();};
     1152  { delete branchingMethod_; branchingMethod_ = method->clone();};
    11241153  /** Set the branching method
    11251154 
     
    11271156  */
    11281157  inline void setBranchingMethod(CbcBranchDecision & method)
    1129   { branchingMethod_ = method.clone();};
     1158  { delete branchingMethod_; branchingMethod_ = method.clone();};
    11301159  //@}
    11311160
     
    14011430  /// Encapsulates solver resolve
    14021431  int resolve(OsiSolverInterface * solver);
     1432
     1433  /** Encapsulates choosing a variable -
     1434      anyAction -2, infeasible (-1 round again), 0 done
     1435  */
     1436  int chooseBranch(CbcNode * newNode, int numberPassesLeft,
     1437                   CbcNode * oldNode, OsiCuts & cuts,
     1438                   bool & resolved, CoinWarmStartBasis *lastws,
     1439                   const double * lowerBefore,const double * upperBefore,
     1440                   OsiSolverBranch * & branches,
     1441                   OsiBranchingInformation * usefulInfo);
     1442  int chooseBranch(CbcNode * newNode, int numberPassesLeft, bool & resolved);
    14031443
    14041444  /** Return an empty basis object of the specified size
     
    15021542  /// Create C++ lines to get to current state
    15031543  void generateCpp( FILE * fp,int options);
     1544  /// Generate an OsiBranchingInformation object
     1545  OsiBranchingInformation usefulInformation() const;
    15041546  //@}
    15051547
     
    17821824          objects.
    17831825  */
    1784   CbcObject ** object_;
     1826  OsiObject ** object_;
    17851827
    17861828 
     
    18051847  /// Maximum number of cut passes
    18061848  int maximumCutPasses_;
     1849  /// Preferred way of branching
     1850  int preferredWay_;
    18071851  /// Current cut pass number
    18081852  int currentPassNumber_;
     
    18541898 //@}
    18551899};
    1856 
     1900/// So we can use osiObject or CbcObject during transition
     1901void getIntegerInformation(const OsiObject * object, double & originalLower,
     1902                           double & originalUpper) ;
    18571903#endif
  • branches/devel/Cbc/src/CbcNode.cpp

    r427 r439  
    1717#define CUTS
    1818#include "OsiSolverInterface.hpp"
     19#include "OsiChooseVariable.hpp"
    1920#include "OsiAuxInfo.hpp"
    2021#include "OsiSolverBranch.hpp"
     
    905906  double integerTolerance =
    906907    model->getDblParam(CbcModel::CbcIntegerTolerance);
     908  // point to useful information
     909  OsiBranchingInformation usefulInfo = model->usefulInformation();
     910  // and modify
     911  usefulInfo.depth_=depth_;
    907912  int i;
    908913  bool beforeSolution = model->getSolutionCount()==0;
     
    937942  if (!decision||dynamicBranchingObject)
    938943    decision = new CbcBranchDefaultDecision();
    939 
     944  decision->initialize(model);
    940945  CbcStrongInfo * choice = new CbcStrongInfo[maximumStrong];
    941946  for (i=0;i<numberColumns;i++) {
     
    993998      bool canDoOneHot=false;
    994999      for (i=0;i<numberObjects;i++) {
    995         CbcObject * object = model->modifiableObject(i);
     1000        OsiObject * object = model->modifiableObject(i);
    9961001        int preferredWay;
    997         double infeasibility = object->infeasibility(preferredWay);
     1002        double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    9981003        int priorityLevel = object->priority();
    9991004        if (hotstartSolution) {
     
    10011006          const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
    10021007          if (thisOne) {
    1003             int iColumn = thisOne->modelSequence();
     1008            int iColumn = thisOne->columnNumber();
    10041009            bool canDoThisHot=true;
    10051010            double targetValue = hotstartSolution[iColumn];
     
    10801085            choice[iSmallest].upMovement=infeasibility;
    10811086            delete choice[iSmallest].possibleBranch;
    1082             choice[iSmallest].possibleBranch=object->createBranch(preferredWay);
     1087            CbcSimpleInteger * obj =
     1088              dynamic_cast <CbcSimpleInteger *>(object) ;
     1089            if (obj) {
     1090              choice[iSmallest].possibleBranch=obj->createBranch(solver,&usefulInfo,preferredWay);
     1091            } else {
     1092              CbcObject * obj =
     1093                dynamic_cast <CbcObject *>(object) ;
     1094              assert (obj);
     1095              choice[iSmallest].possibleBranch=obj->createBranch(preferredWay);
     1096            }
    10831097            numberStrong = CoinMax(numberStrong,iSmallest+1);
    10841098            // Save which object it was
     
    12811295        for (i=0;i<numberStrong;i++) {
    12821296          int iObject = choice[i].objectNumber;
    1283           const CbcObject * object = model->object(iObject);
     1297          const OsiObject * object = model->object(iObject);
    12841298          const CbcSimpleInteger * simple = dynamic_cast <const CbcSimpleInteger *> (object);
    1285           int iSequence = simple->modelSequence();
     1299          int iSequence = simple->columnNumber();
    12861300          newLower[i]= ceil(saveSolution[iSequence]);
    12871301          newUpper[i]= floor(saveSolution[iSequence]);
     
    13161330          for (i=0;i<numberStrong;i++) {
    13171331            int iObject = choice[i].objectNumber;
    1318             const CbcObject * object = model->object(iObject);
     1332            const OsiObject * object = model->object(iObject);
    13191333            const CbcSimpleInteger * simple = dynamic_cast <const CbcSimpleInteger *> (object);
    1320             int iSequence = simple->modelSequence();
     1334            int iSequence = simple->columnNumber();
    13211335            which[i]=iSequence;
    13221336            double * sol = outputSolution[2*i];
     
    16981712            CbcStrongInfo thisChoice = choice[i];
    16991713            choice[i].possibleBranch=NULL;
    1700             const CbcObject * object = model->object(thisChoice.objectNumber);
     1714            const OsiObject * object = model->object(thisChoice.objectNumber);
    17011715            int preferredWay;
    1702             double infeasibility = object->infeasibility(preferredWay);
     1716            double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    17031717            if (!infeasibility) {
    17041718              // take out
     
    18941908    auxiliaryInfo = model->solverCharacteristics();
    18951909  }
     1910  // point to useful information
     1911  OsiBranchingInformation usefulInfo = model->usefulInformation();
     1912  // and modify
     1913  usefulInfo.depth_=depth_;
    18961914  assert (auxiliaryInfo);
    18971915  //assert(objectiveValue_ == solver->getObjSense()*solver->getObjValue());
     
    19731991    int i;
    19741992    for ( i=0;i<numberObjects;i++) {
    1975       CbcObject * object = model->modifiableObject(i);
     1993      OsiObject * object = model->modifiableObject(i);
    19761994      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    19771995        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    20422060      int i;
    20432061      for ( i=0;i<numberObjects;i++) {
    2044         CbcObject * object = model->modifiableObject(i);
     2062        OsiObject * object = model->modifiableObject(i);
    20452063        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    20462064          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    20642082        averageDown=1.0;
    20652083      for ( i=0;i<numberObjects;i++) {
    2066         CbcObject * object = model->modifiableObject(i);
     2084        OsiObject * object = model->modifiableObject(i);
    20672085        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    20682086          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    21662184#define PRINT_STUFF -1
    21672185      for (i=0;i<numberObjects;i++) {
    2168         CbcObject * object = model->modifiableObject(i);
     2186        OsiObject * object = model->modifiableObject(i);
    21692187        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    21702188          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    21712189        assert(dynamicObject);
    21722190        int preferredWay;
    2173         double infeasibility = object->infeasibility(preferredWay);
     2191        double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    21742192        int priorityLevel = object->priority();
    21752193#define ZERO_ONE 0
     
    24332451    if (hitMaxTime||numberPassesLeft<=0||(!numberNotTrusted&&false)||branchingMethod==11) {
    24342452      int iObject = whichObject[bestChoice];
    2435       CbcObject * object = model->modifiableObject(iObject);
     2453      OsiObject * object = model->modifiableObject(iObject);
    24362454      int preferredWay;
    2437       object->infeasibility(preferredWay);
    2438       branch_=object->createBranch(preferredWay);
    2439       branch_->way(preferredWay);
     2455      object->infeasibility(&usefulInfo,preferredWay);
     2456      CbcSimpleInteger * obj =
     2457        dynamic_cast <CbcSimpleInteger *>(object) ;
     2458      if (obj) {
     2459        branch_=obj->createBranch(solver,&usefulInfo,preferredWay);
     2460      } else {
     2461        CbcObject * obj =
     2462          dynamic_cast <CbcObject *>(object) ;
     2463        assert (obj);
     2464        branch_=obj->createBranch(preferredWay);
     2465      }
     2466      {
     2467        CbcBranchingObject * branchObj =
     2468          dynamic_cast <CbcBranchingObject *>(branch_) ;
     2469        assert (branchObj);
     2470        branchObj->way(preferredWay);
     2471      }
    24402472      delete ws;
    24412473      ws=NULL;
     
    24872519          int j = objectMark[i];
    24882520          int iObject = whichObject[j];
    2489           CbcObject * object = model->modifiableObject(iObject);
     2521          OsiObject * object = model->modifiableObject(iObject);
    24902522          CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    24912523            dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    26052637      }
    26062638#endif
    2607       if (depth_<10&&numberStrong) {
     2639      if (depth_<8&&numberStrong) {
    26082640        if (searchStrategy!=2) {
    26092641          doQuickly=false;
     
    27222754      }
    27232755      //printf("skipAll %c doQuickly %c numberTest %d numberTest2 %d numberNot %d\n",
    2724       //     skipAll ? 'Y' : 'N',doQuickly ? 'Y' : 'N',numberTest,numberTest2,numberNotTrusted);
     2756      //   skipAll ? 'Y' : 'N',doQuickly ? 'Y' : 'N',numberTest,numberTest2,numberNotTrusted);
    27252757      // See if we want mini tree
    27262758      bool wantMiniTree=false;
     
    27352767        CbcStrongInfo choice;
    27362768        int iObject = whichObject[iDo];
    2737         CbcObject * object = model->modifiableObject(iObject);
     2769        OsiObject * object = model->modifiableObject(iObject);
    27382770        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    27392771          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    27402772        int iColumn = dynamicObject->columnNumber();
    27412773        int preferredWay;
    2742         object->infeasibility(preferredWay);
    2743         choice.possibleBranch=object->createBranch(preferredWay);
     2774        object->infeasibility(&usefulInfo,preferredWay);
     2775        CbcSimpleInteger * obj =
     2776          dynamic_cast <CbcSimpleInteger *>(object) ;
     2777        if (obj) {
     2778          choice.possibleBranch=obj->createBranch(solver,&usefulInfo,preferredWay);
     2779        } else {
     2780          CbcObject * obj =
     2781            dynamic_cast <CbcObject *>(object) ;
     2782          assert (obj);
     2783          choice.possibleBranch=obj->createBranch(preferredWay);
     2784        }
    27442785        // Save which object it was
    27452786        choice.objectNumber=iObject;
     
    30803121            //assert(gap>0.0);
    30813122            double factor = 1.0; //changeFactor/CoinMin(gap,100.0);
    3082             int betterWay = decision->betterBranch(choice.possibleBranch,
    3083                                                    branch_,
    3084                                                    choice.upMovement*factor,
    3085                                                    choice.numIntInfeasUp ,
    3086                                                    choice.downMovement*factor,
    3087                                                    choice.numIntInfeasDown );
     3123            int betterWay;
     3124            {
     3125              CbcBranchingObject * branchObj =
     3126                dynamic_cast <CbcBranchingObject *>(branch_) ;
     3127              if (branch_)
     3128                assert (branchObj);
     3129              betterWay = decision->betterBranch(choice.possibleBranch,
     3130                                                     branchObj,
     3131                                                     choice.upMovement*factor,
     3132                                                     choice.numIntInfeasUp ,
     3133                                                     choice.downMovement*factor,
     3134                                                     choice.numIntInfeasDown );
     3135            }
    30883136            if (wantMiniTree) {
    30893137              double criterion = decision->getBestCriterion();
     
    31063154              branch_ = choice.possibleBranch;
    31073155              choice.possibleBranch=NULL;
    3108               branch_->way(betterWay);
     3156              {
     3157                CbcBranchingObject * branchObj =
     3158                  dynamic_cast <CbcBranchingObject *>(branch_) ;
     3159                assert (branchObj);
     3160                branchObj->way(preferredWay);
     3161              }
    31093162              if (couldChooseFirst)
    31103163                printf("choosing %d way %d\n",iDo,betterWay);
     
    32413294          for ( int jDo=iDo+1;jDo<numberToDo;jDo++) {
    32423295            int iObject = whichObject[iDo];
    3243             CbcObject * object = model->modifiableObject(iObject);
     3296            OsiObject * object = model->modifiableObject(iObject);
    32443297            CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    32453298              dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    33123365              // See if candidate still possible
    33133366              if (branch_) {
    3314                 const CbcObject * object = model->object(bestChoice);
     3367                const OsiObject * object = model->object(bestChoice);
    33153368                int preferredWay;
    3316                 double infeasibility = object->infeasibility(preferredWay);
     3369                double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    33173370                if (!infeasibility) {
    33183371                  // take out
     
    33203373                  branch_=NULL;
    33213374                } else {
    3322                   branch_->way(preferredWay);
     3375                  CbcBranchingObject * branchObj =
     3376                    dynamic_cast <CbcBranchingObject *>(branch_) ;
     3377                  assert (branchObj);
     3378                  branchObj->way(preferredWay);
    33233379                }
    33243380              }
     
    33853441    for (int iDo=0;iDo<numberMini;iDo++) {
    33863442      int iObject = whichObject[iDo];
    3387       CbcObject * object = model->modifiableObject(iObject);
    3388       OsiSolverBranch * oneBranch = object->solverBranch();
     3443      OsiObject * object = model->modifiableObject(iObject);
     3444      CbcSimpleInteger * obj =
     3445        dynamic_cast <CbcSimpleInteger *>(object) ;
     3446      OsiSolverBranch * oneBranch;
     3447      if (obj) {
     3448        oneBranch = obj->solverBranch(solver,&usefulInfo);
     3449      } else {
     3450        CbcObject * obj =
     3451          dynamic_cast <CbcObject *>(object) ;
     3452        assert (obj);
     3453        oneBranch = obj->solverBranch();
     3454      }
    33893455      branches[iDo]=*oneBranch;
    33903456      delete oneBranch;
     
    34653531  int numberToFix=0;
    34663532  int numberToDo=0;
     3533  double integerTolerance =
     3534    model->getDblParam(CbcModel::CbcIntegerTolerance);
     3535  // point to useful information
     3536  OsiBranchingInformation usefulInfo = model->usefulInformation();
     3537  // and modify
     3538  usefulInfo.depth_=depth_;
    34673539     
    34683540  // compute current state
     
    34963568  numberToDo=0;
    34973569  for (i=0;i<numberObjects;i++) {
    3498     CbcObject * object = model->modifiableObject(i);
     3570    OsiObject * object = model->modifiableObject(i);
    34993571    CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    35003572      dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     
    35023574      continue;
    35033575    int preferredWay;
    3504     double infeasibility = object->infeasibility(preferredWay);
     3576    double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    35053577    int iColumn = dynamicObject->columnNumber();
    35063578    if (saveUpper[iColumn]==saveLower[iColumn])
     
    35253597  //double distanceToCutoff=model->getCutoff()-objectiveValue_;
    35263598  double * currentSolution = model->currentSolution();
    3527   double integerTolerance =
    3528     model->getDblParam(CbcModel::CbcIntegerTolerance);
    35293599  double objMin = 1.0e50;
    35303600  double objMax = -1.0e50;
     
    35343604    CbcStrongInfo choice;
    35353605    int iObject = whichObject[iDo];
    3536     CbcObject * object = model->modifiableObject(iObject);
     3606    OsiObject * object = model->modifiableObject(iObject);
    35373607    CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    35383608      dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    35393609    int iColumn = dynamicObject->columnNumber();
    35403610    int preferredWay;
    3541     object->infeasibility(preferredWay);
     3611    object->infeasibility(&usefulInfo,preferredWay);
    35423612    double value = currentSolution[iColumn];
    35433613    double nearest = floor(value+0.5);
     
    35573627    }
    35583628    double upperValue = lowerValue+1.0;
    3559     choice.possibleBranch=object->createBranch(preferredWay);
     3629    CbcSimpleInteger * obj =
     3630      dynamic_cast <CbcSimpleInteger *>(object) ;
     3631    if (obj) {
     3632      choice.possibleBranch=obj->createBranch(solver,&usefulInfo,preferredWay);
     3633    } else {
     3634      CbcObject * obj =
     3635        dynamic_cast <CbcObject *>(object) ;
     3636      assert (obj);
     3637      choice.possibleBranch=obj->createBranch(preferredWay);
     3638    }
    35603639    currentSolution[iColumn]=value;
    35613640    // Save which object it was
     
    39013980CbcNode::branch()
    39023981{
    3903   double changeInGuessed=branch_->branch(true);
     3982  double changeInGuessed=branch_->branch();
    39043983  guessedObjectiveValue_+= changeInGuessed;
    39053984  //#define PRINTIT
     
    39093988  int parentNodeNumber = -1;
    39103989  //CbcBranchingObject * object1 = branch_->object_;
    3911   //CbcObject * object = object1->
     3990  //OsiObject * object = object1->
    39123991  //int sequence = object->columnNumber);
    39133992  int id=-1;
     
    39264005  return nodeInfo_->branchedOn();
    39274006}
     4007/* Active arm of the attached OsiBranchingObject.
     4008 
     4009   In the simplest instance, coded -1 for the down arm of the branch, +1 for
     4010   the up arm. But see OsiBranchingObject::way()
     4011     Use nodeInfo--.numberBranchesLeft_ to see how active
     4012*/
     4013int
     4014CbcNode::way() const
     4015{
     4016  if (branch_) {
     4017    CbcBranchingObject * obj =
     4018      dynamic_cast <CbcBranchingObject *>(branch_) ;
     4019    assert (obj);
     4020    return obj->way();
     4021  } else {
     4022    return 0;
     4023  }
     4024}
     4025/* Create a branching object for the node
     4026
     4027    The routine scans the object list of the model and selects a set of
     4028    unsatisfied objects as candidates for branching. The candidates are
     4029    evaluated, and an appropriate branch object is installed.
     4030
     4031    The numberPassesLeft is decremented to stop fixing one variable each time
     4032    and going on and on (e.g. for stock cutting, air crew scheduling)
     4033
     4034    If evaluation determines that an object is monotone or infeasible,
     4035    the routine returns immediately. In the case of a monotone object,
     4036    the branch object has already been called to modify the model.
     4037
     4038    Return value:
     4039    <ul>
     4040      <li>  0: A branching object has been installed
     4041      <li> -1: A monotone object was discovered
     4042      <li> -2: An infeasible object was discovered
     4043    </ul>
     4044    Branch state:
     4045    <ul>
     4046      <li> -1: start
     4047      <li> -1: A monotone object was discovered
     4048      <li> -2: An infeasible object was discovered
     4049    </ul>
     4050*/
     4051int
     4052CbcNode::chooseOsiBranch (CbcModel * model,
     4053                          CbcNode * lastNode,
     4054                          OsiBranchingInformation * usefulInfo,
     4055                          int branchState)
     4056{
     4057  int returnStatus=0;
     4058  if (lastNode)
     4059    depth_ = lastNode->depth_+1;
     4060  else
     4061    depth_ = 0;
     4062  objectiveValue_ = usefulInfo->solver_->getObjValue()*usefulInfo->solver_->getObjSense();
     4063  usefulInfo->objectiveValue_ = objectiveValue_;
     4064  usefulInfo->depth_ = depth_;
     4065  OsiChooseVariable * choose = model->branchingMethod()->chooseMethod();
     4066  int numberUnsatisfied=-1;
     4067  if (branchState<0) {
     4068    // initialize
     4069    numberUnsatisfied = choose->setupList(usefulInfo,true);
     4070    numberUnsatisfied_ = numberUnsatisfied;
     4071    branchState=0;
     4072  }
     4073  // unset best
     4074  int best=-1;
     4075  choose->setBestObject(-1);
     4076  if (numberUnsatisfied) {
     4077    if (branchState>0||!choose->numberOnList()) {
     4078      // we need to return at once - don't do strong branching or anything
     4079      if (choose->numberOnList()||!choose->numberStrong()) {
     4080        best = choose->candidates()[0];
     4081        choose->setBestObject(best);
     4082        choose->updateInformation(usefulInfo);
     4083      } else {
     4084        // nothing on list - need to try again - keep any solution
     4085        numberUnsatisfied = choose->setupList(usefulInfo, false);
     4086        numberUnsatisfied_ = numberUnsatisfied;
     4087        if (numberUnsatisfied) {
     4088          best = choose->candidates()[0];
     4089          choose->setBestObject(best);
     4090          choose->updateInformation(usefulInfo);
     4091        }
     4092      }
     4093    } else {
     4094      // carry on with strong branching or whatever
     4095      int returnCode = choose->chooseVariable(usefulInfo);
     4096      if (returnCode>1) {
     4097        // can fix
     4098        returnStatus=-1;
     4099      } else if (returnCode==-1) {
     4100        // infeasible
     4101        returnStatus=-2;
     4102      } else if (returnCode==0) {
     4103        // normal
     4104        returnStatus=0;
     4105        numberUnsatisfied=1;
     4106      } else {
     4107        // ones on list satisfied - double check
     4108        numberUnsatisfied = choose->setupList(usefulInfo, false);
     4109        numberUnsatisfied_ = numberUnsatisfied;
     4110        if (numberUnsatisfied) {
     4111          best = choose->candidates()[0];
     4112          choose->setBestObject(best);
     4113          choose->updateInformation( usefulInfo);
     4114        }
     4115      }
     4116    }
     4117  }
     4118  delete branch_;
     4119  branch_ = NULL;
     4120  guessedObjectiveValue_ = objectiveValue_; // for now
     4121  if (!returnStatus) {
     4122    if (numberUnsatisfied) {
     4123      // create branching object
     4124      const OsiObject * obj = model->object(choose->bestObject());
     4125      //const OsiSolverInterface * solver = usefulInfo->solver_;
     4126      branch_ = obj->createBranch(model->solver(),obj->whichWay());
     4127    }
     4128  }
     4129  return returnStatus;
     4130}
  • branches/devel/Cbc/src/CbcNode.hpp

    r416 r439  
    478478                           OsiSolverBranch * & branches,
    479479                           int numberPassesLeft);
     480  /** Create a branching object for the node
     481
     482    The routine scans the object list of the model and selects a set of
     483    unsatisfied objects as candidates for branching. The candidates are
     484    evaluated, and an appropriate branch object is installed.
     485
     486    The numberPassesLeft is decremented to stop fixing one variable each time
     487    and going on and on (e.g. for stock cutting, air crew scheduling)
     488
     489    If evaluation determines that an object is monotone or infeasible,
     490    the routine returns immediately. In the case of a monotone object,
     491    the branch object has already been called to modify the model.
     492
     493    Return value:
     494    <ul>
     495      <li>  0: A branching object has been installed
     496      <li> -1: A monotone object was discovered
     497      <li> -2: An infeasible object was discovered
     498    </ul>
     499    Branch state:
     500    <ul>
     501      <li> -1: start
     502      <li> -1: A monotone object was discovered
     503      <li> -2: An infeasible object was discovered
     504    </ul>
     505  */
     506  int chooseOsiBranch (CbcModel * model,
     507                       CbcNode * lastNode,
     508                       OsiBranchingInformation * usefulInfo,
     509                       int branchState);
    480510  int analyze(CbcModel * model,double * results);
    481511  /// Decrement active cut counts
     
    491521    This is a convenience routine, which will initialize the reference counts
    492522    in the attached CbcNodeInfo object based on the attached
    493     CbcBranchingObject.
     523    OsiBranchingObject.
    494524
    495525    \sa CbcNodeInfo::initializeInfo(int).
     
    509539  inline void setObjectiveValue(double value)
    510540  { objectiveValue_=value;};
    511   /// Number of arms defined for the attached CbcBranchingObject.
     541  /// Number of arms defined for the attached OsiBranchingObject.
    512542  inline int numberBranches() const
    513543  { if (branch_)
     
    516546      return (-1) ; } ;
    517547
    518   /** Branching `variable' associated with the attached CbcBranchingObject.
    519 
    520     Check CbcBranchingObject::variable() for a longer explanation of
    521     `variable'.
    522   */
    523   inline int variable() const
    524   {if (branch_) return branch_->variable();else return -1;};
    525 
    526   /* Active arm of the attached CbcBranchingObject.
     548  /* Active arm of the attached OsiBranchingObject.
    527549 
    528550   In the simplest instance, coded -1 for the down arm of the branch, +1 for
    529    the up arm. But see CbcBranchingObject::way()
     551   the up arm. But see OsiBranchingObject::way()
    530552     Use nodeInfo--.numberBranchesLeft_ to see how active
    531553  */
    532   inline int way() const
    533   {if (branch_) return branch_->way();else return 0;};
     554  int way() const;
    534555  /// Depth in branch-and-cut search tree
    535556  inline int depth() const
     
    545566  {guessedObjectiveValue_=value;};
    546567  /// Branching object for this node
    547   inline const CbcBranchingObject * branchingObject() const
     568  inline const OsiBranchingObject * branchingObject() const
    548569  { return branch_;};
    549570  /// Modifiable branching object for this node
    550   inline CbcBranchingObject * modifiableBranchingObject() const
     571  inline OsiBranchingObject * modifiableBranchingObject() const
    551572  { return branch_;};
    552573  /// Set branching object for this node (takes ownership)
    553   inline void setBranchingObject(CbcBranchingObject * branchingObject)
     574  inline void setBranchingObject(OsiBranchingObject * branchingObject)
    554575  { branch_ = branchingObject;};
    555576
     
    563584  double guessedObjectiveValue_;
    564585  /// Branching object for this node
    565   CbcBranchingObject * branch_;
     586  OsiBranchingObject * branch_;
    566587  /// Depth of the node in the search tree
    567588  int depth_;
  • branches/devel/Cbc/src/CbcStatistics.cpp

    r311 r439  
    5252  CbcNodeInfo * parent = nodeInfo->parent();
    5353  int numberBranches = nodeInfo->numberBranchesLeft();
    54   const CbcBranchingObject * branch = node->branchingObject();
     54  const CbcBranchingObject * branch = dynamic_cast <const CbcBranchingObject *>(node->branchingObject());
    5555  startingObjective_=node->objectiveValue();
    5656  way_=node->way();
  • branches/devel/Cbc/src/CbcStrategy.cpp

    r424 r439  
    382382            numberIntegers = model.numberIntegers();
    383383          }
    384           CbcObject ** oldObjects = model.objects();
     384          OsiObject ** oldObjects = model.objects();
    385385          // Do sets and priorities
    386           CbcObject ** objects = new CbcObject * [numberSOS];
     386          OsiObject ** objects = new OsiObject * [numberSOS];
    387387          // set old objects to have low priority
    388388          int numberOldObjects = model.numberObjects();
     
    422422            for (int iObject=0;iObject<model.numberObjects();iObject++) {
    423423              // redo ids etc
    424               model.modifiableObject(iObject)->redoSequenceEtc(&model,n,fake);
     424              CbcSimpleInteger * obj =
     425                dynamic_cast <CbcSimpleInteger *>(model.modifiableObject(iObject)) ;
     426              if (obj) {
     427                obj->resetSequenceEtc(n,fake);
     428              } else {
     429                // redo ids etc
     430                CbcObject * obj =
     431                  dynamic_cast <CbcObject *>(model.modifiableObject(iObject)) ;
     432                assert (obj);
     433                obj->redoSequenceEtc(&model,n,fake);
     434              }
    425435            }
    426436            delete [] fake;
  • branches/devel/Cbc/src/CbcTree.cpp

    r424 r439  
    5151void
    5252CbcTree::push(CbcNode * x) {
     53  assert(x->objectiveValue()!=COIN_DBL_MAX&&x->nodeInfo());
    5354  nodes_.push_back(x);
    5455  push_heap(nodes_.begin(), nodes_.end(), comparison_);
  • branches/devel/Cbc/src/Cbc_C_Interface.cpp

    r310 r439  
    863863*/
    864864COINLIBAPI int COINLINKAGE
    865 Cbc_status(Cbc_Model * model)
    866 {
    867   const char prefix[] = "Cbc_C_Interface::Cbc_status(): ";
    868 //  const int  VERBOSE = 1;
    869   if (VERBOSE>0) printf("%s begin\n",prefix);
    870 
    871   int result = 0;
    872   result = model->model_->status();
     865Cbc_LPstatus(Cbc_Model * model)
     866{
     867  const char prefix[] = "Cbc_C_Interface::Cbc_LPstatus(): ";
     868//  const int  VERBOSE = 1;
     869  if (VERBOSE>0) printf("%s begin\n",prefix);
     870
     871  int result = 0;
     872  OsiClpSolverInterface * solver  =  dynamic_cast< OsiClpSolverInterface*> (model->model_->solver());
     873  result = solver->getModelPtr()->status();
    873874
    874875  if (VERBOSE>0) printf("%s return %i\n",prefix,result);
     
    877878/* Set problem status */
    878879COINLIBAPI void COINLINKAGE
    879 Cbc_setProblemStatus(Cbc_Model * model, int problemStatus)
    880 {
    881   const char prefix[] = "Cbc_C_Interface::Cbc_setProblemStatus(): ";
    882 //  const int  VERBOSE = 1;
    883   if (VERBOSE>0) printf("%s begin\n",prefix);
    884 
    885 // cannot find this in Cbc, Osi, or OsiClp
    886 //tbd  model->model_->setProblemStatus(problemStatus);
    887   printf("%s ERROR: NOT IMPLEMENTED\n",prefix);
     880Cbc_setProblemLPStatus(Cbc_Model * model, int problemStatus)
     881{
     882  const char prefix[] = "Cbc_C_Interface::Cbc_setLPProblemStatus(): ";
     883//  const int  VERBOSE = 1;
     884  if (VERBOSE>0) printf("%s begin\n",prefix);
     885
     886  OsiClpSolverInterface * solver  =  dynamic_cast< OsiClpSolverInterface*> (model->model_->solver());
     887  solver->getModelPtr()->setProblemStatus(problemStatus);
    888888
    889889  if (VERBOSE>0) printf("%s return\n",prefix);
     
    897897*/
    898898COINLIBAPI int COINLINKAGE
     899Cbc_secondaryLPStatus(Cbc_Model * model)
     900{
     901  const char prefix[] = "Cbc_C_Interface::Cbc_secondaryLPStatus(): ";
     902//  const int  VERBOSE = 1;
     903  if (VERBOSE>0) printf("%s begin\n",prefix);
     904
     905  int result = 0;
     906  OsiClpSolverInterface * solver  =  dynamic_cast< OsiClpSolverInterface*> (model->model_->solver());
     907  result = solver->getModelPtr()->secondaryStatus();
     908
     909  if (VERBOSE>0) printf("%s return %i\n",prefix,result);
     910  return result;
     911}
     912COINLIBAPI void COINLINKAGE
     913Cbc_setSecondaryLPStatus(Cbc_Model * model, int status)
     914{
     915  const char prefix[] = "Cbc_C_Interface::Cbc_setSecondaryLPStatus(): ";
     916//  const int  VERBOSE = 1;
     917  if (VERBOSE>0) printf("%s begin\n",prefix);
     918
     919  OsiClpSolverInterface * solver  =  dynamic_cast< OsiClpSolverInterface*> (model->model_->solver());
     920  solver->getModelPtr()->setSecondaryStatus(status);
     921
     922  if (VERBOSE>0) printf("%s return\n",prefix);
     923}
     924/* Final status of BAB problem
     925   Some of these can be found out by is...... functions
     926   -1 before branchAndBound
     927   0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found
     928   (or check value of best solution)
     929   1 stopped - on maxnodes, maxsols, maxtime
     930   2 difficulties so run was abandoned
     931   (5 event user programmed event occurred)
     932*/
     933COINLIBAPI int COINLINKAGE
     934Cbc_status(Cbc_Model * model)
     935{
     936  const char prefix[] = "Cbc_C_Interface::Cbc_status(): ";
     937//  const int  VERBOSE = 1;
     938  if (VERBOSE>0) printf("%s begin\n",prefix);
     939
     940  int result = 0;
     941  result = model->model_->status();
     942
     943  if (VERBOSE>0) printf("%s return %i\n",prefix,result);
     944  return result;
     945}
     946/* Set problem status */
     947COINLIBAPI void COINLINKAGE
     948Cbc_setProblemStatus(Cbc_Model * model, int problemStatus)
     949{
     950  const char prefix[] = "Cbc_C_Interface::Cbc_setProblemStatus(): ";
     951//  const int  VERBOSE = 1;
     952  if (VERBOSE>0) printf("%s begin\n",prefix);
     953
     954  model->model_->setProblemStatus(problemStatus);
     955
     956  if (VERBOSE>0) printf("%s return\n",prefix);
     957}
     958/* Secondary status of BAB problem
     959   -1 unset (status_ will also be -1)
     960   0 search completed with solution
     961   1 linear relaxation not feasible (or worse than cutoff)
     962   2 stopped on gap
     963   3 stopped on nodes
     964   4 stopped on time
     965   5 stopped on user event
     966   6 stopped on solutions
     967   7 linear relaxation unbounded
     968*/
     969COINLIBAPI int COINLINKAGE
    899970Cbc_secondaryStatus(Cbc_Model * model)
    900971{
     
    904975
    905976  int result = 0;
    906 // cannot find this in Cbc, Osi, or OsiClp
    907 //tbd  result = model->model_->secondaryStatus();
    908   printf("%s ERROR: NOT IMPLEMENTED\n",prefix);
     977  result = model->model_->secondaryStatus();
    909978
    910979  if (VERBOSE>0) printf("%s return %i\n",prefix,result);
     
    918987  if (VERBOSE>0) printf("%s begin\n",prefix);
    919988
    920 // cannot find this in Cbc, Osi, or OsiClp
    921 //tbd  model->model_->setSecondaryStatus(status);
    922   printf("%s ERROR: NOT IMPLEMENTED\n",prefix);
     989  model->model_->setSecondaryStatus(status);
    923990
    924991  if (VERBOSE>0) printf("%s return\n",prefix);
  • branches/devel/Cbc/src/Cbc_C_Interface.h

    r2 r439  
    130130      4 - stopped due to errors
    131131  */
    132   COINLIBAPI int COINLINKAGE Cbc_status(Cbc_Model * model);
     132  COINLIBAPI int COINLINKAGE Cbc_LPstatus(Cbc_Model * model);
    133133  /** Set problem status */
    134   COINLIBAPI void COINLINKAGE Cbc_setProblemStatus(Cbc_Model * model, int problemStatus);
     134  COINLIBAPI void COINLINKAGE Cbc_setProblemLPStatus(Cbc_Model * model, int problemStatus);
    135135  /** Secondary status of problem - may get extended
    136136      0 - none
     
    139139      3 - scaled problem optimal - unscaled has dual infeasibilities
    140140      4 - scaled problem optimal - unscaled has both dual and primal infeasibilities
     141  */
     142  COINLIBAPI int COINLINKAGE Cbc_secondaryLPStatus(Cbc_Model * model);
     143  COINLIBAPI void COINLINKAGE Cbc_setSecondaryLPStatus(Cbc_Model * model, int status);
     144  /** Final status of BAB problem
     145      Some of these can be found out by is...... functions
     146      -1 before branchAndBound
     147      0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found
     148      (or check value of best solution)
     149      1 stopped - on maxnodes, maxsols, maxtime
     150      2 difficulties so run was abandoned
     151      (5 event user programmed event occurred)
     152  */
     153  COINLIBAPI int COINLINKAGE Cbc_status(Cbc_Model * model);
     154  /** Set problem status */
     155  COINLIBAPI void COINLINKAGE Cbc_setProblemStatus(Cbc_Model * model, int problemStatus);
     156  /** Secondary status of BAB problem
     157      -1 unset (status_ will also be -1)
     158      0 search completed with solution
     159      1 linear relaxation not feasible (or worse than cutoff)
     160      2 stopped on gap
     161      3 stopped on nodes
     162      4 stopped on time
     163      5 stopped on user event
     164      6 stopped on solutions
     165      7 linear relaxation unbounded
    141166  */
    142167  COINLIBAPI int COINLINKAGE Cbc_secondaryStatus(Cbc_Model * model);
  • branches/devel/Cbc/src/CoinSolve.cpp

    r435 r439  
    3636#include "CbcOrClpParam.hpp"
    3737#include "OsiRowCutDebugger.hpp"
     38#include "OsiChooseVariable.hpp"
    3839#ifdef DMALLOC
    3940#include "dmalloc.h"
     
    495496  const double * rowLower = solver->getRowLower();
    496497  const double * rowUpper = solver->getRowUpper();
    497   CbcObject ** objects = babModel->objects();
     498  OsiObject ** objects = babModel->objects();
    498499  int numberObjects = babModel->numberObjects();
    499500  for (int iObj = 0;iObj<numberObjects;iObj++) {
     
    742743    parameters[whichParam(CUTSSTRATEGY,numberParameters,parameters)].setCurrentOption("on");
    743744    parameters[whichParam(HEURISTICSTRATEGY,numberParameters,parameters)].setCurrentOption("on");
     745    parameters[whichParam(NODESTRATEGY,numberParameters,parameters)].setCurrentOption("fewest");
     746    int nodeStrategy=0;
    744747    int doSOS=1;
    745748    int verbose=0;
     
    13071310              mixedAction = action;
    13081311              twomirAction = action;
    1309               landpAction = action;
     1312              //landpAction = action;
    13101313              parameters[whichParam(GOMORYCUTS,numberParameters,parameters)].setCurrentOption(action);
    13111314              parameters[whichParam(PROBINGCUTS,numberParameters,parameters)].setCurrentOption(action);
     
    13501353            case COSTSTRATEGY:
    13511354              useCosts=action;
     1355              break;
     1356            case NODESTRATEGY:
     1357              nodeStrategy=action;
    13521358              break;
    13531359            case PREPROCESS:
     
    20572063              if (useFpump) {
    20582064                heuristic4.setMaximumPasses(parameters[whichParam(FPUMPITS,numberParameters,parameters)].intValue());
    2059                 if (doIdiot>10&&doIdiot<14) {
    2060                   heuristic4.setWhen(doIdiot);
    2061                   doIdiot=-1;
     2065                int pumpTune=parameters[whichParam(FPUMPTUNE,numberParameters,parameters)].intValue();
     2066                if (pumpTune>10) {
     2067                  /*
     2068                    >=1000 use index+2 as number of large loops, if >4 decrement by 5 and clean used array
     2069                    >=100 use 0.05 objvalue as increment
     2070                    >=10 use +0.1 objvalue for cutoff (add)
     2071                    1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds
     2072                  */
     2073                  if (pumpTune) {
     2074                    double value = babModel->solver()->getObjSense()*babModel->solver()->getObjValue();
     2075                    int w = pumpTune/10;
     2076                    int c = w % 10;
     2077                    w /= 10;
     2078                    int i = w % 10;
     2079                    w /= 10;
     2080                    int r = w%10;
     2081                    // fake cutoff
     2082                    if (c) {
     2083                      double cutoff;
     2084                      babModel->solver()->getDblParam(OsiDualObjectiveLimit,cutoff);
     2085                      cutoff = CoinMin(cutoff,value + 0.1*fabs(value)*c);
     2086                      heuristic4.setFakeCutoff(cutoff);
     2087                    }
     2088                    if (i||r) {
     2089                      // also set increment
     2090                      heuristic4.setAbsoluteIncrement((0.01*i+0.005)*(fabs(value)+1.0e-12));
     2091                      if (r>4) {
     2092                        r -=5;
     2093                        heuristic4.setMaximumRetries(-r-2);
     2094                      } else {
     2095                        heuristic4.setMaximumRetries(r+2);
     2096                      }
     2097                    }
     2098                    pumpTune = pumpTune%100;
     2099                    heuristic4.setWhen(pumpTune+10);
     2100                  }
    20622101                }
    20632102                babModel->addHeuristic(&heuristic4);
     
    20852124              int switches[20];
    20862125              int numberGenerators=0;
    2087               int translate[6]={-100,-1,-99,-98,1,1};
     2126              int translate[]={-100,-1,-99,-98,1,1,1,1};
    20882127              if (probingAction) {
    2089                 if (probingAction==5)
     2128                if (probingAction==5||probingAction==7)
    20902129                  probingGen.setRowCuts(-3); // strengthening etc just at root
    2091                 if (probingAction==4) {
     2130                if (probingAction==6||probingAction==7) {
    20922131                  // Number of unsatisfied variables to look at
    20932132                  probingGen.setMaxProbe(1000);
     
    21712210              //babModel->setNumberStrong(0);
    21722211              if (!noPrinting) {
     2212                int iLevel = parameters[log].intValue();
     2213                if (iLevel<0) {
     2214                  babModel->setPrintingMode(1);
     2215                  iLevel = -iLevel;
     2216                }
    21732217                babModel->messageHandler()->setLogLevel(parameters[log].intValue());
    21742218                if (babModel->getNumCols()>2000||babModel->getNumRows()>1500||
     
    22992343                    numberIntegers = babModel->numberIntegers();
    23002344                  }
    2301                   CbcObject ** oldObjects = babModel->objects();
     2345                  OsiObject ** oldObjects = babModel->objects();
    23022346                  // Do sets and priorities
    2303                   CbcObject ** objects = new CbcObject * [numberSOS];
     2347                  OsiObject ** objects = new OsiObject * [numberSOS];
    23042348                  // set old objects to have low priority
    23052349                  int numberOldObjects = babModel->numberObjects();
     
    23132357                    if (originalColumns)
    23142358                      iColumn = originalColumns[iColumn];
    2315                     if (branchDirection)
    2316                       oldObjects[iObj]->setPreferredWay(branchDirection[iColumn]);
     2359                    if (branchDirection) {
     2360                      CbcSimpleInteger * obj =
     2361                        dynamic_cast <CbcSimpleInteger *>(oldObjects[iObj]) ;
     2362                      if (obj) {
     2363                        obj->setPreferredWay(branchDirection[iColumn]);
     2364                      } else {
     2365                        CbcObject * obj =
     2366                          dynamic_cast <CbcObject *>(oldObjects[iObj]) ;
     2367                        assert (obj);
     2368                        obj->setPreferredWay(branchDirection[iColumn]);
     2369                      }
     2370                    }
    23172371                    if (pseudoUp) {
    23182372                      CbcSimpleIntegerPseudoCost * obj1a =
     
    23542408                  if (numberSOS) {
    23552409                    // Do sets and priorities
    2356                     CbcObject ** objects = new CbcObject * [numberSOS];
     2410                    OsiObject ** objects = new OsiObject * [numberSOS];
    23572411                    int iSOS;
    23582412                    if (originalColumns) {
     
    23962450                    delete [] objects;
    23972451                  }
    2398                   CbcObject ** objects = babModel->objects();
     2452                  OsiObject ** objects = babModel->objects();
    23992453                  int numberObjects = babModel->numberObjects();
    24002454                  for (int iObj = 0;iObj<numberObjects;iObj++) {
     
    24082462                    if (originalColumns)
    24092463                      iColumn = originalColumns[iColumn];
    2410                     if (branchDirection)
    2411                       objects[iObj]->setPreferredWay(branchDirection[iColumn]);
     2464                    if (branchDirection) {
     2465                      CbcSimpleInteger * obj =
     2466                        dynamic_cast <CbcSimpleInteger *>(objects[iObj]) ;
     2467                      if (obj) {
     2468                        obj->setPreferredWay(branchDirection[iColumn]);
     2469                      } else {
     2470                        CbcObject * obj =
     2471                          dynamic_cast <CbcObject *>(objects[iObj]) ;
     2472                        assert (obj);
     2473                        obj->setPreferredWay(branchDirection[iColumn]);
     2474                      }
     2475                    }
    24122476                    if (priorities) {
    24132477                      int iPriority = priorities[iColumn];
     
    24552519                }
    24562520#endif               
     2521                if (nodeStrategy) {
     2522                  // change default
     2523                  if (nodeStrategy>1) {
     2524                    // up or down
     2525                    int way = ((nodeStrategy%1)==1) ? -1 : +1;
     2526                    babModel->setPreferredWay(way);
     2527#if 0
     2528                    OsiObject ** objects = babModel->objects();
     2529                    int numberObjects = babModel->numberObjects();
     2530                    for (int iObj = 0;iObj<numberObjects;iObj++) {
     2531                      CbcObject * obj =
     2532                        dynamic_cast <CbcObject *>(objects[iObj]) ;
     2533                      assert (obj);
     2534                      obj->setPreferredWay(way);
     2535                    }
     2536#endif
     2537                  }
     2538                  if (nodeStrategy==1||nodeStrategy>3) {
     2539                    // depth
     2540                    CbcCompareDefault compare;
     2541                    compare.setWeight(-3.0);
     2542                    babModel->setNodeComparison(compare);
     2543                  }
     2544                }
    24572545                if (cppValue>=0) {
    24582546                  int prepro = useStrategy ? -1 : preProcess;
     
    24802568                  strategy.setupPreProcessing(1);
    24812569                  babModel->setStrategy(strategy);
     2570                }
     2571                int testOsiOptions = parameters[whichParam(TESTOSI,numberParameters,parameters)].intValue();
     2572                if (testOsiOptions>0) {
     2573                  printf("Testing OsiObject options %d\n",testOsiOptions);
     2574                  CbcBranchDefaultDecision decision;
     2575                  OsiChooseVariable choose(babModel->solver());
     2576                  decision.setChooseMethod(choose);
     2577                  babModel->setBranchingMethod(decision);
    24822578                }
    24832579                checkSOS(babModel, babModel->solver());
     
    45714667  std::string header[9]=
    45724668  { "","Save values","Redundant save of default values","Set changed values",
    4573     "Redundant set default values","Solve","Restore values","Redundant restore values","Add to model"};
     4669    "Redundant set default values","Solve","Restore values","Redundant restore values","Finish up"};
    45744670  for (int iType=0;iType<9;iType++) {
    45754671    if (!wanted[iType])
  • branches/devel/Cbc/src/Makefile.am

    r438 r439  
    4343        CbcStrategy.cpp CbcStrategy.hpp \
    4444        CbcTree.cpp CbcTree.hpp \
    45         CbcTreeLocal.cpp CbcTreeLocal.hpp \
    46         CoinChooseVariable.cpp CoinChooseVariable.hpp
     45        CbcTreeLocal.cpp CbcTreeLocal.hpp
    4746
    4847# This is for libtool (on Windows)
     
    257256        CbcStrategy.hpp \
    258257        CbcTree.hpp \
    259         CbcTreeLocal.hpp \
    260         CoinChooseVariable.hpp
     258        CbcTreeLocal.hpp
    261259
    262260#############################################################################
  • branches/devel/Cbc/src/Makefile.in

    r438 r439  
    146146        CbcHeuristic.lo CbcHeuristicFPump.lo CbcHeuristicGreedy.lo \
    147147        CbcHeuristicLocal.lo CbcMessage.lo CbcModel.lo CbcNode.lo \
    148         CbcStatistics.lo CbcStrategy.lo CbcTree.lo CbcTreeLocal.lo \
    149         CoinChooseVariable.lo
     148        CbcStatistics.lo CbcStrategy.lo CbcTree.lo CbcTreeLocal.lo
    150149libCbc_la_OBJECTS = $(am_libCbc_la_OBJECTS)
    151150@COIN_HAS_CLP_TRUE@am__EXEEXT_1 = cbc$(EXEEXT)
     
    465464        CbcStrategy.cpp CbcStrategy.hpp \
    466465        CbcTree.cpp CbcTree.hpp \
    467         CbcTreeLocal.cpp CbcTreeLocal.hpp \
    468         CoinChooseVariable.cpp CoinChooseVariable.hpp
     466        CbcTreeLocal.cpp CbcTreeLocal.hpp
    469467
    470468
     
    575573        CbcStrategy.hpp \
    576574        CbcTree.hpp \
    577         CbcTreeLocal.hpp \
    578         CoinChooseVariable.hpp
     575        CbcTreeLocal.hpp
    579576
    580577
     
    714711@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcTreeLocal.Plo@am__quote@
    715712@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Cbc_ampl.Po@am__quote@
    716 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CoinChooseVariable.Plo@am__quote@
    717713@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CoinSolve.Po@am__quote@
    718714@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unitTest.Po@am__quote@
Note: See TracChangeset for help on using the changeset viewer.