Changeset 122 for trunk


Ignore:
Timestamp:
May 6, 2005 10:23:53 AM (15 years ago)
Author:
forrest
Message:

major changes

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/CbcBranchActual.cpp

    r104 r122  
    347347    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
    348348    memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
    349     weights_ = new double[numberMembers_];
    350     memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
    351349  } else {
    352350    members_ = NULL;
     
    376374      weights_ = new double[numberMembers_];
    377375      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
    378       memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
    379       weights_ = new double[numberMembers_];
    380376      memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
    381377    } else {
     
    416412    int iColumn = members_[j];
    417413    if (lower[iColumn]&&(lower[iColumn]!=1.0||sosType_!=1))
    418       throw CoinError("Non zero lower bound in SOS","constructor","CbcSOS");
     414      throw CoinError("Non zero lower bound in SOS","infeasibility","CbcSOS");
    419415    if (lastWeight>=weights_[j]-1.0e-7)
    420       throw CoinError("Weights too close together in SOS","constructor","CbcSOS");
     416      throw CoinError("Weights too close together in SOS","infeasibility","CbcSOS");
    421417    double value = CoinMax(0.0,solution[iColumn]);
    422418    sum += value;
     
    17361732  :CbcBranchDecision()
    17371733{
    1738   bestCriterion_ = 0.0;
    1739   bestChangeUp_ = 0.0;
    1740   bestNumberUp_ = 0;
    1741   bestChangeDown_ = 0.0;
    1742   bestNumberDown_ = 0;
    1743   bestObject_ = NULL;
    17441734}
    17451735
     
    17491739  :CbcBranchDecision()
    17501740{
    1751   bestCriterion_ = rhs.bestCriterion_;
    1752   bestChangeUp_ = rhs.bestChangeUp_;
    1753   bestNumberUp_ = rhs.bestNumberUp_;
    1754   bestChangeDown_ = rhs.bestChangeDown_;
    1755   bestNumberDown_ = rhs.bestNumberDown_;
    1756   bestObject_ = rhs.bestObject_;
    17571741}
    17581742
     
    17721756CbcBranchDefaultDecision::initialize(CbcModel * model)
    17731757{
    1774   bestCriterion_ = 0.0;
    1775   bestChangeUp_ = 0.0;
    1776   bestNumberUp_ = 0;
    1777   bestChangeDown_ = 0.0;
    1778   bestNumberDown_ = 0;
    1779   bestObject_ = NULL;
    17801758}
    17811759
     
    17941772                            double changeDn, int numInfDn)
    17951773{
    1796   bool beforeSolution = thisOne->model()->getSolutionCount()==
    1797     thisOne->model()->getNumberHeuristicSolutions();;
    1798   int betterWay=0;
    1799   if (beforeSolution) {
    1800     if (!bestObject_) {
    1801       bestNumberUp_=INT_MAX;
    1802       bestNumberDown_=INT_MAX;
    1803     }
    1804     // before solution - choose smallest number
    1805     // could add in depth as well
    1806     int bestNumber = CoinMin(bestNumberUp_,bestNumberDown_);
    1807     if (numInfUp<numInfDn) {
    1808       if (numInfUp<bestNumber) {
    1809         betterWay = 1;
    1810       } else if (numInfUp==bestNumber) {
    1811         if (changeUp<bestCriterion_)
    1812           betterWay=1;
     1774  printf("Now obsolete CbcBranchDefaultDecision::betterBranch\n");
     1775  abort();
     1776  return 0;
     1777}
     1778
     1779/* Compare N branching objects. Return index of best
     1780   and sets way of branching in chosen object.
     1781   
     1782   This routine is used only after strong branching.
     1783   This is reccommended version as it can be more sophisticated
     1784*/
     1785
     1786int
     1787CbcBranchDefaultDecision::bestBranch (CbcBranchingObject ** objects, int numberObjects,
     1788                                   int numberUnsatisfied,
     1789                                   double * changeUp, int * numberInfeasibilitiesUp,
     1790                                   double * changeDown, int * numberInfeasibilitiesDown,
     1791                                   double objectiveValue)
     1792{
     1793
     1794  int bestWay=0;
     1795  int whichObject = -1;
     1796  if (numberObjects) {
     1797    CbcModel * model = objects[0]->model();
     1798    // at continuous
     1799    //double continuousObjective = model->getContinuousObjective();
     1800    //int continuousInfeasibilities = model->getContinuousInfeasibilities();
     1801   
     1802    // average cost to get rid of infeasibility
     1803    //double averageCostPerInfeasibility =
     1804    //(objectiveValue-continuousObjective)/
     1805    //(double) (abs(continuousInfeasibilities-numberUnsatisfied)+1);
     1806    /* beforeSolution is :
     1807       0 - before any solution
     1808       n - n heuristic solutions but no branched one
     1809       -1 - branched solution found
     1810    */
     1811    int numberSolutions = model->getSolutionCount();
     1812    double cutoff = model->getCutoff();
     1813    int method=0;
     1814    int i;
     1815    if (numberSolutions) {
     1816      int numberHeuristic = model->getNumberHeuristicSolutions();
     1817      if (numberHeuristic<numberSolutions) {
     1818        method = 1;
     1819      } else {
     1820        method = 2;
     1821        // look further
     1822        for ( i = 0 ; i < numberObjects ; i++) {
     1823          int numberNext = numberInfeasibilitiesUp[i];
     1824         
     1825          if (numberNext<numberUnsatisfied) {
     1826            int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
     1827            double perUnsatisfied = changeUp[i]/(double) numberUp;
     1828            double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
     1829            if (estimatedObjective<cutoff)
     1830              method=3;
     1831          }
     1832          numberNext = numberInfeasibilitiesDown[i];
     1833          if (numberNext<numberUnsatisfied) {
     1834            int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
     1835            double perUnsatisfied = changeDown[i]/(double) numberDown;
     1836            double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
     1837            if (estimatedObjective<cutoff)
     1838              method=3;
     1839          }
     1840        }
    18131841      }
    1814     } else if (numInfUp>numInfDn) {
    1815       if (numInfDn<bestNumber) {
    1816         betterWay = -1;
    1817       } else if (numInfDn==bestNumber) {
    1818         if (changeDn<bestCriterion_)
    1819           betterWay=-1;
     1842      method=2;
     1843    } else {
     1844      method = 0;
     1845    }
     1846    // Uncomment next to force method 4
     1847    //method=4;
     1848    /* Methods :
     1849       0 - fewest infeasibilities
     1850       1 - largest min change in objective
     1851       2 - as 1 but use sum of changes if min close
     1852       3 - predicted best solution
     1853       4 - take cheapest up branch if infeasibilities same
     1854    */
     1855    int bestNumber=INT_MAX;
     1856    double bestCriterion=-1.0e50;
     1857    double alternativeCriterion = -1.0;
     1858    double bestEstimate = 1.0e100;
     1859    switch (method) {
     1860    case 0:
     1861      // could add in depth as well
     1862      for ( i = 0 ; i < numberObjects ; i++) {
     1863        int thisNumber = min(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
     1864        if (thisNumber<=bestNumber) {
     1865          int betterWay=0;
     1866          if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
     1867            if (numberInfeasibilitiesUp[i]<bestNumber) {
     1868              betterWay = 1;
     1869            } else {
     1870              if (changeUp[i]<bestCriterion)
     1871                betterWay=1;
     1872            }
     1873          } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
     1874            if (numberInfeasibilitiesDown[i]<bestNumber) {
     1875              betterWay = -1;
     1876            } else {
     1877              if (changeDown[i]<bestCriterion)
     1878                betterWay=-1;
     1879            }
     1880          } else {
     1881            // up and down have same number
     1882            bool better=false;
     1883            if (numberInfeasibilitiesUp[i]<bestNumber) {
     1884              better=true;
     1885            } else if (numberInfeasibilitiesUp[i]==bestNumber) {
     1886              if (min(changeUp[i],changeDown[i])<bestCriterion)
     1887                better=true;;
     1888            }
     1889            if (better) {
     1890              // see which way
     1891              if (changeUp[i]<=changeDown[i])
     1892                betterWay=1;
     1893              else
     1894                betterWay=-1;
     1895            }
     1896          }
     1897          if (betterWay) {
     1898            bestCriterion = min(changeUp[i],changeDown[i]);
     1899            bestNumber = thisNumber;
     1900            whichObject = i;
     1901            bestWay = betterWay;
     1902          }
     1903        }
    18201904      }
    1821     } else {
    1822       // up and down have same number
    1823       bool better=false;
    1824       if (numInfUp<bestNumber) {
    1825         better=true;
    1826       } else if (numInfUp==bestNumber) {
    1827         if (min(changeUp,changeDn)<bestCriterion_)
    1828           better=true;;
     1905      break;
     1906    case 1:
     1907      for ( i = 0 ; i < numberObjects ; i++) {
     1908        int betterWay=0;
     1909        if (changeUp[i]<=changeDown[i]) {
     1910          if (changeUp[i]>bestCriterion)
     1911            betterWay=1;
     1912        } else {
     1913          if (changeDown[i]>bestCriterion)
     1914            betterWay=-1;
     1915        }
     1916        if (betterWay) {
     1917          bestCriterion = min(changeUp[i],changeDown[i]);
     1918          whichObject = i;
     1919          bestWay = betterWay;
     1920        }
    18291921      }
    1830       if (better) {
    1831         // see which way
    1832         if (changeUp<=changeDn)
    1833           betterWay=1;
    1834         else
    1835           betterWay=-1;
     1922      break;
     1923    case 2:
     1924      for ( i = 0 ; i < numberObjects ; i++) {
     1925        double change = min(changeUp[i],changeDown[i]);
     1926        double sum = changeUp[i] + changeDown[i];
     1927        bool take=false;
     1928        if (change>1.1*bestCriterion)
     1929          take=true;
     1930        else if (change>0.9*bestCriterion&&sum+change>bestCriterion+alternativeCriterion)
     1931          take=true;
     1932        if (take) {
     1933          if (changeUp[i]<=changeDown[i]) {
     1934            if (changeUp[i]>bestCriterion)
     1935              bestWay=1;
     1936          } else {
     1937            if (changeDown[i]>bestCriterion)
     1938              bestWay=-1;
     1939          }
     1940          bestCriterion = change;
     1941          alternativeCriterion = sum;
     1942          whichObject = i;
     1943        }
    18361944      }
    1837     }
    1838   } else {
    1839     if (!bestObject_) {
    1840       bestCriterion_=-1.0;
    1841     }
    1842     // got a solution
    1843     if (changeUp<=changeDn) {
    1844       if (changeUp>bestCriterion_)
    1845         betterWay=1;
    1846     } else {
    1847       if (changeDn>bestCriterion_)
    1848         betterWay=-1;
    1849     }
    1850   }
    1851   if (betterWay) {
    1852     bestCriterion_ = CoinMin(changeUp,changeDn);
    1853     bestChangeUp_ = changeUp;
    1854     bestNumberUp_ = numInfUp;
    1855     bestChangeDown_ = changeDn;
    1856     bestNumberDown_ = numInfDn;
    1857     bestObject_=thisOne;
    1858   }
    1859   return betterWay;
    1860 }
     1945      break;
     1946    case 3:
     1947      for ( i = 0 ; i < numberObjects ; i++) {
     1948        int numberNext = numberInfeasibilitiesUp[i];
     1949       
     1950        if (numberNext<numberUnsatisfied) {
     1951          int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
     1952          double perUnsatisfied = changeUp[i]/(double) numberUp;
     1953          double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
     1954          if (estimatedObjective<bestEstimate) {
     1955            bestEstimate = estimatedObjective;
     1956            bestWay=1;
     1957            whichObject=i;
     1958          }
     1959        }
     1960        numberNext = numberInfeasibilitiesDown[i];
     1961        if (numberNext<numberUnsatisfied) {
     1962          int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
     1963          double perUnsatisfied = changeDown[i]/(double) numberDown;
     1964          double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
     1965          if (estimatedObjective<bestEstimate) {
     1966            bestEstimate = estimatedObjective;
     1967            bestWay=-1;
     1968            whichObject=i;
     1969          }
     1970        }
     1971      }
     1972      break;
     1973    case 4:
     1974      // if number infeas same then cheapest up
     1975      // first get best number or when going down
     1976      // now choose smallest change up amongst equal number infeas
     1977      for ( i = 0 ; i < numberObjects ; i++) {
     1978        int thisNumber = min(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
     1979        if (thisNumber<=bestNumber) {
     1980          int betterWay=0;
     1981          if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
     1982            if (numberInfeasibilitiesUp[i]<bestNumber) {
     1983              betterWay = 1;
     1984            } else {
     1985              if (changeUp[i]<bestCriterion)
     1986                betterWay=1;
     1987            }
     1988          } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
     1989            if (numberInfeasibilitiesDown[i]<bestNumber) {
     1990              betterWay = -1;
     1991            } else {
     1992              if (changeDown[i]<bestCriterion)
     1993                betterWay=-1;
     1994            }
     1995          } else {
     1996            // up and down have same number
     1997            bool better=false;
     1998            if (numberInfeasibilitiesUp[i]<bestNumber) {
     1999              better=true;
     2000            } else if (numberInfeasibilitiesUp[i]==bestNumber) {
     2001              if (min(changeUp[i],changeDown[i])<bestCriterion)
     2002                better=true;;
     2003            }
     2004            if (better) {
     2005              // see which way
     2006              if (changeUp[i]<=changeDown[i])
     2007                betterWay=1;
     2008              else
     2009                betterWay=-1;
     2010            }
     2011          }
     2012          if (betterWay) {
     2013            bestCriterion = min(changeUp[i],changeDown[i]);
     2014            bestNumber = thisNumber;
     2015            whichObject = i;
     2016            bestWay = betterWay;
     2017          }
     2018        }
     2019      }
     2020      bestCriterion=1.0e50;
     2021      for ( i = 0 ; i < numberObjects ; i++) {
     2022        int thisNumber = numberInfeasibilitiesUp[i];
     2023        if (thisNumber==bestNumber&&changeUp) {
     2024          if (changeUp[i]<bestCriterion) {
     2025            bestCriterion = changeUp[i];
     2026            whichObject = i;
     2027            bestWay = 1;
     2028          }
     2029        }
     2030      }
     2031      break;
     2032    }
     2033    // set way in best
     2034    if (whichObject>=0)
     2035      objects[whichObject]->way(bestWay);
     2036  }
     2037  return whichObject;
     2038}
     2039
    18612040// Default Constructor
    18622041CbcFollowOn::CbcFollowOn ()
     
    18742053  matrix_ = *solver->getMatrixByCol();
    18752054  matrix_.removeGaps();
     2055  matrix_.setExtraGap(0.0);
    18762056  matrixByRow_ = *solver->getMatrixByRow();
    18772057  int numberRows = matrix_.getNumRows();
  • trunk/CbcBranchBase.cpp

    r74 r122  
    1818CbcObject::CbcObject()
    1919  :model_(NULL),
    20    id_(-1)
     20   id_(-1),
     21   priority_(1000)
    2122{
    2223}
     
    2627:
    2728  model_(model),
    28   id_(-1)
     29  id_(-1),
     30  priority_(1000)
    2931{
    3032}
     
    4143  model_ = rhs.model_;
    4244  id_ = rhs.id_;
     45  priority_ = rhs.priority_;
    4346}
    4447
     
    5053    model_ = rhs.model_;
    5154    id_ = rhs.id_;
     55    priority_ = rhs.priority_;
    5256  }
    5357  return *this;
  • trunk/CbcModel.cpp

    r108 r122  
    795795    tree_->pop() ;
    796796    bool nodeOnTree=false; // Node has been popped
    797 
     797    // Say not on optimal path
     798    bool onOptimalPath=false;
    798799#   ifdef CHECK_NODE
    799800/*
     
    854855        const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ;
    855856        if (debugger)
    856           { if(debugger->onOptimalPath(*solver_))
     857          { if(debugger->onOptimalPath(*solver_)) {
     858            onOptimalPath=true;
    857859            printf("On optimal path\n") ;
    858           else
     860          } else {
    859861            printf("Not on optimal path\n") ; }
     862          }
    860863      }
    861864/*
     
    893896        use variable() (i.e., presence of a branching variable). Equivalent?
    894897*/
     898        if (onOptimalPath)
     899        assert (feasible);
    895900        if (feasible)
    896901        { newNode = new CbcNode ;
     
    908913          {
    909914            anyAction = newNode->chooseBranch(this,node,numberPassesLeft) ;
     915            if (onOptimalPath)
     916              assert (anyAction!=-2);
    910917            numberPassesLeft--;
    911918            if (numberPassesLeft<=-1) {
     
    916923            }
    917924            if (anyAction == -1)
    918             { feasible = resolve() ;
     925            {
     926              // can do quick optimality check
     927              int easy=2;
     928              solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
     929              feasible = resolve() ;
     930              solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
    919931              resolved = true ;
    920932              if (feasible)
     
    12661278  object_(NULL),
    12671279  originalColumns_(NULL),
    1268   priority_(NULL),
    12691280  howOftenGlobalScan_(1),
    12701281  numberGlobalViolations_(0),
     
    13411352  object_(NULL),
    13421353  originalColumns_(NULL),
    1343   priority_(NULL),
    13441354  howOftenGlobalScan_(1),
    13451355  numberGlobalViolations_(0),
     
    15531563    object_=NULL;
    15541564  }
    1555   if (rhs.priority_) {
    1556     priority_= new int [numberObjects_];
    1557     memcpy(priority_,rhs.priority_,numberObjects_*sizeof(int));
    1558   } else {
    1559     priority_=NULL;
    1560   }
    15611565  if (!noTree||!rhs.continuousSolver_)
    15621566    solver_ = rhs.solver_->clone();
     
    17701774      object_=NULL;
    17711775    }
    1772     delete [] priority_;
    1773     if (rhs.priority_) {
    1774       priority_= new int [numberObjects_];
    1775       memcpy(priority_,rhs.priority_,numberObjects_*sizeof(int));
    1776     } else {
    1777       priority_=NULL;
    1778     }
    17791776    delete [] originalColumns_;
    17801777    if (rhs.originalColumns_) {
     
    18821879  delete [] object_;
    18831880  object_=NULL;
    1884   delete [] priority_;
    1885   priority_=NULL;
    18861881  delete [] originalColumns_;
    18871882  originalColumns_=NULL;
     
    24902485              const int * column = thisCut.row().getIndices();
    24912486              const double * element = thisCut.row().getElements();
     2487              //assert (n);
    24922488              for (int i=0;i<n;i++) {
    24932489                int iColumn = column[i];
    24942490                double value = element[i];
    2495                 assert(fabs(value)>1.0e-12);
     2491                assert(fabs(value)>1.0e-12&&fabs(value)<1.0e20);
    24962492              }
    24972493            }
     
    31143110      {
    31153111        phase_=3;
     3112        // can do quick optimality check
     3113        int easy=2;
     3114        solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
    31163115        solver_->resolve() ;
     3116        solver_->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
    31173117        if (solver_->getIterationCount() == 0)
    31183118        { needPurge = false ; }
     
    34313431    newModel->object_=NULL;
    34323432    newModel->findIntegers(true); //Set up all integer objects
    3433     if (priority_) {
    3434       // old model had priorities
    3435       delete [] newModel->priority_;
    3436       newModel->priority_ = new int[newModel->numberIntegers_+numberCliques];
    3437       memcpy(newModel->priority_,priority_,numberIntegers_*sizeof(int));
    3438       for (i=numberIntegers_;i<newModel->numberIntegers_+numberCliques;i++)
    3439         newModel->priority_[i]=defaultValue;
     3433    for (i=0;i<numberIntegers_;i++) {
     3434      newModel->modifiableObject(i)->setPriority(object_[i]->priority());
    34403435    }
    34413436    if (originalColumns_) {
     
    34643459    }
    34653460    delete [] object;
    3466     if (priority_) {
    3467       // model had priorities
    3468       int * temp = new int[numberIntegers_+numberCliques];
    3469       memcpy(temp,priority_,numberIntegers_*sizeof(int));
    3470       delete [] priority_;
    3471       priority_=temp;
    3472       for (i=numberIntegers_;i<numberIntegers_+numberCliques;i++)
    3473         priority_[i]=defaultValue;
    3474     }
    34753461    delete [] rows;
    34763462    delete [] element;
     
    34903476void
    34913477CbcModel::passInPriorities (const int * priorities,
    3492                             bool ifObject, int defaultValue)
     3478                            bool ifObject)
    34933479{
    34943480  findIntegers(false);
    34953481  int i;
    3496   if (!priority_) {
    3497     priority_ = new int[numberObjects_];
    3498     for (i=0;i<numberObjects_;i++)
    3499       priority_[i]=defaultValue;
    3500   }
    35013482  if (priorities) {
    35023483    int i0=0;
    35033484    int i1=numberObjects_-1;
    35043485    if (ifObject) {
    3505       /* priority_ may be wrong size.  This fix may not cope with
    3506          all possibilities but should for normal use. */
    3507       int * temp = new int[numberObjects_];
    3508       memcpy(temp,priority_,numberIntegers_*sizeof(int));
    3509       delete [] priority_;
    3510       priority_=temp;
    3511       memcpy(priority_+numberIntegers_,priorities,
    3512              (numberObjects_-numberIntegers_)*sizeof(int));
     3486      for (i=numberIntegers_;i<numberObjects_;i++) {
     3487        object_[i]->setPriority(priorities[i-numberIntegers_]);
     3488      }
    35133489      i0=numberIntegers_;
    35143490    } else {
    3515       memcpy(priority_,priorities,numberIntegers_*sizeof(int));
     3491      for (i=0;i<numberIntegers_;i++) {
     3492        object_[i]->setPriority(priorities[i]);
     3493      }
    35163494      i1=numberIntegers_-1;
    35173495    }
     
    35263504CbcModel::deleteObjects()
    35273505{
    3528   delete [] priority_;
    3529   priority_=NULL;
    35303506  int i;
    35313507  for (i=0;i<numberObjects_;i++)
     
    45394515  findIntegers(true);
    45404516  // save original integers
    4541   int * originalPriority = NULL;
    45424517  int * originalIntegers = new int[numberIntegers_];
    45434518  int originalNumberIntegers = numberIntegers_;
    45444519  memcpy(originalIntegers,integerVariable_,numberIntegers_*sizeof(int));
    45454520
    4546   if (priority_) {
    4547     originalPriority = new int[numberIntegers_];
    4548     memcpy(originalPriority,priority_,numberIntegers_*sizeof(int));
    4549     delete [] priority_;
    4550     priority_=NULL;
    4551   }
    45524521  int todo=20;
    45534522  if (weak)
     
    47634732  //solver_->writeMps("xx");
    47644733  delete cleanModel;
    4765   // create new priorities and save list of original columns
    4766   if (originalPriority) {
    4767     priority_ = new int[numberIntegers_];
    4768     int i;
    4769     int number=0;
    4770     // integer variables are in same order if they exist at all
    4771     for (i=0;i<originalNumberIntegers;i++) {
    4772       iColumn = originalIntegers[i];
    4773       int newColumn=original[iColumn];
    4774       if (newColumn >= 0)
    4775         priority_[number++]=originalPriority[i];
    4776     }
    4777     assert (number==numberIntegers_);
    4778     delete [] originalPriority;
    4779   }
    47804734  delete [] originalIntegers;
    47814735  numberColumns = getNumCols();
     
    49014855// Make sure region there
    49024856void
    4903 CbcModel::reserveCurrentSolution()
     4857CbcModel::reserveCurrentSolution(const double * solution)
    49044858{
    49054859  int numberColumns = getNumCols() ;
    49064860  if (!currentSolution_)
    49074861    currentSolution_ = new double[numberColumns] ;
     4862  if (solution)
     4863    memcpy(currentSolution_,solution,numberColumns*sizeof(double));
    49084864}
    49094865/* For passing in an CbcModel to do a sub Tree (with derived tree handlers).
  • trunk/CbcNode.cpp

    r118 r122  
    2323#include "CbcMessage.hpp"
    2424#include "OsiClpSolverInterface.hpp"
     25#include "ClpSimplexOther.hpp"
    2526using namespace std;
    2627#include "CglCutGenerator.hpp"
     
    861862  bool beforeSolution = model->getSolutionCount()==0;
    862863  int numberStrong=model->numberStrong();
     864  int saveNumberStrong=numberStrong;
    863865  int numberObjects = model->numberObjects();
    864866  bool checkFeasibility = numberObjects>model->numberIntegers();
     
    869871
    870872  // Save solution in case heuristics need good solution later
    871 
     873 
    872874  double * saveSolution = new double[numberColumns];
    873875  memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
    874 
    875 /*
    876   Get a branching decision object. Use the default decision criteria unless
    877   the user has loaded a decision method into the model.
    878 */
     876 
     877  /*
     878    Get a branching decision object. Use the default decision criteria unless
     879    the user has loaded a decision method into the model.
     880  */
    879881  CbcBranchDecision *decision = model->branchingMethod();
    880882  if (!decision)
     
    894896    int numItersDown; // number of iterations in solver
    895897    int objectNumber; // Which object it is
     898    int fix; // 0 if no fix, 1 if we can fix up, -1 if we can fix down
    896899  } Strong;
    897900  Strong * choice = new Strong[maximumStrong];
     
    900903    saveUpper[i] = upper[i];
    901904  }
    902   // Some objects may compute an estimate of best solution from here
     905  // May go round twice if strong branching fixes all local candidates
     906  bool finished=false;
    903907  double estimatedDegradation=0.0;
    904   int numberIntegerInfeasibilities=0; // without odd ones
    905 
    906   // We may go round this loop twice (only if we think we have solution)
    907   for (int iPass=0;iPass<2;iPass++) {
    908 
    909     // compute current state
    910     int numberObjectInfeasibilities; // just odd ones
    911     model->feasibleSolution(
    912                             numberIntegerInfeasibilities,
    913                             numberObjectInfeasibilities);
    914     // If forcePriority > 0 then we want best solution
    915     const double * bestSolution = NULL;
    916     int hotstartStrategy=model->getHotstartStrategy();
    917     if (hotstartStrategy>0) {
    918       bestSolution = model->bestSolution();
    919     }
    920    
     908  while(!finished) {
     909    finished=true;
    921910    // Some objects may compute an estimate of best solution from here
    922911    estimatedDegradation=0.0;
    923     numberUnsatisfied_ = 0;
    924     int bestPriority=INT_MAX;
    925     /*
    926       Scan for branching objects that indicate infeasibility. Choose the best
    927       maximumStrong candidates, using priority as the first criteria, then
    928       integer infeasibility.
     912    int numberIntegerInfeasibilities=0; // without odd ones
     913   
     914    // We may go round this loop twice (only if we think we have solution)
     915    for (int iPass=0;iPass<2;iPass++) {
    929916     
    930       The algorithm is to fill the choice array with a set of good candidates (by
    931       infeasibility) with priority bestPriority.  Finding a candidate with
    932       priority better (less) than bestPriority flushes the choice array. (This
    933       serves as initialization when the first candidate is found.)
     917      // compute current state
     918      int numberObjectInfeasibilities; // just odd ones
     919      model->feasibleSolution(
     920                              numberIntegerInfeasibilities,
     921                              numberObjectInfeasibilities);
     922      // If forcePriority > 0 then we want best solution
     923      const double * bestSolution = NULL;
     924      int hotstartStrategy=model->getHotstartStrategy();
     925      if (hotstartStrategy>0) {
     926        bestSolution = model->bestSolution();
     927      }
    934928     
    935       A new candidate is added to choices only if its infeasibility exceeds the
    936       current max infeasibility (mostAway). When a candidate is added, it
    937       replaces the candidate with the smallest infeasibility (tracked by
    938       iSmallest).
    939     */
    940     int iSmallest = 0;
    941     double mostAway = 1.0e-100;
    942     for (i = 0 ; i < maximumStrong ; i++) choice[i].possibleBranch = NULL ;
    943     numberStrong=0;
    944     for (i=0;i<numberObjects;i++) {
    945       const CbcObject * object = model->object(i);
    946       int preferredWay;
    947       double infeasibility = object->infeasibility(preferredWay);
    948       int priorityLevel = model->priority(i);
    949       if (bestSolution) {
    950         // we are doing hot start
    951         const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
    952         if (thisOne) {
    953           int iColumn = thisOne->modelSequence();
    954           if (saveUpper[iColumn]>saveLower[iColumn]) {
    955             double value = saveSolution[iColumn];
    956             double targetValue = bestSolution[iColumn];
    957             //double originalLower = thisOne->originalLower();
    958             //double originalUpper = thisOne->originalUpper();
    959             // switch off if not possible
    960             if (targetValue>=saveLower[iColumn]&&targetValue<=saveUpper[iColumn]) {
    961               /* priority outranks rest always if hotstartStrategy >1
    962                  otherwise can be downgraded if at correct level.
    963                  Infeasibility may be increased by targetValue to choose 1.0 values first.
    964               */
    965               if (fabs(value-targetValue)>integerTolerance) {
    966                 if (value>targetValue) {
    967                   infeasibility += value;
    968                   preferredWay=-1;
     929      // Some objects may compute an estimate of best solution from here
     930      estimatedDegradation=0.0;
     931      numberUnsatisfied_ = 0;
     932      int bestPriority=INT_MAX;
     933      /*
     934        Scan for branching objects that indicate infeasibility. Choose the best
     935        maximumStrong candidates, using priority as the first criteria, then
     936        integer infeasibility.
     937       
     938        The algorithm is to fill the choice array with a set of good candidates (by
     939        infeasibility) with priority bestPriority.  Finding a candidate with
     940        priority better (less) than bestPriority flushes the choice array. (This
     941        serves as initialization when the first candidate is found.)
     942       
     943        A new candidate is added to choices only if its infeasibility exceeds the
     944        current max infeasibility (mostAway). When a candidate is added, it
     945        replaces the candidate with the smallest infeasibility (tracked by
     946        iSmallest).
     947      */
     948      int iSmallest = 0;
     949      double mostAway = 1.0e-100;
     950      for (i = 0 ; i < maximumStrong ; i++) choice[i].possibleBranch = NULL ;
     951      numberStrong=0;
     952      for (i=0;i<numberObjects;i++) {
     953        const CbcObject * object = model->object(i);
     954        int preferredWay;
     955        double infeasibility = object->infeasibility(preferredWay);
     956        int priorityLevel = object->priority();
     957        if (bestSolution) {
     958          // we are doing hot start
     959          const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
     960          if (thisOne) {
     961            int iColumn = thisOne->modelSequence();
     962            if (saveUpper[iColumn]>saveLower[iColumn]) {
     963              double value = saveSolution[iColumn];
     964              double targetValue = bestSolution[iColumn];
     965              //double originalLower = thisOne->originalLower();
     966              //double originalUpper = thisOne->originalUpper();
     967              // switch off if not possible
     968              if (targetValue>=saveLower[iColumn]&&targetValue<=saveUpper[iColumn]) {
     969                /* priority outranks rest always if hotstartStrategy >1
     970                   otherwise can be downgraded if at correct level.
     971                   Infeasibility may be increased by targetValue to choose 1.0 values first.
     972                */
     973                if (fabs(value-targetValue)>integerTolerance) {
     974                  if (value>targetValue) {
     975                    infeasibility += value;
     976                    preferredWay=-1;
     977                  } else {
     978                    infeasibility += targetValue;
     979                    preferredWay=1;
     980                  }
     981                } else if (hotstartStrategy>1) {
     982                  if (targetValue==saveLower[iColumn]) {
     983                    infeasibility += integerTolerance+1.0e-12;
     984                    preferredWay=-1;
     985                  } else if (targetValue==saveUpper[iColumn]) {
     986                    infeasibility += integerTolerance+1.0e-12;
     987                    preferredWay=1;
     988                  } else {
     989                    infeasibility += integerTolerance+1.0e-12;
     990                    preferredWay=1;
     991                  }
    969992                } else {
    970                   infeasibility += targetValue;
    971                   preferredWay=1;
    972                 }
    973               } else if (hotstartStrategy>1) {
    974                 if (targetValue==saveLower[iColumn]) {
    975                   infeasibility += integerTolerance+1.0e-12;
    976                   preferredWay=-1;
    977                 } else if (targetValue==saveUpper[iColumn]) {
    978                   infeasibility += integerTolerance+1.0e-12;
    979                   preferredWay=1;
    980                 } else {
    981                   infeasibility += integerTolerance+1.0e-12;
    982                   preferredWay=1;
     993                  priorityLevel += 10000000;
    983994                }
    984995              } else {
    985                 priorityLevel += 10000000;
     996                // switch off if not possible
     997                bestSolution=NULL;
     998                model->setHotstartStrategy(0);
    986999              }
    987             } else {
    988               // switch off if not possible
    989               bestSolution=NULL;
    990               model->setHotstartStrategy(0);
    9911000            }
    9921001          }
    9931002        }
     1003        if (infeasibility) {
     1004          // Increase estimated degradation to solution
     1005          estimatedDegradation += CoinMin(object->upEstimate(),object->downEstimate());
     1006          numberUnsatisfied_++;
     1007          // Better priority? Flush choices.
     1008          if (priorityLevel<bestPriority) {
     1009            int j;
     1010            iSmallest=0;
     1011            for (j=0;j<maximumStrong;j++) {
     1012              choice[j].upMovement=0.0;
     1013              delete choice[j].possibleBranch;
     1014              choice[j].possibleBranch=NULL;
     1015            }
     1016            bestPriority = priorityLevel;
     1017            mostAway=1.0e-100;
     1018            numberStrong=0;
     1019          } else if (priorityLevel>bestPriority) {
     1020            continue;
     1021          }
     1022          // Check for suitability based on infeasibility.
     1023          if (infeasibility>mostAway) {
     1024            //add to list
     1025            choice[iSmallest].upMovement=infeasibility;
     1026            delete choice[iSmallest].possibleBranch;
     1027            choice[iSmallest].possibleBranch=object->createBranch(preferredWay);
     1028            numberStrong = CoinMax(numberStrong,iSmallest+1);
     1029            // Save which object it was
     1030            choice[iSmallest].objectNumber=i;
     1031            int j;
     1032            iSmallest=-1;
     1033            mostAway = 1.0e50;
     1034            for (j=0;j<maximumStrong;j++) {
     1035              if (choice[j].upMovement<mostAway) {
     1036                mostAway=choice[j].upMovement;
     1037                iSmallest=j;
     1038              }
     1039            }
     1040          }
     1041        }
    9941042      }
    995       if (infeasibility) {
    996         // Increase estimated degradation to solution
    997         estimatedDegradation += CoinMin(object->upEstimate(),object->downEstimate());
    998         numberUnsatisfied_++;
    999         // Better priority? Flush choices.
    1000         if (priorityLevel<bestPriority) {
    1001           int j;
    1002           iSmallest=0;
    1003           for (j=0;j<maximumStrong;j++) {
    1004             choice[j].upMovement=0.0;
    1005             delete choice[j].possibleBranch;
    1006             choice[j].possibleBranch=NULL;
    1007           }
    1008           bestPriority = priorityLevel;
    1009           mostAway=1.0e-100;
    1010           numberStrong=0;
    1011         } else if (priorityLevel>bestPriority) {
    1012           continue;
    1013         }
    1014         // Check for suitability based on infeasibility.
    1015         if (infeasibility>mostAway) {
    1016           //add to list
    1017           choice[iSmallest].upMovement=infeasibility;
    1018           delete choice[iSmallest].possibleBranch;
    1019           choice[iSmallest].possibleBranch=object->createBranch(preferredWay);
    1020           numberStrong = CoinMax(numberStrong,iSmallest+1);
    1021           // Save which object it was
    1022           choice[iSmallest].objectNumber=i;
    1023           int j;
    1024           iSmallest=-1;
    1025           mostAway = 1.0e50;
    1026           for (j=0;j<maximumStrong;j++) {
    1027             if (choice[j].upMovement<mostAway) {
    1028               mostAway=choice[j].upMovement;
    1029               iSmallest=j;
    1030             }
    1031           }
     1043      if (numberUnsatisfied_) {
     1044        // some infeasibilities - go to next steps
     1045        break;
     1046      } else if (!iPass) {
     1047        // looks like a solution - get paranoid
     1048        bool roundAgain=false;
     1049        // get basis
     1050        CoinWarmStartBasis * ws = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
     1051        if (!ws)
     1052          break;
     1053        for (i=0;i<numberColumns;i++) {
     1054          double value = saveSolution[i];
     1055          if (value<lower[i]) {
     1056            saveSolution[i]=lower[i];
     1057            roundAgain=true;
     1058            ws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
     1059          } else if (value>upper[i]) {
     1060            saveSolution[i]=upper[i];
     1061            roundAgain=true;
     1062            ws->setStructStatus(i,CoinWarmStartBasis::atUpperBound);
     1063          }
     1064        }
     1065        if (roundAgain) {
     1066          // restore basis
     1067          solver->setWarmStart(ws);
     1068          delete ws;
     1069          solver->resolve();
     1070          memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
     1071          if (!solver->isProvenOptimal()) {
     1072            // infeasible
     1073            anyAction=-2;
     1074            break;
     1075          }
     1076        } else {
     1077          delete ws;
     1078          break;
    10321079        }
    10331080      }
    10341081    }
    1035     if (numberUnsatisfied_) {
    1036       // some infeasibilities - go to next steps
    1037       break;
    1038     } else if (!iPass) {
    1039       // looks like a solution - get paranoid
    1040       bool roundAgain=false;
    1041       // get basis
    1042       CoinWarmStartBasis * ws = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
    1043       if (!ws)
    1044         break;
    1045       for (i=0;i<numberColumns;i++) {
    1046         double value = saveSolution[i];
    1047         if (value<lower[i]) {
    1048           saveSolution[i]=lower[i];
    1049           roundAgain=true;
    1050           ws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
    1051         } else if (value>upper[i]) {
    1052           saveSolution[i]=upper[i];
    1053           roundAgain=true;
    1054           ws->setStructStatus(i,CoinWarmStartBasis::atUpperBound);
    1055         }
    1056       }
    1057       if (roundAgain) {
    1058         // restore basis
    1059         solver->setWarmStart(ws);
    1060         delete ws;
    1061         solver->resolve();
    1062         memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
    1063         if (!solver->isProvenOptimal()) {
    1064           // infeasible
    1065           anyAction=-2;
    1066           break;
    1067         }
    1068       } else {
    1069         delete ws;
    1070         break;
     1082    /* Some solvers can do the strong branching calculations faster if
     1083       they do them all at once.  At present only Clp does for ordinary
     1084       integers but I think this coding would be easy to modify
     1085    */
     1086    bool allNormal=true; // to say if we can do fast strong branching
     1087    // Say which one will be best
     1088    int bestChoice=0;
     1089    double worstInfeasibility=0.0;
     1090    for (i=0;i<numberStrong;i++) {
     1091      choice[i].numIntInfeasUp = numberUnsatisfied_;
     1092      choice[i].numIntInfeasDown = numberUnsatisfied_;
     1093      choice[i].fix=0; // say not fixed
     1094      if (!dynamic_cast <const CbcSimpleInteger *> (model->object(choice[i].objectNumber)))
     1095        allNormal=false; // Something odd so lets skip clever fast branching
     1096      if ( !model->object(choice[i].objectNumber)->boundBranch())
     1097        numberStrong=0; // switch off
     1098      // Do best choice in case switched off
     1099      if (choice[i].upMovement>worstInfeasibility) {
     1100        worstInfeasibility=choice[i].upMovement;
     1101        bestChoice=i;
    10711102      }
    10721103    }
    1073   }
    1074   /* Some solvers can do the strong branching calculations faster if
    1075      they do them all at once.  At present only Clp does for ordinary
    1076      integers but I think this coding would be easy to modify
    1077   */
    1078   bool allNormal=true; // to say if we can do fast strong branching
    1079   // Say which one will be best
    1080   int bestChoice=0;
    1081   double worstInfeasibility=0.0;
    1082   for (i=0;i<numberStrong;i++) {
    1083     choice[i].numIntInfeasUp = numberUnsatisfied_;
    1084     choice[i].numIntInfeasDown = numberUnsatisfied_;
    1085     if (!dynamic_cast <const CbcSimpleInteger *> (model->object(choice[i].objectNumber)))
    1086       allNormal=false; // Something odd so lets skip clever fast branching
    1087     if ( !model->object(choice[i].objectNumber)->boundBranch())
    1088       numberStrong=0; // switch off
    1089     // Do best choice in case switched off
    1090     if (choice[i].upMovement>worstInfeasibility) {
    1091       worstInfeasibility=choice[i].upMovement;
    1092       bestChoice=i;
    1093     }
    1094   }
    1095   // If we have hit max time don't do strong branching
    1096   bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) >
     1104    // If we have hit max time don't do strong branching
     1105    bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) >
    10971106                        model->getDblParam(CbcModel::CbcMaximumSeconds));
    1098   // also give up if we are looping round too much
    1099   if (hitMaxTime||numberPassesLeft<=0)
    1100     numberStrong=0;
    1101 /*
    1102   Is strong branching enabled? If so, set up and do it. Otherwise, we'll
    1103   fall through to simple branching.
    1104 
    1105   Setup for strong branching involves saving the current basis (for restoration
    1106   afterwards) and setting up for hot starts.
    1107 */
    1108   if (numberStrong&&model->numberStrong()) {
    1109    
    1110     bool solveAll=false; // set true to say look at all even if some fixed (experiment)
    1111     // worth trying if too many times
    1112     // Save basis
    1113     CoinWarmStart * ws = solver->getWarmStart();
    1114     // save limit
    1115     int saveLimit;
    1116     solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
    1117     if (beforeSolution)
    1118       solver->setIntParam(OsiMaxNumIterationHotStart,10000); // go to end
    1119 
    1120     /* If we are doing all strong branching in one go then we create new arrays
    1121        to store information.  If clp NULL then doing old way.
    1122        Going down -
    1123        outputSolution[2*i] is final solution.
    1124        outputStuff[2*i] is status (0 - finished, 1 infeas, other unknown
    1125        outputStuff[2*i+numberStrong] is number iterations
    1126        On entry newUpper[i] is new upper bound, on exit obj change
    1127        Going up -
    1128        outputSolution[2*i+1] is final solution.
    1129        outputStuff[2*i+1] is status (0 - finished, 1 infeas, other unknown
    1130        outputStuff[2*i+1+numberStrong] is number iterations
     1107    // also give up if we are looping round too much
     1108    if (hitMaxTime||numberPassesLeft<=0)
     1109      numberStrong=0;
     1110    /*
     1111      Is strong branching enabled? If so, set up and do it. Otherwise, we'll
     1112      fall through to simple branching.
     1113     
     1114      Setup for strong branching involves saving the current basis (for restoration
     1115      afterwards) and setting up for hot starts.
     1116    */
     1117    if (numberStrong&&saveNumberStrong) {
     1118     
     1119      bool solveAll=false; // set true to say look at all even if some fixed (experiment)
     1120      solveAll=true;
     1121      // worth trying if too many times
     1122      // Save basis
     1123      CoinWarmStart * ws = solver->getWarmStart();
     1124      // save limit
     1125      int saveLimit;
     1126      solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
     1127      if (beforeSolution&&saveLimit<100)
     1128        solver->setIntParam(OsiMaxNumIterationHotStart,100); // go to end
     1129     
     1130      /* If we are doing all strong branching in one go then we create new arrays
     1131         to store information.  If clp NULL then doing old way.
     1132         Going down -
     1133         outputSolution[2*i] is final solution.
     1134         outputStuff[2*i] is status (0 - finished, 1 infeas, other unknown
     1135         outputStuff[2*i+numberStrong] is number iterations
     1136         On entry newUpper[i] is new upper bound, on exit obj change
     1137         Going up -
     1138         outputSolution[2*i+1] is final solution.
     1139         outputStuff[2*i+1] is status (0 - finished, 1 infeas, other unknown
     1140         outputStuff[2*i+1+numberStrong] is number iterations
    11311141       On entry newLower[i] is new lower bound, on exit obj change
    1132     */
    1133     OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
    1134     ClpSimplex * clp=NULL;
    1135     double * newLower = NULL;
    1136     double * newUpper = NULL;
    1137     double ** outputSolution=NULL;
    1138     int * outputStuff=NULL;
    1139     int saveLogLevel=0;
    1140     // Go back to normal way if user wants it
    1141     if (osiclp&&(osiclp->specialOptions()&16)!=0)
    1142       allNormal=false;
    1143     if (osiclp&& allNormal) {
    1144       clp = osiclp->getModelPtr();
    1145       saveLogLevel = clp->logLevel();
    1146       clp->setLogLevel(0);
    1147       int saveOptions = clp->specialOptions();
    1148       int startFinishOptions;
    1149       int specialOptions = osiclp->specialOptions();
    1150       if((specialOptions&1)==0) {
    1151         startFinishOptions=0;
    1152         clp->setSpecialOptions(saveOptions|(64|1024));
     1142      */
     1143      OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
     1144      ClpSimplex * clp=NULL;
     1145      double * newLower = NULL;
     1146      double * newUpper = NULL;
     1147      double ** outputSolution=NULL;
     1148      int * outputStuff=NULL;
     1149      // Go back to normal way if user wants it
     1150      if (osiclp&&(osiclp->specialOptions()&16)!=0&&osiclp->specialOptions()>0)
     1151        allNormal=false;
     1152      if (osiclp&& allNormal) {
     1153        clp = osiclp->getModelPtr();
     1154        // Clp - do a different way
     1155        newLower = new double[numberStrong];
     1156        newUpper = new double[numberStrong];
     1157        outputSolution = new double * [2*numberStrong];
     1158        outputStuff = new int [4*numberStrong];
     1159        int * which = new int[numberStrong];
     1160        int startFinishOptions;
     1161        int specialOptions = osiclp->specialOptions();
     1162        int clpOptions = clp->specialOptions();
     1163        int returnCode=0;
     1164#define CRUNCH
     1165#ifdef CRUNCH
     1166        // Crunch down problem
     1167        int numberRows = clp->numberRows();
     1168        // Use dual region
     1169        double * rhs = clp->dualRowSolution();
     1170        int * whichRow = new int[3*numberRows];
     1171        int * whichColumn = new int[2*numberColumns];
     1172        int nBound;
     1173        ClpSimplex * small = ((ClpSimplexOther *) clp)->crunch(rhs,whichRow,whichColumn,nBound,true);
     1174        if (!small) {
     1175          anyAction=-2;
     1176          //printf("XXXX Inf by inspection\n");
     1177          delete [] whichColumn;
     1178          whichColumn=NULL;
     1179          delete [] whichRow;
     1180          whichRow=NULL;
     1181          break;
     1182        } else {
     1183          clp = small;
     1184        }
     1185#else
     1186        int saveLogLevel = clp->logLevel();
     1187        int saveMaxIts = clp->maximumIterations();
     1188#endif
     1189        clp->setLogLevel(0);
     1190        if((specialOptions&1)==0) {
     1191          startFinishOptions=0;
     1192          clp->setSpecialOptions(clpOptions|(64|1024));
     1193        } else {
     1194          startFinishOptions=1+2+4;
     1195          //startFinishOptions=1+4; // for moment re-factorize
     1196          if((specialOptions&4)==0)
     1197            clp->setSpecialOptions(clpOptions|(64|128|512|1024|4096));
     1198          else
     1199            clp->setSpecialOptions(clpOptions|(64|128|512|1024|2048|4096));
     1200        }
     1201        // User may want to clean up before strong branching
     1202        if ((clp->specialOptions()&32)!=0) {
     1203          clp->primal(1);
     1204          if (clp->numberIterations())
     1205            model->messageHandler()->message(CBC_ITERATE_STRONG,model->messages())
     1206              << clp->numberIterations()
     1207              <<CoinMessageEol;
     1208        }
     1209        clp->setMaximumIterations(saveLimit);
     1210#ifdef CRUNCH
     1211        int * backColumn = whichColumn+numberColumns;
     1212#endif
     1213        for (i=0;i<numberStrong;i++) {
     1214          int iObject = choice[i].objectNumber;
     1215          const CbcObject * object = model->object(iObject);
     1216          const CbcSimpleInteger * simple = dynamic_cast <const CbcSimpleInteger *> (object);
     1217          int iSequence = simple->modelSequence();
     1218          newLower[i]= ceil(saveSolution[iSequence]);
     1219          newUpper[i]= floor(saveSolution[iSequence]);
     1220#ifdef CRUNCH
     1221          iSequence = backColumn[iSequence];
     1222          assert (iSequence>=0);
     1223#endif
     1224          which[i]=iSequence;
     1225          outputSolution[2*i]= new double [numberColumns];
     1226          outputSolution[2*i+1]= new double [numberColumns];
     1227        }
     1228        //clp->writeMps("bad");
     1229        returnCode=clp->strongBranching(numberStrong,which,
     1230                                            newLower, newUpper,outputSolution,
     1231                                            outputStuff,outputStuff+2*numberStrong,!solveAll,false,
     1232                                            startFinishOptions);
     1233#ifndef CRUNCH
     1234        clp->setSpecialOptions(clpOptions); // restore
     1235        clp->setMaximumIterations(saveMaxIts);
     1236        clp->setLogLevel(saveLogLevel);
     1237#endif
     1238        if (returnCode==-2) {
     1239          // bad factorization!!!
     1240          // Doing normal way
     1241          // Mark hot start
     1242          solver->markHotStart();
     1243          clp = NULL;
     1244        } else {
     1245#ifdef CRUNCH
     1246          // extract solution
     1247          //bool checkSol=true;
     1248          for (i=0;i<numberStrong;i++) {
     1249            int iObject = choice[i].objectNumber;
     1250            const CbcObject * object = model->object(iObject);
     1251            const CbcSimpleInteger * simple = dynamic_cast <const CbcSimpleInteger *> (object);
     1252            int iSequence = simple->modelSequence();
     1253            which[i]=iSequence;
     1254            double * sol = outputSolution[2*i];
     1255            double * sol2 = outputSolution[2*i+1];
     1256            //bool x=true;
     1257            //bool x2=true;
     1258            for (int iColumn=numberColumns-1;iColumn>=0;iColumn--) {
     1259              int jColumn = backColumn[iColumn];
     1260              if (jColumn>=0) {
     1261                sol[iColumn]=sol[jColumn];
     1262                sol2[iColumn]=sol2[jColumn];
     1263              } else {
     1264                sol[iColumn]=saveSolution[iColumn];
     1265                sol2[iColumn]=saveSolution[iColumn];
     1266              }
     1267              //printf("strong %d col %d sol %g sol2 %g\n",i,iColumn,sol[iColumn],
     1268              //     sol2[iColumn]);
     1269              //if (fabs(sol[iColumn]-0.5)<0.499)
     1270              //x=false;
     1271              //if (fabs(sol2[iColumn]-0.5)<0.499)
     1272              //x2=false;
     1273            }
     1274#if 0
     1275            if( outputStuff[2*i]!=0&&outputStuff[2*i+1]!=0)
     1276              checkSol=false;
     1277            if (x&&checkSol) {
     1278              int iStatus = outputStuff[2*i];
     1279              double newObjectiveValue = objectiveValue+newUpper[i];
     1280              //printf("solution found - status %d obj %g\n",iStatus,newObjectiveValue);
     1281              if (!iStatus) {
     1282                const double * lower = solver->getRowLower();
     1283                const double * upper = solver->getRowUpper();
     1284                int numberRows = solver->getNumRows();
     1285                double * rhs = new double [numberRows];
     1286                CoinZeroN(rhs,numberRows);
     1287                {
     1288                  int numberColumns = solver->getNumCols();
     1289                  const double * columnLower = solver->getColLower();
     1290                  const double * columnUpper = solver->getColUpper();
     1291                  int numberRows = solver->getNumRows();
     1292                 
     1293                  const double * element = matrix->getElements();
     1294                  const int * row = matrix->getIndices();
     1295                  const CoinBigIndex * columnStart = matrix->getVectorStarts();
     1296                  const int * columnLength = matrix->getVectorLengths();
     1297                  CoinZeroN(rhs,numberRows);
     1298                  int iColumn;
     1299                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
     1300                    double lower = columnLower[iColumn];
     1301                    double upper = columnUpper[iColumn];
     1302                    double solValue = sol[iColumn];
     1303                    assert (solValue>=lower-1.0e-4&&solValue<upper+1.0e-4);
     1304                    for (CoinBigIndex j = columnStart[iColumn];
     1305                         j<columnStart[iColumn]+columnLength[iColumn];j++) {
     1306                      int iRow = row[j];
     1307                      double value = element[j];
     1308                      rhs[iRow] += solValue*value;
     1309                      if (iRow==-19)
     1310                        printf("col %d has sol %g and el %g , rhs now %g\n",
     1311                               iColumn,solValue,element[j],rhs[19]);
     1312                    }
     1313                  }
     1314                }
     1315                for (int i=0;i<numberRows;i++) {
     1316                  assert (rhs[i]>lower[i]-1.0e-3);
     1317                  assert (rhs[i]<upper[i]+1.0e-3);
     1318                }
     1319                delete [] rhs;
     1320              }
     1321            }
     1322            if (x2&&checkSol) {
     1323              int iStatus = outputStuff[2*i+1];
     1324              double newObjectiveValue = objectiveValue+newLower[i];
     1325              //printf("solution found - status %d obj %g\n",iStatus,newObjectiveValue);
     1326              if (!iStatus) {
     1327                const double * lower = solver->getRowLower();
     1328                const double * upper = solver->getRowUpper();
     1329                int numberRows = solver->getNumRows();
     1330                double * rhs = new double [numberRows];
     1331                CoinZeroN(rhs,numberRows);
     1332                solver->getMatrixByCol()->times(sol2,rhs) ;
     1333                for (int i=0;i<numberRows;i++) {
     1334                  assert (rhs[i]>lower[i]-1.0e-4);
     1335                  assert (rhs[i]<upper[i]+1.0e-4);
     1336                }
     1337                delete [] rhs;
     1338              }
     1339            }
     1340#endif
     1341          }
     1342#endif
     1343        }
     1344#ifdef CRUNCH
     1345        delete [] whichColumn;
     1346        delete [] whichRow;
     1347        delete small;
     1348#endif
     1349        delete [] which;
    11531350      } else {
    1154         startFinishOptions=1+2+4;
    1155         //startFinishOptions=1+4; // for moment re-factorize
    1156         if((specialOptions&4)==0)
    1157           clp->setSpecialOptions(saveOptions|(64|128|512|1024|4096));
    1158         else
    1159           clp->setSpecialOptions(saveOptions|(64|128|512|1024|2048|4096));
     1351        // Doing normal way
     1352        // Mark hot start
     1353        solver->markHotStart();
    11601354      }
    1161       // User may want to clean up before strong branching
    1162       if ((clp->specialOptions()&32)!=0) {
    1163         clp->primal(1);
    1164         if (clp->numberIterations())
    1165           model->messageHandler()->message(CBC_ITERATE_STRONG,model->messages())
    1166             << clp->numberIterations()
    1167             <<CoinMessageEol;
    1168       }
    1169       int saveMaxIts = clp->maximumIterations();
    1170       clp->setMaximumIterations(saveLimit);
    1171       // Clp - do a different way
    1172       newLower = new double[numberStrong];
    1173       newUpper = new double[numberStrong];
    1174       outputSolution = new double * [2*numberStrong];
    1175       outputStuff = new int [4*numberStrong];
    1176       int * which = new int[numberStrong];
    1177       for (i=0;i<numberStrong;i++) {
    1178         int iObject = choice[i].objectNumber;
    1179         const CbcObject * object = model->object(iObject);
    1180         const CbcSimpleInteger * simple = dynamic_cast <const CbcSimpleInteger *> (object);
    1181         int iSequence = simple->modelSequence();
    1182         newLower[i]= ceil(saveSolution[iSequence]);
    1183         newUpper[i]= floor(saveSolution[iSequence]);
    1184         which[i]=iSequence;
    1185         outputSolution[2*i]= new double [numberColumns];
    1186         outputSolution[2*i+1]= new double [numberColumns];
    1187       }
    1188       int returnCode=clp->strongBranching(numberStrong,which,
    1189                                           newLower, newUpper,outputSolution,
    1190                                           outputStuff,outputStuff+2*numberStrong,!solveAll,false,
    1191                                           startFinishOptions);
    1192       clp->setSpecialOptions(saveOptions); // restore
    1193       clp->setMaximumIterations(saveMaxIts);
    1194       if (returnCode==-2) {
    1195         // bad factorization!!!
    1196         // Doing normal way
    1197         // Mark hot start
    1198         solver->markHotStart();
    1199         clp->setLogLevel(saveLogLevel);
    1200         clp = NULL;
    1201       }
    1202       delete [] which;
    1203     } else {
    1204       // Doing normal way
    1205       // Mark hot start
    1206       solver->markHotStart();
    1207     }
    1208 /*
    1209   Open a loop to do the strong branching LPs. For each candidate variable,
    1210   solve an LP with the variable forced down, then up. If a direction turns
    1211   out to be infeasible or monotonic (i.e., over the dual objective cutoff),
    1212   force the objective change to be big (1.0e100). If we determine the problem
    1213   is infeasible, or find a monotone variable, escape the loop.
    1214 
    1215   TODO: The `restore bounds' part might be better encapsulated as an
     1355      /*
     1356        Open a loop to do the strong branching LPs. For each candidate variable,
     1357        solve an LP with the variable forced down, then up. If a direction turns
     1358        out to be infeasible or monotonic (i.e., over the dual objective cutoff),
     1359        force the objective change to be big (1.0e100). If we determine the problem
     1360        is infeasible, or find a monotone variable, escape the loop.
     1361       
     1362        TODO: The `restore bounds' part might be better encapsulated as an
    12161363        unbranch() method. Branching objects more exotic than simple integers
    12171364        or cliques might not restrict themselves to variable bounds.
    12181365
    1219   TODO: Virtuous solvers invalidate the current solution (or give bogus
     1366        TODO: Virtuous solvers invalidate the current solution (or give bogus
    12201367        results :-) when the bounds are changed out from under them. So we
    12211368        need to do all the work associated with finding a new solution before
    12221369        restoring the bounds.
    1223 */
    1224     for (i = 0 ; i < numberStrong ; i++)
    1225     { double objectiveChange ;
    1226       double newObjectiveValue=1.0e100;
    1227       // status is 0 finished, 1 infeasible and other
    1228       int iStatus;
    1229 /*
    1230   Try the down direction first. (Specify the initial branching alternative as
    1231   down with a call to way(-1). Each subsequent call to branch() performs the
    1232   specified branch and advances the branch object state to the next branch
    1233   alternative.)
    1234 */
     1370      */
     1371      for (i = 0 ; i < numberStrong ; i++)
     1372        { double objectiveChange ;
     1373        double newObjectiveValue=1.0e100;
     1374        // status is 0 finished, 1 infeasible and other
     1375        int iStatus;
     1376        /*
     1377          Try the down direction first. (Specify the initial branching alternative as
     1378          down with a call to way(-1). Each subsequent call to branch() performs the
     1379          specified branch and advances the branch object state to the next branch
     1380          alternative.)
     1381        */
     1382        if (!clp) {
     1383          choice[i].possibleBranch->way(-1) ;
     1384          choice[i].possibleBranch->branch() ;
     1385          bool feasible=true;
     1386          if (checkFeasibility) {
     1387            // check branching did not make infeasible
     1388            int iColumn;
     1389            int numberColumns = solver->getNumCols();
     1390            const double * columnLower = solver->getColLower();
     1391            const double * columnUpper = solver->getColUpper();
     1392            for (iColumn= 0;iColumn<numberColumns;iColumn++) {
     1393              if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
     1394                feasible=false;
     1395            }
     1396          }
     1397          if (feasible) {
     1398            solver->solveFromHotStart() ;
     1399            /*
     1400              We now have an estimate of objective degradation that we can use for strong
     1401              branching. If we're over the cutoff, the variable is monotone up.
     1402              If we actually made it to optimality, check for a solution, and if we have
     1403              a good one, call setBestSolution to process it. Note that this may reduce the
     1404              cutoff, so we check again to see if we can declare this variable monotone.
     1405            */
     1406            if (solver->isProvenOptimal())
     1407              iStatus=0; // optimal
     1408            else if (solver->isIterationLimitReached()
     1409                     &&!solver->isDualObjectiveLimitReached())
     1410              iStatus=2; // unknown
     1411            else
     1412              iStatus=1; // infeasible
     1413            newObjectiveValue = solver->getObjSense()*solver->getObjValue();
     1414            choice[i].numItersDown = solver->getIterationCount();
     1415          } else {
     1416            iStatus=1; // infeasible
     1417            newObjectiveValue = 1.0e100;
     1418            choice[i].numItersDown = 0;
     1419          }
     1420          objectiveChange = newObjectiveValue-objectiveValue ;
     1421        } else {
     1422          iStatus = outputStuff[2*i];
     1423          choice[i].numItersDown = outputStuff[2*numberStrong+2*i];
     1424          newObjectiveValue = objectiveValue+newUpper[i];
     1425          solver->setColSolution(outputSolution[2*i]);
     1426        }
     1427        objectiveChange = newObjectiveValue  - objectiveValue;
     1428        if (!iStatus) {
     1429          choice[i].finishedDown = true ;
     1430          if (newObjectiveValue>=model->getCutoff()) {
     1431            objectiveChange = 1.0e100; // say infeasible
     1432          } else {
     1433            // See if integer solution
     1434            if (model->feasibleSolution(choice[i].numIntInfeasDown,
     1435                                        choice[i].numObjInfeasDown))
     1436              { model->setBestSolution(CBC_STRONGSOL,
     1437                                       newObjectiveValue,
     1438                                       solver->getColSolution()) ;
     1439              if (newObjectiveValue >= model->getCutoff())      //  *new* cutoff
     1440                objectiveChange = 1.0e100 ;
     1441              }
     1442          }
     1443        } else if (iStatus==1) {
     1444          objectiveChange = 1.0e100 ;
     1445        } else {
     1446          // Can't say much as we did not finish
     1447          choice[i].finishedDown = false ;
     1448        }
     1449        choice[i].downMovement = objectiveChange ;
     1450       
     1451        // restore bounds
     1452        if (!clp)
     1453          { for (int j=0;j<numberColumns;j++) {
     1454            if (saveLower[j] != lower[j])
     1455              solver->setColLower(j,saveLower[j]);
     1456            if (saveUpper[j] != upper[j])
     1457              solver->setColUpper(j,saveUpper[j]);
     1458          }
     1459          }
     1460        //printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
     1461        //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersDown,
     1462        //     choice[i].downMovement,choice[i].finishedDown,choice[i].numIntInfeasDown,
     1463        //     choice[i].numObjInfeasDown);
     1464       
     1465        // repeat the whole exercise, forcing the variable up
     1466        if (!clp) {
     1467          choice[i].possibleBranch->branch();
     1468          bool feasible=true;
     1469          if (checkFeasibility) {
     1470            // check branching did not make infeasible
     1471            int iColumn;
     1472            int numberColumns = solver->getNumCols();
     1473            const double * columnLower = solver->getColLower();
     1474            const double * columnUpper = solver->getColUpper();
     1475            for (iColumn= 0;iColumn<numberColumns;iColumn++) {
     1476              if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
     1477                feasible=false;
     1478            }
     1479          }
     1480          if (feasible) {
     1481            solver->solveFromHotStart() ;
     1482            /*
     1483              We now have an estimate of objective degradation that we can use for strong
     1484              branching. If we're over the cutoff, the variable is monotone up.
     1485              If we actually made it to optimality, check for a solution, and if we have
     1486              a good one, call setBestSolution to process it. Note that this may reduce the
     1487              cutoff, so we check again to see if we can declare this variable monotone.
     1488            */
     1489            if (solver->isProvenOptimal())
     1490              iStatus=0; // optimal
     1491            else if (solver->isIterationLimitReached()
     1492                     &&!solver->isDualObjectiveLimitReached())
     1493              iStatus=2; // unknown
     1494            else
     1495              iStatus=1; // infeasible
     1496            newObjectiveValue = solver->getObjSense()*solver->getObjValue();
     1497            choice[i].numItersUp = solver->getIterationCount();
     1498          } else {
     1499            iStatus=1; // infeasible
     1500            newObjectiveValue = 1.0e100;
     1501            choice[i].numItersDown = 0;
     1502          }
     1503          objectiveChange = newObjectiveValue-objectiveValue ;
     1504        } else {
     1505          iStatus = outputStuff[2*i+1];
     1506          choice[i].numItersUp = outputStuff[2*numberStrong+2*i+1];
     1507          newObjectiveValue = objectiveValue+newLower[i];
     1508          solver->setColSolution(outputSolution[2*i+1]);
     1509        }
     1510        objectiveChange = newObjectiveValue  - objectiveValue;
     1511        if (!iStatus) {
     1512          choice[i].finishedUp = true ;
     1513          if (newObjectiveValue>=model->getCutoff()) {
     1514            objectiveChange = 1.0e100; // say infeasible
     1515          } else {
     1516            // See if integer solution
     1517            if (model->feasibleSolution(choice[i].numIntInfeasUp,
     1518                                        choice[i].numObjInfeasUp))
     1519              { model->setBestSolution(CBC_STRONGSOL,
     1520                                       newObjectiveValue,
     1521                                       solver->getColSolution()) ;
     1522              if (newObjectiveValue >= model->getCutoff())      //  *new* cutoff
     1523                objectiveChange = 1.0e100 ;
     1524              }
     1525          }
     1526        } else if (iStatus==1) {
     1527          objectiveChange = 1.0e100 ;
     1528        } else {
     1529          // Can't say much as we did not finish
     1530          choice[i].finishedUp = false ;
     1531        }
     1532        choice[i].upMovement = objectiveChange ;
     1533       
     1534        // restore bounds
     1535        if (!clp)
     1536          { for (int j=0;j<numberColumns;j++) {
     1537            if (saveLower[j] != lower[j])
     1538              solver->setColLower(j,saveLower[j]);
     1539            if (saveUpper[j] != upper[j])
     1540              solver->setColUpper(j,saveUpper[j]);
     1541          }
     1542          }
     1543       
     1544        //printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
     1545        //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersUp,
     1546        //     choice[i].upMovement,choice[i].finishedUp,choice[i].numIntInfeasUp,
     1547        //     choice[i].numObjInfeasUp);
     1548       
     1549        /*
     1550          End of evaluation for this candidate variable. Possibilities are:
     1551          * Both sides below cutoff; this variable is a candidate for branching.
     1552          * Both sides infeasible or above the objective cutoff: no further action
     1553          here. Break from the evaluation loop and assume the node will be purged
     1554          by the caller.
     1555          * One side below cutoff: Install the branch (i.e., fix the variable). Break
     1556          from the evaluation loop and assume the node will be reoptimised by the
     1557          caller.
     1558        */
     1559        if (choice[i].upMovement<1.0e100) {
     1560          if(choice[i].downMovement<1.0e100) {
     1561            // feasible - no action
     1562          } else {
     1563            // up feasible, down infeasible
     1564            anyAction=-1;
     1565            if (!solveAll) {
     1566              choice[i].possibleBranch->way(1);
     1567              choice[i].possibleBranch->branch();
     1568              break;
     1569            } else {
     1570              choice[i].fix=1;
     1571            }
     1572          }
     1573        } else {
     1574          if(choice[i].downMovement<1.0e100) {
     1575            // down feasible, up infeasible
     1576            anyAction=-1;
     1577            if (!solveAll) {
     1578              choice[i].possibleBranch->way(-1);
     1579              choice[i].possibleBranch->branch();
     1580              break;
     1581            } else {
     1582              choice[i].fix=-1;
     1583            }
     1584          } else {
     1585            // neither side feasible
     1586            anyAction=-2;
     1587            break;
     1588          }
     1589        }
     1590        bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) >
     1591                            model->getDblParam(CbcModel::CbcMaximumSeconds));
     1592        if (hitMaxTime) {
     1593          numberStrong=i+1;
     1594          break;
     1595        }
     1596        }
    12351597      if (!clp) {
    1236         choice[i].possibleBranch->way(-1) ;
    1237         choice[i].possibleBranch->branch() ;
     1598        // Delete the snapshot
     1599        solver->unmarkHotStart();
     1600      } else {
     1601        delete [] newLower;
     1602        delete [] newUpper;
     1603        delete [] outputStuff;
     1604        int i;
     1605        for (i=0;i<2*numberStrong;i++)
     1606          delete [] outputSolution[i];
     1607        delete [] outputSolution;
     1608      }
     1609      solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
     1610      // restore basis
     1611      solver->setWarmStart(ws);
     1612      // Unless infeasible we will carry on
     1613      // But we could fix anyway
     1614      if (anyAction==-1&&solveAll) {
     1615        // apply and take off
     1616        for (i = 0 ; i < numberStrong ; i++) {
     1617          if (choice[i].fix) {
     1618            choice[i].possibleBranch->way(choice[i].fix) ;
     1619            choice[i].possibleBranch->branch() ;
     1620          }
     1621        }
    12381622        bool feasible=true;
    12391623        if (checkFeasibility) {
     
    12491633        }
    12501634        if (feasible) {
    1251           solver->solveFromHotStart() ;
    1252 /*
    1253   We now have an estimate of objective degradation that we can use for strong
    1254   branching. If we're over the cutoff, the variable is monotone up.
    1255   If we actually made it to optimality, check for a solution, and if we have
    1256   a good one, call setBestSolution to process it. Note that this may reduce the
    1257   cutoff, so we check again to see if we can declare this variable monotone.
    1258 */
    1259           if (solver->isProvenOptimal())
    1260             iStatus=0; // optimal
    1261           else if (solver->isIterationLimitReached()
    1262                    &&!solver->isDualObjectiveLimitReached())
    1263             iStatus=2; // unknown
    1264           else
    1265             iStatus=1; // infeasible
    1266           newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    1267           choice[i].numItersDown = solver->getIterationCount();
     1635          // can do quick optimality check
     1636          int easy=2;
     1637          solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
     1638          solver->resolve() ;
     1639          solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
     1640          feasible = solver->isProvenOptimal();
     1641        }
     1642        if (feasible) {
     1643          memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
     1644          model->reserveCurrentSolution(saveSolution);
     1645          memcpy(saveLower,solver->getColLower(),numberColumns*sizeof(double));
     1646          memcpy(saveUpper,solver->getColUpper(),numberColumns*sizeof(double));
     1647          // Clean up all candidates whih are fixed
     1648          int numberLeft=0;
     1649          for (i = 0 ; i < numberStrong ; i++) {
     1650            Strong thisChoice = choice[i];
     1651            choice[i].possibleBranch=NULL;
     1652            const CbcObject * object = model->object(thisChoice.objectNumber);
     1653            int preferredWay;
     1654            double infeasibility = object->infeasibility(preferredWay);
     1655            if (!infeasibility) {
     1656              // take out
     1657              delete thisChoice.possibleBranch;
     1658            } else {
     1659              choice[numberLeft++]=thisChoice;
     1660            }
     1661          }
     1662          numberStrong=numberLeft;
     1663          for (;i<maximumStrong;i++) {
     1664            delete choice[i].possibleBranch;
     1665            choice[i].possibleBranch=NULL;
     1666          }
     1667          // If all fixed then round again
     1668          if (!numberLeft) {
     1669            finished=false;
     1670            numberStrong=0;
     1671            saveNumberStrong=0;
     1672            maximumStrong=1;
     1673          } else {
     1674            anyAction=0;
     1675          }
     1676          // If these two uncommented then different action
     1677          anyAction=-1;
     1678          finished=true;
     1679          //printf("some fixed but continuing %d left\n",numberLeft);
    12681680        } else {
    1269           iStatus=1; // infeasible
    1270           newObjectiveValue = 1.0e100;
    1271           choice[i].numItersDown = 0;
    1272         }
    1273         objectiveChange = newObjectiveValue-objectiveValue ;
    1274       } else {
    1275         iStatus = outputStuff[2*i];
    1276         choice[i].numItersDown = outputStuff[2*numberStrong+2*i];
    1277         newObjectiveValue = objectiveValue+newUpper[i];
    1278         solver->setColSolution(outputSolution[2*i]);
     1681          anyAction=-2; // say infeasible
     1682        }
    12791683      }
    1280       objectiveChange = newObjectiveValue  - objectiveValue;
    1281       if (!iStatus) {
    1282         choice[i].finishedDown = true ;
    1283         if (newObjectiveValue>=model->getCutoff()) {
    1284           objectiveChange = 1.0e100; // say infeasible
    1285         } else {
    1286           // See if integer solution
    1287           if (model->feasibleSolution(choice[i].numIntInfeasDown,
    1288                                       choice[i].numObjInfeasDown))
    1289             { model->setBestSolution(CBC_STRONGSOL,
    1290                                      newObjectiveValue,
    1291                                      solver->getColSolution()) ;
    1292             if (newObjectiveValue >= model->getCutoff())        //  *new* cutoff
    1293               objectiveChange = 1.0e100 ;
    1294             }
    1295         }
    1296       } else if (iStatus==1) {
    1297         objectiveChange = 1.0e100 ;
    1298       } else {
    1299         // Can't say much as we did not finish
    1300         choice[i].finishedDown = false ;
    1301       }
    1302       choice[i].downMovement = objectiveChange ;
    1303 
    1304       // restore bounds
    1305       if (!clp)
    1306       { for (int j=0;j<numberColumns;j++) {
    1307         if (saveLower[j] != lower[j])
    1308           solver->setColLower(j,saveLower[j]);
    1309         if (saveUpper[j] != upper[j])
    1310           solver->setColUpper(j,saveUpper[j]);
    1311         }
    1312       }
    1313       //printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    1314       //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersDown,
    1315       //     choice[i].downMovement,choice[i].finishedDown,choice[i].numIntInfeasDown,
    1316       //     choice[i].numObjInfeasDown);
    1317 
    1318       // repeat the whole exercise, forcing the variable up
    1319       if (!clp) {
    1320         choice[i].possibleBranch->branch();
    1321         bool feasible=true;
    1322         if (checkFeasibility) {
    1323           // check branching did not make infeasible
    1324           int iColumn;
    1325           int numberColumns = solver->getNumCols();
    1326           const double * columnLower = solver->getColLower();
    1327           const double * columnUpper = solver->getColUpper();
    1328           for (iColumn= 0;iColumn<numberColumns;iColumn++) {
    1329             if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
    1330               feasible=false;
    1331           }
    1332         }
    1333         if (feasible) {
    1334           solver->solveFromHotStart() ;
    1335 /*
    1336   We now have an estimate of objective degradation that we can use for strong
    1337   branching. If we're over the cutoff, the variable is monotone up.
    1338   If we actually made it to optimality, check for a solution, and if we have
    1339   a good one, call setBestSolution to process it. Note that this may reduce the
    1340   cutoff, so we check again to see if we can declare this variable monotone.
    1341 */
    1342           if (solver->isProvenOptimal())
    1343             iStatus=0; // optimal
    1344           else if (solver->isIterationLimitReached()
    1345                    &&!solver->isDualObjectiveLimitReached())
    1346             iStatus=2; // unknown
    1347           else
    1348             iStatus=1; // infeasible
    1349           newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    1350           choice[i].numItersUp = solver->getIterationCount();
    1351         } else {
    1352           iStatus=1; // infeasible
    1353           newObjectiveValue = 1.0e100;
    1354           choice[i].numItersDown = 0;
    1355         }
    1356         objectiveChange = newObjectiveValue-objectiveValue ;
    1357       } else {
    1358         iStatus = outputStuff[2*i+1];
    1359         choice[i].numItersUp = outputStuff[2*numberStrong+2*i+1];
    1360         newObjectiveValue = objectiveValue+newLower[i];
    1361         solver->setColSolution(outputSolution[2*i+1]);
    1362       }
    1363       objectiveChange = newObjectiveValue  - objectiveValue;
    1364       if (!iStatus) {
    1365         choice[i].finishedUp = true ;
    1366         if (newObjectiveValue>=model->getCutoff()) {
    1367           objectiveChange = 1.0e100; // say infeasible
    1368         } else {
    1369           // See if integer solution
    1370           if (model->feasibleSolution(choice[i].numIntInfeasUp,
    1371                                       choice[i].numObjInfeasUp))
    1372             { model->setBestSolution(CBC_STRONGSOL,
    1373                                      newObjectiveValue,
    1374                                      solver->getColSolution()) ;
    1375             if (newObjectiveValue >= model->getCutoff())        //  *new* cutoff
    1376               objectiveChange = 1.0e100 ;
    1377             }
    1378         }
    1379       } else if (iStatus==1) {
    1380         objectiveChange = 1.0e100 ;
    1381       } else {
    1382         // Can't say much as we did not finish
    1383         choice[i].finishedUp = false ;
    1384       }
    1385       choice[i].upMovement = objectiveChange ;
    1386 
    1387       // restore bounds
    1388       if (!clp)
    1389       { for (int j=0;j<numberColumns;j++) {
    1390         if (saveLower[j] != lower[j])
    1391           solver->setColLower(j,saveLower[j]);
    1392         if (saveUpper[j] != upper[j])
    1393           solver->setColUpper(j,saveUpper[j]);
    1394         }
    1395       }
    1396 
    1397       //printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    1398       //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersUp,
    1399       //     choice[i].upMovement,choice[i].finishedUp,choice[i].numIntInfeasUp,
    1400       //     choice[i].numObjInfeasUp);
    1401 
    1402 /*
    1403   End of evaluation for this candidate variable. Possibilities are:
    1404     * Both sides below cutoff; this variable is a candidate for branching.
    1405     * Both sides infeasible or above the objective cutoff: no further action
    1406       here. Break from the evaluation loop and assume the node will be purged
    1407       by the caller.
    1408     * One side below cutoff: Install the branch (i.e., fix the variable). Break
    1409       from the evaluation loop and assume the node will be reoptimised by the
    1410       caller.
    1411 */
    1412       if (choice[i].upMovement<1.0e100) {
    1413         if(choice[i].downMovement<1.0e100) {
    1414           // feasible - no action
    1415         } else {
    1416           // up feasible, down infeasible
    1417           anyAction=-1;
    1418           if (!solveAll) {
    1419             choice[i].possibleBranch->way(1);
    1420             choice[i].possibleBranch->branch();
    1421             break;
    1422           }
    1423         }
    1424       } else {
    1425         if(choice[i].downMovement<1.0e100) {
    1426           // down feasible, up infeasible
    1427           anyAction=-1;
    1428           if (!solveAll) {
    1429             choice[i].possibleBranch->way(-1);
    1430             choice[i].possibleBranch->branch();
    1431             break;
    1432           }
    1433         } else {
    1434           // neither side feasible
    1435           anyAction=-2;
    1436           break;
    1437         }
     1684      delete ws;
     1685     
     1686      /*
     1687        anyAction >= 0 indicates that strong branching didn't produce any monotone
     1688        variables. Sift through the candidates for the best one.
     1689       
     1690        QUERY: Setting numberNodes looks to be a distributed noop. numberNodes is
     1691        local to this code block. Perhaps should be numberNodes_ from model?
     1692        Unclear what this calculation is doing.
     1693      */
     1694      if (anyAction>=0) {
     1695       
     1696        int numberNodes = model->getNodeCount();
     1697        // get average cost per iteration and assume stopped ones
     1698        // would stop after 50% more iterations at average cost??? !!! ???
     1699        double averageCostPerIteration=0.0;
     1700        double totalNumberIterations=1.0;
     1701        int smallestNumberInfeasibilities=INT_MAX;
     1702        for (i=0;i<numberStrong;i++) {
     1703          totalNumberIterations += choice[i].numItersDown +
     1704            choice[i].numItersUp ;
     1705          averageCostPerIteration += choice[i].downMovement +
     1706            choice[i].upMovement;
     1707          smallestNumberInfeasibilities=
     1708            CoinMin(CoinMin(choice[i].numIntInfeasDown ,
     1709                            choice[i].numIntInfeasUp ),
     1710                    smallestNumberInfeasibilities);
     1711        }
     1712        if (smallestNumberInfeasibilities>=numberIntegerInfeasibilities)
     1713          numberNodes=1000000; // switch off search for better solution
     1714        numberNodes=1000000; // switch off anyway
     1715        averageCostPerIteration /= totalNumberIterations;
     1716        // all feasible - choose best bet
     1717       
     1718#if 0
     1719        for (i = 0 ; i < numberStrong ; i++)
     1720          { int iColumn =
     1721              model->integerVariable()[choice[i].possibleBranch->variable()] ;
     1722          model->messageHandler()->message(CBC_STRONG,model->messages())
     1723            << i << iColumn
     1724            <<choice[i].downMovement<<choice[i].numIntInfeasDown
     1725            <<choice[i].upMovement<<choice[i].numIntInfeasUp
     1726            <<choice[i].possibleBranch->value()
     1727            <<CoinMessageEol;
     1728          int betterWay = decision->betterBranch(choice[i].possibleBranch,
     1729                                                 branch_,
     1730                                                 choice[i].upMovement,
     1731                                                 choice[i].numIntInfeasUp ,
     1732                                                 choice[i].downMovement,
     1733                                                 choice[i].numIntInfeasDown );
     1734          if (betterWay) {
     1735            delete branch_;
     1736            // C) create branching object
     1737            branch_ = choice[i].possibleBranch;
     1738            choice[i].possibleBranch=NULL;
     1739            branch_->way(betterWay);
     1740          }
     1741          }
     1742#else
     1743        // New method does all at once so it can be more sophisticated
     1744        // in deciding how to balance actions.
     1745        // But it does need arrays
     1746        double * changeUp = new double [numberStrong];
     1747        int * numberInfeasibilitiesUp = new int [numberStrong];
     1748        double * changeDown = new double [numberStrong];
     1749        int * numberInfeasibilitiesDown = new int [numberStrong];
     1750        CbcBranchingObject ** objects = new CbcBranchingObject * [ numberStrong];
     1751        for (i = 0 ; i < numberStrong ; i++) {
     1752          int iColumn = choice[i].possibleBranch->variable() ;
     1753          model->messageHandler()->message(CBC_STRONG,model->messages())
     1754            << i << iColumn
     1755            <<choice[i].downMovement<<choice[i].numIntInfeasDown
     1756            <<choice[i].upMovement<<choice[i].numIntInfeasUp
     1757            <<choice[i].possibleBranch->value()
     1758            <<CoinMessageEol;
     1759          changeUp[i]=choice[i].upMovement;
     1760          numberInfeasibilitiesUp[i] = choice[i].numIntInfeasUp;
     1761          changeDown[i]=choice[i].downMovement;
     1762          numberInfeasibilitiesDown[i] = choice[i].numIntInfeasDown;
     1763          objects[i] = choice[i].possibleBranch;
     1764        }
     1765        int whichObject = decision->bestBranch(objects,numberStrong,numberUnsatisfied_,
     1766                                               changeUp,numberInfeasibilitiesUp,
     1767                                               changeDown,numberInfeasibilitiesDown,
     1768                                               objectiveValue);
     1769        // move branching object and make sure it will not be deleted
     1770        if (whichObject>=0) {
     1771          branch_ = objects[whichObject];
     1772          choice[whichObject].possibleBranch=NULL;
     1773        }
     1774        delete [] changeUp;
     1775        delete [] numberInfeasibilitiesUp;
     1776        delete [] changeDown;
     1777        delete [] numberInfeasibilitiesDown;
     1778        delete [] objects;
     1779#endif
    14381780      }
    14391781    }
    1440 
    1441     if (!clp) {
    1442       // Delete the snapshot
    1443       solver->unmarkHotStart();
    1444     } else {
    1445       clp->setLogLevel(saveLogLevel);
    1446       delete [] newLower;
    1447       delete [] newUpper;
    1448       delete [] outputStuff;
    1449       int i;
    1450       for (i=0;i<2*numberStrong;i++)
    1451         delete [] outputSolution[i];
    1452       delete [] outputSolution;
     1782    /*
     1783      Simple branching. Probably just one, but we may have got here
     1784      because of an odd branch e.g. a cut
     1785    */
     1786    else {
     1787      // not strong
     1788      // C) create branching object
     1789      branch_ = choice[bestChoice].possibleBranch;
     1790      choice[bestChoice].possibleBranch=NULL;
    14531791    }
    1454     solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
    1455     // restore basis
    1456     solver->setWarmStart(ws);
    1457     delete ws;
    1458 
    1459 /*
    1460   anyAction >= 0 indicates that strong branching didn't produce any monotone
    1461   variables. Sift through the candidates for the best one.
    1462 
    1463   QUERY: Setting numberNodes looks to be a distributed noop. numberNodes is
    1464          local to this code block. Perhaps should be numberNodes_ from model?
    1465          Unclear what this calculation is doing.
    1466 */
    1467     if (anyAction>=0) {
    1468 
    1469       int numberNodes = model->getNodeCount();
    1470       // get average cost per iteration and assume stopped ones
    1471       // would stop after 50% more iterations at average cost??? !!! ???
    1472       double averageCostPerIteration=0.0;
    1473       double totalNumberIterations=1.0;
    1474       int smallestNumberInfeasibilities=INT_MAX;
    1475       for (i=0;i<numberStrong;i++) {
    1476         totalNumberIterations += choice[i].numItersDown +
    1477           choice[i].numItersUp ;
    1478         averageCostPerIteration += choice[i].downMovement +
    1479           choice[i].upMovement;
    1480         smallestNumberInfeasibilities=
    1481           CoinMin(CoinMin(choice[i].numIntInfeasDown ,
    1482                   choice[i].numIntInfeasUp ),
    1483               smallestNumberInfeasibilities);
    1484       }
    1485       if (smallestNumberInfeasibilities>=numberIntegerInfeasibilities)
    1486         numberNodes=1000000; // switch off search for better solution
    1487       numberNodes=1000000; // switch off anyway
    1488       averageCostPerIteration /= totalNumberIterations;
    1489       // all feasible - choose best bet
    1490 
    1491 #if 0
    1492       for (i = 0 ; i < numberStrong ; i++)
    1493       { int iColumn =
    1494           model->integerVariable()[choice[i].possibleBranch->variable()] ;
    1495          model->messageHandler()->message(CBC_STRONG,model->messages())
    1496           << i << iColumn
    1497           <<choice[i].downMovement<<choice[i].numIntInfeasDown
    1498           <<choice[i].upMovement<<choice[i].numIntInfeasUp
    1499           <<choice[i].possibleBranch->value()
    1500           <<CoinMessageEol;
    1501         int betterWay = decision->betterBranch(choice[i].possibleBranch,
    1502                                               branch_,
    1503                                               choice[i].upMovement,
    1504                                               choice[i].numIntInfeasUp ,
    1505                                               choice[i].downMovement,
    1506                                               choice[i].numIntInfeasDown );
    1507         if (betterWay) {
    1508           delete branch_;
    1509           // C) create branching object
    1510           branch_ = choice[i].possibleBranch;
    1511           choice[i].possibleBranch=NULL;
    1512           branch_->way(betterWay);
    1513         }
    1514       }
    1515 #else
    1516       // New method does all at once so it can be more sophisticated
    1517       // in deciding how to balance actions.
    1518       // But it does need arrays
    1519       double * changeUp = new double [numberStrong];
    1520       int * numberInfeasibilitiesUp = new int [numberStrong];
    1521       double * changeDown = new double [numberStrong];
    1522       int * numberInfeasibilitiesDown = new int [numberStrong];
    1523       CbcBranchingObject ** objects = new CbcBranchingObject * [ numberStrong];
    1524       for (i = 0 ; i < numberStrong ; i++) {
    1525         int iColumn = choice[i].possibleBranch->variable() ;
    1526         model->messageHandler()->message(CBC_STRONG,model->messages())
    1527           << i << iColumn
    1528           <<choice[i].downMovement<<choice[i].numIntInfeasDown
    1529           <<choice[i].upMovement<<choice[i].numIntInfeasUp
    1530           <<choice[i].possibleBranch->value()
    1531           <<CoinMessageEol;
    1532         changeUp[i]=choice[i].upMovement;
    1533         numberInfeasibilitiesUp[i] = choice[i].numIntInfeasUp;
    1534         changeDown[i]=choice[i].downMovement;
    1535         numberInfeasibilitiesDown[i] = choice[i].numIntInfeasDown;
    1536         objects[i] = choice[i].possibleBranch;
    1537       }
    1538       int whichObject = decision->bestBranch(objects,numberStrong,numberUnsatisfied_,
    1539                                              changeUp,numberInfeasibilitiesUp,
    1540                                              changeDown,numberInfeasibilitiesDown,
    1541                                              objectiveValue);
    1542       // move branching object and make sure it will not be deleted
    1543       if (whichObject>=0) {
    1544         branch_ = objects[whichObject];
    1545         choice[whichObject].possibleBranch=NULL;
    1546       }
    1547       delete [] changeUp;
    1548       delete [] numberInfeasibilitiesUp;
    1549       delete [] changeDown;
    1550       delete [] numberInfeasibilitiesDown;
    1551       delete [] objects;
    1552 #endif
    1553     }
    1554   }
    1555 /*
    1556   Simple branching. Probably just one, but we may have got here
    1557   because of an odd branch e.g. a cut
    1558 */
    1559   else {
    1560     // not strong
    1561     // C) create branching object
    1562     branch_ = choice[bestChoice].possibleBranch;
    1563     choice[bestChoice].possibleBranch=NULL;
    15641792  }
    15651793  // Set guessed solution value
  • trunk/Test/CbcMain.cpp

    r116 r122  
    1414#include <iostream>
    1515
    16 #define CBCVERSION "0.91"
     16#define CBCVERSION "0.93"
    1717
    1818#include "CoinMpsIO.hpp"
     
    2121#include "CoinWarmStartBasis.hpp"
    2222#include "CoinTime.hpp"
    23 
    2423#include "OsiSolverInterface.hpp"
    2524#include "OsiCuts.hpp"
     
    3635#include "CglMixedIntegerRounding.hpp"
    3736#include "CglTwomir.hpp"
     37#include "CglPreProcess.hpp"
    3838
    3939#include "CbcModel.hpp"
     40#include "CbcTree.hpp"
    4041#include "CbcCutGenerator.hpp"
    4142#include "CbcHeuristic.hpp"
     
    6061  // Weight for each infeasibility
    6162  double weight_;
     63  // Weight for each infeasibility - computed from solution
     64  double saveWeight_;
    6265  // Number of solutions
    6366  int numberSolutions_;
     67  // Tree size (at last check)
     68  int treeSize_;
    6469  // Default Constructor
    65   CbcCompareUser () : weight_(-1.0), numberSolutions_(0) {test_=this;};
     70  CbcCompareUser () : CbcCompareBase(),
     71                      weight_(-1.0),saveWeight_(0.0),numberSolutions_(0),
     72                      treeSize_(0)
     73  { test_=this;};
    6674
    6775  // Copy constructor
     
    7078  {
    7179    weight_=rhs.weight_;
     80    saveWeight_ = rhs.saveWeight_;
    7281    numberSolutions_=rhs.numberSolutions_;
     82    treeSize_ = rhs.treeSize_;
    7383  };
    7484   
     
    7989      CbcCompareBase::operator=(rhs);
    8090      weight_=rhs.weight_;
     91      saveWeight_ = rhs.saveWeight_;
    8192      numberSolutions_=rhs.numberSolutions_;
     93      treeSize_ = rhs.treeSize_;
    8294    }
    8395    return *this;
     
    98110  */
    99111  virtual bool test (CbcNode * x, CbcNode * y) {
    100     if (weight_<0.0) {
     112    if (weight_==-1.0) {
    101113      // before solution
    102       /* printf("x %d %d %g, y %d %d %g\n",
    103              x->numberUnsatisfied(),x->depth(),x->objectiveValue(),
    104              y->numberUnsatisfied(),y->depth(),y->objectiveValue()); */
    105114      if (x->numberUnsatisfied() > y->numberUnsatisfied())
    106         return true;
     115        return true;
    107116      else if (x->numberUnsatisfied() < y->numberUnsatisfied())
    108         return false;
     117        return false;
    109118      else
    110         return x->depth() < y->depth();
     119        return x->depth() < y->depth();
    111120    } else {
    112121      // after solution
    113       return x->objectiveValue()+ weight_*x->numberUnsatisfied() >
    114         y->objectiveValue() + weight_*y->numberUnsatisfied();
     122      double weight = CoinMax(weight_,0.0);
     123      return x->objectiveValue()+ weight*x->numberUnsatisfied() >
     124        y->objectiveValue() + weight*y->numberUnsatisfied();
    115125    }
    116126  }
     
    128138      ((double) numberInfeasibilitiesAtContinuous);
    129139    weight_ = 0.98*costPerInteger;
     140    saveWeight_=weight_;
    130141    numberSolutions_++;
    131142    if (numberSolutions_>5)
     
    137148    if (numberNodes>10000)
    138149      weight_ =0.0; // this searches on objective
    139     return false;
     150    else if (numberNodes==1000&&weight_==-2.0)
     151      weight_=-1.0; // Go to depth first
     152    // get size of tree
     153    treeSize_ = model->tree()->size();
     154    if (treeSize_>10000) {
     155      // set weight to reduce size most of time
     156      if (treeSize_>20000)
     157        weight_=-1.0;
     158      else if ((numberNodes%4000)!=0)
     159        weight_=-1.0;
     160      else
     161        weight_=saveWeight_;
     162    }
     163    return numberNodes==11000; // resort if first time
    140164  }
    141165};
     
    293317    parameters[numberParameters-1].append("on");
    294318    parameters[numberParameters++]=
     319      CbcParam("preprocess","Whether to use integer preprocessing",
     320              "off",PREPROCESS);
     321    parameters[numberParameters-1].append("on");
     322    parameters[numberParameters++]=
    295323      CbcParam("initialS!olve","Solve to continuous",
    296324              SOLVECONTINUOUS);
     
    334362      CbcParam("ver!sion","Print out version",
    335363              VERSION);
     364    parameters[numberParameters++]=
     365      CbcParam("alg!orithm","Whether to use dual or primal",
     366              "dual",ALGORITHM);
     367    parameters[numberParameters-1].append("primal");
    336368
    337369    assert(numberParameters<MAXPARAMETERS);
     
    612644    CglGomory gomoryGen;
    613645    // try larger limit
    614     gomoryGen.setLimit(3000);
     646    gomoryGen.setLimit(300);
    615647    // set default action (0=off,1=on,2=root)
    616648    int gomoryAction=1;
     
    619651    probingGen.setUsingObjective(true);
    620652    probingGen.setMaxPass(3);
    621     probingGen.setMaxProbe(100);
    622     probingGen.setMaxLook(50);
     653    probingGen.setMaxPassRoot(3);
     654    // Number of unsatisfied variables to look at
     655    probingGen.setMaxProbe(10);
     656    probingGen.setMaxProbeRoot(50);
     657    // How far to follow the consequences
     658    probingGen.setMaxLook(10);
     659    probingGen.setMaxLookRoot(50);
     660    // Only look at rows with fewer than this number of elements
     661    probingGen.setMaxElements(200);
    623662    probingGen.setRowCuts(3);
    624663    // set default action (0=off,1=on,2=root)
     
    657696   
    658697    int allowImportErrors=0;
     698    int algorithm=0; // dual
    659699    int keepImportNames=1;      // not implemented
    660700    int doScaling=1;
    661701    int preSolve=0;
     702    int preProcess=1;
    662703    double djFix=1.0e100;
    663704    double gapRatio=1.0e100;
    664705    double tightenFactor=0.0;
     706
     707    // Set false if user does anything advanced
     708    bool defaultSettings=true;
    665709
    666710    std::string directory ="./";
     
    680724        if (numberGoodCommands==1&&goodModel) {
    681725          // we just had file name
    682           model->initialSolve();
    683           model->solver()->messageHandler()->setLogLevel(0);
    684           CbcRounding heuristic1(*model);
    685           if (useRounding)
    686             model->addHeuristic(&heuristic1) ;
    687           // add cut generators if wanted
    688           if (probingAction==1)
    689             model->addCutGenerator(&probingGen,-1,"Probing");
    690           else if (probingAction==2)
    691             model->addCutGenerator(&probingGen,-99,"Probing");
    692           if (gomoryAction==1)
    693             model->addCutGenerator(&gomoryGen,-1,"Gomory");
    694           else if (gomoryAction==2)
    695             model->addCutGenerator(&gomoryGen,-99,"Gomory");
    696           if (knapsackAction==1)
    697             model->addCutGenerator(&knapsackGen,-1,"Knapsack");
    698           else if (knapsackAction==2)
    699             model->addCutGenerator(&knapsackGen,-99,"Knapsack");
    700           if (oddholeAction==1)
    701             model->addCutGenerator(&oddholeGen,-1,"OddHole");
    702           else if (oddholeAction==2)
    703             model->addCutGenerator(&oddholeGen,-99,"OddHole");
    704           if (cliqueAction==1)
    705             model->addCutGenerator(&cliqueGen,-1,"Clique");
    706           else if (cliqueAction==2)
    707             model->addCutGenerator(&cliqueGen,-99,"Clique");
    708           if (mixedAction==1)
    709             model->addCutGenerator(&mixedGen,-1,"MixedintegerRounding");
    710           else if (mixedAction==2)
    711             model->addCutGenerator(&mixedGen,-99,"MixedintegerRounding");
    712           if (flowAction==1)
    713             model->addCutGenerator(&flowGen,-1,"FlowCover");
    714           else if (flowAction==2)
    715             model->addCutGenerator(&flowGen,-99,"FlowCover");
    716           if (twomirAction==1)
    717             model->addCutGenerator(&twomirGen,-1,"TwoMirCuts");
    718           else if (twomirAction==2)
    719             model->addCutGenerator(&twomirGen,-99,"TwoMirCuts");
    720           // Say we want timings
    721           int numberGenerators = model->numberCutGenerators();
    722           int iGenerator;
    723           for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
    724             CbcCutGenerator * generator = model->cutGenerator(iGenerator);
    725             generator->setTiming(true);
    726           }
    727           model->branchAndBound();
    728           time2 = CoinCpuTime();
    729           totalTime += time2-time1;
    730           std::cout<<"Result "<<model->getObjValue()<<
    731             " iterations "<<model->getIterationCount()<<
    732             " nodes "<<model->getNodeCount()<<
    733             " took "<<time2-time1<<" seconds - total "<<totalTime<<std::endl;
     726          field="branchAndBound";
    734727        } else if (!numberGoodCommands) {
    735728          // let's give the sucker a hint
     
    739732            <<"Enter ? for list of commands or (-)unitTest or -miplib"
    740733            <<" for tests"<<std::endl;
    741         }
    742         break;
     734          break;
     735        } else {
     736          break;
     737        }
    743738      }
    744739     
     
    809804                djFix=value;
    810805                preSolve=5;
     806                defaultSettings=false; // user knows what she is doing
    811807                break;
    812808              case GAPRATIO:
     
    815811              case TIGHTENFACTOR:
    816812                tightenFactor=value;
     813                defaultSettings=false; // user knows what she is doing
    817814                break;
    818815              default:
     
    876873              allowImportErrors = action;
    877874              break;
     875            case ALGORITHM:
     876              algorithm  = action;
     877              defaultSettings=false; // user knows what she is doing
     878              break;
    878879            case KEEPNAMES:
    879880              keepImportNames = 1-action;
     
    883884              break;
    884885            case GOMORYCUTS:
     886              defaultSettings=false; // user knows what she is doing
    885887              gomoryAction = action;
    886888              break;
    887889            case PROBINGCUTS:
     890              defaultSettings=false; // user knows what she is doing
    888891              probingAction = action;
    889892              break;
    890893            case KNAPSACKCUTS:
     894              defaultSettings=false; // user knows what she is doing
    891895              knapsackAction = action;
    892896              break;
    893897            case ODDHOLECUTS:
     898              defaultSettings=false; // user knows what she is doing
    894899              oddholeAction = action;
    895900              break;
    896901            case CLIQUECUTS:
     902              defaultSettings=false; // user knows what she is doing
    897903              cliqueAction = action;
    898904              break;
    899905            case FLOWCUTS:
     906              defaultSettings=false; // user knows what she is doing
    900907              flowAction = action;
    901908              break;
    902909            case MIXEDCUTS:
     910              defaultSettings=false; // user knows what she is doing
    903911              mixedAction = action;
    904912              break;
    905913            case TWOMIRCUTS:
     914              defaultSettings=false; // user knows what she is doing
    906915              twomirAction = action;
    907916              break;
    908917            case ROUNDING:
     918              defaultSettings=false; // user knows what she is doing
    909919              useRounding = action;
    910920              break;
     
    944954              break;
    945955            case PRESOLVE:
     956                defaultSettings=false; // user knows what she is doing
    946957              preSolve = action*5;
     958              break;
     959            case PREPROCESS:
     960              preProcess = action;
    947961              break;
    948962            case SOLVER:
     
    985999          { if (goodModel)
    9861000            { CbcCompareUser compare; // Definition of node choice
     1001            // If user made settings then use them
     1002            if (!defaultSettings) {
    9871003              model->setNodeComparison(compare);
    9881004              OsiSolverInterface * solver = model->solver();
     
    10261042                  double * solution = modelC->primalColumnSolution();
    10271043                  double * dj = modelC->dualColumnSolution();
     1044                  int numberFixed=0;
    10281045                  for (i=0;i<numberColumns;i++) {
    10291046                    if (type[i]) {
     
    10321049                        solution[i]=lower[i];
    10331050                        upper[i]=lower[i];
     1051                        numberFixed++;
    10341052                      } else if (value>upper[i]-1.0e-5&&dj[i]<-djFix) {
    10351053                        solution[i]=upper[i];
    10361054                        lower[i]=upper[i];
     1055                        numberFixed++;
    10371056                      }
    10381057                    }
    10391058                  }
     1059                  printf("%d columns fixed\n",numberFixed);
    10401060                }
    10411061                {
     
    10481068                    if (useRounding)
    10491069                      model2->addHeuristic(&heuristic1);
     1070                    if (algorithm) {
     1071                      // user wants primal
     1072                      model2->solver()->setHintParam(OsiDoDualInInitial,false,OsiHintTry);
     1073                      model2->solver()->setHintParam(OsiDoDualInResolve,false,OsiHintTry);
     1074                    }
    10501075                    model2->branchAndBound();
    10511076                    // get back solution
     
    11161141                        << " took " << time2-time1 << " seconds - total "
    11171142                        << totalTime << std::endl ;
    1118               time1 = time2 ; }
    1119             else
     1143              time1 = time2 ;
     1144            } else {
     1145              // User is going to get what I think best
     1146              if (!doScaling)
     1147                model->solver()->setHintParam(OsiDoScale,false,OsiHintTry);
     1148              model->initialSolve();
     1149              // See if we want preprocessing
     1150              OsiSolverInterface * saveSolver=NULL;
     1151              CglPreProcess process;
     1152              if (preProcess) {
     1153                saveSolver=model->solver()->clone();
     1154                /* Do not try and produce equality cliques and
     1155                   do up to 10 passes */
     1156                OsiSolverInterface * solver2 = process.preProcess(*saveSolver,false,10);
     1157                if (!solver2) {
     1158                  printf("Pre-processing says infeasible\n");
     1159                  break;
     1160                } else {
     1161                  printf("processed model has %d rows and %d columns\n",
     1162                         solver2->getNumRows(),solver2->getNumCols());
     1163                }
     1164                //solver2->resolve();
     1165                // we have to keep solver2 so pass clone
     1166                solver2 = solver2->clone();
     1167                model->assignSolver(solver2);
     1168                model->initialSolve();
     1169              }
     1170              model->setNodeComparison(compare);
     1171              CbcRounding heuristic1(*model);
     1172              if (useRounding)
     1173                model->addHeuristic(&heuristic1) ;
     1174              // add cut generators if wanted
     1175              if (probingAction==1)
     1176                model->addCutGenerator(&probingGen,-1,"Probing");
     1177              else if (probingAction==2)
     1178                model->addCutGenerator(&probingGen,-99,"Probing");
     1179              if (gomoryAction==1)
     1180                model->addCutGenerator(&gomoryGen,-1,"Gomory");
     1181              else if (gomoryAction==2)
     1182                model->addCutGenerator(&gomoryGen,-99,"Gomory");
     1183              if (knapsackAction==1)
     1184                model->addCutGenerator(&knapsackGen,-1,"Knapsack");
     1185              else if (knapsackAction==2)
     1186                model->addCutGenerator(&knapsackGen,-99,"Knapsack");
     1187              if (oddholeAction==1)
     1188                model->addCutGenerator(&oddholeGen,-1,"OddHole");
     1189              else if (oddholeAction==2)
     1190                model->addCutGenerator(&oddholeGen,-99,"OddHole");
     1191              if (cliqueAction==1)
     1192                model->addCutGenerator(&cliqueGen,-1,"Clique");
     1193              else if (cliqueAction==2)
     1194                model->addCutGenerator(&cliqueGen,-99,"Clique");
     1195              if (mixedAction==1)
     1196                model->addCutGenerator(&mixedGen,-1,"MixedintegerRounding");
     1197              else if (mixedAction==2)
     1198                model->addCutGenerator(&mixedGen,-99,"MixedintegerRounding");
     1199              if (flowAction==1)
     1200                model->addCutGenerator(&flowGen,-1,"FlowCover");
     1201              else if (flowAction==2)
     1202                model->addCutGenerator(&flowGen,-99,"FlowCover");
     1203              if (twomirAction==1)
     1204                model->addCutGenerator(&twomirGen,-1,"TwoMirCuts");
     1205              else if (twomirAction==2)
     1206                model->addCutGenerator(&twomirGen,-99,"TwoMirCuts");
     1207              // Say we want timings
     1208              int numberGenerators = model->numberCutGenerators();
     1209              int iGenerator;
     1210              for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
     1211                CbcCutGenerator * generator = model->cutGenerator(iGenerator);
     1212                generator->setTiming(true);
     1213              }
     1214              // Could tune more
     1215              model->setMinimumDrop(min(1.0,
     1216                                        fabs(model->getMinimizationObjValue())*1.0e-3+1.0e-4));
     1217             
     1218              if (model->getNumCols()<500)
     1219                model->setMaximumCutPassesAtRoot(-100); // always do 100 if possible
     1220              else if (model->getNumCols()<5000)
     1221                model->setMaximumCutPassesAtRoot(100); // use minimum drop
     1222              else
     1223                model->setMaximumCutPassesAtRoot(20);
     1224              model->setMaximumCutPasses(2);
     1225             
     1226              // Do more strong branching if small
     1227              if (model->getNumCols()<5000)
     1228                model->setNumberStrong(20);
     1229              // Switch off strong branching if wanted
     1230              //if (model->getNumCols()>10*model->getNumRows())
     1231              //model->setNumberStrong(0);
     1232              if (model->getNumCols()>2000||model->getNumRows()>1500||
     1233                  model->messageHandler()->logLevel()>1)
     1234                model->setPrintFrequency(100);
     1235             
     1236              model->solver()->setIntParam(OsiMaxNumIterationHotStart,100);
     1237#ifdef COIN_USE_CLP
     1238              OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (model->solver());
     1239              // go faster stripes
     1240              if (osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
     1241                osiclp->setupForRepeatedUse(2,0);
     1242              }
     1243#endif
     1244              if (gapRatio < 1.0e100)
     1245                { double value = model->solver()->getObjValue() ;
     1246                double value2 = gapRatio*(1.0e-5+fabs(value)) ;
     1247                model->setAllowableGap(value2) ;
     1248                std::cout << "Continuous " << value
     1249                          << ", so allowable gap set to "
     1250                          << value2 << std::endl ; }
     1251              model->branchAndBound();
     1252              time2 = CoinCpuTime();
     1253              totalTime += time2-time1;
     1254              if (model->getMinimizationObjValue()<1.0e50) {
     1255                // post process
     1256                if (preProcess) {
     1257                  process.postProcess(*model->solver());
     1258                  // Solution now back in saveSolver
     1259                  model->assignSolver(saveSolver);
     1260                }
     1261              }
     1262              std::cout<<"Result "<<model->getObjValue()<<
     1263                " iterations "<<model->getIterationCount()<<
     1264                " nodes "<<model->getNodeCount()<<
     1265                " took "<<time2-time1<<" seconds - total "<<totalTime<<std::endl;
     1266              time1 = time2;
     1267            }
     1268            } else
    11201269            { std::cout << "** Current model not valid" << std::endl ; }
    11211270            break ; }
  • trunk/Test/CbcParam.cpp

    r2 r122  
    3737// Other constructors
    3838CbcParam::CbcParam (std::string name, std::string help,
    39            double lower, double upper, CbcParameterType type)
     39           double lower, double upper, CbcParameterType type,
     40                    bool display)
    4041  : type_(type),
    4142    lowerIntValue_(0),
     
    5354}
    5455CbcParam::CbcParam (std::string name, std::string help,
    55            int lower, int upper, CbcParameterType type)
     56           int lower, int upper, CbcParameterType type,
     57                    bool display)
    5658  : type_(type),
    5759    lowerDoubleValue_(0.0),
     
    7072// Other strings will be added by append
    7173CbcParam::CbcParam (std::string name, std::string help,
    72                   std::string defaultValue,
    73                   CbcParameterType type)
     74                    std::string firstValue,
     75                    CbcParameterType type,int defaultIndex,
     76                    bool display)
    7477  : type_(type),
    7578    lowerDoubleValue_(0.0),
     
    8588{
    8689  gutsOfConstructor();
    87   definedKeyWords_.push_back(defaultValue);
     90  definedKeyWords_.push_back(firstValue);
    8891}
    8992// Action
    9093CbcParam::CbcParam (std::string name, std::string help,
    91            CbcParameterType type)
     94                    CbcParameterType type,int indexNumber,
     95                    bool display)
    9296  : type_(type),
    9397    lowerDoubleValue_(0.0),
  • trunk/Test/include/CbcParam.hpp

    r2 r122  
    77#include "OsiSolverInterface.hpp"
    88#include "CbcModel.hpp"
    9 
     9class ClpSimplex;
    1010/*! \brief Parameter codes
    1111
     
    1414    <li>   1 -- 100     double parameters
    1515    <li> 101 -- 200     integer parameters
    16     <li> 201 -- 300     string parameters
     16    <li> 201 -- 250     string parameters
     17    <li> 251 -- 300     cuts etc(string but broken out for clarity)
    1718    <li> 301 -- 400     `actions'
    1819  </ul>
     
    2829enum CbcParameterType
    2930
    30 { GENERALQUERY = -100,
    31  
    32   PRIMALTOLERANCE = 1, DUALTOLERANCE,CUTOFF,TIMELIMIT,
     31  { GENERALQUERY = -100,FULLGENERALQUERY,
     32 
     33    PRIMALTOLERANCE = 1, DUALTOLERANCE,CUTOFF,TIMELIMIT,
     34    DUALBOUND, PRIMALWEIGHT,  OBJSCALE, RHSSCALE,
    3335
    3436  INFEASIBILITYWEIGHT = 51, INTEGERTOLERANCE,INCREMENT,ALLOWABLEGAP,
     
    3638  DJFIX = 81, GAPRATIO,TIGHTENFACTOR,
    3739
    38   LOGLEVEL = 151, SOLVERLOGLEVEL, MAXNODES,STRONGBRANCHING,
    39  
    40   DIRECTION = 201,ERRORSALLOWED,KEEPNAMES,SCALING,
     40  LOGLEVEL = 101, SOLVERLOGLEVEL, MAXNODES,STRONGBRANCHING,
     41    MAXFACTOR,PERTVALUE,MAXITERATION,PRESOLVEPASS,IDIOT,SPRINT,
     42    OUTPUTFORMAT,SLPVALUE,PRESOLVEOPTIONS,PRINTOPTIONS,SPECIALOPTIONS,
     43 
     44  DIRECTION=201,DUALPIVOT,SCALING,ERRORSALLOWED,KEEPNAMES,SPARSEFACTOR,
     45  PRIMALPIVOT,PRESOLVE,CRASH,BIASLU,PERTURBATION,MESSAGES,AUTOSCALE,
     46  CHOLESKY,KKT,BARRIERSCALE,GAMMA,CROSSOVER,PFI,ALGORITHM,
    4147
    4248  NODESTRATEGY = 251,BRANCHSTRATEGY,ADDCUTSSTRATEGY,
    43   GOMORYCUTS,PROBINGCUTS,KNAPSACKCUTS,ODDHOLECUTS,PRESOLVE,
     49  GOMORYCUTS,PROBINGCUTS,KNAPSACKCUTS,ODDHOLECUTS,
    4450  ROUNDING,SOLVER,CLIQUECUTS,COSTSTRATEGY,FLOWCUTS,MIXEDCUTS,
    45   TWOMIRCUTS,
    46  
    47   DIRECTORY = 301,IMPORT,EXPORT,RESTORE,SAVE,SOLVECONTINUOUS,BAB,
    48     MAXIMIZE,MINIMIZE,EXIT,STDIN,UNITTEST,MIPLIB,SOLUTION,CLEARCUTS,
    49     VERSION,
     51    TWOMIRCUTS,PREPROCESS,
     52 
     53  DIRECTORY=301,IMPORT,EXPORT,RESTORE,SAVE,DUALSIMPLEX,PRIMALSIMPLEX,
     54  MAXIMIZE,MINIMIZE,EXIT,STDIN,UNITTEST,NETLIB_DUAL,NETLIB_PRIMAL,SOLUTION,
     55  TIGHTEN,FAKEBOUND,HELP,PLUSMINUS,NETWORK,ALLSLACK,REVERSE,BARRIER,NETLIB_BARRIER,
     56    REALLY_SCALE,BASISIN,BASISOUT,SOLVECONTINUOUS,BAB,MIPLIB,CLEARCUTS,VERSION,
    5057
    5158  OSLSTUFF = 401,CBCSTUFF,
     
    5764
    5865class CbcParam
    59 
    60 { public:
     66{
     67public:
    6168
    6269  /**@name Constructor and destructor */
     
    6572  CbcParam (  );
    6673  CbcParam (std::string name, std::string help,
    67            double lower, double upper, CbcParameterType type);
     74           double lower, double upper, CbcParameterType type,bool display=true);
    6875  CbcParam (std::string name, std::string help,
    69            int lower, int upper, CbcParameterType type);
     76           int lower, int upper, CbcParameterType type,bool display=true);
    7077  // Other strings will be added by insert
    71   CbcParam (std::string name, std::string help, std::string defaultValue,
    72            CbcParameterType type);
     78  CbcParam (std::string name, std::string help, std::string firstValue,
     79           CbcParameterType type,int defaultIndex=0,bool display=true);
    7380  // Action
    7481  CbcParam (std::string name, std::string help,
    75            CbcParameterType type);
     82           CbcParameterType type,int indexNumber=-1,bool display=true);
    7683  /// Copy constructor.
    7784  CbcParam(const CbcParam &);
    7885  /// Assignment operator. This copies the data
    79     CbcParam & operator = (const CbcParam & rhs);
     86    CbcParam & operator=(const CbcParam & rhs);
    8087  /// Destructor
    8188  ~CbcParam (  );
     
    97104  };
    98105  /// Sets a double parameter (nonzero code if error)
     106  int setDoubleParameter(CbcModel & model, double value) const;
     107  /// Gets a double parameter
     108  double doubleParameter(CbcModel & model) const;
     109  /// Sets a int parameter (nonzero code if error)
     110  int setIntParameter(CbcModel & model, int value) const;
     111  /// Gets a int parameter
     112  int intParameter(CbcModel & model) const;
     113  /// Sets a double parameter (nonzero code if error)
     114  int setDoubleParameter(ClpSimplex * model, double value) const;
     115  /// Gets a double parameter
     116  double doubleParameter(ClpSimplex * model) const;
     117  /// Sets a int parameter (nonzero code if error)
     118  int setIntParameter(ClpSimplex * model, int value) const;
     119  /// Gets a int parameter
     120  int intParameter(ClpSimplex * model) const;
     121  /// Sets a double parameter (nonzero code if error)
    99122  int setDoubleParameter(OsiSolverInterface * model, double value) const;
    100123  /// Gets a double parameter
     
    104127  /// Gets a int parameter
    105128  int intParameter(OsiSolverInterface * model) const;
    106   /// Sets a double parameter (nonzero code if error)
    107   int setDoubleParameter(CbcModel &model, double value) const;
    108   /// Gets a double parameter
    109   double doubleParameter(CbcModel &model) const;
    110129  /// Checks a double parameter (nonzero code if error)
    111130  int checkDoubleParameter(double value) const;
    112   /// Sets a int parameter (nonzero code if error)
    113   int setIntParameter(CbcModel &model, int value) const;
    114   /// Gets a int parameter
    115   int intParameter(CbcModel &model) const;
    116131  /// Returns name which could match
    117132  std::string matchName (  ) const;
     
    125140  /// Sets current parameter option
    126141  inline void setCurrentOption ( int value )
    127   { currentKeyWord_ = value; };
     142  { currentKeyWord_=value; };
     143  /// Sets int value
     144  inline void setIntValue ( int value )
     145  { intValue_=value; };
     146  inline int intValue () const
     147  { return intValue_; };
     148  /// Sets double value
     149  inline void setDoubleValue ( double value )
     150  { doubleValue_=value; };
     151  inline double doubleValue () const
     152  { return doubleValue_; };
     153  /// Sets string value
     154  inline void setStringValue ( std::string value )
     155  { stringValue_=value; };
     156  inline std::string stringValue () const
     157  { return stringValue_; };
    128158  /// Returns 1 if matches minimum, 2 if matches less, 0 if not matched
    129159  int matches (std::string input) const;
     
    131161  inline CbcParameterType type() const
    132162  { return type_;};
     163  /// whether to display
     164  inline bool displayThis() const
     165  { return display_;};
     166  /// Set Long help
     167  inline void setLonghelp(const std::string help)
     168  {longHelp_=help;};
     169  /// Print Long help
     170  void printLongHelp() const;
     171  /// Print action and string
     172  void printString() const;
     173  /// type for classification
     174  inline int indexNumber() const
     175  { return indexNumber_;};
    133176private:
    134177  /// gutsOfConstructor
     
    161204  std::string shortHelp_;
    162205  /// Long help
    163   std::vector<std::string> longHelp_;
     206  std::string longHelp_;
    164207  /// Action
    165208  CbcParameterType action_;
    166209  /// Current keyWord (if a keyword parameter)
    167210  int currentKeyWord_;
     211  /// Display on ?
     212  bool display_;
     213  /// Integer parameter - current value
     214  int intValue_;
     215  /// Double parameter - current value
     216  double doubleValue_;
     217  /// String parameter - current value
     218  std::string stringValue_;
     219  /// index number to use for display purposes
     220  int indexNumber_;
    168221  //@}
    169222};
    170 
    171223#endif  /* CbcParam_H */
  • trunk/include/CbcBranchActual.hpp

    r74 r122  
    669669                            double changeDn, int numInfDn);
    670670
     671  /** \brief Compare N branching objects. Return index of best
     672      and sets way of branching in chosen object.
     673   
     674    This routine is used only after strong branching.
     675    This is reccommended version as it can be more sophisticated
     676  */
     677
     678  virtual int
     679  bestBranch (CbcBranchingObject ** objects, int numberObjects, int numberUnsatisfied,
     680              double * changeUp, int * numberInfeasibilitiesUp,
     681              double * changeDown, int * numberInfeasibilitiesDown,
     682              double objectiveValue) ;
    671683private:
    672684 
    673685  /// Illegal Assignment operator
    674686  CbcBranchDefaultDecision & operator=(const CbcBranchDefaultDecision& rhs);
    675 
    676   /// data
    677 
    678   /// "best" so far
    679   double bestCriterion_;
    680 
    681   /// Change up for best
    682   double bestChangeUp_;
    683 
    684   /// Number of infeasibilities for up
    685   int bestNumberUp_;
    686 
    687   /// Change down for best
    688   double bestChangeDown_;
    689 
    690   /// Number of infeasibilities for down
    691   int bestNumberDown_;
    692 
    693   /// Pointer to best branching object
    694   CbcBranchingObject * bestObject_;
    695687
    696688};
  • trunk/include/CbcBranchBase.hpp

    r74 r122  
    132132  inline int id() const
    133133  { return id_;};
     134  /// Return Priority
     135  inline int priority() const
     136  { return priority_;};
     137  /// Set priority
     138  inline void setPriority(int priority)
     139  { priority_ = priority;};
    134140 
    135141  /// Column number if single column object -1 otherwise
     
    156162  /// Identifier (normally column number in matrix)
    157163  int id_;
     164  /// Priority
     165  int priority_;
    158166
    159167};
  • trunk/include/CbcModel.hpp

    r102 r122  
    318318  /// Get the specified object
    319319  const inline CbcObject * object(int which) const { return object_[which];};
     320  /// Get the specified object
     321  inline CbcObject * modifiableObject(int which) const { return object_[which];};
    320322
    321323  /// Delete all object information
     
    612614 
    613615  /// Get number of nonzero elements
    614   int getNumElements() const
     616  CoinBigIndex getNumElements() const
    615617  { return solver_->getNumElements();};
    616618
     
    749751  inline double * currentSolution() const
    750752  { return currentSolution_;};
    751   /// Make sure region there
    752   void reserveCurrentSolution();
     753  /// Make sure region there and optionally copy solution
     754  void reserveCurrentSolution(const double * solution=NULL);
    753755
    754756  /// Get pointer to array[getNumCols()] of primal solution vector
     
    10541056      If ifNotSimpleIntegers true then appended to normal integers
    10551057
     1058      This is now deprecated except for simple usage.  If user
     1059      creates Cbcobjects then set priority in them
     1060
    10561061      \internal Added for Kurt Spielberg.
    10571062  */
    1058   void passInPriorities(const int * priorities, bool ifNotSimpleIntegers,
    1059                         int defaultValue=1000);
    1060 
    1061   /// Priorities
    1062   inline const int * priority() const { return priority_;};
     1063  void passInPriorities(const int * priorities, bool ifNotSimpleIntegers);
    10631064
    10641065  /// Returns priority level for an object (or 1000 if no priorities exist)
    10651066  inline int priority(int sequence) const
    1066   {
    1067     if (priority_)
    1068       return priority_[sequence];
    1069     else
    1070       return 1000;
    1071   };
     1067  { return object_[sequence]->priority();};
    10721068  //@}
    10731069   
     
    13491345  /// Original columns as created by integerPresolve
    13501346  int * originalColumns_;
    1351   /// Priorities
    1352   int * priority_;
    13531347  /// How often to scan global cuts
    13541348  int howOftenGlobalScan_;
Note: See TracChangeset for help on using the changeset viewer.