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

towards common use with other solvers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/devel/Cbc/src/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}
Note: See TracChangeset for help on using the changeset viewer.