Changeset 1839 for trunk


Ignore:
Timestamp:
Jan 16, 2013 1:41:25 PM (7 years ago)
Author:
forrest
Message:

multiple root solvers, stronger strong branching and cutoff as constraint

Location:
trunk/Cbc/src
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Cbc/src/CbcCountRowCut.cpp

    r1641 r1839  
    128128    }
    129129}
    130 
     130static double multiplier[] = {1.23456789e2,-9.87654321};
     131static int hashCut (const OsiRowCut2 & x, int size)
     132{
     133  int xN =x.row().getNumElements();
     134  double xLb = x.lb();
     135  double xUb = x.ub();
     136  const int * xIndices = x.row().getIndices();
     137  const double * xElements = x.row().getElements();
     138  unsigned int hashValue;
     139  double value=1.0;
     140  if (xLb>-1.0e10)
     141    value += xLb*multiplier[0];
     142  if (xUb<1.0e10)
     143    value += xUb*multiplier[1];
     144  for( int j=0;j<xN;j++) {
     145    int xColumn = xIndices[j];
     146    double xValue = xElements[j];
     147    int k=(j&1);
     148    value += (j+1)*multiplier[k]*(xColumn+1)*xValue;
     149  }
     150  // should be compile time but too lazy for now
     151  if (sizeof(value)>sizeof(hashValue)) {
     152    assert (sizeof(value)==2*sizeof(hashValue));
     153    union { double d; int i[2]; } xx;
     154    xx.d = value;
     155    hashValue = (xx.i[0] + xx.i[1]);
     156  } else {
     157    assert (sizeof(value)==sizeof(hashValue));
     158    union { double d; unsigned int i[2]; } xx;
     159    xx.d = value;
     160    hashValue = xx.i[0];
     161  }
     162  return hashValue%(size);
     163}
     164static int hashCut2 (const OsiRowCut2 & x, int size)
     165{
     166  int xN =x.row().getNumElements();
     167  double xLb = x.lb();
     168  double xUb = x.ub();
     169  const int * xIndices = x.row().getIndices();
     170  const double * xElements = x.row().getElements();
     171  unsigned int hashValue;
     172  double value=1.0;
     173  if (xLb>-1.0e10)
     174    value += xLb*multiplier[0];
     175  if (xUb<1.0e10)
     176    value += xUb*multiplier[1];
     177  for( int j=0;j<xN;j++) {
     178    int xColumn = xIndices[j];
     179    double xValue = xElements[j];
     180    int k=(j&1);
     181    value += (j+1)*multiplier[k]*(xColumn+1)*xValue;
     182  }
     183  // should be compile time but too lazy for now
     184  if (sizeof(value)>sizeof(hashValue)) {
     185    assert (sizeof(value)==2*sizeof(hashValue));
     186    union { double d; int i[2]; } xx;
     187    xx.d = value;
     188    hashValue = (xx.i[0] + xx.i[1]);
     189  } else {
     190    assert (sizeof(value)==sizeof(hashValue));
     191    union { double d; unsigned int i[2]; } xx;
     192    xx.d = value;
     193    hashValue = xx.i[0];
     194  }
     195  return hashValue%(size);
     196}
     197static bool same (const OsiRowCut2 & x, const OsiRowCut2 & y)
     198{
     199  int xN =x.row().getNumElements();
     200  int yN =y.row().getNumElements();
     201  bool identical=false;
     202  if (xN==yN) {
     203    double xLb = x.lb();
     204    double xUb = x.ub();
     205    double yLb = y.lb();
     206    double yUb = y.ub();
     207    if (fabs(xLb-yLb)<1.0e-8&&fabs(xUb-yUb)<1.0e-8) {
     208      const int * xIndices = x.row().getIndices();
     209      const double * xElements = x.row().getElements();
     210      const int * yIndices = y.row().getIndices();
     211      const double * yElements = y.row().getElements();
     212      int j;
     213      for( j=0;j<xN;j++) {
     214        if (xIndices[j]!=yIndices[j])
     215          break;
     216        if (fabs(xElements[j]-yElements[j])>1.0e-12)
     217          break;
     218      }
     219      identical =  (j==xN);
     220    }
     221  }
     222  return identical;
     223}
     224static bool same2 (const OsiRowCut2 & x, const OsiRowCut2 & y)
     225{
     226  int xN =x.row().getNumElements();
     227  int yN =y.row().getNumElements();
     228  bool identical=false;
     229  if (xN==yN) {
     230    double xLb = x.lb();
     231    double xUb = x.ub();
     232    double yLb = y.lb();
     233    double yUb = y.ub();
     234    if (fabs(xLb-yLb)<1.0e-8&&fabs(xUb-yUb)<1.0e-8) {
     235      const int * xIndices = x.row().getIndices();
     236      const double * xElements = x.row().getElements();
     237      const int * yIndices = y.row().getIndices();
     238      const double * yElements = y.row().getElements();
     239      int j;
     240      for( j=0;j<xN;j++) {
     241        if (xIndices[j]!=yIndices[j])
     242          break;
     243        if (fabs(xElements[j]-yElements[j])>1.0e-12)
     244          break;
     245      }
     246      identical =  (j==xN);
     247    }
     248  }
     249  return identical;
     250}
     251CbcRowCuts::CbcRowCuts(int initialMaxSize, int hashMultiplier)
     252{
     253  numberCuts_=0;
     254  size_ = initialMaxSize;
     255  hashMultiplier_ = hashMultiplier;
     256  int hashSize=hashMultiplier_*size_;
     257  if (size_) {
     258    rowCut_ = new  OsiRowCut2 * [size_];
     259    hash_ = new CoinHashLink[hashSize];
     260  } else {
     261    rowCut_ = NULL;
     262    hash_ = NULL;
     263  }
     264  for (int i=0;i<hashSize;i++) {
     265    hash_[i].index=-1;
     266    hash_[i].next=-1;
     267  }
     268  lastHash_=-1;
     269}
     270CbcRowCuts::~CbcRowCuts()
     271{
     272  for (int i=0;i<numberCuts_;i++)
     273    delete rowCut_[i];
     274  delete [] rowCut_;
     275  delete [] hash_;
     276}
     277CbcRowCuts::CbcRowCuts(const CbcRowCuts& rhs)
     278{
     279  numberCuts_=rhs.numberCuts_;
     280  hashMultiplier_ = rhs.hashMultiplier_;
     281  size_ = rhs.size_;
     282  int hashSize= size_*hashMultiplier_;
     283  lastHash_=rhs.lastHash_;
     284  if (size_) {
     285    rowCut_ = new  OsiRowCut2 * [size_];
     286    hash_ = new CoinHashLink[hashSize];
     287    for (int i=0;i<hashSize;i++) {
     288      hash_[i] = rhs.hash_[i];
     289    }
     290    for (int i=0;i<size_;i++) {
     291      if (rhs.rowCut_[i])
     292        rowCut_[i]=new OsiRowCut2(*rhs.rowCut_[i]);
     293      else
     294        rowCut_[i]=NULL;
     295    }
     296  } else {
     297    rowCut_ = NULL;
     298    hash_ = NULL;
     299  }
     300}
     301CbcRowCuts&
     302CbcRowCuts::operator=(const CbcRowCuts& rhs)
     303{
     304  if (this != &rhs) {
     305    for (int i=0;i<numberCuts_;i++)
     306      delete rowCut_[i];
     307    delete [] rowCut_;
     308    delete [] hash_;
     309    numberCuts_=rhs.numberCuts_;
     310    hashMultiplier_ = rhs.hashMultiplier_;
     311    size_ = rhs.size_;
     312    lastHash_=rhs.lastHash_;
     313    if (size_) {
     314      rowCut_ = new  OsiRowCut2 * [size_];
     315      int hashSize= size_*hashMultiplier_;
     316      hash_ = new CoinHashLink[hashSize];
     317      for (int i=0;i<hashSize;i++) {
     318        hash_[i] = rhs.hash_[i];
     319      }
     320      for (int i=0;i<size_;i++) {
     321        if (rhs.rowCut_[i])
     322          rowCut_[i]=new OsiRowCut2(*rhs.rowCut_[i]);
     323        else
     324          rowCut_[i]=NULL;
     325      }
     326    } else {
     327      rowCut_ = NULL;
     328      hash_ = NULL;
     329    }
     330  }
     331  return *this;
     332}
     333void
     334CbcRowCuts::eraseRowCut(int sequence)
     335{
     336  // find
     337  assert (sequence>=0&&sequence<numberCuts_);
     338  OsiRowCut2 * cut = rowCut_[sequence];
     339  int hashSize= size_*hashMultiplier_;
     340  int ipos = hashCut(*cut,hashSize);
     341  int found = -1;
     342  while ( true ) {
     343    int j1 = hash_[ipos].index;
     344    if ( j1 >= 0 ) {
     345      if (j1!=sequence) {
     346        int k = hash_[ipos].next;
     347        if ( k != -1 )
     348          ipos = k;
     349        else
     350          break;
     351      } else {
     352        found = j1;
     353        break;
     354      }
     355    } else {
     356      break;
     357    }
     358  }
     359  assert (found>=0);
     360  assert (hash_[ipos].index==sequence);
     361  // shuffle up
     362  while (hash_[ipos].next>=0) {
     363    int k = hash_[ipos].next;
     364    hash_[ipos]=hash_[k];
     365    ipos=k;
     366  }
     367  delete cut;
     368  // move last to found
     369  numberCuts_--;
     370  if (numberCuts_) {
     371    ipos = hashCut(*rowCut_[numberCuts_],hashSize);
     372    while ( true ) {
     373      int j1 = hash_[ipos].index;
     374      if (j1!=numberCuts_) {
     375        int k = hash_[ipos].next;
     376        ipos = k;
     377      } else {
     378        // change
     379        hash_[ipos].index=found;
     380        rowCut_[found]=rowCut_[numberCuts_];
     381        rowCut_[numberCuts_]=NULL;
     382        break;
     383      }
     384    }
     385  }
     386  assert (!rowCut_[numberCuts_]);
     387}
     388// Return 0 if added, 1 if not, -1 if not added because of space
     389int
     390CbcRowCuts::addCutIfNotDuplicate(const OsiRowCut & cut,int whichType)
     391{
     392  int hashSize= size_*hashMultiplier_;
     393  if (numberCuts_==size_) {
     394    size_ = 2*size_+100;
     395    hashSize=hashMultiplier_*size_;
     396    OsiRowCut2 ** temp = new  OsiRowCut2 * [size_];
     397    delete [] hash_;
     398    hash_ = new CoinHashLink[hashSize];
     399    for (int i=0;i<hashSize;i++) {
     400      hash_[i].index=-1;
     401      hash_[i].next=-1;
     402    }
     403    for (int i=0;i<numberCuts_;i++) {
     404      temp[i]=rowCut_[i];
     405      int ipos = hashCut(*temp[i],hashSize);
     406      int found = -1;
     407      int jpos=ipos;
     408      while ( true ) {
     409        int j1 = hash_[ipos].index;
     410       
     411        if ( j1 >= 0 ) {
     412          if ( !same(*temp[i],*temp[j1]) ) {
     413            int k = hash_[ipos].next;
     414            if ( k != -1 )
     415              ipos = k;
     416            else
     417              break;
     418          } else {
     419            found = j1;
     420            break;
     421          }
     422        } else {
     423          break;
     424        }
     425      }
     426      if (found<0) {
     427        assert (hash_[ipos].next==-1);
     428        if (ipos==jpos) {
     429          // first
     430          hash_[ipos].index=i;
     431        } else {
     432          // find next space
     433          while ( true ) {
     434            ++lastHash_;
     435            assert (lastHash_<hashSize);
     436            if ( hash_[lastHash_].index == -1 )
     437              break;
     438          }
     439          hash_[ipos].next = lastHash_;
     440          hash_[lastHash_].index = i;
     441        }
     442      }
     443    }
     444    delete [] rowCut_;
     445    rowCut_ = temp;
     446  }
     447  if (numberCuts_<size_) {
     448    double newLb = cut.lb();
     449    double newUb = cut.ub();
     450    CoinPackedVector vector = cut.row();
     451    int numberElements =vector.getNumElements();
     452    int * newIndices = vector.getIndices();
     453    double * newElements = vector.getElements();
     454    CoinSort_2(newIndices,newIndices+numberElements,newElements);
     455    int i;
     456    bool bad=false;
     457    for (i=0;i<numberElements;i++) {
     458      double value = fabs(newElements[i]);
     459      if (value<1.0e-12||value>1.0e12)
     460        bad=true;
     461    }
     462    if (bad)
     463      return 1;
     464    OsiRowCut2 newCut(whichType);
     465    newCut.setLb(newLb);
     466    newCut.setUb(newUb);
     467    newCut.setRow(vector);
     468    int ipos = hashCut(newCut,hashSize);
     469    int found = -1;
     470    int jpos=ipos;
     471    while ( true ) {
     472      int j1 = hash_[ipos].index;
     473     
     474      if ( j1 >= 0 ) {
     475        if ( !same(newCut,*rowCut_[j1]) ) {
     476          int k = hash_[ipos].next;
     477          if ( k != -1 )
     478            ipos = k;
     479          else
     480            break;
     481        } else {
     482          found = j1;
     483          break;
     484        }
     485      } else {
     486        break;
     487      }
     488    }
     489    if (found<0) {
     490      assert (hash_[ipos].next==-1);
     491      if (ipos==jpos) {
     492        // first
     493        hash_[ipos].index=numberCuts_;
     494      } else {
     495        // find next space
     496        while ( true ) {
     497          ++lastHash_;
     498          assert (lastHash_<hashSize);
     499          if ( hash_[lastHash_].index == -1 )
     500            break;
     501        }
     502        hash_[ipos].next = lastHash_;
     503        hash_[lastHash_].index = numberCuts_;
     504      }
     505      OsiRowCut2 * newCutPtr = new OsiRowCut2(whichType);
     506      newCutPtr->setLb(newLb);
     507      newCutPtr->setUb(newUb);
     508      newCutPtr->setRow(vector);
     509      rowCut_[numberCuts_++]=newCutPtr;
     510      return 0;
     511    } else {
     512      return 1;
     513    }
     514  } else {
     515    return -1;
     516  }
     517}
     518// Return 0 if added, 1 if not, -1 if not added because of space
     519int
     520CbcRowCuts::addCutIfNotDuplicateWhenGreedy(const OsiRowCut & cut,int whichType)
     521{
     522  int hashSize= size_*hashMultiplier_;
     523  if (numberCuts_==size_) {
     524    size_ = 2*size_+100;
     525    hashSize=hashMultiplier_*size_;
     526    OsiRowCut2 ** temp = new  OsiRowCut2 * [size_];
     527    delete [] hash_;
     528    hash_ = new CoinHashLink[hashSize];
     529    for (int i=0;i<hashSize;i++) {
     530      hash_[i].index=-1;
     531      hash_[i].next=-1;
     532    }
     533    for (int i=0;i<numberCuts_;i++) {
     534      temp[i]=rowCut_[i];
     535      int ipos = hashCut2(*temp[i],hashSize);
     536      int found = -1;
     537      int jpos=ipos;
     538      while ( true ) {
     539        int j1 = hash_[ipos].index;
     540       
     541        if ( j1 >= 0 ) {
     542          if ( !same2(*temp[i],*temp[j1]) ) {
     543            int k = hash_[ipos].next;
     544            if ( k != -1 )
     545              ipos = k;
     546            else
     547              break;
     548          } else {
     549            found = j1;
     550            break;
     551          }
     552        } else {
     553          break;
     554        }
     555      }
     556      if (found<0) {
     557        assert (hash_[ipos].next==-1);
     558        if (ipos==jpos) {
     559          // first
     560          hash_[ipos].index=i;
     561        } else {
     562          // find next space
     563          while ( true ) {
     564            ++lastHash_;
     565            assert (lastHash_<hashSize);
     566            if ( hash_[lastHash_].index == -1 )
     567              break;
     568          }
     569          hash_[ipos].next = lastHash_;
     570          hash_[lastHash_].index = i;
     571        }
     572      }
     573    }
     574    delete [] rowCut_;
     575    rowCut_ = temp;
     576  }
     577  if (numberCuts_<size_) {
     578    double newLb = cut.lb();
     579    double newUb = cut.ub();
     580    CoinPackedVector vector = cut.row();
     581    int numberElements =vector.getNumElements();
     582    int * newIndices = vector.getIndices();
     583    double * newElements = vector.getElements();
     584    CoinSort_2(newIndices,newIndices+numberElements,newElements);
     585    int i;
     586    bool bad=false;
     587    for (i=0;i<numberElements;i++) {
     588      double value = fabs(newElements[i]);
     589      if (value<1.0e-12||value>1.0e12)
     590        bad=true;
     591    }
     592    if (bad)
     593      return 1;
     594    OsiRowCut2 newCut(whichType);
     595    newCut.setLb(newLb);
     596    newCut.setUb(newUb);
     597    newCut.setRow(vector);
     598    int ipos = hashCut2(newCut,hashSize);
     599    int found = -1;
     600    int jpos=ipos;
     601    while ( true ) {
     602      int j1 = hash_[ipos].index;
     603     
     604      if ( j1 >= 0 ) {
     605        if ( !same2(newCut,*rowCut_[j1]) ) {
     606          int k = hash_[ipos].next;
     607          if ( k != -1 )
     608            ipos = k;
     609          else
     610            break;
     611        } else {
     612          found = j1;
     613          break;
     614        }
     615      } else {
     616        break;
     617      }
     618    }
     619    if (found<0) {
     620      assert (hash_[ipos].next==-1);
     621      if (ipos==jpos) {
     622        // first
     623        hash_[ipos].index=numberCuts_;
     624      } else {
     625        // find next space
     626        while ( true ) {
     627          ++lastHash_;
     628          assert (lastHash_<hashSize);
     629          if ( hash_[lastHash_].index == -1 )
     630            break;
     631        }
     632        hash_[ipos].next = lastHash_;
     633        hash_[lastHash_].index = numberCuts_;
     634      }
     635      OsiRowCut2 * newCutPtr = new OsiRowCut2(whichType);
     636      newCutPtr->setLb(newLb);
     637      newCutPtr->setUb(newUb);
     638      newCutPtr->setRow(vector);
     639      rowCut_[numberCuts_++]=newCutPtr;
     640      return 0;
     641    } else {
     642      return 1;
     643    }
     644  } else {
     645    return -1;
     646  }
     647}
     648// Add in cuts as normal cuts and delete
     649void
     650CbcRowCuts::addCuts(OsiCuts & cs)
     651{
     652  for (int i=0;i<numberCuts_;i++) {
     653    cs.insert(*rowCut_[i]);
     654    delete rowCut_[i] ;
     655    rowCut_[i] = NULL ;
     656  }
     657  numberCuts_=0;
     658}
  • trunk/Cbc/src/CbcCountRowCut.hpp

    r1573 r1839  
    110110    int numberPointingToThis_;
    111111
    112     /// Which generator created this cut
     112    /** Which generator created this cut
     113        (add 10000 if globally valid)
     114        if -1 then from global cut pool
     115        -2 cut branch
     116        -3 unknown
     117    */
    113118    int whichCutGenerator_;
    114119
    115120};
     121/**
     122   Really for Conflict cuts to -
     123   a) stop duplicates
     124   b) allow half baked cuts
     125   The whichRow_ field in OsiRowCut2 is used for a type
     126   0 - normal
     127   1 - processed cut
     128   2 - unprocessed cut i.e. dual ray computation
     129*/
     130// for hashing
     131typedef struct {
     132  int index, next;
     133} CoinHashLink;
     134class CbcRowCuts {
     135public:
    116136
     137  CbcRowCuts(int initialMaxSize=0, int hashMultiplier=4 );
     138  ~CbcRowCuts();
     139  CbcRowCuts(const CbcRowCuts& rhs);
     140  CbcRowCuts& operator=(const CbcRowCuts& rhs);
     141  inline OsiRowCut2 * cut(int sequence) const
     142  { return rowCut_[sequence];}
     143  inline int numberCuts() const
     144  { return numberCuts_;}
     145  inline int sizeRowCuts() const
     146  { return numberCuts_;}
     147  inline OsiRowCut * rowCutPtr(int sequence)
     148  { return rowCut_[sequence];}
     149  void eraseRowCut(int sequence);
     150  // Return 0 if added, 1 if not, -1 if not added because of space
     151  int addCutIfNotDuplicate(const OsiRowCut & cut,int whichType=0);
     152  // Return 0 if added, 1 if not, -1 if not added because of space
     153  int addCutIfNotDuplicateWhenGreedy(const OsiRowCut & cut,int whichType=0);
     154  // Add in cuts as normal cuts (and delete)
     155  void addCuts(OsiCuts & cs);
     156private:
     157  OsiRowCut2 ** rowCut_;
     158  /// Hash table
     159  CoinHashLink *hash_;
     160  int size_;
     161  int hashMultiplier_;
     162  int numberCuts_;
     163  int lastHash_;
     164};
    117165#endif
    118166
  • trunk/Cbc/src/CbcCutGenerator.cpp

    r1656 r1839  
    11831183    depthCutGeneratorInSub_ = value;
    11841184}
     1185// Add in statistics from other
     1186void
     1187CbcCutGenerator::addStatistics(const CbcCutGenerator * other)
     1188{
     1189  // Time in cut generator
     1190  timeInCutGenerator_ += other->timeInCutGenerator_;
     1191  // Number times cut generator entered
     1192  numberTimes_ += other->numberTimes_;
     1193  // Total number of cuts added
     1194  numberCuts_ += other->numberCuts_;
     1195  // Total number of elements added
     1196  numberElements_ += other->numberElements_;
     1197  // Total number of column cuts added
     1198  numberColumnCuts_ += other->numberColumnCuts_;
     1199  // Total number of cuts active after (at end of n cut passes at each node)
     1200  numberCutsActive_ += other->numberCutsActive_;
     1201  // Number of cuts generated at root
     1202  numberCutsAtRoot_ += other->numberCutsAtRoot_;
     1203  // Number of cuts active at root
     1204  numberActiveCutsAtRoot_ += other->numberActiveCutsAtRoot_;
     1205  // Number of short cuts at root
     1206  numberShortCutsAtRoot_ += other->numberShortCutsAtRoot_;
     1207}
     1208// Scale back statistics by factor
     1209void
     1210CbcCutGenerator::scaleBackStatistics(int factor)
     1211{
     1212  // leave time
     1213  // Number times cut generator entered
     1214  numberTimes_ = (numberTimes_+factor-1)/factor;
     1215  // Total number of cuts added
     1216  numberCuts_ = (numberCuts_+factor-1)/factor;
     1217  // Total number of elements added
     1218  numberElements_ = (numberElements_+factor-1)/factor;
     1219  // Total number of column cuts added
     1220  numberColumnCuts_ = (numberColumnCuts_+factor-1)/factor;
     1221  // Total number of cuts active after (at end of n cut passes at each node)
     1222  numberCutsActive_ = (numberCutsActive_+factor-1)/factor;
     1223  // Number of cuts generated at root
     1224  numberCutsAtRoot_ = (numberCutsAtRoot_+factor-1)/factor;
     1225  // Number of cuts active at root
     1226  numberActiveCutsAtRoot_ = (numberActiveCutsAtRoot_+factor-1)/factor;
     1227  // Number of short cuts at root
     1228  numberShortCutsAtRoot_ = (numberShortCutsAtRoot_+factor-1)/factor;
     1229}
    11851230// Create C++ lines to get to current state
    11861231void
  • trunk/Cbc/src/CbcCutGenerator.hpp

    r1656 r1839  
    360360        return numberShortCutsAtRoot_;
    361361    }
     362    inline void setNumberShortCutsAtRoot(int value) {
     363        numberShortCutsAtRoot_ = value;
     364    }
    362365    /// Set model
    363366    inline void setModel(CbcModel * model) {
     
    382385        switches_ |= yesNo ? 256 : 0;
    383386    }
     387    /// Add in statistics from other
     388    void addStatistics(const CbcCutGenerator * other);
     389    /// Scale back statistics by factor
     390    void scaleBackStatistics(int factor);
    384391    //@}
    385392
  • trunk/Cbc/src/CbcFullNodeInfo.hpp

    r1573 r1839  
    124124        return lower_;
    125125    }
     126    /// Set a bound
     127    inline void setColLower(int sequence, double value)
     128    { lower_[sequence]=value;}
     129    /// Mutable lower bounds
     130    inline double * mutableLower() const {
     131        return lower_;
     132    }
    126133    /// Upper bounds
    127134    inline const double * upper() const {
     135        return upper_;
     136    }
     137    /// Set a bound
     138    inline void setColUpper(int sequence, double value)
     139    { upper_[sequence]=value;}
     140    /// Mutable upper bounds
     141    inline double * mutableUpper() const {
    128142        return upper_;
    129143    }
  • trunk/Cbc/src/CbcHeuristic.cpp

    r1836 r1839  
    913913                solver2->resolve();
    914914                CbcModel model(*solver2);
     915                // move seed across
     916                model.randomNumberGenerator()->setSeed(model_->randomNumberGenerator()->getSeed());
    915917                if (numberNodes >= 0) {
    916918                    // normal
     
    923925                    model.setFastNodeDepth(-1);
    924926                    model.setCutoff(signedCutoff);
     927                    model.setStrongStrategy(0);
    925928                    // Don't do if original fraction > 1.0 and too large
    926929                    if (fractionSmall_>1.0 && fractionSmall_ < 1000000.0) {
     
    945948                    if ((saveModelOptions&2048) == 0)
    946949                      model.setMoreSpecialOptions(model_->moreSpecialOptions());
     950                    // off conflict analysis
     951                    model.setMoreSpecialOptions(model.moreSpecialOptions()&~4194304);
     952                   
    947953                    // Lightweight
    948954                    CbcStrategyDefaultSubTree strategy(model_, 1, 5, 1, 0);
     
    958964                    // going for full search and copy across more stuff
    959965                    model.gutsOfCopy(*model_, 2);
     966                    assert (!model_->heuristicModel());
     967                    model_->setHeuristicModel(&model);
    960968                    for (int i = 0; i < model.numberCutGenerators(); i++) {
    961969                        CbcCutGenerator * generator = model.cutGenerator(i);
     
    9961004                        CglStored cuts = process.cuts();
    9971005                        model.addCutGenerator(&cuts, 1, "Stored from first");
     1006                        model.cutGenerator(model.numberCutGenerators()-1)->setGlobalCuts(true);
    9981007                    }
    9991008                }
     
    12091218                    model_->setSpecialOptions(saveOptions|1048576);
    12101219                    model.branchAndBound();
     1220                    model_->setHeuristicModel(NULL);
    12111221                    model_->setSpecialOptions(saveOptions);
    12121222#ifdef ALWAYS_DUAL
  • trunk/Cbc/src/CbcHeuristicFPump.cpp

    r1813 r1839  
    16751675        if (usedColumn && !exitAll) {
    16761676            OsiSolverInterface * newSolver = cloneBut(3); // was model_->continuousSolver()->clone();
     1677#if 0 //def COIN_HAS_CLP
     1678            OsiClpSolverInterface * clpSolver
     1679              = dynamic_cast<OsiClpSolverInterface *> (newSolver);
     1680            if (clpSolver) {
     1681              ClpSimplex * simplex = clpSolver->getModelPtr();
     1682              simplex->writeMps("start.mps",2,1);
     1683            }
     1684#endif
    16771685            const double * colLower = newSolver->getColLower();
    16781686            const double * colUpper = newSolver->getColUpper();
     
    17621770                    double cutoff2 = newSolutionValue +
    17631771                                     CoinMax(model_->getCutoffIncrement(), 1.0e-3);
     1772#if 0
     1773                      {
     1774                        OsiClpSolverInterface * clpSolver
     1775                        = dynamic_cast<OsiClpSolverInterface *> (newSolver);
     1776                        if (clpSolver) {
     1777                            ClpSimplex * simplex = clpSolver->getModelPtr();
     1778                            simplex->writeMps("testA.mps",2,1);
     1779                        }
     1780                      }
     1781#endif
    17641782                    int returnCode2 = smallBranchAndBound(newSolver, numberNodes_, newSolution, newSolutionValue,
    17651783                                                          cutoff2, "CbcHeuristicLocalAfterFPump");
     
    18001818                // recompute solution value
    18011819                if (returnCode && true) {
     1820#if 0
     1821                      {
     1822                        OsiClpSolverInterface * clpSolver
     1823                        = dynamic_cast<OsiClpSolverInterface *> (newSolver);
     1824                        if (clpSolver) {
     1825                            ClpSimplex * simplex = clpSolver->getModelPtr();
     1826                            simplex->writeMps("testB.mps",2,1);
     1827                        }
     1828                      }
     1829#endif
    18021830                    delete newSolver;
    18031831                    newSolver = cloneBut(3); // was model_->continuousSolver()->clone();
     
    19331961                        } else {
    19341962                            //newSolver->writeMps("bad3.mps");
     1963                          sprintf(pumpPrint, "On closer inspection solution is not valid");
     1964                          model_->messageHandler()->message(CBC_FPUMP1, model_->messages())
     1965                            << pumpPrint
     1966                            << CoinMessageEol;
    19351967                            exitAll = true;
    19361968                            break;
  • trunk/Cbc/src/CbcHeuristicLocal.cpp

    r1822 r1839  
    10671067
    10681068  numCouldRun_++;
    1069   if (!model_->bestSolution())
    1070     return 0; // odd - because in parallel mode
    10711069  int nodeCount = model_->getNodeCount();
    10721070  if (numberSolutions_ == model_->getSolutionCount())
    10731071    return 0;
     1072  if (!model_->bestSolution())
     1073    return 0; // odd - because in parallel mode
    10741074  numberSolutions_ = model_->getSolutionCount();
    10751075  lastRunDeep_ = nodeCount;
     
    13421342        }
    13431343    }
    1344     // Now fix all integers as close to zero if zero or large cost
     1344    // Now fix all integers as close to zero if not zero or large cost
    13451345    int nFix = 0;
    13461346    for (i = 0; i < numberIntegers; i++) {
  • trunk/Cbc/src/CbcMessage.cpp

    r1791 r1839  
    2424    {CBC_END, 5, 1, "Partial search - best objective %g (best possible %g), took %d iterations and %d nodes (%.2f seconds)"},
    2525    {CBC_INFEAS, 6, 1, "The LP relaxation is infeasible or too expensive"},
    26     {CBC_STRONG, 7, 3, "Strong branching on %d (%d), down %g (%d) up %g (%d) value %g"},
     26    {CBC_STRONG, 7, 4, "Strong branching on %d (%d), down %g (%d) up %g (%d) value %g"},
    2727    {CBC_SOLINDIVIDUAL, 8, 2, "%d has value %g"},
    2828    {CBC_INTEGERINCREMENT, 9, 1, "Objective coefficients multiple of %g"},
     
    3232    {CBC_ROOT, 13, 1, "At root node, %d cuts changed objective from %g to %g in %d passes"},
    3333    {CBC_GENERATOR, 14, 1, "Cut generator %d (%s) - %d row cuts average %.1f elements, %d column cuts (%d active) %? in %.3f seconds - new frequency is %d"},
    34     {CBC_BRANCH, 15, 2, "Node %d Obj %g Unsat %d depth %d"},
     34    {CBC_BRANCH, 15, 3, "Node %d Obj %g Unsat %d depth %d"},
    3535    {CBC_STRONGSOL, 16, 1, "Integer solution of %g found by strong branching after %d iterations and %d nodes (%.2f seconds)"},
    3636    {CBC_VUB_PASS, 17, 1, "%d solved, %d variables fixed, %d tightened"},
  • trunk/Cbc/src/CbcModel.cpp

    r1832 r1839  
    6262#include "CbcFeasibilityBase.hpp"
    6363#include "CbcFathom.hpp"
     64#include "CbcFullNodeInfo.hpp"
    6465// include Probing
    6566#include "CglProbing.hpp"
     
    16931694                // try and redo debugger
    16941695                OsiRowCutDebugger * debugger = const_cast<OsiRowCutDebugger *> (solver_->getRowCutDebuggerAlways());
    1695                 if (debugger)
     1696                if (debugger) {
     1697                  if (numberColumns<=debugger->numberColumns())
    16961698                    debugger->redoSolution(numberColumns, originalColumns);
     1699                  else
     1700                    debugger=NULL; // no idea how to handle (SOS?)
     1701                }
    16971702                // User-provided solution might have been best. Synchronise.
    16981703                if (bestSolution_) {
     
    22182223    continuousSolver_ = solver_->clone() ;
    22192224
     2225    // add cutoff as constraint if wanted
     2226    if ((moreSpecialOptions_&16777216)!=0) {
     2227      if (!parentModel_) {
     2228        int numberColumns=solver_->getNumCols();
     2229        double * obj = CoinCopyOfArray(solver_->getObjCoefficients(),numberColumns);
     2230        int * indices = new int [numberColumns];
     2231        int n=0;
     2232        for (int i=0;i<numberColumns;i++) {
     2233          if (obj[i]) {
     2234            indices[n]=i;
     2235            obj[n++]=obj[i];
     2236          }
     2237        }
     2238        if (n) {
     2239          double cutoff=getCutoff();
     2240          double offset;
     2241          solver_->getDblParam(OsiObjOffset, offset);
     2242          solver_->addRow(n,indices,obj,-COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset);
     2243        } else {
     2244          // no objective!
     2245          moreSpecialOptions_ &= ~16777216;
     2246        }
     2247        delete [] indices;
     2248        delete [] obj;
     2249      } else {
     2250        // switch off
     2251        moreSpecialOptions_ &= ~16777216;
     2252      }
     2253    }
    22202254    numberRowsAtContinuous_ = getNumRows() ;
    22212255    solver_->saveBaseModel();
     
    23462380        CglCutGenerator * generator = generator_[iCutGenerator]->generator();
    23472381        generator->setAggressiveness(generator->getAggressiveness() + 100);
     2382        if (!generator->canDoGlobalCuts())
     2383          generator->setGlobalCuts(false);
    23482384    }
    23492385    OsiCuts cuts ;
     
    24142450      will be removed from the heuristics list by doHeuristicsAtRoot.
    24152451    */
     2452    // See if multiple runs wanted
     2453    CbcModel ** rootModels=NULL;
     2454    if (!parentModel_&&multipleRootTries_%100) {
     2455      double rootTimeCpu=CoinCpuTime();
     2456      double startTimeRoot=CoinGetTimeOfDay();
     2457      int numberRootThreads=1;
     2458      /* undocumented fine tuning
     2459         aabbcc where cc is number of tries
     2460         bb if nonzero is number of threads
     2461         aa if nonzero just do heuristics
     2462      */
     2463      int numberModels = multipleRootTries_%100;
     2464#ifdef CBC_THREAD
     2465      numberRootThreads = (multipleRootTries_/100)%100;
     2466      if (!numberRootThreads)
     2467        numberRootThreads=numberModels;
     2468#endif
     2469      int otherOptions = (multipleRootTries_/10000)%100;
     2470      rootModels = new CbcModel * [numberModels];
     2471      unsigned int newSeed = randomSeed_;
     2472      if (newSeed==0) {
     2473        double time = fabs(CoinGetTimeOfDay());
     2474        while (time>=COIN_INT_MAX)
     2475          time *= 0.5;
     2476        newSeed = static_cast<unsigned int>(time);
     2477      } else if (newSeed<0) {
     2478        newSeed = 123456789;
     2479#ifdef COIN_HAS_CLP
     2480        OsiClpSolverInterface * clpSolver
     2481          = dynamic_cast<OsiClpSolverInterface *> (solver_);
     2482        if (clpSolver) {
     2483          newSeed += clpSolver->getModelPtr()->randomNumberGenerator()->getSeed();
     2484        }
     2485#endif
     2486      }
     2487      CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis *> (solver_->getEmptyWarmStart());
     2488      for (int i=0;i<numberModels;i++) {
     2489        rootModels[i]=new CbcModel(*this);
     2490        rootModels[i]->setNumberThreads(0);
     2491        rootModels[i]->setMaximumNodes(otherOptions ? -1 : 0);
     2492        rootModels[i]->setRandomSeed(newSeed+10000000*i);
     2493        rootModels[i]->randomNumberGenerator()->setSeed(newSeed+50000000*i);
     2494        rootModels[i]->setMultipleRootTries(0);
     2495        // use seed
     2496        rootModels[i]->setSpecialOptions(specialOptions_ |(4194304|8388608));
     2497        rootModels[i]->solver_->setWarmStart(basis);
     2498#ifdef COIN_HAS_CLP
     2499        OsiClpSolverInterface * clpSolver
     2500          = dynamic_cast<OsiClpSolverInterface *> (rootModels[i]->solver_);
     2501        if (clpSolver) {
     2502          clpSolver->getModelPtr()->setRandomSeed(newSeed+20000000*i);
     2503          clpSolver->getModelPtr()->allSlackBasis();
     2504        }
     2505#endif
     2506      }
     2507      delete basis;
     2508      void * doRootCbcThread(void * voidInfo);
     2509#ifdef CBC_THREAD
     2510      if (numberRootThreads==1) {
     2511#endif
     2512        for (int iModel=0;iModel<numberModels;iModel++) {
     2513          doRootCbcThread(rootModels[iModel]);
     2514          // see if solved at root node
     2515          if (rootModels[iModel]->getMaximumNodes()) {
     2516            feasible=false;
     2517            break;
     2518          }
     2519        }
     2520#ifdef CBC_THREAD
     2521      } else {
     2522        Coin_pthread_t * threadId = new Coin_pthread_t [numberRootThreads];
     2523        for (int kModel=0;kModel<numberModels;kModel+=numberRootThreads) {
     2524          bool finished=false;
     2525          for (int iModel=kModel;iModel<CoinMin(numberModels,kModel+numberRootThreads);iModel++) {
     2526            pthread_create(&(threadId[iModel-kModel].thr), NULL,
     2527                           doRootCbcThread,
     2528                           rootModels[iModel]);
     2529          }
     2530          // wait
     2531          for (int iModel=kModel;iModel<CoinMin(numberModels,kModel+numberRootThreads);iModel++) {
     2532            pthread_join(threadId[iModel-kModel].thr, NULL);
     2533          }
     2534          // see if solved at root node
     2535          for (int iModel=kModel;iModel<CoinMin(numberModels,kModel+numberRootThreads);iModel++) {
     2536            if (rootModels[iModel]->getMaximumNodes())
     2537              finished=true;
     2538          }
     2539          if (finished) {
     2540            feasible=false;
     2541            break;
     2542          }
     2543        }
     2544        delete [] threadId;
     2545      }
     2546#endif
     2547      // sort solutions
     2548      int * which = new int [numberModels];
     2549      double * value = new double [numberModels];
     2550      int numberSolutions=0;
     2551      for (int iModel=0;iModel<numberModels;iModel++) {
     2552        if (rootModels[iModel]->bestSolution()) {
     2553          which[numberSolutions]=iModel;
     2554          value[numberSolutions++]=
     2555            -rootModels[iModel]->getMinimizationObjValue();
     2556        }
     2557      }
     2558      char general[100];
     2559      rootTimeCpu=CoinCpuTime()-rootTimeCpu;
     2560      if (numberRootThreads==1)
     2561        sprintf(general,"Multiple root solvers took a total of %.2f seconds\n",
     2562                rootTimeCpu);
     2563      else
     2564        sprintf(general,"Multiple root solvers took a total of %.2f seconds (%.2f elapsed)\n",
     2565                rootTimeCpu,CoinGetTimeOfDay()-startTimeRoot);
     2566      messageHandler()->message(CBC_GENERAL,
     2567                                messages())
     2568        << general << CoinMessageEol ;
     2569      CoinSort_2(value,value+numberSolutions,which);
     2570      // to get name
     2571      CbcHeuristicRINS dummyHeuristic;
     2572      dummyHeuristic.setHeuristicName("Multiple root solvers");
     2573      lastHeuristic_=&dummyHeuristic;
     2574      for (int i=0;i<numberSolutions;i++) {
     2575        double objValue = - value[i];
     2576        if (objValue<getCutoff()) {
     2577          int iModel=which[i];
     2578          setBestSolution(CBC_ROUNDING,objValue,
     2579                          rootModels[iModel]->bestSolution());
     2580        }
     2581      }
     2582      lastHeuristic_=NULL;
     2583      delete [] which;
     2584      delete [] value;
     2585    }
    24162586    // Do heuristics
    2417     if (numberObjects_)
     2587    if (numberObjects_&&!rootModels)
    24182588        doHeuristicsAtRoot();
    24192589    if (solverCharacteristics_->solutionAddsCuts()) {
     
    24962666            // User event
    24972667            if (!eventHappened_ && feasible) {
     2668                if (rootModels) {
     2669                  int numberModels = multipleRootTries_%100;
     2670                  const OsiSolverInterface ** solvers = new
     2671                    const OsiSolverInterface * [numberModels];
     2672                  int numberRows=continuousSolver_->getNumRows();
     2673                  int maxCuts=0;
     2674                  for (int i=0;i<numberModels;i++) {
     2675                    solvers[i]=rootModels[i]->solver();
     2676                    int numberRows2=solvers[i]->getNumRows();
     2677                    assert (numberRows2>=numberRows);
     2678                    maxCuts += numberRows2-numberRows;
     2679                    // accumulate statistics
     2680                    for (int j=0;j<numberCutGenerators_;j++) {
     2681                      generator_[j]->addStatistics(rootModels[i]->cutGenerator(j));
     2682                    }
     2683                  }
     2684                  for (int j=0;j<numberCutGenerators_;j++) {
     2685                    generator_[j]->scaleBackStatistics(numberModels);
     2686                  }
     2687                  CbcRowCuts rowCut(maxCuts);
     2688                  for (int iModel=0;iModel<numberModels;iModel++) {
     2689                    int numberRows2=solvers[iModel]->getNumRows();
     2690                    const CoinPackedMatrix * rowCopy = solvers[iModel]->getMatrixByRow();
     2691                    const int * rowLength = rowCopy->getVectorLengths();
     2692                    const double * elements = rowCopy->getElements();
     2693                    const int * column = rowCopy->getIndices();
     2694                    const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
     2695                    const double * rowLower = solvers[iModel]->getRowLower();
     2696                    const double * rowUpper = solvers[iModel]->getRowUpper();
     2697                    for (int iRow=numberRows;iRow<numberRows2;iRow++) {
     2698                      OsiRowCut rc;
     2699                      rc.setLb(rowLower[iRow]);
     2700                      rc.setUb(rowUpper[iRow]);
     2701                      CoinBigIndex start = rowStart[iRow];
     2702                      rc.setRow(rowLength[iRow],column+start,elements+start,false);
     2703                      rowCut.addCutIfNotDuplicate(rc);
     2704                    }
     2705                    //int cutsAdded=rowCut.numberCuts()-numberCuts;
     2706                    //numberCuts += cutsAdded;
     2707                    //printf("Model %d gave %d cuts (out of %d possible)\n",
     2708                    //     iModel,cutsAdded,numberRows2-numberRows);
     2709                  }
     2710                  rowCut.addCuts(cuts);
     2711                  char printBuffer[200];
     2712                  sprintf(printBuffer,"%d solvers added %d different cuts out of pool of %d",
     2713                          numberModels,cuts.sizeRowCuts(),maxCuts);
     2714                  messageHandler()->message(CBC_GENERAL, messages())
     2715                    << printBuffer << CoinMessageEol ;
     2716                  delete [] solvers;
     2717                }
    24982718                feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_,
    24992719                                         NULL);
     
    25882808        }
    25892809    }
     2810    if (rootModels) {
     2811      int numberModels = multipleRootTries_%100;
     2812      for (int i=0;i<numberModels;i++)
     2813        delete rootModels[i];
     2814      delete [] rootModels;
     2815    }
    25902816    // check extra info on feasibility
    25912817    if (!solverCharacteristics_->mipFeasible())
    25922818        feasible = false;
    2593 
     2819    // If max nodes==0 - don't do strong branching
     2820    if (!getMaximumNodes()) {
     2821      if (feasible)
     2822        feasible=false;
     2823      else
     2824        setMaximumNodes(1); //allow to stop on success
     2825    }
     2826    topOfTree_=NULL;
    25942827#ifdef CLP_RESOLVE
    25952828    if ((moreSpecialOptions_&2097152)!=0&&!parentModel_&&feasible) {
     
    28263059    //solverCharacteristics_->setSolver(solver_);
    28273060    if (feasible) {
    2828         //#define HOTSTART -1
     3061#define HOTSTART -1
    28293062#if HOTSTART<0
    28303063        if (bestSolution_ && !parentModel_ && !hotstartSolution_ &&
     
    29313164                        changed = true;
    29323165                    } else {
    2933                         if (nForced + nZeroDj > 50 ||
    2934                                 (nForced + nZeroDj)*4 > numberIntegers_)
     3166                        if (nForced + nZeroDj > 5000 ||
     3167                                (nForced + nZeroDj)*2 > numberIntegers_)
    29353168                            possible = false;
    29363169                    }
     
    32103443                CglImplication implication(probingInfo_);
    32113444                addCutGenerator(&implication, 1, "ImplicationCuts", true, false, false, -200);
     3445                generator_[numberCutGenerators_-1]->setGlobalCuts(true);
    32123446            } else {
    32133447                delete probingInfo_;
     
    32973531            newNode->initializeInfo() ;
    32983532            tree_->push(newNode) ;
     3533            // save pointer to root node - so can pick up bounds
     3534            if (!topOfTree_)
     3535              topOfTree_ = dynamic_cast<CbcFullNodeInfo *>(newNode->nodeInfo()) ;
    32993536            if (statistics_) {
    33003537                if (numberNodes2_ == maximumStatistics_) {
     
    42074444      outside world will be able to obtain information about the solution using
    42084445      public methods.
     4446
     4447      Don't replace if we are trying to save cuts
    42094448    */
    4210     if (bestSolution_ && (solverCharacteristics_->solverType() < 2 || solverCharacteristics_->solverType() == 4)) {
     4449    if (bestSolution_ && (solverCharacteristics_->solverType() < 2 || solverCharacteristics_->solverType() == 4) &&
     4450        ((specialOptions_&8388608)==0||(specialOptions_&2048)!=0)) {
    42114451        setCutoff(1.0e50) ; // As best solution should be worse than cutoff
     4452        // change cutoff as constraint if wanted
     4453        if ((moreSpecialOptions_&16777216)!=0) {
     4454          if (solver_->getNumRows()>=numberRowsAtContinuous_)
     4455            solver_->setRowUpper(numberRowsAtContinuous_-1,1.0e50);
     4456        }
    42124457        // also in continuousSolver_
    42134458        if (continuousSolver_) {
     
    42684513      Destroy global cuts by replacing with an empty OsiCuts object.
    42694514    */
    4270     globalCuts_ = OsiCuts() ;
     4515    globalCuts_ = CbcRowCuts() ;
     4516    delete globalConflictCuts_;
     4517    globalConflictCuts_=NULL;
    42714518    if (!bestSolution_) {
    42724519        // make sure lp solver is infeasible
     
    44614708        currentSolution_(NULL),
    44624709        testSolution_(NULL),
     4710        globalConflictCuts_(NULL),
    44634711        minimumDrop_(1.0e-4),
    44644712        numberSolutions_(0),
     
    44984746        specialOptions_(0),
    44994747        moreSpecialOptions_(0),
     4748        topOfTree_(NULL),
    45004749        subTreeModel_(NULL),
     4750        heuristicModel_(NULL),
    45014751        numberStoppedSubTrees_(0),
    45024752        presolve_(0),
     
    45374787        maximumRows_(0),
    45384788        randomSeed_(-1),
     4789        multipleRootTries_(0),
    45394790        currentDepth_(0),
    45404791        whichGenerator_(NULL),
     
    45524803        numberNewCuts_(0),
    45534804        searchStrategy_(-1),
     4805        strongStrategy_(0),
    45544806        numberStrongIterations_(0),
    45554807        resolveAfterTakeOffCuts_(true),
     
    46234875        sumChangeObjective1_(0.0),
    46244876        sumChangeObjective2_(0.0),
     4877        globalConflictCuts_(NULL),
    46254878        minimumDrop_(1.0e-4),
    46264879        numberSolutions_(0),
     
    46564909        specialOptions_(0),
    46574910        moreSpecialOptions_(0),
     4911        topOfTree_(NULL),
    46584912        subTreeModel_(NULL),
     4913        heuristicModel_(NULL),
    46594914        numberStoppedSubTrees_(0),
    46604915        presolve_(0),
     
    46954950        maximumRows_(0),
    46964951        randomSeed_(-1),
     4952        multipleRootTries_(0),
    46974953        currentDepth_(0),
    46984954        whichGenerator_(NULL),
     
    47104966        numberNewCuts_(0),
    47114967        searchStrategy_(-1),
     4968        strongStrategy_(0),
    47124969        numberStrongIterations_(0),
    47134970        resolveAfterTakeOffCuts_(true),
     
    48975154        sumChangeObjective1_(rhs.sumChangeObjective1_),
    48985155        sumChangeObjective2_(rhs.sumChangeObjective2_),
     5156        globalConflictCuts_(NULL),
    48995157        minimumDrop_(rhs.minimumDrop_),
    49005158        numberSolutions_(rhs.numberSolutions_),
     
    49125170        specialOptions_(rhs.specialOptions_),
    49135171        moreSpecialOptions_(rhs.moreSpecialOptions_),
     5172        topOfTree_(NULL),
    49145173        subTreeModel_(rhs.subTreeModel_),
     5174        heuristicModel_(NULL),
    49155175        numberStoppedSubTrees_(rhs.numberStoppedSubTrees_),
    49165176        presolve_(rhs.presolve_),
     
    49405200        maximumRows_(0),
    49415201        randomSeed_(rhs.randomSeed_),
     5202        multipleRootTries_(rhs.multipleRootTries_),
    49425203        currentDepth_(0),
    49435204        whichGenerator_(NULL),
     
    49555216        numberNewCuts_(rhs.numberNewCuts_),
    49565217        searchStrategy_(rhs.searchStrategy_),
     5218        strongStrategy_(rhs.strongStrategy_),
    49575219        numberStrongIterations_(rhs.numberStrongIterations_),
    49585220        resolveAfterTakeOffCuts_(rhs.resolveAfterTakeOffCuts_),
     
    52625524        moreSpecialOptions_ = rhs.moreSpecialOptions_;
    52635525        subTreeModel_ = rhs.subTreeModel_;
     5526        heuristicModel_ = NULL;
    52645527        numberStoppedSubTrees_ = rhs.numberStoppedSubTrees_;
    52655528        presolve_ = rhs.presolve_;
     
    52855548        maximumCutPasses_ = rhs.maximumCutPasses_;
    52865549        randomSeed_ = rhs.randomSeed_;
     5550        multipleRootTries_ = rhs.multipleRootTries_;
    52875551        preferredWay_ = rhs.preferredWay_;
    52885552        currentPassNumber_ = rhs.currentPassNumber_;
     
    52905554        memcpy(dblParam_, rhs.dblParam_, sizeof(dblParam_));
    52915555        globalCuts_ = rhs.globalCuts_;
     5556        delete globalConflictCuts_;
     5557        globalConflictCuts_=NULL;
    52925558        int i;
    52935559        for (i = 0; i < numberCutGenerators_; i++) {
     
    53405606        masterThread_ = NULL;
    53415607        searchStrategy_ = rhs.searchStrategy_;
     5608        strongStrategy_ = rhs.strongStrategy_;
    53425609        numberStrongIterations_ = rhs.numberStrongIterations_;
    53435610        strongInfo_[0] = rhs.strongInfo_[0];
     
    55685835    delete cutModifier_;
    55695836    cutModifier_ = NULL;
     5837    topOfTree_ = NULL;
    55705838    resetModel();
    55715839}
     
    56485916        tree_->cleanTree(this, -1.0e100, bestPossibleObjective_) ;
    56495917    subTreeModel_ = NULL;
     5918    heuristicModel_ = NULL;
    56505919    numberStoppedSubTrees_ = 0;
    56515920    numberInfeasibleNodes_ = 0;
     
    56645933    numberNewCuts_ = 0;
    56655934    searchStrategy_ = -1;
     5935    strongStrategy_ = 0;
    56665936    numberStrongIterations_ = 0;
    56675937    // Parameters which need to be reset
     
    56715941    dblParam_[CbcCurrentObjectiveValue] = 1.0e100;
    56725942    dblParam_[CbcCurrentMinimizationObjectiveValue] = 1.0e100;
     5943    delete globalConflictCuts_;
     5944    globalConflictCuts_=NULL;
    56735945}
    56745946/* Most of copy constructor
     
    56925964    maximumCutPasses_ =  rhs.maximumCutPasses_;
    56935965    randomSeed_ = rhs.randomSeed_;
     5966    multipleRootTries_ = rhs.multipleRootTries_;
    56945967    preferredWay_ = rhs.preferredWay_;
    56955968    resolveAfterTakeOffCuts_ = rhs.resolveAfterTakeOffCuts_;
     
    66326905#endif
    66336906    bool feasible = true ;
    6634     int lastNumberCuts = 0 ;
    66356907    int violated = 0 ;
    66366908    int numberRowsAtStart = solver_->getNumRows() ;
     
    66406912
    66416913    numberOldActiveCuts_ = numberRowsAtStart - numberRowsAtContinuous_ ;
    6642     numberNewCuts_ = 0 ;
     6914    numberNewCuts_ = cuts.sizeRowCuts();
     6915    int lastNumberCuts = numberNewCuts_ ;
     6916    if (numberNewCuts_) {
     6917      // from multiple root passes
     6918      const OsiRowCut **addCuts = new const OsiRowCut* [numberNewCuts_];
     6919      for (int i = 0; i < numberNewCuts_; i++) {
     6920        addCuts[i] = cuts.rowCutPtr(i);
     6921      }
     6922      solver_->applyRowCuts(numberNewCuts_, addCuts);
     6923      delete [] addCuts;
     6924    }
    66436925
    66446926    bool onOptimalPath = false ;
     
    66806962        objectiveValue = node->objectiveValue();
    66816963    }
     6964    int save = moreSpecialOptions_;
     6965    if ((moreSpecialOptions_&4194304)!=0)
     6966      moreSpecialOptions_ |= 8388608;
    66826967    int returnCode = resolve(node ? node->nodeInfo() : NULL, 1);
     6968    moreSpecialOptions_=save;
     6969#ifdef CONFLICT_CUTS
     6970#ifdef COIN_HAS_CLP
     6971    // if infeasible conflict analysis
     6972    if (solver_->isProvenPrimalInfeasible()&&!parentModel_&&
     6973        (moreSpecialOptions_&4194304)!=0&&clpSolver) {
     6974      //printf("infeasible - do conflict analysis\n");
     6975      assert (topOfTree_);
     6976      int iType=1;
     6977      OsiRowCut * cut = clpSolver->modelCut(topOfTree_->lower(),
     6978                                            topOfTree_->upper(),
     6979                                            numberRowsAtContinuous_,whichGenerator_,iType);
     6980      if (cut) {
     6981        printf("XXXXXX cut\n");
     6982        //cut->print();
     6983        if (!iType) {
     6984          makeGlobalCut(cut) ;
     6985          if ((specialOptions_&1) != 0) {
     6986            debugger = continuousSolver_->getRowCutDebugger() ;
     6987            if (debugger)
     6988              if (debugger->invalidCut(*cut)) {
     6989                continuousSolver_->applyRowCuts(1,cut);
     6990                continuousSolver_->writeMps("bad");
     6991              }
     6992              CoinAssert (!debugger->invalidCut(*cut));
     6993          }
     6994        } else {
     6995          makePartialCut(cut);
     6996        }
     6997        delete cut;
     6998      }
     6999    }
     7000    if ((moreSpecialOptions_&4194304)!=0&&solver_->isProvenPrimalInfeasible()
     7001        &&clpSolver&&clpSolver->lastAlgorithm()==2&&
     7002        clpSolver->getModelPtr()->infeasibilityRay()&&
     7003        !parentModel_) {
     7004      printf("ray exists\n");
     7005    }
     7006#endif
     7007#endif   
    66837008#if COIN_DEVELOP>1
    66847009    //if (!solver_->getIterationCount()&&solver_->isProvenOptimal())
     
    70187343                (numberNodes_ % howOftenGlobalScan_) == 0 &&
    70197344                (doCutsNow(1) || true)) {
    7020             int numberCuts = globalCuts_.sizeColCuts() ;
    7021             int i;
     7345            // global column cuts now done in node at top of tree
     7346            int numberCuts = globalCuts_.sizeRowCuts() ;
    70227347            // possibly extend whichGenerator
    70237348            resizeWhichGenerator(numberViolated, numberViolated + numberCuts);
    7024             for ( i = 0 ; i < numberCuts ; i++) {
    7025                 OsiColCut *thisCut = globalCuts_.colCutPtr(i) ;
    7026                 if (thisCut->violated(cbcColSolution_) > primalTolerance ||
    7027                         thisCut->effectiveness() == COIN_DBL_MAX) {
    7028 #ifdef CLP_INVESTIGATE
    7029                     if (thisCut->violated(cbcColSolution_) > primalTolerance)
    7030                         printf("Global cut added - violation %g\n",
    7031                                thisCut->violated(cbcColSolution_)) ;
    7032 #endif
    7033                     whichGenerator_[numberViolated++] = -1;
    7034 #ifndef GLOBAL_CUTS_JUST_POINTERS
    7035                     theseCuts.insert(*thisCut) ;
    7036 #else
    7037                     theseCuts.insert(thisCut) ;
    7038 #endif
    7039                 }
    7040             }
    7041             numberCuts = globalCuts_.sizeRowCuts() ;
    7042             // possibly extend whichGenerator
    7043             resizeWhichGenerator(numberViolated, numberViolated + numberCuts);
    7044             for ( i = 0; i < numberCuts; i++) {
     7349            for (int i = 0; i < numberCuts; i++) {
    70457350                OsiRowCut * thisCut = globalCuts_.rowCutPtr(i) ;
    70467351                if (thisCut->violated(cbcColSolution_) > primalTolerance ||
    70477352                        thisCut->effectiveness() == COIN_DBL_MAX) {
    7048                     //printf("Global cut added - violation %g\n",
    7049                     // thisCut->violated(cbcColSolution_)) ;
     7353#ifndef NDEBUG
     7354                  printf("Global cut added - violation %g\n",
     7355                           thisCut->violated(cbcColSolution_)) ;
     7356#endif
    70507357                    whichGenerator_[numberViolated++] = -1;
    70517358#ifndef GLOBAL_CUTS_JUST_POINTERS
     
    76657972                        whichGenerator_[numberNewCuts_++] = -1;
    76667973#ifndef GLOBAL_CUTS_JUST_POINTERS
    7667                         cuts.insert(globalCuts_.rowCut(i)) ;
     7974                        cuts.insert(*globalCuts_.rowCutPtr(i)) ;
    76687975#else
    76697976                        OsiRowCut * rowCutPointer = globalCuts_.rowCutPtr(i);
     
    78308137        */
    78318138        if (!numberNodes_) {
     8139          //solver_->writeMps("second");
    78328140            if (numberRowsAdded)
    78338141                handler_->message(CBC_CUTS_STATS, messages_)
     
    80058313        for (i = 0; i < numberNewCuts_; i++) {
    80068314            int iGenerator = whichGenerator_[i];
     8315            if (iGenerator>=0)
     8316              iGenerator=iGenerator%10000;
    80078317            if (iGenerator >= 0 && iGenerator < numberCutGenerators_)
    80088318                count[iGenerator]++ ;
    80098319        }
     8320        // add in any active cuts if at root node (for multiple solvers)
     8321        if (!numberNodes_) {
     8322          for (i = 0; i < numberCutGenerators_; i++)
     8323            count[i] += generator_[i]->numberCutsActive();
     8324        }
    80108325        double totalCuts = 0.0 ;
    80118326        //#define JUST_ACTIVE
     
    83588673                for (i = 0; i < numberNewCuts_; i++) {
    83598674                    int iGenerator = whichGenerator_[i];
     8675                    if (iGenerator>=0)
     8676                      iGenerator=iGenerator%10000;
    83608677                    if (iGenerator >= 0)
    83618678                        generator_[iGenerator]->incrementNumberCutsActive();
     
    85758892            }
    85768893            whichGenerator_[numberBefore++] = i ;
     8894            if (!numberNodes_||generator_[i]->globalCuts())
     8895              whichGenerator_[numberBefore-1]=i+10000;
    85778896            if (thisCut->lb() > thisCut->ub())
    85788897                status = -1; // sub-problem is infeasible
     
    85828901                newCut.setGloballyValid(true);
    85838902                newCut.mutableRow().setTestForDuplicateIndex(false);
    8584                 globalCuts_.insert(newCut) ;
     8903                globalCuts_.addCutIfNotDuplicate(newCut) ;
     8904                whichGenerator_[numberBefore-1] = i+10000 ;
    85858905            }
    85868906        }
     
    85978917                const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ;
    85988918                whichGenerator_[numberBefore++] = i ;
     8919                if (!numberNodes_||generator_[i]->globalCuts())
     8920                  whichGenerator_[numberBefore-1]=i+10000;
    85998921                if (thisCut->globallyValid()) {
    86008922                    // add to global list
     
    86028924                    newCut.setGloballyValid(true);
    86038925                    newCut.mutableRow().setTestForDuplicateIndex(false);
    8604                     globalCuts_.insert(newCut) ;
     8926                    globalCuts_.addCutIfNotDuplicate(newCut) ;
     8927                    whichGenerator_[numberBefore-1]=i+10000;
    86058928                }
    86068929            }
     
    86108933            const OsiColCut * thisCut = theseCuts.colCutPtr(j) ;
    86118934            if (thisCut->globallyValid()) {
    8612                 // add to global list
    8613                 OsiColCut newCut(*thisCut);
    8614                 newCut.setGloballyValid(true);
    8615                 globalCuts_.insert(newCut) ;
     8935                // fix
     8936                makeGlobalCut(thisCut);
    86168937            }
    86178938        }
     
    86468967                    printf("Old cut added - violation %g\n",
    86478968                           thisCut->violated(cbcColSolution_)) ;
    8648                 whichGenerator_[numberOld++] = -1;
     8969                whichGenerator_[numberOld++] = -3;
    86498970                theseCuts.insert(*thisCut) ;
    86508971            }
     
    1089511216                            newCut.setGloballyValid(true);
    1089611217                            newCut.mutableRow().setTestForDuplicateIndex(false);
    10897                             globalCuts_.insert(newCut) ;
     11218                            globalCuts_.addCutIfNotDuplicate(newCut) ;
    1089811219                        } else {
    1089911220                            // obviously wrong
     
    1112811449            //setCutoff(cutoff*direction);
    1112911450            setCutoff(cutoff);
     11451            // change cutoff as constraint if wanted
     11452            if ((moreSpecialOptions_&16777216)!=0) {
     11453              if (solver_->getNumRows()>=numberRowsAtContinuous_) {
     11454                double offset;
     11455                solver_->getDblParam(OsiObjOffset, offset);
     11456                solver_->setRowUpper(numberRowsAtContinuous_-1,cutoff+offset);
     11457              }
     11458            }
    1113011459
    1113111460            if (how == CBC_ROUNDING)
     
    1119111520                            newCut.setGloballyValid(true);
    1119211521                            newCut.mutableRow().setTestForDuplicateIndex(false);
    11193                             globalCuts_.insert(newCut) ;
     11522                            globalCuts_.addCutIfNotDuplicate(newCut) ;
    1119411523                            generator_[i]->incrementNumberCutsInTotal();
    1119511524                        }
     
    1120111530                const OsiColCut * thisCut = theseCuts.colCutPtr(i);
    1120211531                if (thisCut->globallyValid()) {
    11203                     // add to global list
    11204                     OsiColCut newCut(*thisCut);
    11205                     newCut.setGloballyValid(true);
    11206                     globalCuts_.insert(newCut) ;
     11532                    // fix
     11533                    makeGlobalCut(thisCut);
    1120711534                }
    1120811535            }
     
    1130211629                //setCutoff(cutoff*direction);
    1130311630                setCutoff(cutoff);
     11631                // change cutoff as constraint if wanted
     11632                if ((moreSpecialOptions_&16777216)!=0) {
     11633                  if (solver_->getNumRows()>=numberRowsAtContinuous_) {
     11634                    double offset;
     11635                    solver_->getDblParam(OsiObjOffset, offset);
     11636                    solver_->setRowUpper(numberRowsAtContinuous_-1,cutoff+offset);
     11637                  }
     11638                }
    1130411639
    1130511640                numberSolutions_++;
     
    1192012255                thisCut.setRow(rowLength[iRow], column + start, elementByRow + start, false);
    1192112256                thisCut.setGloballyValid(true);
    11922                 globalCuts_.insert(thisCut) ;
     12257                globalCuts_.addCutIfNotDuplicate(thisCut) ;
    1192312258            }
    1192412259        }
     
    1193512270    newCut.setGloballyValidAsInteger(2);
    1193612271    newCut.mutableRow().setTestForDuplicateIndex(false);
    11937     globalCuts_.insert(newCut) ;
     12272    globalCuts_.addCutIfNotDuplicate(newCut) ;
    1193812273}
    1193912274// Make given cut into a global cut
     
    1194412279    newCut.setGloballyValid(true);
    1194512280    newCut.mutableRow().setTestForDuplicateIndex(false);
    11946     globalCuts_.insert(newCut) ;
     12281    globalCuts_.addCutIfNotDuplicate(newCut) ;
    1194712282}
    1194812283// Make given column cut into a global cut
     
    1195012285CbcModel::makeGlobalCut(const OsiColCut * cut)
    1195112286{
    11952     OsiColCut newCut(*cut);
    11953     newCut.setGloballyValidAsInteger(2);
    11954     globalCuts_.insert(newCut) ;
     12287  const double * lower;
     12288  const double * upper;
     12289  if (topOfTree_) {
     12290    lower = topOfTree_->lower();
     12291    upper = topOfTree_->upper();
     12292  } else {
     12293    lower = solver_->getColLower();
     12294    upper = solver_->getColUpper();
     12295  }
     12296  int nLower=cut->lbs().getNumElements();
     12297  const int * indexLower=cut->lbs().getIndices();
     12298  const double * boundLower=cut->lbs().getElements();
     12299  for (int i=0;i<nLower;i++) {
     12300    int iColumn=indexLower[i];
     12301    double newValue=CoinMax(lower[iColumn],boundLower[iColumn]);
     12302    if (topOfTree_)
     12303      topOfTree_->setColLower(iColumn,newValue);
     12304    else
     12305      solver_->setColLower(iColumn,newValue);
     12306  }
     12307  int nUpper=cut->ubs().getNumElements();
     12308  const int * indexUpper=cut->ubs().getIndices();
     12309  const double * boundUpper=cut->ubs().getElements();
     12310  for (int i=0;i<nUpper;i++) {
     12311    int iColumn=indexUpper[i];
     12312    double newValue=CoinMin(upper[iColumn],boundUpper[iColumn]);
     12313    if (topOfTree_)
     12314      topOfTree_->setColUpper(iColumn,newValue);
     12315    else
     12316      solver_->setColUpper(iColumn,newValue);
     12317  }
    1195512318}
    1195612319// Make given column cut into a global cut
     
    1195812321CbcModel::makeGlobalCut(const OsiColCut & cut)
    1195912322{
    11960     OsiColCut newCut(cut);
     12323  const double * lower;
     12324  const double * upper;
     12325  if (topOfTree_) {
     12326    lower = topOfTree_->lower();
     12327    upper = topOfTree_->upper();
     12328  } else {
     12329    lower = solver_->getColLower();
     12330    upper = solver_->getColUpper();
     12331  }
     12332  int nLower=cut.lbs().getNumElements();
     12333  const int * indexLower=cut.lbs().getIndices();
     12334  const double * boundLower=cut.lbs().getElements();
     12335  for (int i=0;i<nLower;i++) {
     12336    int iColumn=indexLower[i];
     12337    double newValue=CoinMax(lower[iColumn],boundLower[iColumn]);
     12338    if (topOfTree_)
     12339      topOfTree_->setColLower(iColumn,newValue);
     12340    else
     12341      solver_->setColLower(iColumn,newValue);
     12342  }
     12343  int nUpper=cut.ubs().getNumElements();
     12344  const int * indexUpper=cut.ubs().getIndices();
     12345  const double * boundUpper=cut.ubs().getElements();
     12346  for (int i=0;i<nUpper;i++) {
     12347    int iColumn=indexUpper[i];
     12348    double newValue=CoinMin(upper[iColumn],boundUpper[iColumn]);
     12349    if (topOfTree_)
     12350      topOfTree_->setColUpper(iColumn,newValue);
     12351    else
     12352      solver_->setColUpper(iColumn,newValue);
     12353  }
     12354}
     12355// Make partial cut into a global cut and save
     12356void
     12357CbcModel::makePartialCut(const OsiRowCut * partialCut)
     12358{
     12359  // get greedy cut
     12360  double bSum = partialCut->lb();
     12361  assert (bSum<0.0);
     12362  int nConflict = partialCut->row().getNumElements();
     12363  const int * column = partialCut->row().getIndices();
     12364  const double * element = partialCut->row().getElements();
     12365  double * originalLower = topOfTree_->mutableLower();
     12366  const double * columnLower = solver_->getColLower();
     12367  double * originalUpper = topOfTree_->mutableUpper();
     12368  const double * columnUpper = solver_->getColUpper();
     12369  int nC=nConflict;
     12370  while (nConflict) {
     12371    int iColumn = column[nConflict-1];
     12372    double farkasValue = element[nConflict-1];
     12373    double change;
     12374    if (farkasValue>0.0) {
     12375      change=farkasValue*(originalUpper[iColumn]-columnUpper[iColumn]);
     12376    } else {
     12377      change=farkasValue*(originalLower[iColumn]-columnLower[iColumn]);
     12378    }
     12379    if (bSum+change>-1.0e-4)
     12380      break;
     12381    nConflict--;
     12382    bSum += change;
     12383  }
     12384  OsiRowCut newCut;
     12385  newCut.setUb(COIN_DBL_MAX);
     12386  double lo=1.0;
     12387  double * values = new double[nConflict];
     12388  for (int i=0;i<nConflict;i++) {
     12389    int iColumn = column[i];
     12390    if (originalLower[iColumn]==columnLower[iColumn]) {
     12391      // must be at least one higher
     12392      values[i]=1.0;
     12393      lo += originalLower[iColumn];
     12394    } else {
     12395      // must be at least one lower
     12396      values[i]=-1.0;
     12397      lo -= originalUpper[iColumn];
     12398    }
     12399  }
     12400  newCut.setLb(lo);
     12401  newCut.setRow(nConflict,column,values);
     12402  printf("CUTa has %d (started at %d) - final bSum %g\n",nConflict,nC,bSum);
     12403  if (nConflict>1) {
    1196112404    newCut.setGloballyValidAsInteger(2);
    11962     globalCuts_.insert(newCut) ;
     12405    newCut.mutableRow().setTestForDuplicateIndex(false);
     12406    globalCuts_.addCutIfNotDuplicate(newCut) ;
     12407  } else {
     12408    // change bounds
     12409    int iColumn=column[0];
     12410    if (values[0]<0.0) {
     12411      // change upper bound
     12412      double newUpper = -lo;
     12413      assert (newUpper<originalUpper[iColumn]);
     12414      printf("Changing upper bound on %d from %g to %g\n",
     12415             iColumn,originalUpper[iColumn],newUpper);
     12416      originalUpper[iColumn]=newUpper;
     12417    } else {
     12418      // change lower bound
     12419      double newLower = lo;
     12420      assert (newLower>originalLower[iColumn]);
     12421      printf("Changing lower bound on %d from %g to %g\n",
     12422             iColumn,originalLower[iColumn],newLower);
     12423      originalLower[iColumn]=newLower;
     12424    }
     12425  }
     12426  // add to partial cuts
     12427  if (globalConflictCuts_) {
     12428    globalConflictCuts_->addCutIfNotDuplicateWhenGreedy(*partialCut,2);
     12429  }
     12430  delete [] values;
     12431}
     12432// Make partial cuts into global cuts
     12433void
     12434CbcModel::makeGlobalCuts()
     12435{
    1196312436}
    1196412437void
     
    1213012603        ClpSimplex * clpSimplex = clpSolver->getModelPtr();
    1213112604        int save = clpSimplex->specialOptions();
    12132         clpSimplex->setSpecialOptions(save | 0x11000000); // say is Cbc (and in branch and bound)
     12605        if ((moreSpecialOptions_&8388608)==0)
     12606          clpSimplex->setSpecialOptions(save | 0x11000000); // say is Cbc (and in branch and bound)
     12607        else
     12608          clpSimplex->setSpecialOptions(save | 0x11200000); // say is Cbc (and in branch and bound - but save ray)
    1213312609        int save2 = clpSolver->specialOptions();
    1213412610        if (false && (save2&2048) == 0) {
     
    1268613162            }
    1268713163#endif
     13164#ifdef COIN_HAS_CLP
     13165            int save;
     13166            OsiClpSolverInterface * clpSolver
     13167              = dynamic_cast<OsiClpSolverInterface *> (solver_);
     13168            if (clpSolver&&(moreSpecialOptions_&4194304)!=0) {
     13169              ClpSimplex * clpSimplex = clpSolver->getModelPtr();
     13170              save=clpSimplex->specialOptions();
     13171              clpSimplex->setSpecialOptions(save | 0x11200000); // say is Cbc (and in branch and bound - but save ray)
     13172            }
     13173#endif
    1268813174            if (numberBeforeTrust_ == 0 ) {
    1268913175                anyAction = newNode->chooseBranch(this, oldNode, numberPassesLeft) ;
     
    1269313179                    anyAction = newNode->chooseBranch(this, oldNode, numberPassesLeft) ; // dynamic did nothing
    1269413180            }
     13181#ifdef COIN_HAS_CLP
     13182            if (clpSolver&&(moreSpecialOptions_&4194304)!=0) {
     13183              ClpSimplex * clpSimplex = clpSolver->getModelPtr();
     13184              clpSimplex->setSpecialOptions(save);
     13185            }
     13186#endif
    1269513187            /*
    1269613188              We're on the new (Osi) side of the branching hierarchy.
     
    1307213564        cutoff = objectiveValue - increment ;
    1307313565        setCutoff(cutoff) ;
     13566        // change cutoff as constraint if wanted
     13567        if ((moreSpecialOptions_&16777216)!=0) {
     13568          if (solver_->getNumRows()>=numberRowsAtContinuous_) {
     13569            double offset;
     13570            solver_->getDblParam(OsiObjOffset, offset);
     13571            solver_->setRowUpper(numberRowsAtContinuous_-1,cutoff+offset);
     13572          }
     13573        }
    1307413574    }
    1307513575    int n = CoinMax(numberColumns, solver_->getNumCols());
     
    1377714277            = dynamic_cast<OsiClpSolverInterface *> (solver_);
    1377814278            if ((clpSolver || (specialOptions_&16384) != 0) && fastNodeDepth_ < -1
    13779                     && (specialOptions_&2048) == 0) {
     14279                && (specialOptions_&2048) == 0) {
    1378014280#define FATHOM_BIAS -2
    1378114281                if (numberNodes_ == 1) {
     
    1390414404                        numberExtraNodes_ += info->numberNodesExplored_;
    1390514405                        numberExtraIterations_ += info->numberIterations_;
     14406                        char general[200];
     14407                        int fathomStatus=info->nNodes_;
     14408                        if (feasible)
     14409                          fathomStatus=1;
     14410                        sprintf(general, "fathom took %d nodes, %d iterations - status %d",
     14411                                info->numberNodesExplored_,
     14412                                info->numberIterations_,fathomStatus);
     14413                        messageHandler()->message(CBC_FPUMP2,
     14414                                          messages())
     14415                          << general << CoinMessageEol ;
    1390614416                        if (info->numberNodesExplored_ > 10000 /* && !feasible */
    1390714417                            && (moreSpecialOptions_&524288) == 0  && info->nNodes_>=0) {
     
    1408514595        }
    1408614596        if ((specialOptions_&1) != 0 && onOptimalPath) {
    14087             if (!solver_->getRowCutDebugger() || !feasible) {
    14088                 // dj fix did something???
    14089                 solver_->writeMpsNative("infeas2.mps", NULL, NULL, 2);
    14090                 solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
    14091                 assert (solver_->getRowCutDebugger()) ;
    14092                 assert (feasible);
     14597            if(solver_->getRowCutDebuggerAlways()->optimalValue()<getCutoff()) {
     14598                if (!solver_->getRowCutDebugger() || !feasible) {
     14599                  // dj fix did something???
     14600                  solver_->writeMpsNative("infeas2.mps", NULL, NULL, 2);
     14601                  solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     14602                  assert (solver_->getRowCutDebugger()) ;
     14603                  assert (feasible);
     14604                }
    1409314605            }
    1409414606        }
     
    1411714629            bool objLim = solver_->isDualObjectiveLimitReached() ;
    1411814630            if (!feasible && !objLim) {
     14631              if(solver_->getRowCutDebuggerAlways()->optimalValue()<getCutoff()) {
    1411914632                printf("infeas2\n");
    1412014633                solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_);
     
    1412714640                solver_->initialSolve();
    1412814641                assert (!solver_->isProvenOptimal());
    14129             }
    14130             assert (feasible || objLim);
     14642                assert (feasible || objLim);
     14643              }
     14644            }
    1413114645        }
    1413214646        bool checkingNode = false;
    1413314647        if (feasible) {
    14134 #ifdef FUNNY_BRANCHING
     14648#ifdef FUNNY_BRANCHING2
    1413514649            // Far too clever
    1413614650            if ((numberThreads_ == -10 || true) && node->numberBranches() == 2) {
     
    1472915243    if (bestObjective > bestObjective_)
    1473015244        foundSolution = 2;
    14731     if (parallelMode() >= 0 && foundSolution) {
     15245    if (parallelMode() > 0 && foundSolution) {
    1473215246        lockThread();
    1473315247        // might as well mark all including continuous
     
    1473715251            usedInSolution_[i] = 0;
    1473815252        }
    14739         baseModel->numberSolutions_ = numberSolutions_;
     15253        baseModel->numberSolutions_++;
    1474015254        if (bestObjective_ < baseModel->bestObjective_ && bestObjective_ < baseModel->getCutoff()) {
    1474115255            baseModel->bestObjective_ = bestObjective_ ;
     
    1611816632    */
    1611916633    globalCuts_ = OsiCuts() ;
     16634    delete globalConflictCuts_;
     16635    globalConflictCuts_=NULL;
    1612016636    numberHeuristics_ = saveNumberHeuristics;
    1612116637
     
    1636316879}
    1636416880#endif
    16365 
     16881#ifdef CBC_THREAD
     16882void * doRootCbcThread(void * voidInfo)
     16883{
     16884    CbcModel * model = reinterpret_cast<CbcModel *> (voidInfo);
     16885#ifdef COIN_HAS_CLP
     16886    OsiClpSolverInterface * clpSolver
     16887      = dynamic_cast<OsiClpSolverInterface *> (model->solver());
     16888    char general[200];
     16889    if (clpSolver) {
     16890      clpSolver->getModelPtr()->dual(); // to get more randomness
     16891      clpSolver->setWarmStart(NULL);
     16892      sprintf(general,"Starting multiple root solver - %d iterations in initialSolve",
     16893              clpSolver->getIterationCount());
     16894    } else {
     16895#endif
     16896#ifdef COIN_HAS_CLP
     16897      model->initialSolve();
     16898      sprintf(general,"Solver did %d iterations in initialSolve\n",
     16899             model->solver()->getIterationCount());
     16900    }
     16901#endif
     16902    model->messageHandler()->message(CBC_GENERAL,
     16903                              model->messages())
     16904      << general << CoinMessageEol ;
     16905    model->branchAndBound();
     16906    sprintf(general,"Ending multiple root solver");
     16907    model->messageHandler()->message(CBC_GENERAL,
     16908                              model->messages())
     16909      << general << CoinMessageEol ;
     16910    return NULL;
     16911}
     16912#endif
     16913
     16914
  • trunk/Cbc/src/CbcModel.hpp

    r1813 r1839  
    1414#include "CoinWarmStartBasis.hpp"
    1515#include "CbcCompareBase.hpp"
     16#include "CbcCountRowCut.hpp"
    1617#include "CbcMessage.hpp"
    1718#include "CbcEventHandler.hpp"
     
    3536class CbcFeasibilityBase;
    3637class CbcStatistics;
     38class CbcFullNodeInfo;
    3739class CbcEventHandler ;
    3840class CglPreProcess;
     
    356358    /// Make given column cut into a global cut
    357359    void makeGlobalCut(const OsiColCut & cut);
     360    /// Make partial cut into a global cut and save
     361    void makePartialCut(const OsiRowCut * cut);
     362    /// Make partial cuts into global cuts
     363    void makeGlobalCuts();
     364    /// Which cut generator generated this cut
     365    inline const int * whichGenerator() const
     366    { return whichGenerator_;}
    358367    //@}
    359368
     
    810819        return numberPenalties_;
    811820    }
     821    /// Pointer to top of tree
     822    inline const CbcFullNodeInfo * topOfTree() const
     823    { return topOfTree_;}
    812824    /// Number of analyze iterations to do
    813825    inline void setNumberAnalyzeIterations(int number) {
     
    13951407        stopNumberIterations_ = value;
    13961408    }
     1409    /// A pointer to model from CbcHeuristic
     1410    inline CbcModel * heuristicModel() const
     1411    { return heuristicModel_;}
     1412    /// Set a pointer to model from CbcHeuristic
     1413    inline void setHeuristicModel(CbcModel * model)
     1414    { heuristicModel_ = model;}
    13971415    //@}
    13981416
     
    15141532    inline void setSearchStrategy(int value) {
    15151533        searchStrategy_ = value;
     1534    }
     1535    /// Stong branching strategy
     1536    inline int strongStrategy() const {
     1537        return strongStrategy_;
     1538    }
     1539    /// Set strong branching strategy
     1540    inline void setStrongStrategy(int value) {
     1541        strongStrategy_ = value;
    15161542    }
    15171543
     
    17381764        20 bit (1048576) - waiting for sub model to return
    17391765        22 bit (4194304) - do not initialize random seed in solver (user has)
     1766        23 bit (8388608) - leave solver_ with cuts
    17401767    */
    17411768    inline void setSpecialOptions(int value) {
     
    17531780    inline int getRandomSeed() const {
    17541781        return randomSeed_;
     1782    }
     1783    /// Set multiple root tries
     1784    inline void setMultipleRootTries(int value) {
     1785        multipleRootTries_ = value;
     1786    }
     1787    /// Get multiple root tries
     1788    inline int getMultipleRootTries() const {
     1789        return multipleRootTries_;
    17551790    }
    17561791    /// Tell model to stop on event
     
    17811816        20 bit (1048576) - Reduce sum of infeasibilities before cuts
    17821817        21 bit (2097152) - Reduce sum of infeasibilities after cuts
     1818        22 bit (4194304) - Conflict analysis
     1819        23 bit (8388608) - Conflict analysis - temporary bit
     1820        24 bit (16777216) - Add cutoff as LP constraint
    17831821    */
    17841822    inline void setMoreSpecialOptions(int value) {
     
    21802218    }
    21812219    /// Global cuts
    2182     inline OsiCuts * globalCuts() {
     2220    inline CbcRowCuts * globalCuts() {
    21832221        return &globalCuts_;
    21842222    }
     
    23622400    CoinWarmStartBasis bestSolutionBasis_ ;
    23632401    /// Global cuts
    2364     OsiCuts globalCuts_;
     2402    CbcRowCuts globalCuts_;
     2403    /// Global conflict cuts
     2404    CbcRowCuts * globalConflictCuts_;
    23652405
    23662406    /// Minimum degradation in objective value to continue cut generation
     
    25172557    /// Tree
    25182558    CbcTree * tree_;
     2559    /// Pointer to top of tree
     2560    CbcFullNodeInfo * topOfTree_;
    25192561    /// A pointer to model to be used for subtrees
    25202562    CbcModel * subTreeModel_;
     2563    /// A pointer to model from CbcHeuristic
     2564    CbcModel * heuristicModel_;
    25212565    /// Number of times any subtree stopped on nodes, time etc
    25222566    int numberStoppedSubTrees_;
     
    26602704    /// Random seed
    26612705    int randomSeed_;
     2706    /// Multiple root tries
     2707    int multipleRootTries_;
    26622708    /// Current depth
    26632709    int currentDepth_;
     
    26942740    /// Strategy worked out - mainly at root node
    26952741    int searchStrategy_;
     2742    /** Strategy for strong branching
     2743        0 - normal
     2744        when to do all fractional
     2745        1 - root node
     2746        2 - depth less than modifier
     2747        4 - if objective == best possible
     2748        6 - as 2+4
     2749        when to do all including satisfied
     2750        10 - root node etc.
     2751        If >=100 then do when depth <= strategy/100 (otherwise 5)
     2752     */
     2753    int strongStrategy_;
    26962754    /// Number of iterations in strong branching
    26972755    int numberStrongIterations_;
  • trunk/Cbc/src/CbcNode.cpp

    r1802 r1839  
    1010
    1111#include "CbcConfig.h"
    12 
     12//#define DEBUG_SOLUTION
     13#ifdef DEBUG_SOLUTION
     14#define COIN_DETAIL
     15#endif
    1316#include <string>
    1417//#define CBC_DEBUG 1
     
    14411444            }
    14421445            delete ws;
    1443             int numberNodes = model->getNodeCount();
     1446            //int numberNodes = model->getNodeCount();
    14441447            // update number of strong iterations etc
    14451448            model->incrementStrongInfo(numberStrongDone, numberStrongIterations,
     
    14731476                //if (smallestNumberInfeasibilities>=numberIntegerInfeasibilities)
    14741477                //numberNodes=1000000; // switch off search for better solution
    1475                 numberNodes = 1000000; // switch off anyway
     1478                int numberNodes = 1000000; // switch off anyway
    14761479                averageCostPerIteration /= totalNumberIterations;
    14771480                // all feasible - choose best bet
     
    19341937    int numberStrongInfeasible = 0;
    19351938    int numberStrongIterations = 0;
     1939    int strongType=0;
     1940#define DO_ALL_AT_ROOT
     1941#ifdef DO_ALL_AT_ROOT
     1942    int saveSatisfiedVariables=0;
     1943    int saveNumberToDo=0;
     1944#endif
    19361945    // so we can save lots of stuff
    19371946    CbcStrongInfo choice;
     
    19431952    choice.possibleBranch = choiceObject;
    19441953    numberPassesLeft = CoinMax(numberPassesLeft, 2);
     1954    //#define DEBUG_SOLUTION
     1955#ifdef DEBUG_SOLUTION
     1956    bool onOptimalPath=false;
     1957    if ((model->specialOptions()&1) != 0) {
     1958      const OsiRowCutDebugger *debugger = model->continuousSolver()->getRowCutDebugger() ;
     1959      if (debugger) {
     1960        const OsiRowCutDebugger *debugger2 = model->solver()->getRowCutDebugger() ;
     1961        printf("On optimal in CbcNode %s\n",debugger2 ? "" : "but bad cuts");
     1962        onOptimalPath=true;
     1963      }
     1964    }
     1965#endif
    19451966    while (!finished) {
    19461967        numberPassesLeft--;
     
    24032424        // But adjust depending on ratio of iterations
    24042425        if (searchStrategy > 0) {
    2405             if (numberBeforeTrust >= 5 && numberBeforeTrust <= 10) {
     2426          if (numberBeforeTrust >= /*5*/ 10 && numberBeforeTrust <= 10) {
    24062427                if (searchStrategy != 2) {
    24072428                    assert (searchStrategy == 1);
     
    24732494                solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, &easy) ;
    24742495            int iDo;
     2496#define RESET_BOUNDS
    24752497#ifdef RANGING
    24762498            bool useRanging = model->allDynamic() && !skipAll;
     
    25102532                        osiclp->setSpecialOptions(save | 256);
    25112533                        solver->markHotStart();
     2534#ifdef RESET_BOUNDS
     2535                        memcpy(saveLower,solver->getColLower(),solver->getNumCols()*sizeof(double));
     2536                        memcpy(saveUpper,solver->getColUpper(),solver->getNumCols()*sizeof(double));
     2537#endif
    25122538                        osiclp->setSpecialOptions(save);
    25132539                    } else {
    25142540                        solver->markHotStart();
     2541#ifdef RESET_BOUNDS
     2542                        memcpy(saveLower,solver->getColLower(),solver->getNumCols()*sizeof(double));
     2543                        memcpy(saveUpper,solver->getColUpper(),solver->getNumCols()*sizeof(double));
     2544#endif
    25152545                    }
    25162546                    doneHotStart = true;
     
    25682598                            sort[j] = - min1;
    25692599                        }
    2570                         if (CoinMax(downPenalty, upPenalty) > gap) {
     2600                        // seems unreliable
     2601                        if (false&&CoinMax(downPenalty, upPenalty) > gap) {
    25712602                            COIN_DETAIL_PRINT(printf("gap %g object %d has down range %g, up %g\n",
    25722603                                                     gap, i, downPenalty, upPenalty));
     
    26012632                        objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
    26022633                        solver->markHotStart();
     2634#ifdef RESET_BOUNDS
     2635                        memcpy(saveLower,solver->getColLower(),solver->getNumCols()*sizeof(double));
     2636                        memcpy(saveUpper,solver->getColUpper(),solver->getNumCols()*sizeof(double));
     2637#endif
    26032638                        problemFeasible = solver->isProvenOptimal();
    26042639                    }
     
    26412676                    if (20*numberInfeasible + 4*numberFixed < numberNodes) {
    26422677                        // Say never do
    2643                         skipAll = -1;
     2678                        if (numberBeforeTrust == 5)
     2679                          skipAll = -1;
    26442680                    }
    26452681                }
     
    27272763            if (skipAll < 0)
    27282764                numberToDo = 1;
     2765            strongType=0;
    27292766#ifdef DO_ALL_AT_ROOT
    2730             if (!numberNodes) {
    2731                 printf("DOX %d test %d unsat %d - nobj %d\n",
    2732                        numberToDo, numberTest, numberUnsatisfied_,
    2733                        numberObjects);
     2767            if (model->strongStrategy()) {
     2768              int iStrategy=model->strongStrategy();
     2769              int kDepth = iStrategy/100;
     2770              if (kDepth)
     2771                iStrategy -= 100*kDepth;
     2772              else
     2773                kDepth=5;
     2774              double objValue = solver->getObjSense()*solver->getObjValue();
     2775              double bestPossible = model->getBestPossibleObjValue();
     2776              bestPossible += 1.0e-7*(1.0+fabs(bestPossible));
     2777              int jStrategy = iStrategy/10;
     2778              if (jStrategy) {
     2779                if ((jStrategy&1)!=0&&!depth_)
     2780                  strongType=2;
     2781                else if ((jStrategy&2)!=0&&depth_<=kDepth)
     2782                  strongType=2;
     2783                else if ((jStrategy&4)!=0&&objValue<bestPossible)
     2784                  strongType=2;
     2785                iStrategy-=10*jStrategy;
     2786              }
     2787              if (!strongType) {
     2788                if ((iStrategy&1)!=0&&!depth_)
     2789                  strongType=1;
     2790                else if ((iStrategy&2)!=0&&depth_<=kDepth)
     2791                  strongType=1;
     2792                else if ((iStrategy&4)!=0&&objValue<bestPossible)
     2793                  strongType=1;
     2794              }
     2795              saveNumberToDo=numberToDo;
     2796              if (strongType==2) {
     2797                // add in satisfied
     2798                const int * integerVariable = model->integerVariable();
     2799                int numberIntegers = model->numberIntegers();
     2800                if (numberIntegers==numberObjects) {
     2801                  numberToDo=0;
     2802                  for (int i=0;i<numberIntegers;i++) {
     2803                    int iColumn=integerVariable[i];
     2804                    if (saveUpper[iColumn]>saveLower[iColumn]) {
     2805                      whichObject [numberToDo++]=i;
     2806                    }
     2807                  }
     2808                  saveSatisfiedVariables=numberToDo-saveNumberToDo;
     2809                } else {
     2810                  strongType=1;
     2811                }
     2812              }
     2813              if (strongType) {
    27342814                numberTest = numberToDo;
    2735             }
     2815                numberStrong=numberToDo;
     2816                skipAll=false;
     2817                searchStrategy=0;
     2818                solver->setIntParam(OsiMaxNumIterationHotStart, 100000);
     2819              }
     2820            }
    27362821#endif
    27372822            for ( iDo = 0; iDo < numberToDo; iDo++) {
     
    27442829                double infeasibility = object->infeasibility(&usefulInfo, preferredWay);
    27452830                // may have become feasible
    2746                 if (!infeasibility)
     2831                if (!infeasibility) {
     2832                  if(strongType!=2||solver->getColLower()[iColumn]==solver->getColUpper()[iColumn])
    27472833                    continue;
     2834                }
    27482835#ifndef NDEBUG
    27492836                if (iColumn < numberColumns) {
     
    27712858                choice.numIntInfeasUp = numberUnsatisfied_;
    27722859                choice.numIntInfeasDown = numberUnsatisfied_;
    2773                 choice.upMovement = upEstimate[iObject];
    2774                 choice.downMovement = downEstimate[iObject];
    2775                 assert (choice.upMovement >= 0.0);
    2776                 assert (choice.downMovement >= 0.0);
     2860                if (strongType!=2) {
     2861                  choice.upMovement = upEstimate[iObject];
     2862                  choice.downMovement = downEstimate[iObject];
     2863                } else {
     2864                  choice.upMovement = 0.1;
     2865                  choice.downMovement = 0.1;
     2866                }
     2867                  assert (choice.upMovement >= 0.0);
     2868                  assert (choice.downMovement >= 0.0);
    27772869                choice.fix = 0; // say not fixed
    27782870                // see if can skip strong branching
     
    27802872                if ((numberTest <= 0 || skipAll)) {
    27812873                    if (iDo > 20) {
    2782 #ifdef DO_ALL_AT_ROOT
    2783                         if (!numberNodes)
    2784                             printf("DOY test %d - iDo %d\n",
    2785                                    numberTest, iDo);
    2786 #endif
    27872874                        if (!choiceObject) {
    27882875                            delete choice.possibleBranch;
     
    27962883                if (skipAll < 0)
    27972884                    canSkip = true;
     2885                if (strongType)
     2886                  canSkip=false;
    27982887                if (!canSkip) {
    27992888                    if (!doneHotStart) {
     
    28012890                        doneHotStart = true;
    28022891                        solver->markHotStart();
     2892#ifdef RESET_BOUNDS
     2893                        memcpy(saveLower,solver->getColLower(),solver->getNumCols()*sizeof(double));
     2894                        memcpy(saveUpper,solver->getColUpper(),solver->getNumCols()*sizeof(double));
     2895#endif
    28032896                        if (!solver->isProvenOptimal()) {
    28042897                          skipAll=-2;
     
    28442937                    } else {
    28452938                        iStatus = 1; // infeasible
     2939#ifdef CONFLICT_CUTS
     2940# ifdef COIN_HAS_CLP
     2941                        if (osiclp&&(model->moreSpecialOptions()&4194304)!=0) {
     2942                          const CbcFullNodeInfo * topOfTree =
     2943                            model->topOfTree();
     2944                          if (topOfTree) {
     2945                            OsiRowCut * cut = osiclp->smallModelCut(topOfTree->lower(),
     2946                                                                    topOfTree->upper(),
     2947                                                                    model->numberRowsAtContinuous(),
     2948                                                                    model->whichGenerator());
     2949                            if (cut) {
     2950                              printf("XXXXXX found conflict cut in strong branching\n");
     2951                              //cut->print();
     2952                              if ((model->specialOptions()&1) != 0) {
     2953                                const OsiRowCutDebugger *debugger = model->continuousSolver()->getRowCutDebugger() ;
     2954                                if (debugger) {
     2955                                  if (debugger->invalidCut(*cut)) {
     2956                                    model->continuousSolver()->applyRowCuts(1,cut);
     2957                                    model->continuousSolver()->writeMps("bad");
     2958                                  }
     2959                                  CoinAssert (!debugger->invalidCut(*cut));
     2960                                }
     2961                              }
     2962                              model->makeGlobalCut(cut) ;
     2963                            }
     2964                          }
     2965                        }
     2966#endif
     2967#endif
    28462968                    }
    28472969                    if (iStatus != 2 && solver->getIterationCount() >
     
    29633085                        }
    29643086                        solver->markHotStart();
    2965                     }
    2966 #ifdef DO_ALL_AT_ROOT
    2967                     if (!numberNodes)
     3087#ifdef RESET_BOUNDS
     3088                        memcpy(saveLower,solver->getColLower(),solver->getNumCols()*sizeof(double));
     3089                        memcpy(saveUpper,solver->getColUpper(),solver->getNumCols()*sizeof(double));
     3090#endif
     3091                    }
     3092#if 0 //def DO_ALL_AT_ROOT
     3093                    if (strongType)
    29683094                        printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    29693095                               choice.objectNumber, iStatus, newObjectiveValue, choice.numItersDown,
     
    29913117                    } else {
    29923118                        iStatus = 1; // infeasible
     3119#ifdef CONFLICT_CUTS
     3120# ifdef COIN_HAS_CLP
     3121                        if (osiclp&&(model->moreSpecialOptions()&4194304)!=0) {
     3122                          const CbcFullNodeInfo * topOfTree =
     3123                            model->topOfTree();
     3124                          if (topOfTree) {
     3125                            OsiRowCut * cut = osiclp->smallModelCut(topOfTree->lower(),
     3126                                                                    topOfTree->upper(),
     3127                                                                    model->numberRowsAtContinuous(),
     3128                                                                    model->whichGenerator());
     3129                            if (cut) {
     3130                              printf("XXXXXX found conflict cut in strong branching\n");
     3131                              //cut->print();
     3132                              if ((model->specialOptions()&1) != 0) {
     3133                                const OsiRowCutDebugger *debugger = model->continuousSolver()->getRowCutDebugger() ;
     3134                                if (debugger) {
     3135                                  if (debugger->invalidCut(*cut)) {
     3136                                    model->continuousSolver()->applyRowCuts(1,cut);
     3137                                    model->continuousSolver()->writeMps("bad");
     3138                                  }
     3139                                  CoinAssert (!debugger->invalidCut(*cut));
     3140                                }
     3141                              }
     3142                              model->makeGlobalCut(cut) ;
     3143                            }
     3144                          }
     3145                        }
     3146#endif
     3147#endif
    29933148                    }
    29943149                    if (iStatus != 2 && solver->getIterationCount() >
     
    31183273                        }
    31193274                        solver->markHotStart();
    3120                     }
    3121 
    3122 #ifdef DO_ALL_AT_ROOT
    3123                     if (!numberNodes)
     3275#ifdef RESET_BOUNDS
     3276                        memcpy(saveLower,solver->getColLower(),solver->getNumCols()*sizeof(double));
     3277                        memcpy(saveUpper,solver->getColUpper(),solver->getNumCols()*sizeof(double));
     3278#endif
     3279                    }
     3280
     3281#if 0 //def DO_ALL_AT_ROOT
     3282                    if (strongType)
    31243283                        printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    31253284                               choice.objectNumber, iStatus, newObjectiveValue, choice.numItersUp,
     
    31663325                            << CoinMessageEol;
    31673326                        }
    3168                         int betterWay;
    3169                         {
     3327                        int betterWay=0;
     3328                        // If was feasible (extra strong branching) skip
     3329                        if (infeasibility) {
    31703330                            CbcBranchingObject * branchObj =
    31713331                                dynamic_cast <CbcBranchingObject *>(branch_) ;
     
    32623422                        bool goneInfeasible = (!solver->isProvenOptimal()||solver->isDualObjectiveLimitReached());
    32633423                        solver->markHotStart();
     3424#ifdef RESET_BOUNDS
     3425                        memcpy(saveLower,solver->getColLower(),solver->getNumCols()*sizeof(double));
     3426                        memcpy(saveUpper,solver->getColUpper(),solver->getNumCols()*sizeof(double));
     3427#endif
    32643428                        // may be infeasible (if other way stopped on iterations)
    32653429                        if (goneInfeasible) {
     
    33053469                        bool goneInfeasible = (!solver->isProvenOptimal()||solver->isDualObjectiveLimitReached());
    33063470                        solver->markHotStart();
     3471#ifdef RESET_BOUNDS
     3472                        memcpy(saveLower,solver->getColLower(),solver->getNumCols()*sizeof(double));
     3473                        memcpy(saveUpper,solver->getColUpper(),solver->getNumCols()*sizeof(double));
     3474#endif
    33073475                        // may be infeasible (if other way stopped on iterations)
    33083476                        if (goneInfeasible) {
     
    34903658    // Set guessed solution value
    34913659    guessedObjectiveValue_ = objectiveValue_ + estimatedDegradation;
    3492 
     3660#ifdef DO_ALL_AT_ROOT
     3661    if (strongType) {
     3662      char general[200];
     3663      if (strongType==1)
     3664        sprintf(general,"Strong branching on all %d unsatisfied, %d iterations (depth %d)\n",
     3665                saveNumberToDo,numberStrongIterations,depth_);
     3666      else
     3667        sprintf(general,"Strong branching on all %d unfixed variables (%d unsatisfied), %d iterations (depth %d)\n",
     3668                saveNumberToDo+saveSatisfiedVariables,saveNumberToDo,numberStrongIterations,depth_);
     3669      model->messageHandler()->message(CBC_FPUMP2,model->messages())
     3670        << general << CoinMessageEol ;
     3671    }
     3672#endif
     3673#ifdef DEBUG_SOLUTION
     3674    if(onOptimalPath&&anyAction==-2) {
     3675      printf("Gone off optimal path in CbcNode\n");
     3676      assert(!onOptimalPath||anyAction!=-2);
     3677    }
     3678#endif
    34933679    /*
    34943680      Cleanup, then we're finished
  • trunk/Cbc/src/CbcPartialNodeInfo.cpp

    r1644 r1839  
    145145            if ((variable&0x80000000) == 0) {
    146146                // lower bound changing
    147                 //#define CBC_PRINT2
     147              //#define CBC_PRINT2
    148148#ifdef CBC_PRINT2
    149149                if (solver->getColLower()[k] != newBounds_[i])
  • trunk/Cbc/src/CbcSimpleInteger.cpp

    r1624 r1839  
    187187    assert (info->upper_[columnNumber_] > info->lower_[columnNumber_]);
    188188    if (!info->hotstartSolution_ && priority_ != -999) {
    189 #ifndef NDEBUG
     189#if 0 // out because of very strong branching ndef NDEBUG
    190190        double nearest = floor(value + 0.5);
    191191        assert (fabs(value - nearest) > info->integerTolerance_);
  • trunk/Cbc/src/CbcSolver.cpp

    r1832 r1839  
    827827
    828828extern "C" {
    829     static void signal_handler(int /*whichSignal*/) {
    830         if (currentBranchModel != NULL)
    831             currentBranchModel->sayEventHappened(); // say why stopped
     829    static void signal_handler(int whichSignal) {
     830      if (currentBranchModel != NULL) {
     831        currentBranchModel->sayEventHappened(); // say why stopped
     832        if (currentBranchModel->heuristicModel())
     833          currentBranchModel->heuristicModel()->sayEventHappened();
     834      }
    832835        return;
    833836    }
     
    16101613        int landpAction = 0;
    16111614        CglResidualCapacity residualCapacityGen;
     1615        residualCapacityGen.setDoPreproc(1); // always preprocess
    16121616        // set default action (0=off,1=on,2=root)
    16131617        int residualCapacityAction = 0;
     
    44484452                                    << generalPrint
    44494453                                    << CoinMessageEol;
     4454#if 1
     4455                                    // some options may have been set already
     4456                                    // e.g. use elapsed time
     4457                                    babModel_->setMoreSpecialOptions(moreMipOptions|babModel_->moreSpecialOptions());
     4458#else
    44504459                                    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver());
    44514460                                    if (moreMipOptions == 10000) {
     
    44734482                                        }
    44744483                                    }
     4484#endif
    44754485                                }
    44764486                            }
     
    56385648                                }
    56395649#endif
     5650                                int multipleRoot = parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].intValue();
     5651                                babModel_->setMultipleRootTries(multipleRoot);
     5652                                int specialOptions = parameters_[whichParam(CBC_PARAM_INT_STRONG_STRATEGY, numberParameters_, parameters_)].intValue();
     5653                                if (specialOptions>=0)
     5654                                  babModel_->setStrongStrategy(specialOptions);
    56405655                                babModel_->branchAndBound(statistics);
    56415656                                //#define CLP_FACTORIZATION_INSTRUMENT
     
    57705785                                        model_.setFastNodeDepth(-2); // Use Cplex at root
    57715786                                }
     5787                                int multipleRoot = parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].intValue();
     5788                                model_.setMultipleRootTries(multipleRoot);
     5789                                int specialOptions = parameters_[whichParam(CBC_PARAM_INT_STRONG_STRATEGY, numberParameters_, parameters_)].intValue();
     5790                                if (specialOptions>=0)
     5791                                  model_.setStrongStrategy(specialOptions);
    57725792                                if (!pumpChanged) {
    57735793                                    // Make more lightweight
  • trunk/Cbc/src/CbcThread.cpp

    r1816 r1839  
    13941394        bestObjective_ = baseModel->bestObjective_;
    13951395        assert (!baseModel->globalCuts_.sizeRowCuts());
    1396         numberSolutions_ = baseModel->numberSolutions_;
     1396        if (numberSolutions_ < baseModel->numberSolutions_) {
     1397          assert (baseModel->bestSolution_);
     1398          int numberColumns = solver_->getNumCols();
     1399          if (!bestSolution_)
     1400            bestSolution_ = new double [numberColumns];
     1401          memcpy(bestSolution_,baseModel->bestSolution_,
     1402                 numberColumns*sizeof(double));
     1403          numberSolutions_ = baseModel->numberSolutions_;
     1404        }
    13971405        stateOfSearch_ = baseModel->stateOfSearch_;
    13981406        numberNodes_ = baseModel->numberNodes_;
     
    18151823                newCut.setGloballyValid(true);
    18161824                newCut.mutableRow().setTestForDuplicateIndex(false);
    1817                 globalCuts_.insert(newCut) ;
     1825                globalCuts_.addCutIfNotDuplicate(newCut) ;
    18181826            }
    18191827        }
     
    18231831            if (thisCut->globallyValid()) {
    18241832                // add to global list
    1825                 OsiColCut newCut(*thisCut);
    1826                 newCut.setGloballyValid(true);
    1827                 globalCuts_.insert(newCut) ;
     1833                makeGlobalCut(thisCut);
    18281834            }
    18291835        }
  • trunk/Cbc/src/CbcTreeLocal.cpp

    r1641 r1839  
    369369            // Add to global cuts
    370370            // we came in with solution
    371             model_->globalCuts()->insert(cut_);
     371            model_->makeGlobalCut(cut_);
    372372            if (model_->messageHandler()->logLevel() > 1)
    373373                printf("initial cut - rhs %g %g\n",
     
    634634        if (goodSolution >= 0) {
    635635            // Add to global cuts
    636             model_->globalCuts()->insert(cut_);
    637             OsiCuts * global = model_->globalCuts();
     636            model_->makeGlobalCut(cut_);
     637            CbcRowCuts * global = model_->globalCuts();
    638638            int n = global->sizeRowCuts();
    639639            OsiRowCut * rowCut = global->rowCutPtr(n - 1);
     
    807807{
    808808    // find global cut
    809     OsiCuts * global = model_->globalCuts();
     809    CbcRowCuts * global = model_->globalCuts();
    810810    int n = global->sizeRowCuts();
    811811    int i;
     
    853853{
    854854    // find global cut
    855     OsiCuts * global = model_->globalCuts();
     855    CbcRowCuts * global = model_->globalCuts();
    856856    int n = global->sizeRowCuts();
    857857    int i;
     
    12431243            // Add to global cuts
    12441244            // we came in with solution
    1245             model_->globalCuts()->insert(cut_);
     1245            model_->makeGlobalCut(cut_);
    12461246            if (model_->messageHandler()->logLevel() > 1)
    12471247                printf("initial cut - rhs %g %g\n",
     
    15081508        if (goodSolution >= 0) {
    15091509            // Add to global cuts
    1510             model_->globalCuts()->insert(cut_);
    1511             OsiCuts * global = model_->globalCuts();
     1510            model_->makeGlobalCut(cut_);
     1511            CbcRowCuts * global = model_->globalCuts();
    15121512            int n = global->sizeRowCuts();
    15131513            OsiRowCut * rowCut = global->rowCutPtr(n - 1);
     
    16721672{
    16731673    // find global cut
    1674     OsiCuts * global = model_->globalCuts();
     1674    CbcRowCuts * global = model_->globalCuts();
    16751675    int n = global->sizeRowCuts();
    16761676    int i;
     
    17181718{
    17191719    // find global cut
    1720     OsiCuts * global = model_->globalCuts();
     1720    CbcRowCuts * global = model_->globalCuts();
    17211721    int n = global->sizeRowCuts();
    17221722    int i;
Note: See TracChangeset for help on using the changeset viewer.