source: stable/2.4/Cbc/src/CbcBranchActual.cpp @ 1271

Last change on this file since 1271 was 1271, checked in by forrest, 10 years ago

Creating new stable branch 2.4 from trunk (rev 1270)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 149.0 KB
Line 
1/* $Id: CbcBranchActual.cpp 1271 2009-11-05 15:57:25Z forrest $ */
2// Copyright (C) 2002, International Business Machines
3// Corporation and others.  All Rights Reserved.
4#if defined(_MSC_VER)
5// Turn off compiler warning about long names
6#  pragma warning(disable:4786)
7#endif
8#include <cassert>
9#include <cstdlib>
10#include <cmath>
11#include <cfloat>
12//#define CBC_DEBUG
13
14#include "CoinTypes.hpp"
15#include "OsiSolverInterface.hpp"
16#include "OsiSolverBranch.hpp"
17#include "CbcModel.hpp"
18#include "CbcMessage.hpp"
19#include "CbcBranchActual.hpp"
20#include "CoinSort.hpp"
21#include "CoinError.hpp"
22
23//##############################################################################
24
25// Default Constructor
26CbcClique::CbcClique ()
27  : CbcObject(),
28    numberMembers_(0),
29    numberNonSOSMembers_(0),
30    members_(NULL),
31    type_(NULL),
32    cliqueType_(-1),
33    slack_(-1)
34{
35}
36
37// Useful constructor (which are integer indices)
38CbcClique::CbcClique (CbcModel * model, int cliqueType, int numberMembers,
39           const int * which, const char * type, int identifier,int slack)
40  : CbcObject(model)
41{
42  id_=identifier;
43  numberMembers_=numberMembers;
44  if (numberMembers_) {
45    members_ = new int[numberMembers_];
46    memcpy(members_,which,numberMembers_*sizeof(int));
47    type_ = new char[numberMembers_];
48    if (type) {
49      memcpy(type_,type,numberMembers_*sizeof(char));
50    } else {
51      for (int i=0;i<numberMembers_;i++)
52        type_[i]=1;
53    }
54  } else {
55    members_ = NULL;
56    type_ = NULL;
57  }
58  // Find out how many non sos
59  int i;
60  numberNonSOSMembers_=0;
61  for (i=0;i<numberMembers_;i++)
62    if (!type_[i])
63      numberNonSOSMembers_++;
64  cliqueType_ = cliqueType;
65  slack_ = slack;
66}
67
68// Copy constructor
69CbcClique::CbcClique ( const CbcClique & rhs)
70  :CbcObject(rhs)
71{
72  numberMembers_ = rhs.numberMembers_;
73  numberNonSOSMembers_ = rhs.numberNonSOSMembers_;
74  if (numberMembers_) {
75    members_ = new int[numberMembers_];
76    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
77    type_ = new char[numberMembers_];
78    memcpy(type_,rhs.type_,numberMembers_*sizeof(char));
79  } else {
80    members_ = NULL;
81    type_ = NULL;
82  }
83  cliqueType_ = rhs.cliqueType_;
84  slack_ = rhs.slack_;
85}
86
87// Clone
88CbcObject *
89CbcClique::clone() const
90{
91  return new CbcClique(*this);
92}
93
94// Assignment operator
95CbcClique & 
96CbcClique::operator=( const CbcClique& rhs)
97{
98  if (this!=&rhs) {
99    CbcObject::operator=(rhs);
100    delete [] members_;
101    delete [] type_;
102    numberMembers_ = rhs.numberMembers_;
103    numberNonSOSMembers_ = rhs.numberNonSOSMembers_;
104    if (numberMembers_) {
105      members_ = new int[numberMembers_];
106      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
107      type_ = new char[numberMembers_];
108      memcpy(type_,rhs.type_,numberMembers_*sizeof(char));
109    } else {
110      members_ = NULL;
111      type_ = NULL;
112    }
113    cliqueType_ = rhs.cliqueType_;
114    slack_ = rhs.slack_;
115  }
116  return *this;
117}
118
119// Destructor
120CbcClique::~CbcClique ()
121{
122  delete [] members_;
123  delete [] type_;
124}
125double 
126CbcClique::infeasibility(const OsiBranchingInformation * /*info*/,
127                               int &preferredWay) const
128{
129  int numberUnsatis=0, numberFree=0;
130  int j;
131  const int * integer = model_->integerVariable();
132  OsiSolverInterface * solver = model_->solver();
133  const double * solution = model_->testSolution();
134  const double * lower = solver->getColLower();
135  const double * upper = solver->getColUpper();
136  double largestValue=0.0;
137  double integerTolerance = 
138    model_->getDblParam(CbcModel::CbcIntegerTolerance);
139  double * sort = new double[numberMembers_];
140
141  double slackValue=0.0;
142  for (j=0;j<numberMembers_;j++) {
143    int sequence = members_[j];
144    int iColumn = integer[sequence];
145    double value = solution[iColumn];
146    value = CoinMax(value, lower[iColumn]);
147    value = CoinMin(value, upper[iColumn]);
148    double nearest = floor(value+0.5);
149    double distance = fabs(value-nearest);
150    if (distance>integerTolerance) {
151      if (!type_[j])
152        value = 1.0-value; // non SOS
153      // if slack then choose that
154      if (j==slack_&&value>0.05)
155        slackValue = value;
156      largestValue = CoinMax(value,largestValue);
157      sort[numberUnsatis++]=-value;
158    } else if (upper[iColumn]>lower[iColumn]) {
159      numberFree++;
160    }
161  }
162  preferredWay=1;
163  double otherWay = 0.0;
164  if (numberUnsatis) {
165    // sort
166    std::sort(sort,sort+numberUnsatis);
167    for (j=0;j<numberUnsatis;j++) {
168      if ((j&1)!=0)
169        otherWay += -sort[j];
170    }
171    // Need to think more
172    double value = 0.2*numberUnsatis+0.01*(numberMembers_-numberFree);
173    if (fabs(largestValue-0.5)<0.1) {
174      // close to half
175      value +=0.1;
176    }
177    if (slackValue) {
178      // branching on slack
179      value += slackValue;
180    }
181    // scale other way
182    otherWay *= value/(1.0-otherWay);
183    delete [] sort;
184    return value;
185  } else {
186    delete [] sort;
187    return 0.0; // satisfied
188  }
189}
190
191// This looks at solution and sets bounds to contain solution
192void 
193CbcClique::feasibleRegion()
194{
195  int j;
196  const int * integer = model_->integerVariable();
197  OsiSolverInterface * solver = model_->solver();
198  const double * solution = model_->testSolution();
199  const double * lower = solver->getColLower();
200  const double * upper = solver->getColUpper();
201#ifndef NDEBUG
202  double integerTolerance = 
203    model_->getDblParam(CbcModel::CbcIntegerTolerance);
204#endif 
205  for (j=0;j<numberMembers_;j++) {
206    int sequence = members_[j];
207    int iColumn = integer[sequence];
208    double value = solution[iColumn];
209    value = CoinMax(value, lower[iColumn]);
210    value = CoinMin(value, upper[iColumn]);
211    double nearest = floor(value+0.5);
212#ifndef NDEBUG
213    double distance = fabs(value-nearest);
214    assert(distance<=integerTolerance);
215#endif
216    solver->setColLower(iColumn,nearest);
217    solver->setColUpper(iColumn,nearest);
218  }
219}
220// Redoes data when sequence numbers change
221void 
222CbcClique::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
223{
224  model_=model;
225  int n2=0;
226  for (int j=0;j<numberMembers_;j++) {
227    int iColumn = members_[j];
228    int i;
229    for (i=0;i<numberColumns;i++) {
230      if (originalColumns[i]==iColumn)
231        break;
232    }
233    if (i<numberColumns) {
234      members_[n2]=i;
235      type_[n2++]=type_[j];
236    }
237  }
238  if (n2<numberMembers_) {
239    //printf("** SOS number of members reduced from %d to %d!\n",numberMembers_,n2);
240    numberMembers_=n2;
241  }
242  // Find out how many non sos
243  int i;
244  numberNonSOSMembers_=0;
245  for (i=0;i<numberMembers_;i++)
246    if (!type_[i])
247      numberNonSOSMembers_++;
248}
249CbcBranchingObject * 
250CbcClique::createCbcBranch(OsiSolverInterface * solver,const OsiBranchingInformation * /*info*/, int way) 
251{
252  int numberUnsatis=0;
253  int j;
254  int nUp=0;
255  int nDown=0;
256  int numberFree=numberMembers_;
257  const int * integer = model_->integerVariable();
258  //OsiSolverInterface * solver = model_->solver();
259  const double * solution = model_->testSolution();
260  const double * lower = solver->getColLower();
261  const double * upper = solver->getColUpper();
262  int * upList = new int[numberMembers_];
263  int * downList = new int[numberMembers_];
264  double * sort = new double[numberMembers_];
265  double integerTolerance = 
266      model_->getDblParam(CbcModel::CbcIntegerTolerance);
267
268  double slackValue=0.0;
269  for (j=0;j<numberMembers_;j++) {
270    int sequence = members_[j];
271    int iColumn = integer[sequence];
272    double value = solution[iColumn];
273    value = CoinMax(value, lower[iColumn]);
274    value = CoinMin(value, upper[iColumn]);
275    double nearest = floor(value+0.5);
276    double distance = fabs(value-nearest);
277    if (distance>integerTolerance) {
278      if (!type_[j])
279        value = 1.0-value; // non SOS
280      // if slack then choose that
281      if (j==slack_&&value>0.05)
282        slackValue = value;
283      value = -value; // for sort
284      upList[numberUnsatis]=j;
285      sort[numberUnsatis++]=value;
286    } else if (upper[iColumn]>lower[iColumn]) {
287      upList[--numberFree]=j;
288    }
289  }
290  assert (numberUnsatis);
291  if (!slackValue) {
292    // sort
293    CoinSort_2(sort,sort+numberUnsatis,upList);
294    // put first in up etc
295    int kWay=1;
296    for (j=0;j<numberUnsatis;j++) {
297      if (kWay>0) 
298        upList[nUp++]=upList[j];
299      else
300        downList[nDown++]=upList[j];
301      kWay = -kWay;
302    }
303    for (j=numberFree;j<numberMembers_;j++) {
304      if (kWay>0)
305        upList[nUp++]=upList[j];
306      else
307        downList[nDown++]=upList[j];
308      kWay = -kWay;
309    }
310  } else {
311    // put slack to 0 in first way
312    nUp = 1;
313    upList[0]=slack_;
314    for (j=0;j<numberUnsatis;j++) {
315      downList[nDown++]=upList[j];
316    }
317    for (j=numberFree;j<numberMembers_;j++) {
318      downList[nDown++]=upList[j];
319    }
320  }
321  // create object
322  CbcBranchingObject * branch;
323  if (numberMembers_ <=64)
324     branch = new CbcCliqueBranchingObject(model_,this,way,
325                                         nDown,downList,nUp,upList);
326  else
327    branch = new CbcLongCliqueBranchingObject(model_,this,way,
328                                            nDown,downList,nUp,upList);
329  delete [] upList;
330  delete [] downList;
331  delete [] sort;
332  return branch;
333}
334
335//##############################################################################
336
337// Default Constructor
338CbcSOS::CbcSOS ()
339  : CbcObject(),
340    members_(NULL),
341    weights_(NULL),
342    shadowEstimateDown_(1.0),
343    shadowEstimateUp_(1.0),
344    downDynamicPseudoRatio_(0.0),
345    upDynamicPseudoRatio_(0.0),
346    numberTimesDown_(0),
347    numberTimesUp_(0),
348    numberMembers_(0),
349    sosType_(-1),
350    integerValued_(false)
351{
352}
353
354// Useful constructor (which are indices)
355CbcSOS::CbcSOS (CbcModel * model,  int numberMembers,
356           const int * which, const double * weights, int identifier,int type)
357  : CbcObject(model),
358    shadowEstimateDown_(1.0),
359    shadowEstimateUp_(1.0),
360    downDynamicPseudoRatio_(0.0),
361    upDynamicPseudoRatio_(0.0),
362    numberTimesDown_(0),
363    numberTimesUp_(0),
364    numberMembers_(numberMembers),
365    sosType_(type)
366{
367  id_=identifier;
368  integerValued_ = type==1;
369  if (integerValued_) {
370    // check all members integer
371    OsiSolverInterface * solver = model->solver();
372    if (solver) {
373      for (int i=0;i<numberMembers_;i++) {
374        if (!solver->isInteger(which[i]))
375          integerValued_=false;
376      }
377    } else {
378      // can't tell
379      integerValued_=false;
380    }
381  }
382  if (numberMembers_) {
383    members_ = new int[numberMembers_];
384    weights_ = new double[numberMembers_];
385    memcpy(members_,which,numberMembers_*sizeof(int));
386    if (weights) {
387      memcpy(weights_,weights,numberMembers_*sizeof(double));
388    } else {
389      for (int i=0;i<numberMembers_;i++)
390        weights_[i]=i;
391    }
392    // sort so weights increasing
393    CoinSort_2(weights_,weights_+numberMembers_,members_);
394    double last = -COIN_DBL_MAX;
395    int i;
396    for (i=0;i<numberMembers_;i++) {
397      double possible = CoinMax(last+1.0e-10,weights_[i]);
398      weights_[i] = possible;
399      last=possible;
400    }
401  } else {
402    members_ = NULL;
403    weights_ = NULL;
404  }
405  assert (sosType_>0&&sosType_<3);
406}
407
408// Copy constructor
409CbcSOS::CbcSOS ( const CbcSOS & rhs)
410  :CbcObject(rhs)
411{
412  shadowEstimateDown_ = rhs.shadowEstimateDown_;
413  shadowEstimateUp_ = rhs.shadowEstimateUp_;
414  downDynamicPseudoRatio_ = rhs.downDynamicPseudoRatio_;
415  upDynamicPseudoRatio_ = rhs.upDynamicPseudoRatio_;
416  numberTimesDown_ = rhs.numberTimesDown_;
417  numberTimesUp_ = rhs.numberTimesUp_;
418  numberMembers_ = rhs.numberMembers_;
419  sosType_ = rhs.sosType_;
420  integerValued_ = rhs.integerValued_;
421  if (numberMembers_) {
422    members_ = new int[numberMembers_];
423    weights_ = new double[numberMembers_];
424    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
425    memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
426  } else {
427    members_ = NULL;
428    weights_ = NULL;
429  }
430}
431
432// Clone
433CbcObject *
434CbcSOS::clone() const
435{
436  return new CbcSOS(*this);
437}
438
439// Assignment operator
440CbcSOS & 
441CbcSOS::operator=( const CbcSOS& rhs)
442{
443  if (this!=&rhs) {
444    CbcObject::operator=(rhs);
445    delete [] members_;
446    delete [] weights_;
447    shadowEstimateDown_ = rhs.shadowEstimateDown_;
448    shadowEstimateUp_ = rhs.shadowEstimateUp_;
449    downDynamicPseudoRatio_ = rhs.downDynamicPseudoRatio_;
450    upDynamicPseudoRatio_ = rhs.upDynamicPseudoRatio_;
451    numberTimesDown_ = rhs.numberTimesDown_;
452    numberTimesUp_ = rhs.numberTimesUp_;
453    numberMembers_ = rhs.numberMembers_;
454    sosType_ = rhs.sosType_;
455    integerValued_ = rhs.integerValued_;
456    if (numberMembers_) {
457      members_ = new int[numberMembers_];
458      weights_ = new double[numberMembers_];
459      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
460      memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
461    } else {
462      members_ = NULL;
463      weights_ = NULL;
464    }
465  }
466  return *this;
467}
468
469// Destructor
470CbcSOS::~CbcSOS ()
471{
472  delete [] members_;
473  delete [] weights_;
474}
475double 
476CbcSOS::infeasibility(const OsiBranchingInformation * info,
477                               int &preferredWay) const
478{
479  int j;
480  int firstNonZero=-1;
481  int lastNonZero = -1;
482  OsiSolverInterface * solver = model_->solver();
483  const double * solution = model_->testSolution();
484  //const double * lower = solver->getColLower();
485  const double * upper = solver->getColUpper();
486  //double largestValue=0.0;
487  double integerTolerance = 
488    model_->getDblParam(CbcModel::CbcIntegerTolerance);
489  double weight = 0.0;
490  double sum =0.0;
491
492  // check bounds etc
493  double lastWeight=-1.0e100;
494  for (j=0;j<numberMembers_;j++) {
495    int iColumn = members_[j];
496    if (lastWeight>=weights_[j]-1.0e-7)
497      throw CoinError("Weights too close together in SOS","infeasibility","CbcSOS");
498    double value = CoinMax(0.0,solution[iColumn]);
499    sum += value;
500    if (value>integerTolerance&&upper[iColumn]) {
501      // Possibly due to scaling a fixed variable might slip through
502      if (value>upper[iColumn]) {
503        value=upper[iColumn];
504        // Could change to #ifdef CBC_DEBUG
505#ifndef NDEBUG
506        if (model_->messageHandler()->logLevel()>2)
507          printf("** Variable %d (%d) has value %g and upper bound of %g\n",
508                 iColumn,j,value,upper[iColumn]);
509#endif
510      } 
511      weight += weights_[j]*value;
512      if (firstNonZero<0)
513        firstNonZero=j;
514      lastNonZero=j;
515    }
516  }
517  preferredWay=1;
518  if (lastNonZero-firstNonZero>=sosType_) {
519    // find where to branch
520    assert (sum>0.0);
521    weight /= sum;
522    if (info->defaultDual_>=0.0&&info->usefulRegion_&&info->columnStart_) {
523      assert (sosType_==1);
524      int iWhere;
525      for (iWhere=firstNonZero;iWhere<lastNonZero-1;iWhere++) {
526        if (weight<weights_[iWhere+1]) {
527          break;
528        }
529      }
530      int jColumnDown = members_[iWhere];
531      int jColumnUp = members_[iWhere+1];
532      int n=0;
533      CoinBigIndex j;
534      double objMove = info->objective_[jColumnDown];
535      for (j=info->columnStart_[jColumnDown];
536           j<info->columnStart_[jColumnDown]+info->columnLength_[jColumnDown];j++) {
537        double value = info->elementByColumn_[j];
538        int iRow = info->row_[j];
539        info->indexRegion_[n++]=iRow;
540        info->usefulRegion_[iRow]=value;
541      }
542      for (iWhere=firstNonZero;iWhere<lastNonZero;iWhere++) {
543        int jColumn = members_[iWhere];
544        double solValue = info->solution_[jColumn];
545        if (!solValue)
546          continue;
547        objMove -= info->objective_[jColumn]*solValue;
548        for (j=info->columnStart_[jColumn];
549             j<info->columnStart_[jColumn]+info->columnLength_[jColumn];j++) {
550          double value = -info->elementByColumn_[j]*solValue;
551          int iRow = info->row_[j];
552          double oldValue = info->usefulRegion_[iRow];
553          if (!oldValue) {
554            info->indexRegion_[n++]=iRow;
555          } else {
556            value += oldValue;
557            if (!value)
558              value = 1.0e-100;
559          }
560          info->usefulRegion_[iRow]=value;
561        }
562      }
563      const double * pi = info->pi_;
564      const double * activity = info->rowActivity_;
565      const double * lower = info->rowLower_;
566      const double * upper = info->rowUpper_;
567      double tolerance = info->primalTolerance_;
568      double direction = info->direction_;
569      shadowEstimateDown_ = objMove*direction;
570      bool infeasible=false;
571      for (int k=0;k<n;k++) {
572        int iRow = info->indexRegion_[k];
573        double movement=info->usefulRegion_[iRow];
574        // not this time info->usefulRegion_[iRow]=0.0;
575        if (lower[iRow]<-1.0e20) 
576          assert (pi[iRow]<=1.0e-3);
577        if (upper[iRow]>1.0e20) 
578          assert (pi[iRow]>=-1.0e-3);
579        double valueP = pi[iRow]*direction;
580        // if move makes infeasible then make at least default
581        double newValue = activity[iRow] + movement;
582        if (newValue>upper[iRow]+tolerance||newValue<lower[iRow]-tolerance) {
583          shadowEstimateDown_ += fabs(movement)*CoinMax(fabs(valueP),info->defaultDual_);
584          infeasible=true;
585        }
586      }
587      if (shadowEstimateDown_<info->integerTolerance_) {
588        if (!infeasible) {
589          shadowEstimateDown_=1.0e-10;
590#ifdef COIN_DEVELOP
591          printf("zero pseudoShadowPrice\n");
592#endif
593        } else
594          shadowEstimateDown_ = info->integerTolerance_;
595      }
596      // And other way
597      // take off
598      objMove -= info->objective_[jColumnDown];
599      for (j=info->columnStart_[jColumnDown];
600           j<info->columnStart_[jColumnDown]+info->columnLength_[jColumnDown];j++) {
601        double value = -info->elementByColumn_[j];
602        int iRow = info->row_[j];
603        double oldValue = info->usefulRegion_[iRow];
604        if (!oldValue) {
605          info->indexRegion_[n++]=iRow;
606          } else {
607          value += oldValue;
608          if (!value)
609            value = 1.0e-100;
610        }
611        info->usefulRegion_[iRow]=value;
612      }
613      // add on
614      objMove += info->objective_[jColumnUp];
615      for (j=info->columnStart_[jColumnUp];
616           j<info->columnStart_[jColumnUp]+info->columnLength_[jColumnUp];j++) {
617        double value = info->elementByColumn_[j];
618        int iRow = info->row_[j];
619        double oldValue = info->usefulRegion_[iRow];
620        if (!oldValue) {
621          info->indexRegion_[n++]=iRow;
622          } else {
623          value += oldValue;
624          if (!value)
625            value = 1.0e-100;
626        }
627        info->usefulRegion_[iRow]=value;
628      }
629      shadowEstimateUp_ = objMove*direction;
630      infeasible=false;
631      for (int k=0;k<n;k++) {
632        int iRow = info->indexRegion_[k];
633        double movement=info->usefulRegion_[iRow];
634        info->usefulRegion_[iRow]=0.0;
635        if (lower[iRow]<-1.0e20) 
636          assert (pi[iRow]<=1.0e-3);
637        if (upper[iRow]>1.0e20) 
638          assert (pi[iRow]>=-1.0e-3);
639        double valueP = pi[iRow]*direction;
640        // if move makes infeasible then make at least default
641        double newValue = activity[iRow] + movement;
642        if (newValue>upper[iRow]+tolerance||newValue<lower[iRow]-tolerance) {
643          shadowEstimateUp_ += fabs(movement)*CoinMax(fabs(valueP),info->defaultDual_);
644          infeasible=true;
645        }
646      }
647      if (shadowEstimateUp_<info->integerTolerance_) {
648        if (!infeasible) {
649          shadowEstimateUp_=1.0e-10;
650#ifdef COIN_DEVELOP
651          printf("zero pseudoShadowPrice\n");
652#endif
653        } else
654          shadowEstimateUp_ = info->integerTolerance_;
655      }
656      // adjust
657      double downCost = shadowEstimateDown_;
658      double upCost = shadowEstimateUp_;
659      if (numberTimesDown_) 
660        downCost *= downDynamicPseudoRatio_/
661          static_cast<double> (numberTimesDown_);
662      if (numberTimesUp_) 
663        upCost *= upDynamicPseudoRatio_/
664          static_cast<double> (numberTimesUp_);
665#define WEIGHT_AFTER 0.7
666#define WEIGHT_BEFORE 0.1
667      int stateOfSearch = model_->stateOfSearch()%10;
668      double returnValue=0.0;
669      double minValue = CoinMin(downCost,upCost);
670      double maxValue = CoinMax(downCost,upCost);
671      if (stateOfSearch<=2) {
672        // no branching solution
673        returnValue = WEIGHT_BEFORE*minValue + (1.0-WEIGHT_BEFORE)*maxValue;
674      } else {
675        returnValue = WEIGHT_AFTER*minValue + (1.0-WEIGHT_AFTER)*maxValue;
676      }
677#ifdef PRINT_SHADOW
678      printf("%d id - down %d %g up %d %g shadow %g, %g returned %g\n",
679             id_,numberTimesDown_,downDynamicPseudoRatio_,
680             numberTimesUp_,upDynamicPseudoRatio_,shadowEstimateDown_,
681             shadowEstimateUp_,returnValue);
682#endif
683      return returnValue;
684    } else {
685      double value = lastNonZero-firstNonZero+1;
686      value *= 0.5/static_cast<double> (numberMembers_);
687      return value;
688    }
689  } else {
690    return 0.0; // satisfied
691  }
692}
693
694// This looks at solution and sets bounds to contain solution
695void 
696CbcSOS::feasibleRegion()
697{
698  int j;
699  int firstNonZero=-1;
700  int lastNonZero = -1;
701  OsiSolverInterface * solver = model_->solver();
702  const double * solution = model_->testSolution();
703  //const double * lower = solver->getColLower();
704  const double * upper = solver->getColUpper();
705  double integerTolerance = 
706    model_->getDblParam(CbcModel::CbcIntegerTolerance);
707  double weight = 0.0;
708  double sum =0.0;
709
710  for (j=0;j<numberMembers_;j++) {
711    int iColumn = members_[j];
712    double value = CoinMax(0.0,solution[iColumn]);
713    sum += value;
714    if (value>integerTolerance&&upper[iColumn]) {
715      weight += weights_[j]*value;
716      if (firstNonZero<0)
717        firstNonZero=j;
718      lastNonZero=j;
719    }
720  }
721  assert (lastNonZero-firstNonZero<sosType_) ;
722  for (j=0;j<firstNonZero;j++) {
723    int iColumn = members_[j];
724    solver->setColUpper(iColumn,0.0);
725  }
726  for (j=lastNonZero+1;j<numberMembers_;j++) {
727    int iColumn = members_[j];
728    solver->setColUpper(iColumn,0.0);
729  }
730}
731// Redoes data when sequence numbers change
732void 
733CbcSOS::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
734{
735  model_=model;
736  int n2=0;
737  for (int j=0;j<numberMembers_;j++) {
738    int iColumn = members_[j];
739    int i;
740    for (i=0;i<numberColumns;i++) {
741      if (originalColumns[i]==iColumn)
742        break;
743    }
744    if (i<numberColumns) {
745      members_[n2]=i;
746      weights_[n2++]=weights_[j];
747    }
748  }
749  if (n2<numberMembers_) {
750    //printf("** SOS number of members reduced from %d to %d!\n",numberMembers_,n2);
751    numberMembers_=n2;
752  }
753}
754CbcBranchingObject * 
755CbcSOS::createCbcBranch(OsiSolverInterface * solver,const OsiBranchingInformation * /*info*/, int way) 
756{
757  int j;
758  const double * solution = model_->testSolution();
759  double integerTolerance = 
760      model_->getDblParam(CbcModel::CbcIntegerTolerance);
761  //OsiSolverInterface * solver = model_->solver();
762  const double * upper = solver->getColUpper();
763  int firstNonFixed=-1;
764  int lastNonFixed=-1;
765  int firstNonZero=-1;
766  int lastNonZero = -1;
767  double weight = 0.0;
768  double sum =0.0;
769  for (j=0;j<numberMembers_;j++) {
770    int iColumn = members_[j];
771    if (upper[iColumn]) {
772      double value = CoinMax(0.0,solution[iColumn]);
773      sum += value;
774      if (firstNonFixed<0)
775        firstNonFixed=j;
776      lastNonFixed=j;
777      if (value>integerTolerance) {
778        weight += weights_[j]*value;
779        if (firstNonZero<0)
780          firstNonZero=j;
781        lastNonZero=j;
782      }
783    }
784  }
785  assert (lastNonZero-firstNonZero>=sosType_) ;
786  // find where to branch
787  assert (sum>0.0);
788  weight /= sum;
789  int iWhere;
790  double separator=0.0;
791  for (iWhere=firstNonZero;iWhere<lastNonZero;iWhere++) 
792    if (weight<weights_[iWhere+1])
793      break;
794  if (sosType_==1) {
795    // SOS 1
796    separator = 0.5 *(weights_[iWhere]+weights_[iWhere+1]);
797  } else {
798    // SOS 2
799    if (iWhere==firstNonFixed)
800      iWhere++;;
801    if (iWhere==lastNonFixed-1)
802      iWhere = lastNonFixed-2;
803    separator = weights_[iWhere+1];
804  }
805  // create object
806  CbcBranchingObject * branch;
807  branch = new CbcSOSBranchingObject(model_,this,way,separator);
808  branch->setOriginalObject(this);
809  return branch;
810}
811/* Pass in information on branch just done and create CbcObjectUpdateData instance.
812   If object does not need data then backward pointer will be NULL.
813   Assumes can get information from solver */
814CbcObjectUpdateData
815CbcSOS::createUpdateInformation(const OsiSolverInterface * solver, 
816                                const CbcNode * node,
817                                const CbcBranchingObject * branchingObject)
818{
819  double originalValue=node->objectiveValue();
820  int originalUnsatisfied = node->numberUnsatisfied();
821  double objectiveValue = solver->getObjValue()*solver->getObjSense();
822  int unsatisfied=0;
823  int i;
824  //might be base model - doesn't matter
825  int numberIntegers = model_->numberIntegers();;
826  const double * solution = solver->getColSolution();
827  //const double * lower = solver->getColLower();
828  //const double * upper = solver->getColUpper();
829  double change = CoinMax(0.0,objectiveValue-originalValue);
830  int iStatus;
831  if (solver->isProvenOptimal())
832    iStatus=0; // optimal
833  else if (solver->isIterationLimitReached()
834           &&!solver->isDualObjectiveLimitReached())
835    iStatus=2; // unknown
836  else
837    iStatus=1; // infeasible
838
839  bool feasible = iStatus!=1;
840  if (feasible) {
841    double integerTolerance = 
842      model_->getDblParam(CbcModel::CbcIntegerTolerance);
843    const int * integerVariable = model_->integerVariable();
844    for (i=0;i<numberIntegers;i++) {
845      int j=integerVariable[i];
846      double value = solution[j];
847      double nearest = floor(value+0.5);
848      if (fabs(value-nearest)>integerTolerance) 
849        unsatisfied++;
850    }
851  }
852  int way = branchingObject->way();
853  way = - way; // because after branch so moved on
854  double value = branchingObject->value();
855  CbcObjectUpdateData newData (this, way,
856                               change, iStatus,
857                               originalUnsatisfied-unsatisfied,value);
858  newData.originalObjective_ = originalValue;
859  // Solvers know about direction
860  double direction = solver->getObjSense();
861  solver->getDblParam(OsiDualObjectiveLimit,newData.cutoff_);
862  newData.cutoff_ *= direction;
863  return newData;
864}
865// Update object by CbcObjectUpdateData
866void 
867CbcSOS::updateInformation(const CbcObjectUpdateData & data)
868{
869  bool feasible = data.status_!=1;
870  int way = data.way_;
871  //double value = data.branchingValue_;
872  double originalValue = data.originalObjective_;
873  double change = data.change_;
874  if (way<0) {
875    // down
876    if (!feasible) {
877      double distanceToCutoff=0.0;
878      //double objectiveValue = model_->getCurrentMinimizationObjValue();
879      distanceToCutoff =  model_->getCutoff()  - originalValue;
880      if (distanceToCutoff<1.0e20) 
881        change = distanceToCutoff*2.0;
882      else 
883        change = (downDynamicPseudoRatio_*shadowEstimateDown_+1.0e-3)*10.0;
884    } 
885    change = CoinMax(1.0e-12*(1.0+fabs(originalValue)),change);
886#ifdef PRINT_SHADOW
887    if (numberTimesDown_)
888      printf("Updating id %d - down change %g (true %g) - ndown %d estimated change %g - raw shadow estimate %g\n",
889             id_,change,data.change_,numberTimesDown_,shadowEstimateDown_*
890             (downDynamicPseudoRatio_/((double) numberTimesDown_)),
891             shadowEstimateDown_);
892    else
893      printf("Updating id %d - down change %g (true %g) - shadow estimate %g\n",
894             id_,change,data.change_,shadowEstimateDown_);
895#endif
896    numberTimesDown_++;
897    downDynamicPseudoRatio_ += change/shadowEstimateDown_;
898  } else {
899    // up
900    if (!feasible) {
901      double distanceToCutoff=0.0;
902      //double objectiveValue = model_->getCurrentMinimizationObjValue();
903      distanceToCutoff =  model_->getCutoff()  - originalValue;
904      if (distanceToCutoff<1.0e20) 
905        change = distanceToCutoff*2.0;
906      else 
907        change = (upDynamicPseudoRatio_*shadowEstimateUp_+1.0e-3)*10.0;
908    } 
909    change = CoinMax(1.0e-12*(1.0+fabs(originalValue)),change);
910#ifdef PRINT_SHADOW
911    if (numberTimesUp_)
912      printf("Updating id %d - up change %g (true %g) - nup %d estimated change %g - raw shadow estimate %g\n",
913             id_,change,data.change_,numberTimesUp_,shadowEstimateUp_*
914             (upDynamicPseudoRatio_/((double) numberTimesUp_)),
915             shadowEstimateUp_);
916    else
917      printf("Updating id %d - up change %g (true %g) - shadow estimate %g\n",
918             id_,change,data.change_,shadowEstimateUp_);
919#endif
920    numberTimesUp_++;
921    upDynamicPseudoRatio_ += change/shadowEstimateUp_;
922  }
923}
924
925/* Create an OsiSolverBranch object
926   
927This returns NULL if branch not represented by bound changes
928*/
929OsiSolverBranch * 
930CbcSOS::solverBranch() const
931{
932  int j;
933  const double * solution = model_->testSolution();
934  double integerTolerance = 
935      model_->getDblParam(CbcModel::CbcIntegerTolerance);
936  OsiSolverInterface * solver = model_->solver();
937  const double * upper = solver->getColUpper();
938  int firstNonFixed=-1;
939  int lastNonFixed=-1;
940  int firstNonZero=-1;
941  int lastNonZero = -1;
942  double weight = 0.0;
943  double sum =0.0;
944  double * fix = new double[numberMembers_];
945  int * which = new int[numberMembers_];
946  for (j=0;j<numberMembers_;j++) {
947    int iColumn = members_[j];
948    // fix all on one side or other (even if fixed)
949    fix[j]=0.0;
950    which[j]=iColumn;
951    if (upper[iColumn]) {
952      double value = CoinMax(0.0,solution[iColumn]);
953      sum += value;
954      if (firstNonFixed<0)
955        firstNonFixed=j;
956      lastNonFixed=j;
957      if (value>integerTolerance) {
958        weight += weights_[j]*value;
959        if (firstNonZero<0)
960          firstNonZero=j;
961        lastNonZero=j;
962      }
963    }
964  }
965  assert (lastNonZero-firstNonZero>=sosType_) ;
966  // find where to branch
967  assert (sum>0.0);
968  weight /= sum;
969  // down branch fixes ones above weight to 0
970  int iWhere;
971  int iDownStart=0;
972  int iUpEnd=0;
973  for (iWhere=firstNonZero;iWhere<lastNonZero;iWhere++) 
974    if (weight<weights_[iWhere+1])
975      break;
976  if (sosType_==1) {
977    // SOS 1
978    iUpEnd=iWhere+1;
979    iDownStart=iUpEnd;
980  } else {
981    // SOS 2
982    if (iWhere==firstNonFixed)
983      iWhere++;;
984    if (iWhere==lastNonFixed-1)
985      iWhere = lastNonFixed-2;
986    iUpEnd=iWhere+1;
987    iDownStart=iUpEnd+1;
988  }
989  //
990  OsiSolverBranch * branch = new OsiSolverBranch();
991  branch->addBranch(-1,0,NULL,NULL,numberMembers_-iDownStart,which+iDownStart,fix);
992  branch->addBranch(1,0,NULL,NULL,iUpEnd,which,fix);
993  delete [] fix;
994  delete [] which;
995  return branch;
996}
997// Construct an OsiSOS object
998OsiSOS * 
999CbcSOS::osiObject(const OsiSolverInterface * solver) const
1000{
1001  OsiSOS * obj = new OsiSOS(solver,numberMembers_,members_,weights_,sosType_);
1002  obj->setPriority(priority());
1003  return obj;
1004}
1005
1006//##############################################################################
1007
1008/** Default Constructor
1009
1010  Equivalent to an unspecified binary variable.
1011*/
1012CbcSimpleInteger::CbcSimpleInteger ()
1013  : CbcObject(),
1014    originalLower_(0.0),
1015    originalUpper_(1.0),
1016    breakEven_(0.5),
1017    columnNumber_(-1),
1018    preferredWay_(0)
1019{
1020}
1021
1022/** Useful constructor
1023
1024  Loads actual upper & lower bounds for the specified variable.
1025*/
1026CbcSimpleInteger::CbcSimpleInteger ( CbcModel * model, int iColumn, double breakEven)
1027  : CbcObject(model)
1028{
1029  columnNumber_ = iColumn ;
1030  originalLower_ = model->solver()->getColLower()[columnNumber_] ;
1031  originalUpper_ = model->solver()->getColUpper()[columnNumber_] ;
1032  breakEven_ = breakEven;
1033  assert (breakEven_>0.0&&breakEven_<1.0);
1034  preferredWay_ = 0;
1035}
1036
1037
1038// Copy constructor
1039CbcSimpleInteger::CbcSimpleInteger ( const CbcSimpleInteger & rhs)
1040  :CbcObject(rhs)
1041
1042{
1043  columnNumber_ = rhs.columnNumber_;
1044  originalLower_ = rhs.originalLower_;
1045  originalUpper_ = rhs.originalUpper_;
1046  breakEven_ = rhs.breakEven_;
1047  preferredWay_ = rhs.preferredWay_;
1048}
1049
1050// Clone
1051CbcObject *
1052CbcSimpleInteger::clone() const
1053{
1054  return new CbcSimpleInteger(*this);
1055}
1056
1057// Assignment operator
1058CbcSimpleInteger & 
1059CbcSimpleInteger::operator=( const CbcSimpleInteger& rhs)
1060{
1061  if (this!=&rhs) {
1062    CbcObject::operator=(rhs);
1063    columnNumber_ = rhs.columnNumber_;
1064    originalLower_ = rhs.originalLower_;
1065    originalUpper_ = rhs.originalUpper_;
1066    breakEven_ = rhs.breakEven_;
1067    preferredWay_ = rhs.preferredWay_;
1068  }
1069  return *this;
1070}
1071
1072// Destructor
1073CbcSimpleInteger::~CbcSimpleInteger ()
1074{
1075}
1076// Construct an OsiSimpleInteger object
1077OsiSimpleInteger * 
1078CbcSimpleInteger::osiObject() const
1079{
1080  OsiSimpleInteger * obj = new OsiSimpleInteger(columnNumber_,
1081                                                originalLower_,originalUpper_);
1082  obj->setPriority(priority());
1083  return obj;
1084}
1085double 
1086CbcSimpleInteger::infeasibility(const OsiBranchingInformation * info,
1087                               int &preferredWay) const
1088{
1089  double value = info->solution_[columnNumber_];
1090  value = CoinMax(value, info->lower_[columnNumber_]);
1091  value = CoinMin(value, info->upper_[columnNumber_]);
1092  double nearest = floor(value+(1.0-breakEven_));
1093  assert (breakEven_>0.0&&breakEven_<1.0);
1094  if (nearest>value) 
1095    preferredWay=1;
1096  else
1097    preferredWay=-1;
1098  if (preferredWay_)
1099    preferredWay=preferredWay_;
1100  double weight = fabs(value-nearest);
1101  // normalize so weight is 0.5 at break even
1102  if (nearest<value)
1103    weight = (0.5/breakEven_)*weight;
1104  else
1105    weight = (0.5/(1.0-breakEven_))*weight;
1106  if (fabs(value-nearest)<=info->integerTolerance_) 
1107    return 0.0;
1108  else
1109    return weight;
1110}
1111double 
1112CbcSimpleInteger::feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const 
1113{
1114  double value = info->solution_[columnNumber_];
1115#ifdef COIN_DEVELOP
1116  if (fabs(value-floor(value+0.5))>1.0e-5)
1117    printf("value for %d away from integer %g\n",columnNumber_,value);
1118#endif
1119  double newValue = CoinMax(value, info->lower_[columnNumber_]);
1120  newValue = CoinMin(newValue, info->upper_[columnNumber_]);
1121  newValue = floor(newValue+0.5);
1122  solver->setColLower(columnNumber_,newValue);
1123  solver->setColUpper(columnNumber_,newValue);
1124  return fabs(value-newValue);
1125}
1126
1127/* Create an OsiSolverBranch object
1128   
1129This returns NULL if branch not represented by bound changes
1130*/
1131OsiSolverBranch * 
1132CbcSimpleInteger::solverBranch(OsiSolverInterface * /*solver*/, 
1133                               const OsiBranchingInformation * info) const
1134{
1135  double value = info->solution_[columnNumber_];
1136  value = CoinMax(value, info->lower_[columnNumber_]);
1137  value = CoinMin(value, info->upper_[columnNumber_]);
1138  assert (info->upper_[columnNumber_]>info->lower_[columnNumber_]);
1139#ifndef NDEBUG
1140  double nearest = floor(value+0.5);
1141  assert (fabs(value-nearest)>info->integerTolerance_);
1142#endif
1143  OsiSolverBranch * branch = new OsiSolverBranch();
1144  branch->addBranch(columnNumber_,value);
1145  return branch;
1146}
1147// Creates a branching object
1148CbcBranchingObject * 
1149CbcSimpleInteger::createCbcBranch(OsiSolverInterface * /*solver*/, 
1150                               const OsiBranchingInformation * info, int way) 
1151{
1152  CbcIntegerBranchingObject * branch = new CbcIntegerBranchingObject(model_,0,-1,0.5);
1153  fillCreateBranch(branch,info,way);
1154  return branch;
1155}
1156// Fills in a created branching object
1157void 
1158CbcSimpleInteger::fillCreateBranch(CbcIntegerBranchingObject * branch, const OsiBranchingInformation * info, int way) 
1159{
1160  branch->setOriginalObject(this);
1161  double value = info->solution_[columnNumber_];
1162  value = CoinMax(value, info->lower_[columnNumber_]);
1163  value = CoinMin(value, info->upper_[columnNumber_]);
1164  assert (info->upper_[columnNumber_]>info->lower_[columnNumber_]);
1165  if (!info->hotstartSolution_&&priority_!=-999) {
1166#ifndef NDEBUG
1167    double nearest = floor(value+0.5);
1168    assert (fabs(value-nearest)>info->integerTolerance_);
1169#endif
1170  } else if (info->hotstartSolution_) {
1171    double targetValue = info->hotstartSolution_[columnNumber_];
1172    if (way>0)
1173      value = targetValue-0.1;
1174    else
1175      value = targetValue+0.1;
1176  } else {
1177    if (value<=info->lower_[columnNumber_])
1178      value += 0.1;
1179    else if (value>=info->upper_[columnNumber_])
1180      value -= 0.1;
1181  }
1182  assert (value>=info->lower_[columnNumber_]&&
1183          value<=info->upper_[columnNumber_]);
1184  branch->fillPart(columnNumber_,way,value);
1185}
1186/* Column number if single column object -1 otherwise,
1187   so returns >= 0
1188   Used by heuristics
1189*/
1190int 
1191CbcSimpleInteger::columnNumber() const
1192{
1193  return columnNumber_;
1194}
1195/* Reset variable bounds to their original values.
1196 
1197    Bounds may be tightened, so it may be good to be able to set this info in object.
1198*/
1199void 
1200CbcSimpleInteger::resetBounds(const OsiSolverInterface * solver) 
1201{
1202  originalLower_ = solver->getColLower()[columnNumber_] ;
1203  originalUpper_ = solver->getColUpper()[columnNumber_] ;
1204}
1205
1206/*  Change column numbers after preprocessing
1207 */
1208void 
1209CbcSimpleInteger::resetSequenceEtc(int /*numberColumns*/, 
1210                                   const int * originalColumns) 
1211{
1212  //assert (numberColumns>0);
1213  int iColumn;
1214#if 0
1215  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1216    if (columnNumber_==originalColumns[iColumn])
1217      break;
1218  }
1219  assert (iColumn<numberColumns);
1220#else
1221  iColumn=originalColumns[columnNumber_];
1222  assert (iColumn>=0);
1223#endif
1224  columnNumber_ = iColumn;
1225}
1226// This looks at solution and sets bounds to contain solution
1227/** More precisely: it first forces the variable within the existing
1228    bounds, and then tightens the bounds to fix the variable at the
1229    nearest integer value.
1230*/
1231void 
1232CbcSimpleInteger::feasibleRegion()
1233{
1234  abort();
1235}
1236
1237//##############################################################################
1238
1239// Default Constructor
1240CbcIntegerBranchingObject::CbcIntegerBranchingObject()
1241  :CbcBranchingObject()
1242{
1243  down_[0] = 0.0;
1244  down_[1] = 0.0;
1245  up_[0] = 0.0;
1246  up_[1] = 0.0;
1247#ifdef FUNNY_BRANCHING
1248  variables_ = NULL;
1249  newBounds_ = NULL;
1250  numberExtraChangedBounds_ = 0;
1251#endif
1252}
1253// Useful constructor
1254CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
1255                                                      int variable, int way , double value)
1256  :CbcBranchingObject(model,variable,way,value)
1257{
1258  int iColumn = variable;
1259  assert (model_->solver()->getNumCols()>0);
1260  down_[0] = model_->solver()->getColLower()[iColumn];
1261  down_[1] = floor(value_);
1262  up_[0] = ceil(value_);
1263  up_[1] = model->getColUpper()[iColumn];
1264#ifdef FUNNY_BRANCHING
1265  variables_ = NULL;
1266  newBounds_ = NULL;
1267  numberExtraChangedBounds_ = 0;
1268#endif
1269}
1270// Does part of constructor
1271void 
1272CbcIntegerBranchingObject::fillPart (int variable,
1273                                 int way , double value) 
1274{
1275  //originalObject_=NULL;
1276  branchIndex_=0;
1277  value_=value;
1278  numberBranches_=2;
1279  //model_= model;
1280  //originalCbcObject_=NULL;
1281  variable_=variable;
1282  way_=way;
1283  int iColumn = variable;
1284  down_[0] = model_->solver()->getColLower()[iColumn];
1285  down_[1] = floor(value_);
1286  up_[0] = ceil(value_);
1287  up_[1] = model_->getColUpper()[iColumn];
1288}
1289// Useful constructor for fixing
1290CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
1291                                                      int variable, int way,
1292                                                      double lowerValue, 
1293                                                      double upperValue)
1294  :CbcBranchingObject(model,variable,way,lowerValue)
1295{
1296  setNumberBranchesLeft(1);
1297  down_[0] = lowerValue;
1298  down_[1] = upperValue;
1299  up_[0] = lowerValue;
1300  up_[1] = upperValue;
1301#ifdef FUNNY_BRANCHING
1302  variables_ = NULL;
1303  newBounds_ = NULL;
1304  numberExtraChangedBounds_ = 0;
1305#endif
1306}
1307 
1308
1309// Copy constructor
1310CbcIntegerBranchingObject::CbcIntegerBranchingObject ( const CbcIntegerBranchingObject & rhs) :CbcBranchingObject(rhs)
1311{
1312  down_[0] = rhs.down_[0];
1313  down_[1] = rhs.down_[1];
1314  up_[0] = rhs.up_[0];
1315  up_[1] = rhs.up_[1];
1316#ifdef FUNNY_BRANCHING
1317  numberExtraChangedBounds_ = rhs.numberExtraChangedBounds_;
1318  int size = numberExtraChangedBounds_*(sizeof(double)+sizeof(int));
1319  char * temp = new char [size];
1320  newBounds_ = (double *) temp;
1321  variables_ = (int *) (newBounds_+numberExtraChangedBounds_);
1322
1323  int i ;
1324  for (i=0;i<numberExtraChangedBounds_;i++) {
1325    variables_[i]=rhs.variables_[i];
1326    newBounds_[i]=rhs.newBounds_[i];
1327  }
1328#endif
1329}
1330
1331// Assignment operator
1332CbcIntegerBranchingObject & 
1333CbcIntegerBranchingObject::operator=( const CbcIntegerBranchingObject& rhs)
1334{
1335  if (this != &rhs) {
1336    CbcBranchingObject::operator=(rhs);
1337    down_[0] = rhs.down_[0];
1338    down_[1] = rhs.down_[1];
1339    up_[0] = rhs.up_[0];
1340    up_[1] = rhs.up_[1];
1341#ifdef FUNNY_BRANCHING
1342    delete [] newBounds_;
1343    numberExtraChangedBounds_ = rhs.numberExtraChangedBounds_;
1344    int size = numberExtraChangedBounds_*(sizeof(double)+sizeof(int));
1345    char * temp = new char [size];
1346    newBounds_ = (double *) temp;
1347    variables_ = (int *) (newBounds_+numberExtraChangedBounds_);
1348   
1349    int i ;
1350    for (i=0;i<numberExtraChangedBounds_;i++) {
1351      variables_[i]=rhs.variables_[i];
1352      newBounds_[i]=rhs.newBounds_[i];
1353    }
1354#endif
1355  }
1356  return *this;
1357}
1358CbcBranchingObject * 
1359CbcIntegerBranchingObject::clone() const
1360{ 
1361  return (new CbcIntegerBranchingObject(*this));
1362}
1363
1364
1365// Destructor
1366CbcIntegerBranchingObject::~CbcIntegerBranchingObject ()
1367{
1368  // for debugging threads
1369  way_=-23456789;
1370#ifdef FUNNY_BRANCHING
1371  delete [] newBounds_;
1372#endif
1373}
1374
1375/*
1376  Perform a branch by adjusting the bounds of the specified variable. Note
1377  that each arm of the branch advances the object to the next arm by
1378  advancing the value of way_.
1379
1380  Providing new values for the variable's lower and upper bounds for each
1381  branching direction gives a little bit of additional flexibility and will
1382  be easily extensible to multi-way branching.
1383  Returns change in guessed objective on next branch
1384*/
1385double
1386CbcIntegerBranchingObject::branch()
1387{
1388  // for debugging threads
1389  if (way_<-1||way_>100000) {
1390    printf("way %d, left %d, iCol %d, variable %d\n",
1391           way_,numberBranchesLeft(),
1392           originalCbcObject_->columnNumber(),variable_);
1393    assert (way_!=-23456789);
1394  }
1395  decrementNumberBranchesLeft();
1396  if (down_[1]==-COIN_DBL_MAX)
1397    return 0.0;
1398  int iColumn = originalCbcObject_->columnNumber();
1399  assert (variable_==iColumn);
1400  double olb,oub ;
1401  olb = model_->solver()->getColLower()[iColumn] ;
1402  oub = model_->solver()->getColUpper()[iColumn] ;
1403  //#define TIGHTEN_BOUNDS
1404#ifndef TIGHTEN_BOUNDS
1405#ifdef COIN_DEVELOP
1406  if (olb!=down_[0]||oub!=up_[1]) {
1407    if (way_>0)
1408      printf("branching up on var %d: [%g,%g] => [%g,%g] - other [%g,%g]\n",
1409             iColumn,olb,oub,up_[0],up_[1],down_[0],down_[1]) ; 
1410    else
1411      printf("branching down on var %d: [%g,%g] => [%g,%g] - other [%g,%g]\n",
1412             iColumn,olb,oub,down_[0],down_[1],up_[0],up_[1]) ; 
1413  }
1414#endif
1415#endif
1416  if (way_<0) {
1417#ifdef CBC_DEBUG
1418  { double olb,oub ;
1419    olb = model_->solver()->getColLower()[iColumn] ;
1420    oub = model_->solver()->getColUpper()[iColumn] ;
1421    printf("branching down on var %d: [%g,%g] => [%g,%g]\n",
1422           iColumn,olb,oub,down_[0],down_[1]) ; }
1423#endif
1424#ifndef TIGHTEN_BOUNDS
1425    model_->solver()->setColLower(iColumn,down_[0]);
1426#else
1427    model_->solver()->setColLower(iColumn,CoinMax(down_[0],olb));
1428#endif
1429    model_->solver()->setColUpper(iColumn,down_[1]);
1430    //#define CBC_PRINT2
1431#ifdef CBC_PRINT2
1432    printf("%d branching down has bounds %g %g",iColumn,down_[0],down_[1]);
1433#endif
1434#ifdef FUNNY_BRANCHING
1435    // branch - do extra bounds
1436    for (int i=0;i<numberExtraChangedBounds_;i++) {
1437      int variable = variables_[i];
1438      if ((variable&0x40000000)!=0) {
1439        // for going down
1440        int k = variable&0x3fffffff;
1441        assert (k!=iColumn);
1442        if ((variable&0x80000000)==0) {
1443          // lower bound changing
1444#ifdef CBC_PRINT2
1445          printf(" extra for %d changes lower from %g to %g",
1446                 k,model_->solver()->getColLower()[k],newBounds_[i]);
1447#endif
1448          model_->solver()->setColLower(k,newBounds_[i]);
1449        } else {
1450          // upper bound changing
1451#ifdef CBC_PRINT2
1452          printf(" extra for %d changes upper from %g to %g",
1453                 k,model_->solver()->getColUpper()[k],newBounds_[i]);
1454#endif
1455          model_->solver()->setColUpper(k,newBounds_[i]);
1456        }
1457      }
1458    }
1459#endif
1460#ifdef CBC_PRINT2
1461    printf("\n");
1462#endif
1463    way_=1;
1464  } else {
1465#ifdef CBC_DEBUG
1466  { double olb,oub ;
1467    olb = model_->solver()->getColLower()[iColumn] ;
1468    oub = model_->solver()->getColUpper()[iColumn] ;
1469    printf("branching up on var %d: [%g,%g] => [%g,%g]\n",
1470           iColumn,olb,oub,up_[0],up_[1]) ; }
1471#endif
1472    model_->solver()->setColLower(iColumn,up_[0]);
1473#ifndef TIGHTEN_BOUNDS
1474    model_->solver()->setColUpper(iColumn,up_[1]);
1475#else
1476    model_->solver()->setColUpper(iColumn,CoinMin(up_[1],oub));
1477#endif
1478#ifdef CBC_PRINT2
1479    printf("%d branching up has bounds %g %g",iColumn,up_[0],up_[1]);
1480#endif
1481#ifdef FUNNY_BRANCHING
1482    // branch - do extra bounds
1483    for (int i=0;i<numberExtraChangedBounds_;i++) {
1484      int variable = variables_[i];
1485      if ((variable&0x40000000)==0) {
1486        // for going up
1487        int k = variable&0x3fffffff;
1488        assert (k!=iColumn);
1489        if ((variable&0x80000000)==0) {
1490          // lower bound changing
1491#ifdef CBC_PRINT2
1492          printf(" extra for %d changes lower from %g to %g",
1493                 k,model_->solver()->getColLower()[k],newBounds_[i]);
1494#endif
1495          model_->solver()->setColLower(k,newBounds_[i]);
1496        } else {
1497          // upper bound changing
1498#ifdef CBC_PRINT2
1499          printf(" extra for %d changes upper from %g to %g",
1500                 k,model_->solver()->getColUpper()[k],newBounds_[i]);
1501#endif
1502          model_->solver()->setColUpper(k,newBounds_[i]);
1503        }
1504      }
1505    }
1506#endif
1507#ifdef CBC_PRINT2
1508    printf("\n");
1509#endif
1510    way_=-1;      // Swap direction
1511  }
1512  double nlb = model_->solver()->getColLower()[iColumn];
1513  double nub = model_->solver()->getColUpper()[iColumn];
1514  if (nlb<olb) {
1515#ifndef NDEBUG
1516    printf("bad lb change for column %d from %g to %g\n",iColumn,olb,nlb);
1517#endif
1518    model_->solver()->setColLower(iColumn,CoinMin(olb,nub));
1519    nlb=olb;
1520  }
1521  if (nub>oub) {
1522#ifndef NDEBUG
1523    printf("bad ub change for column %d from %g to %g\n",iColumn,oub,nub);
1524#endif
1525    model_->solver()->setColUpper(iColumn,CoinMax(oub,nlb));
1526  }
1527#ifndef NDEBUG
1528  if (nlb<olb+1.0e-8&&nub>oub-1.0e-8&&false)
1529    printf("bad null change for column %d - bounds %g,%g\n",iColumn,olb,oub);
1530#endif
1531  return 0.0;
1532}
1533/* Update bounds in solver as in 'branch' and update given bounds.
1534   branchState is -1 for 'down' +1 for 'up' */
1535void 
1536CbcIntegerBranchingObject::fix(OsiSolverInterface * /*solver*/,
1537                               double * lower, double * upper,
1538                               int branchState) const 
1539{
1540  int iColumn = originalCbcObject_->columnNumber();
1541  assert (variable_==iColumn);
1542  if (branchState<0) {
1543    model_->solver()->setColLower(iColumn,down_[0]);
1544    lower[iColumn]=down_[0];
1545    model_->solver()->setColUpper(iColumn,down_[1]);
1546    upper[iColumn]=down_[1];
1547  } else {
1548    model_->solver()->setColLower(iColumn,up_[0]);
1549    lower[iColumn]=up_[0];
1550    model_->solver()->setColUpper(iColumn,up_[1]);
1551    upper[iColumn]=up_[1];
1552  }
1553}
1554#ifdef FUNNY_BRANCHING
1555// Deactivate bounds for branching
1556void 
1557CbcIntegerBranchingObject::deactivate()
1558{
1559  down_[1]=-COIN_DBL_MAX;
1560}
1561int
1562CbcIntegerBranchingObject::applyExtraBounds(int iColumn, double lower, double upper, int way)
1563{
1564  // branch - do bounds
1565
1566  int i;
1567  int found=0;
1568  if (variable_==iColumn) {
1569    printf("odd applyExtra %d\n",iColumn);
1570    if (way<0) {
1571      down_[0]=CoinMax(lower,down_[0]);
1572      down_[1]=CoinMin(upper,down_[1]);
1573      assert (down_[0]<=down_[1]);
1574    } else {
1575      up_[0]=CoinMax(lower,up_[0]);
1576      up_[1]=CoinMin(upper,up_[1]);
1577      assert (up_[0]<=up_[1]);
1578    }
1579    return 0;
1580  }
1581  int check = (way<0) ? 0x40000000 : 0;
1582  double newLower=lower;
1583  double newUpper=upper;
1584  for (i=0;i<numberExtraChangedBounds_;i++) {
1585    int variable = variables_[i];
1586    if ((variable&0x40000000)==check) {
1587      int k = variable&0x3fffffff;
1588      if (k==iColumn) {
1589        if ((variable&0x80000000)==0) {
1590          // lower bound changing
1591          found |= 1;
1592          newBounds_[i] = CoinMax(lower,newBounds_[i]);
1593          newLower = newBounds_[i];
1594        } else {
1595          // upper bound changing
1596          found |= 2;
1597          newBounds_[i] = CoinMin(upper,newBounds_[i]);
1598          newUpper = newBounds_[i];
1599        }
1600      }
1601    }
1602  }
1603  int nAdd=0;
1604  if ((found&2)==0) {
1605    // need to add new upper
1606    nAdd++;
1607  }
1608  if ((found&1)==0) {
1609    // need to add new lower
1610    nAdd++;
1611  }
1612  if (nAdd) { 
1613    int size = (numberExtraChangedBounds_+nAdd)*(sizeof(double)+sizeof(int));
1614    char * temp = new char [size];
1615    double * newBounds = (double *) temp;
1616    int * variables = (int *) (newBounds+numberExtraChangedBounds_+nAdd);
1617
1618    int i ;
1619    for (i=0;i<numberExtraChangedBounds_;i++) {
1620      variables[i]=variables_[i];
1621      newBounds[i]=newBounds_[i];
1622    }
1623    delete [] newBounds_;
1624    newBounds_ = newBounds;
1625    variables_ = variables;
1626    if ((found&2)==0) {
1627      // need to add new upper
1628      int variable = iColumn | 0x80000000;
1629      variables_[numberExtraChangedBounds_]=variable;
1630      newBounds_[numberExtraChangedBounds_++]=newUpper;
1631    }
1632    if ((found&1)==0) {
1633      // need to add new lower
1634      int variable = iColumn;
1635      variables_[numberExtraChangedBounds_]=variable;
1636      newBounds_[numberExtraChangedBounds_++]=newLower;
1637    }
1638  }
1639 
1640  return (newUpper>=newLower) ? 0 : 1;
1641}
1642#endif
1643// Print what would happen 
1644void
1645CbcIntegerBranchingObject::print()
1646{
1647  int iColumn = originalCbcObject_->columnNumber();
1648  assert (variable_==iColumn);
1649  if (way_<0) {
1650  { double olb,oub ;
1651    olb = model_->solver()->getColLower()[iColumn] ;
1652    oub = model_->solver()->getColUpper()[iColumn] ;
1653    printf("CbcInteger would branch down on var %d (int var %d): [%g,%g] => [%g,%g]\n",
1654           iColumn,variable_,olb,oub,down_[0],down_[1]) ; }
1655  } else {
1656  { double olb,oub ;
1657    olb = model_->solver()->getColLower()[iColumn] ;
1658    oub = model_->solver()->getColUpper()[iColumn] ;
1659    printf("CbcInteger would branch up on var %d (int var %d): [%g,%g] => [%g,%g]\n",
1660           iColumn,variable_,olb,oub,up_[0],up_[1]) ; }
1661  }
1662}
1663
1664/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
1665    same type and must have the same original object, but they may have
1666    different feasible regions.
1667    Return the appropriate CbcRangeCompare value (first argument being the
1668    sub/superset if that's the case). In case of overlap (and if \c
1669    replaceIfOverlap is true) replace the current branching object with one
1670    whose feasible region is the overlap.
1671   */
1672CbcRangeCompare
1673CbcIntegerBranchingObject::compareBranchingObject
1674(const CbcBranchingObject* brObj, const bool replaceIfOverlap)
1675{
1676  const CbcIntegerBranchingObject* br =
1677    dynamic_cast<const CbcIntegerBranchingObject*>(brObj);
1678  assert(br);
1679  double* thisBd = way_ < 0 ? down_ : up_;
1680  const double* otherBd = br->way_ < 0 ? br->down_ : br->up_;
1681  return CbcCompareRanges(thisBd, otherBd, replaceIfOverlap);
1682}
1683
1684//##############################################################################
1685
1686/** Default Constructor
1687
1688  Equivalent to an unspecified binary variable.
1689*/
1690CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ()
1691  : CbcSimpleInteger(),
1692    downPseudoCost_(1.0e-5),
1693    upPseudoCost_(1.0e-5),
1694    upDownSeparator_(-1.0),
1695    method_(0)
1696{
1697}
1698
1699/** Useful constructor
1700
1701  Loads actual upper & lower bounds for the specified variable.
1702*/
1703CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model,
1704                                    int iColumn, double breakEven)
1705  : CbcSimpleInteger(model,iColumn,breakEven)
1706{
1707  const double * cost = model->getObjCoefficients();
1708  double costValue = CoinMax(1.0e-5,fabs(cost[iColumn]));
1709  // treat as if will cost what it says up
1710  upPseudoCost_=costValue;
1711  // and balance at breakeven
1712  downPseudoCost_=((1.0-breakEven_)*upPseudoCost_)/breakEven_;
1713  upDownSeparator_ = -1.0;
1714  method_=0;
1715}
1716
1717/** Useful constructor
1718
1719  Loads actual upper & lower bounds for the specified variable.
1720*/
1721CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model,
1722                                    int iColumn, double downPseudoCost,
1723                                                        double upPseudoCost)
1724  : CbcSimpleInteger(model,iColumn)
1725{
1726  downPseudoCost_ = CoinMax(1.0e-10,downPseudoCost);
1727  upPseudoCost_ = CoinMax(1.0e-10,upPseudoCost);
1728  breakEven_ = upPseudoCost_/(upPseudoCost_+downPseudoCost_);
1729  upDownSeparator_ = -1.0;
1730  method_=0;
1731}
1732// Useful constructor - passed and model index and pseudo costs
1733CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, 
1734                                                        int /*dummy*/,
1735                                                        int iColumn, 
1736                                                        double downPseudoCost, double upPseudoCost)
1737{
1738  *this=CbcSimpleIntegerPseudoCost(model,iColumn,downPseudoCost,upPseudoCost);
1739  columnNumber_=iColumn;
1740}
1741
1742// Copy constructor
1743CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ( const CbcSimpleIntegerPseudoCost & rhs)
1744  :CbcSimpleInteger(rhs),
1745   downPseudoCost_(rhs.downPseudoCost_),
1746   upPseudoCost_(rhs.upPseudoCost_),
1747   upDownSeparator_(rhs.upDownSeparator_),
1748   method_(rhs.method_)
1749
1750{
1751}
1752
1753// Clone
1754CbcObject *
1755CbcSimpleIntegerPseudoCost::clone() const
1756{
1757  return new CbcSimpleIntegerPseudoCost(*this);
1758}
1759
1760// Assignment operator
1761CbcSimpleIntegerPseudoCost & 
1762CbcSimpleIntegerPseudoCost::operator=( const CbcSimpleIntegerPseudoCost& rhs)
1763{
1764  if (this!=&rhs) {
1765    CbcSimpleInteger::operator=(rhs);
1766    downPseudoCost_=rhs.downPseudoCost_;
1767    upPseudoCost_=rhs.upPseudoCost_;
1768    upDownSeparator_=rhs.upDownSeparator_;
1769    method_=rhs.method_;
1770  }
1771  return *this;
1772}
1773
1774// Destructor
1775CbcSimpleIntegerPseudoCost::~CbcSimpleIntegerPseudoCost ()
1776{
1777}
1778CbcBranchingObject * 
1779CbcSimpleIntegerPseudoCost::createCbcBranch(OsiSolverInterface * solver,const OsiBranchingInformation * /*info*/, int way) 
1780{
1781  //OsiSolverInterface * solver = model_->solver();
1782  const double * solution = model_->testSolution();
1783  const double * lower = solver->getColLower();
1784  const double * upper = solver->getColUpper();
1785  double value = solution[columnNumber_];
1786  value = CoinMax(value, lower[columnNumber_]);
1787  value = CoinMin(value, upper[columnNumber_]);
1788#ifndef NDEBUG
1789  double nearest = floor(value+0.5);
1790  double integerTolerance = 
1791    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1792  assert (upper[columnNumber_]>lower[columnNumber_]);
1793#endif
1794  if (!model_->hotstartSolution()) {
1795    assert (fabs(value-nearest)>integerTolerance);
1796  } else {
1797    const double * hotstartSolution = model_->hotstartSolution();
1798    double targetValue = hotstartSolution[columnNumber_];
1799    if (way>0)
1800      value = targetValue-0.1;
1801    else
1802      value = targetValue+0.1;
1803  }
1804  CbcIntegerPseudoCostBranchingObject * newObject = 
1805    new CbcIntegerPseudoCostBranchingObject(model_,columnNumber_,way,
1806                                            value);
1807  double up =  upPseudoCost_*(ceil(value)-value);
1808  double down =  downPseudoCost_*(value-floor(value));
1809  double changeInGuessed=up-down;
1810  if (way>0)
1811    changeInGuessed = - changeInGuessed;
1812  changeInGuessed=CoinMax(0.0,changeInGuessed);
1813  //if (way>0)
1814  //changeInGuessed += 1.0e8; // bias to stay up
1815  newObject->setChangeInGuessed(changeInGuessed);
1816  newObject->setOriginalObject(this);
1817  return newObject;
1818}
1819double 
1820CbcSimpleIntegerPseudoCost::infeasibility(const OsiBranchingInformation * /*info*/,
1821                               int &preferredWay) const
1822{
1823  OsiSolverInterface * solver = model_->solver();
1824  const double * solution = model_->testSolution();
1825  const double * lower = solver->getColLower();
1826  const double * upper = solver->getColUpper();
1827  if (upper[columnNumber_]==lower[columnNumber_]) {
1828    // fixed
1829    preferredWay=1;
1830    return 0.0;
1831  }
1832  double value = solution[columnNumber_];
1833  value = CoinMax(value, lower[columnNumber_]);
1834  value = CoinMin(value, upper[columnNumber_]);
1835  /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
1836    solution[columnNumber_],upper[columnNumber_]);*/
1837  double nearest = floor(value+0.5);
1838  double integerTolerance = 
1839    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1840  double below = floor(value+integerTolerance);
1841  double above = below+1.0;
1842  if (above>upper[columnNumber_]) {
1843    above=below;
1844    below = above -1;
1845  }
1846  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1847  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1848  if (downCost>=upCost)
1849    preferredWay=1;
1850  else
1851    preferredWay=-1;
1852  // See if up down choice set
1853  if (upDownSeparator_>0.0) {
1854    preferredWay = (value-below>=upDownSeparator_) ? 1 : -1;
1855  }
1856  if (preferredWay_)
1857    preferredWay=preferredWay_;
1858  if (fabs(value-nearest)<=integerTolerance) {
1859    return 0.0;
1860  } else {
1861    // can't get at model so 1,2 don't make sense
1862    assert(method_<1||method_>2);
1863    if (!method_)
1864      return CoinMin(downCost,upCost);
1865    else
1866      return CoinMax(downCost,upCost);
1867  }
1868}
1869
1870// Return "up" estimate
1871double 
1872CbcSimpleIntegerPseudoCost::upEstimate() const
1873{
1874  OsiSolverInterface * solver = model_->solver();
1875  const double * solution = model_->testSolution();
1876  const double * lower = solver->getColLower();
1877  const double * upper = solver->getColUpper();
1878  double value = solution[columnNumber_];
1879  value = CoinMax(value, lower[columnNumber_]);
1880  value = CoinMin(value, upper[columnNumber_]);
1881  if (upper[columnNumber_]==lower[columnNumber_]) {
1882    // fixed
1883    return 0.0;
1884  }
1885  double integerTolerance = 
1886    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1887  double below = floor(value+integerTolerance);
1888  double above = below+1.0;
1889  if (above>upper[columnNumber_]) {
1890    above=below;
1891    below = above -1;
1892  }
1893  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1894  return upCost;
1895}
1896// Return "down" estimate
1897double 
1898CbcSimpleIntegerPseudoCost::downEstimate() const
1899{
1900  OsiSolverInterface * solver = model_->solver();
1901  const double * solution = model_->testSolution();
1902  const double * lower = solver->getColLower();
1903  const double * upper = solver->getColUpper();
1904  double value = solution[columnNumber_];
1905  value = CoinMax(value, lower[columnNumber_]);
1906  value = CoinMin(value, upper[columnNumber_]);
1907  if (upper[columnNumber_]==lower[columnNumber_]) {
1908    // fixed
1909    return 0.0;
1910  }
1911  double integerTolerance = 
1912    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1913  double below = floor(value+integerTolerance);
1914  double above = below+1.0;
1915  if (above>upper[columnNumber_]) {
1916    above=below;
1917    below = above -1;
1918  }
1919  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1920  return downCost;
1921}
1922
1923//##############################################################################
1924
1925// Default Constructor
1926CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject()
1927  :CbcIntegerBranchingObject()
1928{
1929  changeInGuessed_=1.0e-5;
1930}
1931
1932// Useful constructor
1933CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1934                                                      int variable, int way , double value)
1935  :CbcIntegerBranchingObject(model,variable,way,value)
1936{
1937}
1938// Useful constructor for fixing
1939CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1940                                                      int variable, int way,
1941                                                      double lowerValue, 
1942                                                                          double /*upperValue*/)
1943  :CbcIntegerBranchingObject(model,variable,way,lowerValue)
1944{
1945  changeInGuessed_=1.0e100;
1946}
1947 
1948
1949// Copy constructor
1950CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject ( 
1951                                 const CbcIntegerPseudoCostBranchingObject & rhs)
1952  :CbcIntegerBranchingObject(rhs)
1953{
1954  changeInGuessed_ = rhs.changeInGuessed_;
1955}
1956
1957// Assignment operator
1958CbcIntegerPseudoCostBranchingObject & 
1959CbcIntegerPseudoCostBranchingObject::operator=( const CbcIntegerPseudoCostBranchingObject& rhs)
1960{
1961  if (this != &rhs) {
1962    CbcIntegerBranchingObject::operator=(rhs);
1963    changeInGuessed_ = rhs.changeInGuessed_;
1964  }
1965  return *this;
1966}
1967CbcBranchingObject * 
1968CbcIntegerPseudoCostBranchingObject::clone() const
1969{ 
1970  return (new CbcIntegerPseudoCostBranchingObject(*this));
1971}
1972
1973
1974// Destructor
1975CbcIntegerPseudoCostBranchingObject::~CbcIntegerPseudoCostBranchingObject ()
1976{
1977}
1978
1979/*
1980  Perform a branch by adjusting the bounds of the specified variable. Note
1981  that each arm of the branch advances the object to the next arm by
1982  advancing the value of way_.
1983
1984  Providing new values for the variable's lower and upper bounds for each
1985  branching direction gives a little bit of additional flexibility and will
1986  be easily extensible to multi-way branching.
1987  Returns change in guessed objective on next branch
1988*/
1989double
1990CbcIntegerPseudoCostBranchingObject::branch()
1991{
1992  CbcIntegerBranchingObject::branch();
1993  return changeInGuessed_;
1994}
1995
1996/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
1997    same type and must have the same original object, but they may have
1998    different feasible regions.
1999    Return the appropriate CbcRangeCompare value (first argument being the
2000    sub/superset if that's the case). In case of overlap (and if \c
2001    replaceIfOverlap is true) replace the current branching object with one
2002    whose feasible region is the overlap.
2003*/
2004CbcRangeCompare
2005CbcIntegerPseudoCostBranchingObject::compareBranchingObject
2006(const CbcBranchingObject* brObj, const bool replaceIfOverlap)
2007{
2008  const CbcIntegerPseudoCostBranchingObject* br =
2009    dynamic_cast<const CbcIntegerPseudoCostBranchingObject*>(brObj);
2010  assert(br);
2011  double* thisBd = way_ < 0 ? down_ : up_;
2012  const double* otherBd = br->way_ < 0 ? br->down_ : br->up_;
2013  return CbcCompareRanges(thisBd, otherBd, replaceIfOverlap);
2014}
2015
2016
2017//##############################################################################
2018
2019// Default Constructor
2020CbcCliqueBranchingObject::CbcCliqueBranchingObject()
2021  :CbcBranchingObject()
2022{
2023  clique_ = NULL;
2024  downMask_[0]=0;
2025  downMask_[1]=0;
2026  upMask_[0]=0;
2027  upMask_[1]=0;
2028}
2029
2030// Useful constructor
2031CbcCliqueBranchingObject::CbcCliqueBranchingObject (CbcModel * model,
2032                                                    const CbcClique * clique,
2033                                                    int way ,
2034                                                    int numberOnDownSide, const int * down,
2035                                                    int numberOnUpSide, const int * up)
2036  :CbcBranchingObject(model,clique->id(),way,0.5)
2037{
2038  clique_ = clique;
2039  downMask_[0]=0;
2040  downMask_[1]=0;
2041  upMask_[0]=0;
2042  upMask_[1]=0;
2043  int i;
2044  for (i=0;i<numberOnDownSide;i++) {
2045    int sequence = down[i];
2046    int iWord = sequence>>5;
2047    int iBit = sequence - 32*iWord;
2048    unsigned int k = 1<<iBit;
2049    downMask_[iWord] |= k;
2050  }
2051  for (i=0;i<numberOnUpSide;i++) {
2052    int sequence = up[i];
2053    int iWord = sequence>>5;
2054    int iBit = sequence - 32*iWord;
2055    unsigned int k = 1<<iBit;
2056    upMask_[iWord] |= k;
2057  }
2058}
2059
2060// Copy constructor
2061CbcCliqueBranchingObject::CbcCliqueBranchingObject ( const CbcCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
2062{
2063  clique_=rhs.clique_;
2064  downMask_[0]=rhs.downMask_[0];
2065  downMask_[1]=rhs.downMask_[1];
2066  upMask_[0]=rhs.upMask_[0];
2067  upMask_[1]=rhs.upMask_[1];
2068}
2069
2070// Assignment operator
2071CbcCliqueBranchingObject & 
2072CbcCliqueBranchingObject::operator=( const CbcCliqueBranchingObject& rhs)
2073{
2074  if (this != &rhs) {
2075    CbcBranchingObject::operator=(rhs);
2076    clique_=rhs.clique_;
2077    downMask_[0]=rhs.downMask_[0];
2078    downMask_[1]=rhs.downMask_[1];
2079    upMask_[0]=rhs.upMask_[0];
2080    upMask_[1]=rhs.upMask_[1];
2081  }
2082  return *this;
2083}
2084CbcBranchingObject * 
2085CbcCliqueBranchingObject::clone() const
2086{ 
2087  return (new CbcCliqueBranchingObject(*this));
2088}
2089
2090
2091// Destructor
2092CbcCliqueBranchingObject::~CbcCliqueBranchingObject ()
2093{
2094}
2095double
2096CbcCliqueBranchingObject::branch()
2097{
2098  decrementNumberBranchesLeft();
2099  int iWord;
2100  int numberMembers = clique_->numberMembers();
2101  const int * which = clique_->members();
2102  const int * integerVariables = model_->integerVariable();
2103  int numberWords=(numberMembers+31)>>5;
2104  // *** for way - up means fix all those in down section
2105  if (way_<0) {
2106#ifdef FULL_PRINT
2107    printf("Down Fix ");
2108#endif
2109    for (iWord=0;iWord<numberWords;iWord++) {
2110      int i;
2111      for (i=0;i<32;i++) {
2112        unsigned int k = 1<<i;
2113        if ((upMask_[iWord]&k)!=0) {
2114          int iColumn = which[i+32*iWord];
2115#ifdef FULL_PRINT
2116          printf("%d ",i+32*iWord);
2117#endif
2118          // fix weak way
2119          if (clique_->type(i+32*iWord))
2120            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
2121          else
2122            model_->solver()->setColLower(integerVariables[iColumn],1.0);
2123        }
2124      }
2125    }
2126    way_=1;       // Swap direction
2127  } else {
2128#ifdef FULL_PRINT
2129    printf("Up Fix ");
2130#endif
2131    for (iWord=0;iWord<numberWords;iWord++) {
2132      int i;
2133      for (i=0;i<32;i++) {
2134        unsigned int k = 1<<i;
2135        if ((downMask_[iWord]&k)!=0) {
2136          int iColumn = which[i+32*iWord];
2137#ifdef FULL_PRINT
2138          printf("%d ",i+32*iWord);
2139#endif
2140          // fix weak way
2141          if (clique_->type(i+32*iWord))
2142            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
2143          else
2144            model_->solver()->setColLower(integerVariables[iColumn],1.0);
2145        }
2146      }
2147    }
2148    way_=-1;      // Swap direction
2149  }
2150#ifdef FULL_PRINT
2151  printf("\n");
2152#endif
2153  return 0.0;
2154}
2155// Print what would happen 
2156void
2157CbcCliqueBranchingObject::print()
2158{
2159  int iWord;
2160  int numberMembers = clique_->numberMembers();
2161  const int * which = clique_->members();
2162  const int * integerVariables = model_->integerVariable();
2163  int numberWords=(numberMembers+31)>>5;
2164  // *** for way - up means fix all those in down section
2165  if (way_<0) {
2166    printf("Clique - Down Fix ");
2167    for (iWord=0;iWord<numberWords;iWord++) {
2168      int i;
2169      for (i=0;i<32;i++) {
2170        unsigned int k = 1<<i;
2171        if ((upMask_[iWord]&k)!=0) {
2172          int iColumn = which[i+32*iWord];
2173          printf("%d ",integerVariables[iColumn]);
2174        }
2175      }
2176    }
2177  } else {
2178    printf("Clique - Up Fix ");
2179    for (iWord=0;iWord<numberWords;iWord++) {
2180      int i;
2181      for (i=0;i<32;i++) {
2182        unsigned int k = 1<<i;
2183        if ((downMask_[iWord]&k)!=0) {
2184          int iColumn = which[i+32*iWord];
2185          printf("%d ",integerVariables[iColumn]);
2186        }
2187      }
2188    }
2189  }
2190  printf("\n");
2191}
2192
2193static inline int
2194CbcCompareCliques(const CbcClique* cl0, const CbcClique* cl1)
2195{
2196  if (cl0->cliqueType() < cl1->cliqueType()) {
2197    return -1;
2198  }
2199  if (cl0->cliqueType() > cl1->cliqueType()) {
2200    return 1;
2201  }
2202  if (cl0->numberMembers() != cl1->numberMembers()) {
2203    return cl0->numberMembers() - cl1->numberMembers();
2204  }
2205  if (cl0->numberNonSOSMembers() != cl1->numberNonSOSMembers()) {
2206    return cl0->numberNonSOSMembers() - cl1->numberNonSOSMembers();
2207  }
2208  return memcmp(cl0->members(), cl1->members(),
2209                cl0->numberMembers() * sizeof(int));
2210}
2211
2212/** Compare the original object of \c this with the original object of \c
2213    brObj. Assumes that there is an ordering of the original objects.
2214    This method should be invoked only if \c this and brObj are of the same
2215    type.
2216    Return negative/0/positive depending on whether \c this is
2217    smaller/same/larger than the argument.
2218*/
2219int
2220CbcCliqueBranchingObject::compareOriginalObject
2221(const CbcBranchingObject* brObj) const
2222{
2223  const CbcCliqueBranchingObject* br =
2224    dynamic_cast<const CbcCliqueBranchingObject*>(brObj);
2225  assert(br);
2226  return CbcCompareCliques(clique_, br->clique_);
2227}
2228
2229/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
2230    same type and must have the same original object, but they may have
2231    different feasible regions.
2232    Return the appropriate CbcRangeCompare value (first argument being the
2233    sub/superset if that's the case). In case of overlap (and if \c
2234    replaceIfOverlap is true) replace the current branching object with one
2235    whose feasible region is the overlap.
2236*/
2237CbcRangeCompare
2238CbcCliqueBranchingObject::compareBranchingObject
2239(const CbcBranchingObject* brObj, const bool /*replaceIfOverlap*/)
2240{
2241  const CbcCliqueBranchingObject* br =
2242    dynamic_cast<const CbcCliqueBranchingObject*>(brObj);
2243  assert(br);
2244  unsigned int* thisMask = way_ < 0 ? upMask_ : downMask_;
2245  const unsigned int* otherMask = br->way_ < 0 ? br->upMask_ : br->downMask_;
2246  const CoinUInt64 cl0 =
2247    (static_cast<CoinUInt64>(thisMask[0]) << 32) | thisMask[1];
2248  const CoinUInt64 cl1 =
2249    (static_cast<CoinUInt64>(otherMask[0]) << 32) | otherMask[1];
2250  if (cl0 == cl1) {
2251    return CbcRangeSame;
2252  }
2253  const CoinUInt64 cl_intersection = (cl0 & cl1);
2254  if (cl_intersection == cl0) {
2255    return CbcRangeSuperset;
2256  }
2257  if (cl_intersection == cl1) {
2258    return CbcRangeSubset;
2259  }
2260  const CoinUInt64 cl_xor = (cl0 ^ cl1);
2261  if (cl_intersection == 0 && cl_xor == 0) {
2262    return CbcRangeDisjoint;
2263  }
2264  const CoinUInt64 cl_union = (cl0 | cl1);
2265  thisMask[0] = static_cast<unsigned int>(cl_union >> 32);
2266  thisMask[1] = static_cast<unsigned int>(cl_union & 0xffffffff);
2267  return CbcRangeOverlap;
2268}
2269
2270//##############################################################################
2271
2272// Default Constructor
2273CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject()
2274  :CbcBranchingObject()
2275{
2276  clique_=NULL;
2277  downMask_=NULL;
2278  upMask_=NULL;
2279}
2280
2281// Useful constructor
2282CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject (CbcModel * model,
2283                                                            const CbcClique * clique, 
2284                                                            int way ,
2285                                                    int numberOnDownSide, const int * down,
2286                                                    int numberOnUpSide, const int * up)
2287  :CbcBranchingObject(model,clique->id(),way,0.5)
2288{
2289  clique_ = clique;
2290  int numberMembers = clique_->numberMembers();
2291  int numberWords=(numberMembers+31)>>5;
2292  downMask_ = new unsigned int [numberWords];
2293  upMask_ = new unsigned int [numberWords];
2294  memset(downMask_,0,numberWords*sizeof(unsigned int));
2295  memset(upMask_,0,numberWords*sizeof(unsigned int));
2296  int i;
2297  for (i=0;i<numberOnDownSide;i++) {
2298    int sequence = down[i];
2299    int iWord = sequence>>5;
2300    int iBit = sequence - 32*iWord;
2301    unsigned int k = 1<<iBit;
2302    downMask_[iWord] |= k;
2303  }
2304  for (i=0;i<numberOnUpSide;i++) {
2305    int sequence = up[i];
2306    int iWord = sequence>>5;
2307    int iBit = sequence - 32*iWord;
2308    unsigned int k = 1<<iBit;
2309    upMask_[iWord] |= k;
2310  }
2311}
2312
2313// Copy constructor
2314CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject ( const CbcLongCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
2315{
2316  clique_=rhs.clique_;
2317  if (rhs.downMask_) {
2318    int numberMembers = clique_->numberMembers();
2319    int numberWords=(numberMembers+31)>>5;
2320    downMask_ = new unsigned int [numberWords];
2321    memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
2322    upMask_ = new unsigned int [numberWords];
2323    memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
2324  } else {
2325    downMask_=NULL;
2326    upMask_=NULL;
2327  }   
2328}
2329
2330// Assignment operator
2331CbcLongCliqueBranchingObject & 
2332CbcLongCliqueBranchingObject::operator=( const CbcLongCliqueBranchingObject& rhs)
2333{
2334  if (this != &rhs) {
2335    CbcBranchingObject::operator=(rhs);
2336    clique_=rhs.clique_;
2337    delete [] downMask_;
2338    delete [] upMask_;
2339    if (rhs.downMask_) {
2340      int numberMembers = clique_->numberMembers();
2341      int numberWords=(numberMembers+31)>>5;
2342      downMask_ = new unsigned int [numberWords];
2343      memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
2344      upMask_ = new unsigned int [numberWords];
2345      memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
2346    } else {
2347      downMask_=NULL;
2348      upMask_=NULL;
2349    }   
2350  }
2351  return *this;
2352}
2353CbcBranchingObject * 
2354CbcLongCliqueBranchingObject::clone() const
2355{ 
2356  return (new CbcLongCliqueBranchingObject(*this));
2357}
2358
2359
2360// Destructor
2361CbcLongCliqueBranchingObject::~CbcLongCliqueBranchingObject ()
2362{
2363  delete [] downMask_;
2364  delete [] upMask_;
2365}
2366double
2367CbcLongCliqueBranchingObject::branch()
2368{
2369  decrementNumberBranchesLeft();
2370  int iWord;
2371  int numberMembers = clique_->numberMembers();
2372  const int * which = clique_->members();
2373  const int * integerVariables = model_->integerVariable();
2374  int numberWords=(numberMembers+31)>>5;
2375  // *** for way - up means fix all those in down section
2376  if (way_<0) {
2377#ifdef FULL_PRINT
2378    printf("Down Fix ");
2379#endif
2380    for (iWord=0;iWord<numberWords;iWord++) {
2381      int i;
2382      for (i=0;i<32;i++) {
2383        unsigned int k = 1<<i;
2384        if ((upMask_[iWord]&k)!=0) {
2385          int iColumn = which[i+32*iWord];
2386#ifdef FULL_PRINT
2387          printf("%d ",i+32*iWord);
2388#endif
2389          // fix weak way
2390          if (clique_->type(i+32*iWord))
2391            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
2392          else
2393            model_->solver()->setColLower(integerVariables[iColumn],1.0);
2394        }
2395      }
2396    }
2397    way_=1;       // Swap direction
2398  } else {
2399#ifdef FULL_PRINT
2400    printf("Up Fix ");
2401#endif
2402    for (iWord=0;iWord<numberWords;iWord++) {
2403      int i;
2404      for (i=0;i<32;i++) {
2405        unsigned int k = 1<<i;
2406        if ((downMask_[iWord]&k)!=0) {
2407          int iColumn = which[i+32*iWord];
2408#ifdef FULL_PRINT
2409          printf("%d ",i+32*iWord);
2410#endif
2411          // fix weak way
2412          if (clique_->type(i+32*iWord))
2413            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
2414          else
2415            model_->solver()->setColLower(integerVariables[iColumn],1.0);
2416        }
2417      }
2418    }
2419    way_=-1;      // Swap direction
2420  }
2421#ifdef FULL_PRINT
2422  printf("\n");
2423#endif
2424  return 0.0;
2425}
2426void
2427CbcLongCliqueBranchingObject::print()
2428{
2429  int iWord;
2430  int numberMembers = clique_->numberMembers();
2431  const int * which = clique_->members();
2432  const int * integerVariables = model_->integerVariable();
2433  int numberWords=(numberMembers+31)>>5;
2434  // *** for way - up means fix all those in down section
2435  if (way_<0) {
2436    printf("Clique - Down Fix ");
2437    for (iWord=0;iWord<numberWords;iWord++) {
2438      int i;
2439      for (i=0;i<32;i++) {
2440        unsigned int k = 1<<i;
2441        if ((upMask_[iWord]&k)!=0) {
2442          int iColumn = which[i+32*iWord];
2443          printf("%d ",integerVariables[iColumn]);
2444        }
2445      }
2446    }
2447  } else {
2448    printf("Clique - Up Fix ");
2449    for (iWord=0;iWord<numberWords;iWord++) {
2450      int i;
2451      for (i=0;i<32;i++) {
2452        unsigned int k = 1<<i;
2453        if ((downMask_[iWord]&k)!=0) {
2454          int iColumn = which[i+32*iWord];
2455          printf("%d ",integerVariables[iColumn]);
2456        }
2457      }
2458    }
2459  }
2460  printf("\n");
2461}
2462
2463/** Compare the original object of \c this with the original object of \c
2464    brObj. Assumes that there is an ordering of the original objects.
2465    This method should be invoked only if \c this and brObj are of the same
2466    type.
2467    Return negative/0/positive depending on whether \c this is
2468    smaller/same/larger than the argument.
2469*/
2470int
2471CbcLongCliqueBranchingObject::compareOriginalObject
2472(const CbcBranchingObject* brObj) const
2473{
2474  const CbcLongCliqueBranchingObject* br =
2475    dynamic_cast<const CbcLongCliqueBranchingObject*>(brObj);
2476  assert(br);
2477  return CbcCompareCliques(clique_, br->clique_);
2478}
2479
2480/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
2481    same type and must have the same original object, but they may have
2482    different feasible regions.
2483    Return the appropriate CbcRangeCompare value (first argument being the
2484    sub/superset if that's the case). In case of overlap (and if \c
2485    replaceIfOverlap is true) replace the current branching object with one
2486    whose feasible region is the overlap.
2487*/
2488CbcRangeCompare
2489CbcLongCliqueBranchingObject::compareBranchingObject
2490(const CbcBranchingObject* brObj, const bool /*replaceIfOverlap*/)
2491{
2492  const CbcLongCliqueBranchingObject* br =
2493    dynamic_cast<const CbcLongCliqueBranchingObject*>(brObj);
2494  assert(br);
2495  const int numberMembers = clique_->numberMembers();
2496  const int numberWords=(numberMembers+31)>>5;
2497  unsigned int* thisMask = way_ < 0 ? upMask_ : downMask_;
2498  const unsigned int* otherMask = br->way_ < 0 ? br->upMask_ : br->downMask_;
2499
2500  if (memcmp(thisMask, otherMask, numberWords * sizeof(unsigned int)) == 0) {
2501    return CbcRangeSame;
2502  }
2503  bool canBeSuperset = true;
2504  bool canBeSubset = true;
2505  int i;
2506  for (i = numberWords-1; i >= 0 && (canBeSuperset || canBeSubset); --i) {
2507    const unsigned int both = (thisMask[i] & otherMask[i]);
2508    canBeSuperset &= (both == thisMask[i]);
2509    canBeSubset &= (both == otherMask[i]);
2510  }
2511  if (canBeSuperset) {
2512    return CbcRangeSuperset;
2513  }
2514  if (canBeSubset) {
2515    return CbcRangeSubset;
2516  }
2517
2518  for (i = numberWords-1; i >= 0; --i) {
2519    if ((thisMask[i] ^ otherMask[i]) != 0) {
2520      break;
2521    }
2522  }
2523  if (i == -1) { // complement
2524    return CbcRangeDisjoint;
2525  }
2526  // must be overlap
2527  for (i = numberWords-1; i >= 0; --i) {
2528    thisMask[i] |= otherMask[i];
2529  }
2530  return CbcRangeOverlap;
2531}
2532
2533//##############################################################################
2534
2535// Default Constructor
2536CbcSOSBranchingObject::CbcSOSBranchingObject()
2537  :CbcBranchingObject(),
2538   firstNonzero_(-1),
2539   lastNonzero_(-1)
2540{
2541  set_ = NULL;
2542  separator_=0.0;
2543}
2544
2545// Useful constructor
2546CbcSOSBranchingObject::CbcSOSBranchingObject (CbcModel * model,
2547                                              const CbcSOS * set,
2548                                              int way ,
2549                                              double separator)
2550  :CbcBranchingObject(model,set->id(),way,0.5)
2551{
2552  set_ = set;
2553  separator_ = separator;
2554  computeNonzeroRange();
2555}
2556
2557// Copy constructor
2558CbcSOSBranchingObject::CbcSOSBranchingObject (const CbcSOSBranchingObject & rhs)
2559 :CbcBranchingObject(rhs),
2560  firstNonzero_(rhs.firstNonzero_),
2561  lastNonzero_(rhs.lastNonzero_)
2562{
2563  set_=rhs.set_;
2564  separator_ = rhs.separator_;
2565}
2566
2567// Assignment operator
2568CbcSOSBranchingObject & 
2569CbcSOSBranchingObject::operator=( const CbcSOSBranchingObject& rhs)
2570{
2571  if (this != &rhs) {
2572    CbcBranchingObject::operator=(rhs);
2573    set_=rhs.set_;
2574    separator_ = rhs.separator_;
2575    firstNonzero_ = rhs.firstNonzero_;
2576    lastNonzero_ = rhs.lastNonzero_;
2577  }
2578  return *this;
2579}
2580CbcBranchingObject * 
2581CbcSOSBranchingObject::clone() const
2582{ 
2583  return (new CbcSOSBranchingObject(*this));
2584}
2585
2586
2587// Destructor
2588CbcSOSBranchingObject::~CbcSOSBranchingObject ()
2589{
2590}
2591
2592void
2593CbcSOSBranchingObject::computeNonzeroRange()
2594{
2595  const int numberMembers = set_->numberMembers();
2596  const double * weights = set_->weights();
2597  int i = 0;
2598  if (way_ < 0) {
2599    for ( i=0;i<numberMembers;i++) {
2600      if (weights[i] > separator_)
2601        break;
2602    }
2603    assert (i<numberMembers);
2604    firstNonzero_ = 0;
2605    lastNonzero_ = i;
2606  } else {
2607    for ( i=0;i<numberMembers;i++) {
2608      if (weights[i] >= separator_)
2609        break;
2610    }
2611    assert (i<numberMembers);
2612    firstNonzero_ = i;
2613    lastNonzero_ = numberMembers;
2614  }
2615}
2616
2617double
2618CbcSOSBranchingObject::branch()
2619{
2620  decrementNumberBranchesLeft();
2621  int numberMembers = set_->numberMembers();
2622  const int * which = set_->members();
2623  const double * weights = set_->weights();
2624  OsiSolverInterface * solver = model_->solver();
2625  //const double * lower = solver->getColLower();
2626  //const double * upper = solver->getColUpper();
2627  // *** for way - up means fix all those in down section
2628  if (way_<0) {
2629    int i;
2630    for ( i=0;i<numberMembers;i++) {
2631      if (weights[i] > separator_)
2632        break;
2633    }
2634    assert (i<numberMembers);
2635    for (;i<numberMembers;i++) 
2636      solver->setColUpper(which[i],0.0);
2637    way_=1;       // Swap direction
2638  } else {
2639    int i;
2640    for ( i=0;i<numberMembers;i++) {
2641      if (weights[i] >= separator_)
2642        break;
2643      else
2644        solver->setColUpper(which[i],0.0);
2645    }
2646    assert (i<numberMembers);
2647    way_=-1;      // Swap direction
2648  }
2649  computeNonzeroRange();
2650  return 0.0;
2651}
2652/* Update bounds in solver as in 'branch' and update given bounds.
2653   branchState is -1 for 'down' +1 for 'up' */
2654void 
2655CbcSOSBranchingObject::fix(OsiSolverInterface * solver,
2656                           double * /*lower*/, double * upper,
2657                               int branchState) const 
2658{
2659  int numberMembers = set_->numberMembers();
2660  const int * which = set_->members();
2661  const double * weights = set_->weights();
2662  //const double * lower = solver->getColLower();
2663  //const double * upper = solver->getColUpper();
2664  // *** for way - up means fix all those in down section
2665  if (branchState<0) {
2666    int i;
2667    for ( i=0;i<numberMembers;i++) {
2668      if (weights[i] > separator_)
2669        break;
2670    }
2671    assert (i<numberMembers);
2672    for (;i<numberMembers;i++) {
2673      solver->setColUpper(which[i],0.0);
2674      upper[which[i]]=0.0;
2675    }
2676  } else {
2677    int i;
2678    for ( i=0;i<numberMembers;i++) {
2679      if (weights[i] >= separator_) {
2680        break;
2681      } else {
2682        solver->setColUpper(which[i],0.0);
2683        upper[which[i]]=0.0;
2684      }
2685    }
2686    assert (i<numberMembers);
2687  }
2688}
2689// Print what would happen 
2690void
2691CbcSOSBranchingObject::print()
2692{
2693  int numberMembers = set_->numberMembers();
2694  const int * which = set_->members();
2695  const double * weights = set_->weights();
2696  OsiSolverInterface * solver = model_->solver();
2697  //const double * lower = solver->getColLower();
2698  const double * upper = solver->getColUpper();
2699  int first=numberMembers;
2700  int last=-1;
2701  int numberFixed=0;
2702  int numberOther=0;
2703  int i;
2704  for ( i=0;i<numberMembers;i++) {
2705    double bound = upper[which[i]];
2706    if (bound) {
2707      first = CoinMin(first,i);
2708      last = CoinMax(last,i);
2709    }
2710  }
2711  // *** for way - up means fix all those in down section
2712  if (way_<0) {
2713    printf("SOS Down");
2714    for ( i=0;i<numberMembers;i++) {
2715      double bound = upper[which[i]];
2716      if (weights[i] > separator_)
2717        break;
2718      else if (bound)
2719        numberOther++;
2720    }
2721    assert (i<numberMembers);
2722    for (;i<numberMembers;i++) {
2723      double bound = upper[which[i]];
2724      if (bound)
2725        numberFixed++;
2726    }
2727  } else {
2728    printf("SOS Up");
2729    for ( i=0;i<numberMembers;i++) {
2730      double bound = upper[which[i]];
2731      if (weights[i] >= separator_)
2732        break;
2733      else if (bound)
2734        numberFixed++;
2735    }
2736    assert (i<numberMembers);
2737    for (;i<numberMembers;i++) {
2738      double bound = upper[which[i]];
2739      if (bound)
2740        numberOther++;
2741    }
2742  }
2743  printf(" - at %g, free range %d (%g) => %d (%g), %d would be fixed, %d other way\n",
2744         separator_,which[first],weights[first],which[last],weights[last],numberFixed,numberOther);
2745}
2746 
2747/** Compare the original object of \c this with the original object of \c
2748    brObj. Assumes that there is an ordering of the original objects.
2749    This method should be invoked only if \c this and brObj are of the same
2750    type.
2751    Return negative/0/positive depending on whether \c this is
2752    smaller/same/larger than the argument.
2753*/
2754int
2755CbcSOSBranchingObject::compareOriginalObject
2756(const CbcBranchingObject* brObj) const
2757{
2758  const CbcSOSBranchingObject* br =
2759    dynamic_cast<const CbcSOSBranchingObject*>(brObj);
2760  assert(br);
2761  const CbcSOS* s0 = set_;
2762  const CbcSOS* s1 = br->set_;
2763  if (s0->sosType() != s1->sosType()) {
2764    return s0->sosType() - s1->sosType();
2765  }
2766  if (s0->numberMembers() != s1->numberMembers()) {
2767    return s0->numberMembers() - s1->numberMembers();
2768  }
2769  const int memberCmp = memcmp(s0->members(), s1->members(),
2770                               s0->numberMembers() * sizeof(int));
2771  if (memberCmp != 0) {
2772    return memberCmp;
2773  }
2774  return memcmp(s0->weights(), s1->weights(),
2775                s0->numberMembers() * sizeof(double));
2776}
2777
2778/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
2779    same type and must have the same original object, but they may have
2780    different feasible regions.
2781    Return the appropriate CbcRangeCompare value (first argument being the
2782    sub/superset if that's the case). In case of overlap (and if \c
2783    replaceIfOverlap is true) replace the current branching object with one
2784    whose feasible region is the overlap.
2785*/
2786CbcRangeCompare
2787CbcSOSBranchingObject::compareBranchingObject
2788(const CbcBranchingObject* brObj, const bool replaceIfOverlap)
2789{
2790  const CbcSOSBranchingObject* br =
2791    dynamic_cast<const CbcSOSBranchingObject*>(brObj);
2792  assert(br);
2793  if (firstNonzero_ < br->firstNonzero_) {
2794    if (lastNonzero_ >= br->lastNonzero_) {
2795      return CbcRangeSuperset;
2796    } else if (lastNonzero_ <= br->firstNonzero_) {
2797      return CbcRangeDisjoint;
2798    } else {
2799      // overlap
2800      if (replaceIfOverlap) {
2801        firstNonzero_ = br->firstNonzero_;
2802      }
2803      return CbcRangeOverlap;
2804    }
2805  } else if (firstNonzero_ > br->firstNonzero_) {
2806    if (lastNonzero_ <= br->lastNonzero_) {
2807      return CbcRangeSubset;
2808    } else if (firstNonzero_ >= br->lastNonzero_) {
2809      return CbcRangeDisjoint;
2810    } else {
2811      // overlap
2812      if (replaceIfOverlap) {
2813        lastNonzero_ = br->lastNonzero_;
2814      }
2815      return CbcRangeOverlap;
2816    }
2817  } else {
2818    if (lastNonzero_ == br->lastNonzero_) {
2819      return CbcRangeSame;
2820    }
2821    return lastNonzero_ < br->lastNonzero_ ? CbcRangeSubset : CbcRangeSuperset;
2822  }
2823  return CbcRangeSame; // fake return
2824}
2825
2826//##############################################################################
2827
2828// Default Constructor
2829CbcBranchDefaultDecision::CbcBranchDefaultDecision()
2830  :CbcBranchDecision()
2831{
2832  bestCriterion_ = 0.0;
2833  bestChangeUp_ = 0.0;
2834  bestNumberUp_ = 0;
2835  bestChangeDown_ = 0.0;
2836  bestObject_ = NULL;
2837  bestNumberDown_ = 0;
2838}
2839
2840// Copy constructor
2841CbcBranchDefaultDecision::CbcBranchDefaultDecision (
2842                                    const CbcBranchDefaultDecision & rhs)
2843  :CbcBranchDecision(rhs)
2844{
2845  bestCriterion_ = rhs.bestCriterion_;
2846  bestChangeUp_ = rhs.bestChangeUp_;
2847  bestNumberUp_ = rhs.bestNumberUp_;
2848  bestChangeDown_ = rhs.bestChangeDown_;
2849  bestNumberDown_ = rhs.bestNumberDown_;
2850  bestObject_ = rhs.bestObject_;
2851  model_ = rhs.model_;
2852}
2853
2854CbcBranchDefaultDecision::~CbcBranchDefaultDecision()
2855{
2856}
2857
2858// Clone
2859CbcBranchDecision * 
2860CbcBranchDefaultDecision::clone() const
2861{
2862  return new CbcBranchDefaultDecision(*this);
2863}
2864
2865// Initialize i.e. before start of choosing at a node
2866void 
2867CbcBranchDefaultDecision::initialize(CbcModel * model)
2868{
2869  bestCriterion_ = 0.0;
2870  bestChangeUp_ = 0.0;
2871  bestNumberUp_ = 0;
2872  bestChangeDown_ = 0.0;
2873  bestNumberDown_ = 0;
2874  bestObject_ = NULL;
2875  model_ = model;
2876}
2877
2878
2879/*
2880  Simple default decision algorithm. Compare based on infeasibility (numInfUp,
2881  numInfDn) until a solution is found by search, then switch to change in
2882  objective (changeUp, changeDn). Note that bestSoFar is remembered in
2883  bestObject_, so the parameter bestSoFar is unused.
2884*/
2885
2886int
2887CbcBranchDefaultDecision::betterBranch(CbcBranchingObject * thisOne,
2888                                       CbcBranchingObject * /*bestSoFar*/,
2889                            double changeUp, int numInfUp,
2890                            double changeDn, int numInfDn)
2891{
2892  bool beforeSolution = cbcModel()->getSolutionCount()==
2893    cbcModel()->getNumberHeuristicSolutions();;
2894  int betterWay=0;
2895  if (beforeSolution) {
2896    if (!bestObject_) {
2897      bestNumberUp_=COIN_INT_MAX;
2898      bestNumberDown_=COIN_INT_MAX;
2899    }
2900    // before solution - choose smallest number
2901    // could add in depth as well
2902    int bestNumber = CoinMin(bestNumberUp_,bestNumberDown_);
2903    if (numInfUp<numInfDn) {
2904      if (numInfUp<bestNumber) {
2905        betterWay = 1;
2906      } else if (numInfUp==bestNumber) {
2907        if (changeUp<bestCriterion_)
2908          betterWay=1;
2909      }
2910    } else if (numInfUp>numInfDn) {
2911      if (numInfDn<bestNumber) {
2912        betterWay = -1;
2913      } else if (numInfDn==bestNumber) {
2914        if (changeDn<bestCriterion_)
2915          betterWay=-1;
2916      }
2917    } else {
2918      // up and down have same number
2919      bool better=false;
2920      if (numInfUp<bestNumber) {
2921        better=true;
2922      } else if (numInfUp==bestNumber) {
2923        if (CoinMin(changeUp,changeDn)<bestCriterion_)
2924          better=true;;
2925      }
2926      if (better) {
2927        // see which way
2928        if (changeUp<=changeDn)
2929          betterWay=1;
2930        else
2931          betterWay=-1;
2932      }
2933    }
2934  } else {
2935    if (!bestObject_) {
2936      bestCriterion_=-1.0;
2937    }
2938    // got a solution
2939    if (changeUp<=changeDn) {
2940      if (changeUp>bestCriterion_)
2941        betterWay=1;
2942    } else {
2943      if (changeDn>bestCriterion_)
2944        betterWay=-1;
2945    }
2946  }
2947  if (betterWay) {
2948    bestCriterion_ = CoinMin(changeUp,changeDn);
2949    bestChangeUp_ = changeUp;
2950    bestNumberUp_ = numInfUp;
2951    bestChangeDown_ = changeDn;
2952    bestNumberDown_ = numInfDn;
2953    bestObject_=thisOne;
2954    // See if user is overriding way
2955    if (thisOne->object()&&thisOne->object()->preferredWay())
2956      betterWay = thisOne->object()->preferredWay();
2957  }
2958  return betterWay;
2959}
2960/* Sets or gets best criterion so far */
2961void 
2962CbcBranchDefaultDecision::setBestCriterion(double value)
2963{ 
2964  bestCriterion_ = value;
2965}
2966double 
2967CbcBranchDefaultDecision::getBestCriterion() const
2968{ 
2969  return bestCriterion_;
2970}
2971
2972/* Compare N branching objects. Return index of best
2973   and sets way of branching in chosen object.
2974   
2975   This routine is used only after strong branching.
2976*/
2977
2978int
2979CbcBranchDefaultDecision::bestBranch (CbcBranchingObject ** objects, int numberObjects,
2980                                   int numberUnsatisfied,
2981                                   double * changeUp, int * numberInfeasibilitiesUp,
2982                                   double * changeDown, int * numberInfeasibilitiesDown,
2983                                   double objectiveValue) 
2984{
2985
2986  int bestWay=0;
2987  int whichObject = -1;
2988  if (numberObjects) {
2989    CbcModel * model = cbcModel();
2990    // at continuous
2991    //double continuousObjective = model->getContinuousObjective();
2992    //int continuousInfeasibilities = model->getContinuousInfeasibilities();
2993   
2994    // average cost to get rid of infeasibility
2995    //double averageCostPerInfeasibility =
2996    //(objectiveValue-continuousObjective)/
2997    //(double) (abs(continuousInfeasibilities-numberUnsatisfied)+1);
2998    /* beforeSolution is :
2999       0 - before any solution
3000       n - n heuristic solutions but no branched one
3001       -1 - branched solution found
3002    */
3003    int numberSolutions = model->getSolutionCount();
3004    double cutoff = model->getCutoff();
3005    int method=0;
3006    int i;
3007    if (numberSolutions) {
3008      int numberHeuristic = model->getNumberHeuristicSolutions();
3009      if (numberHeuristic<numberSolutions) {
3010        method = 1;
3011      } else {
3012        method = 2;
3013        // look further
3014        for ( i = 0 ; i < numberObjects ; i++) {
3015          int numberNext = numberInfeasibilitiesUp[i];
3016         
3017          if (numberNext<numberUnsatisfied) {
3018            int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
3019            double perUnsatisfied = changeUp[i]/static_cast<double> (numberUp);
3020            double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
3021            if (estimatedObjective<cutoff) 
3022              method=3;
3023          }
3024          numberNext = numberInfeasibilitiesDown[i];
3025          if (numberNext<numberUnsatisfied) {
3026            int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
3027            double perUnsatisfied = changeDown[i]/static_cast<double> (numberDown);
3028            double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
3029            if (estimatedObjective<cutoff) 
3030              method=3;
3031          }
3032        }
3033      }
3034      method=2;
3035    } else {
3036      method = 0;
3037    }
3038    // Uncomment next to force method 4
3039    //method=4;
3040    /* Methods :
3041       0 - fewest infeasibilities
3042       1 - largest min change in objective
3043       2 - as 1 but use sum of changes if min close
3044       3 - predicted best solution
3045       4 - take cheapest up branch if infeasibilities same
3046    */
3047    int bestNumber=COIN_INT_MAX;
3048    double bestCriterion=-1.0e50;
3049    double alternativeCriterion = -1.0;
3050    double bestEstimate = 1.0e100;
3051    switch (method) {
3052    case 0:
3053      // could add in depth as well
3054      for ( i = 0 ; i < numberObjects ; i++) {
3055        int thisNumber = CoinMin(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
3056        if (thisNumber<=bestNumber) {
3057          int betterWay=0;
3058          if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
3059            if (numberInfeasibilitiesUp[i]<bestNumber) {
3060              betterWay = 1;
3061            } else {
3062              if (changeUp[i]<bestCriterion)
3063                betterWay=1;
3064            }
3065          } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
3066            if (numberInfeasibilitiesDown[i]<bestNumber) {
3067              betterWay = -1;
3068            } else {
3069              if (changeDown[i]<bestCriterion)
3070                betterWay=-1;
3071            }
3072          } else {
3073            // up and down have same number
3074            bool better=false;
3075            if (numberInfeasibilitiesUp[i]<bestNumber) {
3076              better=true;
3077            } else if (numberInfeasibilitiesUp[i]==bestNumber) {
3078              if (CoinMin(changeUp[i],changeDown[i])<bestCriterion)
3079                better=true;;
3080            }
3081            if (better) {
3082              // see which way
3083              if (changeUp[i]<=changeDown[i])
3084                betterWay=1;
3085              else
3086                betterWay=-1;
3087            }
3088          }
3089          if (betterWay) {
3090            bestCriterion = CoinMin(changeUp[i],changeDown[i]);
3091            bestNumber = thisNumber;
3092            whichObject = i;
3093            bestWay = betterWay;
3094          }
3095        }
3096      }
3097      break;
3098    case 1:
3099      for ( i = 0 ; i < numberObjects ; i++) {
3100        int betterWay=0;
3101        if (changeUp[i]<=changeDown[i]) {
3102          if (changeUp[i]>bestCriterion)
3103            betterWay=1;
3104        } else {
3105          if (changeDown[i]>bestCriterion)
3106            betterWay=-1;
3107        }
3108        if (betterWay) {
3109          bestCriterion = CoinMin(changeUp[i],changeDown[i]);
3110          whichObject = i;
3111          bestWay = betterWay;
3112        }
3113      }
3114      break;
3115    case 2:
3116      for ( i = 0 ; i < numberObjects ; i++) {
3117        double change = CoinMin(changeUp[i],changeDown[i]);
3118        double sum = changeUp[i] + changeDown[i];
3119        bool take=false;
3120        if (change>1.1*bestCriterion) 
3121          take=true;
3122        else if (change>0.9*bestCriterion&&sum+change>bestCriterion+alternativeCriterion) 
3123          take=true;
3124        if (take) {
3125          if (changeUp[i]<=changeDown[i]) {
3126            if (changeUp[i]>bestCriterion)
3127              bestWay=1;
3128          } else {
3129            if (changeDown[i]>bestCriterion)
3130              bestWay=-1;
3131          }
3132          bestCriterion = change;
3133          alternativeCriterion = sum;
3134          whichObject = i;
3135        }
3136      }
3137      break;
3138    case 3:
3139      for ( i = 0 ; i < numberObjects ; i++) {
3140        int numberNext = numberInfeasibilitiesUp[i];
3141       
3142        if (numberNext<numberUnsatisfied) {
3143          int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
3144          double perUnsatisfied = changeUp[i]/static_cast<double> (numberUp);
3145          double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
3146          if (estimatedObjective<bestEstimate) {
3147            bestEstimate = estimatedObjective;
3148            bestWay=1;
3149            whichObject=i;
3150          }
3151        }
3152        numberNext = numberInfeasibilitiesDown[i];
3153        if (numberNext<numberUnsatisfied) {
3154          int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
3155          double perUnsatisfied = changeDown[i]/static_cast<double> (numberDown);
3156          double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
3157          if (estimatedObjective<bestEstimate) {
3158            bestEstimate = estimatedObjective;
3159            bestWay=-1;
3160            whichObject=i;
3161          }
3162        }
3163      }
3164      break;
3165    case 4:
3166      // if number infeas same then cheapest up
3167      // first get best number or when going down
3168      // now choose smallest change up amongst equal number infeas
3169      for ( i = 0 ; i < numberObjects ; i++) {
3170        int thisNumber = CoinMin(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
3171        if (thisNumber<=bestNumber) {
3172          int betterWay=0;
3173          if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
3174            if (numberInfeasibilitiesUp[i]<bestNumber) {
3175              betterWay = 1;
3176            } else {
3177              if (changeUp[i]<bestCriterion)
3178                betterWay=1;
3179            }
3180          } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
3181            if (numberInfeasibilitiesDown[i]<bestNumber) {
3182              betterWay = -1;
3183            } else {
3184              if (changeDown[i]<bestCriterion)
3185                betterWay=-1;
3186            }
3187          } else {
3188            // up and down have same number
3189            bool better=false;
3190            if (numberInfeasibilitiesUp[i]<bestNumber) {
3191              better=true;
3192            } else if (numberInfeasibilitiesUp[i]==bestNumber) {
3193              if (CoinMin(changeUp[i],changeDown[i])<bestCriterion)
3194                better=true;;
3195            }
3196            if (better) {
3197              // see which way
3198              if (changeUp[i]<=changeDown[i])
3199                betterWay=1;
3200              else
3201                betterWay=-1;
3202            }
3203          }
3204          if (betterWay) {
3205            bestCriterion = CoinMin(changeUp[i],changeDown[i]);
3206            bestNumber = thisNumber;
3207            whichObject = i;
3208            bestWay = betterWay;
3209          }
3210        }
3211      }
3212      bestCriterion=1.0e50;
3213      for ( i = 0 ; i < numberObjects ; i++) {
3214        int thisNumber = numberInfeasibilitiesUp[i];
3215        if (thisNumber==bestNumber&&changeUp) {
3216          if (changeUp[i]<bestCriterion) {
3217            bestCriterion = changeUp[i];
3218            whichObject = i;
3219            bestWay = 1;
3220          }
3221        }
3222      }
3223      break;
3224    }
3225    // set way in best
3226    if (whichObject>=0) {
3227      CbcBranchingObject * bestObject = objects[whichObject];
3228      if (bestObject->object()&&bestObject->object()->preferredWay()) 
3229        bestWay = bestObject->object()->preferredWay();
3230      bestObject->way(bestWay);
3231    } else {
3232      printf("debug\n");
3233    }
3234  }
3235  return whichObject;
3236}
3237
3238//##############################################################################
3239
3240// Default Constructor
3241CbcFollowOn::CbcFollowOn ()
3242  : CbcObject(),
3243    rhs_(NULL)
3244{
3245}
3246
3247// Useful constructor
3248CbcFollowOn::CbcFollowOn (CbcModel * model)
3249  : CbcObject(model)
3250{
3251  assert (model);
3252  OsiSolverInterface * solver = model_->solver();
3253  matrix_ = *solver->getMatrixByCol();
3254  matrix_.removeGaps();
3255  matrix_.setExtraGap(0.0);
3256  matrixByRow_ = *solver->getMatrixByRow();
3257  int numberRows = matrix_.getNumRows();
3258 
3259  rhs_ = new int[numberRows];
3260  int i;
3261  const double * rowLower = solver->getRowLower();
3262  const double * rowUpper = solver->getRowUpper();
3263  // Row copy
3264  const double * elementByRow = matrixByRow_.getElements();
3265  const int * column = matrixByRow_.getIndices();
3266  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
3267  const int * rowLength = matrixByRow_.getVectorLengths();
3268  for (i=0;i<numberRows;i++) {
3269    rhs_[i]=0;
3270    double value = rowLower[i];
3271    if (value==rowUpper[i]) {
3272      if (floor(value)==value&&value>=1.0&&value<10.0) {
3273        // check elements
3274        bool good=true;
3275        for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
3276          int iColumn = column[j];
3277          if (!solver->isBinary(iColumn))
3278            good=false;
3279          double elValue = elementByRow[j];
3280          if (floor(elValue)!=elValue||value<1.0)
3281            good=false;
3282        }
3283        if (good)
3284          rhs_[i]=static_cast<int> (value);
3285      }
3286    }
3287  }
3288}
3289
3290// Copy constructor
3291CbcFollowOn::CbcFollowOn ( const CbcFollowOn & rhs)
3292  :CbcObject(rhs),
3293   matrix_(rhs.matrix_),
3294   matrixByRow_(rhs.matrixByRow_)
3295{
3296  int numberRows = matrix_.getNumRows();
3297  rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
3298}
3299
3300// Clone
3301CbcObject *
3302CbcFollowOn::clone() const
3303{
3304  return new CbcFollowOn(*this);
3305}
3306
3307// Assignment operator
3308CbcFollowOn & 
3309CbcFollowOn::operator=( const CbcFollowOn& rhs)
3310{
3311  if (this!=&rhs) {
3312    CbcObject::operator=(rhs);
3313    delete [] rhs_;
3314    matrix_ = rhs.matrix_;
3315    matrixByRow_ = rhs.matrixByRow_;
3316    int numberRows = matrix_.getNumRows();
3317    rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
3318  }
3319  return *this;
3320}
3321
3322// Destructor
3323CbcFollowOn::~CbcFollowOn ()
3324{
3325  delete [] rhs_;
3326}
3327// As some computation is needed in more than one place - returns row
3328int 
3329CbcFollowOn::gutsOfFollowOn(int & otherRow, int & preferredWay) const
3330{
3331  int whichRow=-1;
3332  otherRow=-1;
3333  int numberRows = matrix_.getNumRows();
3334 
3335  int i;
3336  // For sorting
3337  int * sort = new int [numberRows];
3338  int * isort = new int [numberRows];
3339  // Column copy
3340  //const double * element = matrix_.getElements();
3341  const int * row = matrix_.getIndices();
3342  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
3343  const int * columnLength = matrix_.getVectorLengths();
3344  // Row copy
3345  const double * elementByRow = matrixByRow_.getElements();
3346  const int * column = matrixByRow_.getIndices();
3347  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
3348  const int * rowLength = matrixByRow_.getVectorLengths();
3349  OsiSolverInterface * solver = model_->solver();
3350  const double * columnLower = solver->getColLower();
3351  const double * columnUpper = solver->getColUpper();
3352  const double * solution = solver->getColSolution();
3353  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
3354  int nSort=0;
3355  for (i=0;i<numberRows;i++) {
3356    if (rhs_[i]) {
3357      // check elements
3358      double smallest=1.0e10;
3359      double largest=0.0;
3360      int rhsValue=rhs_[i];
3361      int number1=0;
3362      int numberUnsatisfied=0;
3363      for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
3364        int iColumn = column[j];
3365        double value = elementByRow[j];
3366        double solValue = solution[iColumn];
3367        if (columnLower[iColumn]!=columnUpper[iColumn]) {
3368          smallest = CoinMin(smallest,value);
3369          largest = CoinMax(largest,value);
3370          if (value==1.0)
3371            number1++;
3372          if (solValue<1.0-integerTolerance&&solValue>integerTolerance)
3373            numberUnsatisfied++;
3374        } else {
3375          rhsValue -= static_cast<int>(value*floor(solValue+0.5));
3376        }
3377      }
3378      if (numberUnsatisfied>1) {
3379        if (smallest<largest) {
3380          // probably no good but check a few things
3381          assert (largest<=rhsValue);
3382          if (number1==1&&largest==rhsValue)
3383            printf("could fix\n");
3384        } else if (largest==rhsValue) {
3385          sort[nSort]=i;
3386          isort[nSort++]=-numberUnsatisfied;
3387        }
3388      }
3389    }
3390  }
3391  if (nSort>1) {
3392    CoinSort_2(isort,isort+nSort,sort);
3393    CoinZeroN(isort,numberRows);
3394    double * other = new double[numberRows];
3395    CoinZeroN(other,numberRows);
3396    int * which = new int[numberRows];
3397    //#define COUNT
3398#ifndef COUNT
3399    bool beforeSolution = model_->getSolutionCount()==0;
3400#endif
3401    for (int k=0;k<nSort-1;k++) {
3402      i=sort[k];
3403      int numberUnsatisfied = 0;
3404      int n=0;
3405      int j;
3406      for (j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
3407        int iColumn = column[j];
3408        if (columnLower[iColumn]!=columnUpper[iColumn]) {
3409          double solValue = solution[iColumn]-columnLower[iColumn];
3410          if (solValue<1.0-integerTolerance&&solValue>integerTolerance) {
3411            numberUnsatisfied++;
3412            for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
3413              int iRow = row[jj];
3414              if (rhs_[iRow]) {
3415                other[iRow]+=solValue;
3416                if (isort[iRow]) {
3417                  isort[iRow]++;
3418                } else {
3419                  isort[iRow]=1;
3420                  which[n++]=iRow;
3421                }
3422              }
3423            }
3424          }
3425        }
3426      }
3427      double total=0.0;
3428      // Take out row
3429      double sumThis=other[i];
3430      other[i]=0.0;
3431      assert (numberUnsatisfied==isort[i]);
3432      // find one nearest half if solution, one if before solution
3433      int iBest=-1;
3434      double dtarget=0.5*total;
3435#ifdef COUNT
3436      int target = (numberUnsatisfied+1)>>1;
3437      int best=numberUnsatisfied;
3438#else
3439      double best;
3440      if (beforeSolution)
3441        best=dtarget;
3442      else
3443        best=1.0e30;
3444#endif
3445      for (j=0;j<n;j++) {
3446        int iRow = which[j];
3447        double dvalue=other[iRow];
3448        other[iRow]=0.0;
3449#ifdef COUNT
3450        int value = isort[iRow];
3451#endif
3452        isort[iRow]=0;
3453        if (fabs(dvalue)<1.0e-8||fabs(sumThis-dvalue)<1.0e-8)
3454          continue;
3455        if (dvalue<integerTolerance||dvalue>1.0-integerTolerance)
3456          continue;
3457#ifdef COUNT
3458        if (abs(value-target)<best&&value!=numberUnsatisfied) {
3459          best=abs(value-target);
3460          iBest=iRow;
3461          if (dvalue<dtarget)
3462            preferredWay=1;
3463          else
3464            preferredWay=-1;
3465        }
3466#else
3467        if (beforeSolution) {
3468          if (fabs(dvalue-dtarget)>best) {
3469            best = fabs(dvalue-dtarget);
3470            iBest=iRow;
3471            if (dvalue<dtarget)
3472              preferredWay=1;
3473            else
3474              preferredWay=-1;
3475          }
3476        } else {
3477          if (fabs(dvalue-dtarget)<best) {
3478            best = fabs(dvalue-dtarget);
3479            iBest=iRow;
3480            if (dvalue<dtarget)
3481              preferredWay=1;
3482            else
3483              preferredWay=-1;
3484          }
3485        }
3486#endif
3487      }
3488      if (iBest>=0) {
3489        whichRow=i;
3490        otherRow=iBest;
3491        break;
3492      }
3493    }
3494    delete [] which;
3495    delete [] other;
3496  }
3497  delete [] sort;
3498  delete [] isort;
3499  return whichRow;
3500}
3501double 
3502CbcFollowOn::infeasibility(const OsiBranchingInformation * /*info*/,
3503                               int &preferredWay) const
3504{
3505  int otherRow=0;
3506  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
3507  if (whichRow<0)
3508    return 0.0;
3509  else
3510  return 2.0* model_->getDblParam(CbcModel::CbcIntegerTolerance);
3511}
3512
3513// This looks at solution and sets bounds to contain solution
3514void 
3515CbcFollowOn::feasibleRegion()
3516{
3517}
3518
3519CbcBranchingObject * 
3520CbcFollowOn::createCbcBranch(OsiSolverInterface * solver,const OsiBranchingInformation * /*info*/, int way) 
3521{
3522  int otherRow=0;
3523  int preferredWay;
3524  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
3525  assert(way==preferredWay);
3526  assert (whichRow>=0);
3527  int numberColumns = matrix_.getNumCols();
3528 
3529  // Column copy
3530  //const double * element = matrix_.getElements();
3531  const int * row = matrix_.getIndices();
3532  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
3533  const int * columnLength = matrix_.getVectorLengths();
3534  // Row copy
3535  //const double * elementByRow = matrixByRow_.getElements();
3536  const int * column = matrixByRow_.getIndices();
3537  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
3538  const int * rowLength = matrixByRow_.getVectorLengths();
3539  //OsiSolverInterface * solver = model_->solver();
3540  const double * columnLower = solver->getColLower();
3541  const double * columnUpper = solver->getColUpper();
3542  //const double * solution = solver->getColSolution();
3543  int nUp=0;
3544  int nDown=0;
3545  int * upList = new int[numberColumns];
3546  int * downList = new int[numberColumns];
3547  int j;
3548  for (j=rowStart[whichRow];j<rowStart[whichRow]+rowLength[whichRow];j++) {
3549    int iColumn = column[j];
3550    if (columnLower[iColumn]!=columnUpper[iColumn]) {
3551      bool up=true;
3552      for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
3553        int iRow = row[jj];
3554        if (iRow==otherRow) {
3555          up=false;
3556          break;
3557        }
3558      }
3559      if (up)
3560        upList[nUp++]=iColumn;
3561      else
3562        downList[nDown++]=iColumn;
3563    }
3564  }
3565  //printf("way %d\n",way);
3566  // create object
3567  //printf("would fix %d down and %d up\n",nDown,nUp);
3568  CbcBranchingObject * branch
3569     = new CbcFixingBranchingObject(model_,way,
3570                                         nDown,downList,nUp,upList);
3571  delete [] upList;
3572  delete [] downList;
3573  return branch;
3574}
3575
3576//##############################################################################
3577
3578// Default Constructor
3579CbcFixingBranchingObject::CbcFixingBranchingObject()
3580  :CbcBranchingObject()
3581{
3582  numberDown_=0;
3583  numberUp_=0;
3584  downList_=NULL;
3585  upList_=NULL;
3586}
3587
3588// Useful constructor
3589CbcFixingBranchingObject::CbcFixingBranchingObject (CbcModel * model,
3590                                                    int way ,
3591                                                    int numberOnDownSide, const int * down,
3592                                                    int numberOnUpSide, const int * up)
3593  :CbcBranchingObject(model,0,way,0.5)
3594{
3595  numberDown_=numberOnDownSide;
3596  numberUp_=numberOnUpSide;
3597  downList_ = CoinCopyOfArray(down,numberDown_);
3598  upList_ = CoinCopyOfArray(up,numberUp_);
3599}
3600
3601// Copy constructor
3602CbcFixingBranchingObject::CbcFixingBranchingObject ( const CbcFixingBranchingObject & rhs) :CbcBranchingObject(rhs)
3603{
3604  numberDown_=rhs.numberDown_;
3605  numberUp_=rhs.numberUp_;
3606  downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
3607  upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
3608}
3609
3610// Assignment operator
3611CbcFixingBranchingObject & 
3612CbcFixingBranchingObject::operator=( const CbcFixingBranchingObject& rhs)
3613{
3614  if (this != &rhs) {
3615    CbcBranchingObject::operator=(rhs);
3616    delete [] downList_;
3617    delete [] upList_;
3618    numberDown_=rhs.numberDown_;
3619    numberUp_=rhs.numberUp_;
3620    downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
3621    upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
3622  }
3623  return *this;
3624}
3625CbcBranchingObject * 
3626CbcFixingBranchingObject::clone() const
3627{ 
3628  return (new CbcFixingBranchingObject(*this));
3629}
3630
3631
3632// Destructor
3633CbcFixingBranchingObject::~CbcFixingBranchingObject ()
3634{
3635  delete [] downList_;
3636  delete [] upList_;
3637}
3638double
3639CbcFixingBranchingObject::branch()
3640{
3641  decrementNumberBranchesLeft();
3642  OsiSolverInterface * solver = model_->solver();
3643  const double * columnLower = solver->getColLower();
3644  int i;
3645  // *** for way - up means fix all those in up section
3646  if (way_<0) {
3647#ifdef FULL_PRINT
3648    printf("Down Fix ");
3649#endif
3650    //printf("Down Fix %d\n",numberDown_);
3651    for (i=0;i<numberDown_;i++) {
3652      int iColumn = downList_[i];
3653      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
3654#ifdef FULL_PRINT
3655      printf("Setting bound on %d to lower bound\n",iColumn);
3656#endif
3657    }
3658    way_=1;       // Swap direction
3659  } else {
3660#ifdef FULL_PRINT
3661    printf("Up Fix ");
3662#endif
3663    //printf("Up Fix %d\n",numberUp_);
3664    for (i=0;i<numberUp_;i++) {
3665      int iColumn = upList_[i];
3666      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
3667#ifdef FULL_PRINT
3668      printf("Setting bound on %d to lower bound\n",iColumn);
3669#endif
3670    }
3671    way_=-1;      // Swap direction
3672  }
3673#ifdef FULL_PRINT
3674  printf("\n");
3675#endif
3676  return 0.0;
3677}
3678void
3679CbcFixingBranchingObject::print()
3680{
3681  int i;
3682  // *** for way - up means fix all those in up section
3683  if (way_<0) {
3684    printf("Down Fix ");
3685    for (i=0;i<numberDown_;i++) {
3686      int iColumn = downList_[i];
3687      printf("%d ",iColumn);
3688    }
3689  } else {
3690    printf("Up Fix ");
3691    for (i=0;i<numberUp_;i++) {
3692      int iColumn = upList_[i];
3693      printf("%d ",iColumn);
3694    }
3695  }
3696  printf("\n");
3697}
3698
3699/** Compare the original object of \c this with the original object of \c
3700    brObj. Assumes that there is an ordering of the original objects.
3701    This method should be invoked only if \c this and brObj are of the same
3702    type.
3703    Return negative/0/positive depending on whether \c this is
3704    smaller/same/larger than the argument.
3705*/
3706int
3707CbcFixingBranchingObject::compareOriginalObject
3708(const CbcBranchingObject* /*brObj*/) const
3709{
3710  throw("must implement");
3711}
3712
3713/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
3714    same type and must have the same original object, but they may have
3715    different feasible regions.
3716    Return the appropriate CbcRangeCompare value (first argument being the
3717    sub/superset if that's the case). In case of overlap (and if \c
3718    replaceIfOverlap is true) replace the current branching object with one
3719    whose feasible region is the overlap.
3720   */
3721CbcRangeCompare
3722CbcFixingBranchingObject::compareBranchingObject
3723(const CbcBranchingObject* /*brObj*/, const bool /*replaceIfOverlap*/)
3724{
3725#if 0 //ndef NDEBUG
3726  const CbcFixingBranchingObject* br =
3727    dynamic_cast<const CbcFixingBranchingObject*>(brObj);
3728  assert(br);
3729#endif
3730  // If two FixingBranchingObject's have the same base object then it's pretty
3731  // much guaranteed
3732  throw("must implement");
3733}
3734
3735//##############################################################################
3736
3737// Default Constructor
3738CbcNWay::CbcNWay ()
3739  : CbcObject(),
3740    numberMembers_(0),
3741    members_(NULL),
3742    consequence_(NULL)
3743{
3744}
3745
3746// Useful constructor (which are integer indices)
3747CbcNWay::CbcNWay (CbcModel * model, int numberMembers,
3748                  const int * which, int identifier)
3749  : CbcObject(model)
3750{
3751  id_=identifier;
3752  numberMembers_=numberMembers;
3753  if (numberMembers_) {
3754    members_ = new int[numberMembers_];
3755    memcpy(members_,which,numberMembers_*sizeof(int));
3756  } else {
3757    members_ = NULL;
3758  }
3759  consequence_ = NULL;
3760}
3761
3762// Copy constructor
3763CbcNWay::CbcNWay ( const CbcNWay & rhs)
3764  :CbcObject(rhs)
3765{
3766  numberMembers_ = rhs.numberMembers_;
3767  consequence_ = NULL;
3768  if (numberMembers_) {
3769    members_ = new int[numberMembers_];
3770    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
3771    if (rhs.consequence_) {
3772      consequence_ = new CbcConsequence * [numberMembers_];
3773      for (int i=0;i<numberMembers_;i++) {
3774        if (rhs.consequence_[i])
3775          consequence_[i]= rhs.consequence_[i]->clone();
3776        else
3777          consequence_[i]=NULL;
3778      }
3779    }
3780  } else {
3781    members_ = NULL;
3782  }
3783}
3784
3785// Clone
3786CbcObject *
3787CbcNWay::clone() const
3788{
3789  return new CbcNWay(*this);
3790}
3791
3792// Assignment operator
3793CbcNWay & 
3794CbcNWay::operator=( const CbcNWay& rhs)
3795{
3796  if (this!=&rhs) {
3797    CbcObject::operator=(rhs);
3798    delete [] members_;
3799    numberMembers_ = rhs.numberMembers_;
3800    if (consequence_) {
3801      for (int i=0;i<numberMembers_;i++) 
3802        delete consequence_[i];
3803      delete [] consequence_;
3804      consequence_=NULL;
3805    }
3806    if (numberMembers_) {
3807      members_ = new int[numberMembers_];
3808      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
3809    } else {
3810      members_ = NULL;
3811    }
3812    if (rhs.consequence_) {
3813      consequence_ = new CbcConsequence * [numberMembers_];
3814      for (int i=0;i<numberMembers_;i++) {
3815        if (rhs.consequence_[i])
3816          consequence_[i]= rhs.consequence_[i]->clone();
3817        else
3818          consequence_[i]=NULL;
3819      }
3820    }
3821  }
3822  return *this;
3823}
3824
3825// Destructor
3826CbcNWay::~CbcNWay ()
3827{
3828  delete [] members_;
3829  if (consequence_) {
3830    for (int i=0;i<numberMembers_;i++) 
3831      delete consequence_[i];
3832    delete [] consequence_;
3833  }
3834}
3835// Set up a consequence for a single member
3836void 
3837CbcNWay::setConsequence(int iColumn, const CbcConsequence & consequence)
3838{
3839  if (!consequence_) {
3840    consequence_ = new CbcConsequence * [numberMembers_];
3841    for (int i=0;i<numberMembers_;i++) 
3842      consequence_[i]=NULL;
3843  }
3844  for (int i=0;i<numberMembers_;i++) {
3845    if (members_[i]==iColumn) {
3846      consequence_[i]=consequence.clone();
3847      break;
3848    }
3849  }
3850}
3851
3852// Applies a consequence for a single member
3853void 
3854CbcNWay::applyConsequence(int iSequence, int state) const
3855{
3856  assert (state==-9999||state==9999);
3857  if (consequence_) {
3858    CbcConsequence * consequence = consequence_[iSequence];
3859    if (consequence) 
3860      consequence->applyToSolver(model_->solver(),state);
3861  }
3862}
3863double 
3864CbcNWay::infeasibility(const OsiBranchingInformation * /*info*/,
3865                               int &preferredWay) const
3866{
3867  int numberUnsatis=0;
3868  int j;
3869  OsiSolverInterface * solver = model_->solver();
3870  const double * solution = model_->testSolution();
3871  const double * lower = solver->getColLower();
3872  const double * upper = solver->getColUpper();
3873  double largestValue=0.0;
3874 
3875  double integerTolerance = 
3876    model_->getDblParam(CbcModel::CbcIntegerTolerance);
3877
3878  for (j=0;j<numberMembers_;j++) {
3879    int iColumn = members_[j];
3880    double value = solution[iColumn];
3881    value = CoinMax(value, lower[iColumn]);
3882    value = CoinMin(value, upper[iColumn]);
3883    double distance = CoinMin(value-lower[iColumn],upper[iColumn]-value);
3884    if (distance>integerTolerance) {
3885      numberUnsatis++;
3886      largestValue = CoinMax(distance,largestValue);
3887    }
3888  }
3889  preferredWay=1;
3890  if (numberUnsatis) {
3891    return largestValue;
3892  } else {
3893    return 0.0; // satisfied
3894  }
3895}
3896
3897// This looks at solution and sets bounds to contain solution
3898void 
3899CbcNWay::feasibleRegion()
3900{
3901  int j;
3902  OsiSolverInterface * solver = model_->solver();
3903  const double * solution = model_->testSolution();
3904  const double * lower = solver->getColLower();
3905  const double * upper = solver->getColUpper();
3906  double integerTolerance = 
3907    model_->getDblParam(CbcModel::CbcIntegerTolerance);
3908  for (j=0;j<numberMembers_;j++) {
3909    int iColumn = members_[j];
3910    double value = solution[iColumn];
3911    value = CoinMax(value, lower[iColumn]);
3912    value = CoinMin(value, upper[iColumn]);
3913    if (value>=upper[iColumn]-integerTolerance) {
3914      solver->setColLower(iColumn,upper[iColumn]);
3915    } else {
3916      assert (value<=lower[iColumn]+integerTolerance);
3917      solver->setColUpper(iColumn,lower[iColumn]);
3918    }
3919  }
3920}
3921// Redoes data when sequence numbers change
3922void 
3923CbcNWay::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
3924{
3925  model_=model;
3926  int n2=0;
3927  for (int j=0;j<numberMembers_;j++) {
3928    int iColumn = members_[j];
3929    int i;
3930    for (i=0;i<numberColumns;i++) {
3931      if (originalColumns[i]==iColumn)
3932        break;
3933    }
3934    if (i<numberColumns) {
3935      members_[n2]=i;
3936      consequence_[n2++]=consequence_[j];
3937    } else {
3938      delete consequence_[j];
3939    }
3940  }
3941  if (n2<numberMembers_) {
3942    printf("** NWay number of members reduced from %d to %d!\n",numberMembers_,n2);
3943    numberMembers_=n2;
3944  }
3945}
3946CbcBranchingObject * 
3947CbcNWay::createCbcBranch(OsiSolverInterface * solver,const OsiBranchingInformation * /*info*/, int /*way*/) 
3948{
3949  int numberFree=0;
3950  int j;
3951
3952  //OsiSolverInterface * solver = model_->solver();
3953  const double * solution = model_->testSolution();
3954  const double * lower = solver->getColLower();
3955  const double * upper = solver->getColUpper();
3956  int * list = new int[numberMembers_];
3957  double * sort = new double[numberMembers_];
3958
3959  for (j=0;j<numberMembers_;j++) {
3960    int iColumn = members_[j];
3961    double value = solution[iColumn];
3962    value = CoinMax(value, lower[iColumn]);
3963    value = CoinMin(value, upper[iColumn]);
3964    if (upper[iColumn]>lower[iColumn]) {
3965      double distance = upper[iColumn]-value;
3966      list[numberFree]=j;
3967      sort[numberFree++]=distance;
3968    }
3969  }
3970  assert (numberFree);
3971  // sort
3972  CoinSort_2(sort,sort+numberFree,list);
3973  // create object
3974  CbcBranchingObject * branch;
3975  branch = new CbcNWayBranchingObject(model_,this,numberFree,list);
3976  branch->setOriginalObject(this);
3977  delete [] list;
3978  delete [] sort;
3979  return branch;
3980}
3981 
3982//##############################################################################
3983
3984// Default Constructor
3985CbcNWayBranchingObject::CbcNWayBranchingObject()
3986  :CbcBranchingObject()
3987{
3988  order_=NULL;
3989  object_=NULL;
3990  numberInSet_=0;
3991  way_=0;
3992}
3993
3994// Useful constructor
3995CbcNWayBranchingObject::CbcNWayBranchingObject (CbcModel * model,
3996                                                const CbcNWay * nway, 
3997                                                int number, const int * order)
3998  :CbcBranchingObject(model,nway->id(),-1,0.5)
3999{
4000  numberBranches_ = number;
4001  order_ = new int [number];
4002  object_=nway;
4003  numberInSet_=number;
4004  memcpy(order_,order,number*sizeof(int));
4005}
4006
4007// Copy constructor
4008CbcNWayBranchingObject::CbcNWayBranchingObject ( const CbcNWayBranchingObject & rhs) :CbcBranchingObject(rhs)
4009{
4010  numberInSet_=rhs.numberInSet_;
4011  object_=rhs.object_;
4012  if (numberInSet_) {
4013    order_ = new int [numberInSet_];
4014    memcpy(order_,rhs.order_,numberInSet_*sizeof(int));
4015  } else {
4016    order_=NULL;
4017  }   
4018}
4019
4020// Assignment operator
4021CbcNWayBranchingObject & 
4022CbcNWayBranchingObject::operator=( const CbcNWayBranchingObject& rhs)
4023{
4024  if (this != &rhs) {
4025    CbcBranchingObject::operator=(rhs);
4026    object_=rhs.object_;
4027    delete [] order_;
4028    numberInSet_=rhs.numberInSet_;
4029    if (numberInSet_) {
4030      order_ = new int [numberInSet_];
4031      memcpy(order_,rhs.order_,numberInSet_*sizeof(int));
4032    } else {
4033      order_=NULL;
4034    }   
4035  }
4036  return *this;
4037}
4038CbcBranchingObject * 
4039CbcNWayBranchingObject::clone() const
4040{ 
4041  return (new CbcNWayBranchingObject(*this));
4042}
4043
4044
4045// Destructor
4046CbcNWayBranchingObject::~CbcNWayBranchingObject ()
4047{
4048  delete [] order_;
4049}
4050double
4051CbcNWayBranchingObject::branch()
4052{
4053  int which = branchIndex_;
4054  branchIndex_++;
4055  assert (numberBranchesLeft()>=0);
4056  if (which==0) {
4057    // first branch so way_ may mean something
4058    assert (way_==-1||way_==1);
4059    if (way_==-1)
4060      which++;
4061  } else if (which==1) {
4062    // second branch so way_ may mean something
4063    assert (way_==-1||way_==1);
4064    if (way_==-1)
4065      which--;
4066    // switch way off
4067    way_=0;
4068  }
4069  const double * lower = model_->solver()->getColLower();
4070  const double * upper = model_->solver()->getColUpper();
4071  const int * members = object_->members();
4072  for (int j=0;j<numberInSet_;j++) {
4073    int iSequence = order_[j];
4074    int iColumn = members[iSequence];
4075    if (j!=which) {
4076      model_->solver()->setColUpper(iColumn,lower[iColumn]);
4077      //model_->solver()->setColLower(iColumn,lower[iColumn]);
4078      assert (lower[iColumn]>-1.0e20);
4079      // apply any consequences
4080      object_->applyConsequence(iSequence,-9999);
4081    } else {
4082      model_->solver()->setColLower(iColumn,upper[iColumn]);
4083      //model_->solver()->setColUpper(iColumn,upper[iColumn]);
4084#ifdef FULL_PRINT
4085      printf("Up Fix %d to %g\n",iColumn,upper[iColumn]);
4086#endif
4087      assert (upper[iColumn]<1.0e20);
4088      // apply any consequences
4089      object_->applyConsequence(iSequence,9999);
4090    }
4091  }
4092  return 0.0;
4093}
4094void
4095CbcNWayBranchingObject::print()
4096{
4097  printf("NWay - Up Fix ");
4098  const int * members = object_->members();
4099  for (int j=0;j<way_;j++) {
4100    int iColumn = members[order_[j]];
4101    printf("%d ",iColumn);
4102  }
4103  printf("\n");
4104}
4105
4106/** Compare the original object of \c this with the original object of \c
4107    brObj. Assumes that there is an ordering of the original objects.
4108    This method should be invoked only if \c this and brObj are of the same
4109    type.
4110    Return negative/0/positive depending on whether \c this is
4111    smaller/same/larger than the argument.
4112*/
4113int
4114CbcNWayBranchingObject::compareOriginalObject
4115(const CbcBranchingObject* /*brObj*/) const
4116{
4117  throw("must implement");
4118}
4119
4120/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
4121    same type and must have the same original object, but they may have
4122    different feasible regions.
4123    Return the appropriate CbcRangeCompare value (first argument being the
4124    sub/superset if that's the case). In case of overlap (and if \c
4125    replaceIfOverlap is true) replace the current branching object with one
4126    whose feasible region is the overlap.
4127*/
4128CbcRangeCompare
4129CbcNWayBranchingObject::compareBranchingObject
4130(const CbcBranchingObject* /*brObj*/, const bool /*replaceIfOverlap*/)
4131{
4132  throw("must implement");
4133}
4134
4135//##############################################################################
4136
4137// Default Constructor
4138CbcFixVariable::CbcFixVariable ()
4139  : CbcConsequence(),
4140    numberStates_(0),
4141    states_(NULL),
4142    startLower_(NULL),
4143    startUpper_(NULL),
4144    newBound_(NULL),
4145    variable_(NULL)
4146{
4147}
4148
4149// One useful Constructor
4150CbcFixVariable::CbcFixVariable (int numberStates,const int * states, const int * numberNewLower, 
4151                                const int ** newLowerValue,
4152                                const int ** lowerColumn,
4153                                const int * numberNewUpper, const int ** newUpperValue,
4154                                const int ** upperColumn)
4155  : CbcConsequence(),
4156    states_(NULL),
4157    startLower_(NULL),
4158    startUpper_(NULL),
4159    newBound_(NULL),
4160    variable_(NULL)
4161{
4162  // How much space
4163  numberStates_ = numberStates;
4164  if (numberStates_) {
4165    states_ = new int[numberStates_];
4166    memcpy(states_,states,numberStates_*sizeof(int));
4167    int i;
4168    int n=0;
4169    startLower_ = new int[numberStates_+1];
4170    startUpper_ = new int[numberStates_+1];
4171    startLower_[0]=0;
4172    //count
4173    for (i=0;i<numberStates_;i++) {
4174      n += numberNewLower[i];
4175      startUpper_[i]=n;
4176      n += numberNewUpper[i];
4177      startLower_[i+1]=n;
4178    }
4179    newBound_ = new double [n];
4180    variable_ = new int [n];
4181    n=0;
4182    for (i=0;i<numberStates_;i++) {
4183      int j;
4184      int k;
4185      const int * bound;
4186      const int * variable;
4187      k=numberNewLower[i];
4188      bound = newLowerValue[i];
4189      variable = lowerColumn[i];
4190      for (j=0;j<k;j++) {
4191        newBound_[n]=bound[j];
4192        variable_[n++]=variable[j];
4193      }
4194      k=numberNewUpper[i];
4195      bound = newUpperValue[i];
4196      variable = upperColumn[i];
4197      for (j=0;j<k;j++) {
4198        newBound_[n]=bound[j];
4199        variable_[n++]=variable[j];
4200      }
4201    }
4202  }
4203}
4204
4205// Copy constructor
4206CbcFixVariable::CbcFixVariable ( const CbcFixVariable & rhs)
4207  :CbcConsequence(rhs)
4208{
4209  numberStates_ = rhs.numberStates_;
4210  states_ = NULL;
4211  startLower_ = NULL;
4212  startUpper_ = NULL;
4213  newBound_ = NULL;
4214  variable_ = NULL;
4215  if (numberStates_) {
4216    states_ = CoinCopyOfArray(rhs.states_,numberStates_);
4217    startLower_ = CoinCopyOfArray(rhs.startLower_,numberStates_+1);
4218    startUpper_ = CoinCopyOfArray(rhs.startUpper_,numberStates_+1);
4219    int n=startLower_[numberStates_];
4220    newBound_ = CoinCopyOfArray(rhs.newBound_,n);
4221    variable_ = CoinCopyOfArray(rhs.variable_,n);
4222  }
4223}
4224
4225// Clone
4226CbcConsequence *
4227CbcFixVariable::clone() const
4228{
4229  return new CbcFixVariable(*this);
4230}
4231
4232// Assignment operator
4233CbcFixVariable & 
4234CbcFixVariable::operator=( const CbcFixVariable& rhs)
4235{
4236  if (this!=&rhs) {
4237    CbcConsequence::operator=(rhs);
4238    delete [] states_;
4239    delete [] startLower_;
4240    delete [] startUpper_;
4241    delete [] newBound_;
4242    delete [] variable_;
4243    states_ = NULL;
4244    startLower_ = NULL;
4245    startUpper_ = NULL;
4246    newBound_ = NULL;
4247    variable_ = NULL;
4248    numberStates_ = rhs.numberStates_;
4249    if (numberStates_) {
4250      states_ = CoinCopyOfArray(rhs.states_,numberStates_);
4251      startLower_ = CoinCopyOfArray(rhs.startLower_,numberStates_+1);
4252      startUpper_ = CoinCopyOfArray(rhs.startUpper_,numberStates_+1);
4253      int n=startLower_[numberStates_];
4254      newBound_ = CoinCopyOfArray(rhs.newBound_,n);
4255      variable_ = CoinCopyOfArray(rhs.variable_,n);
4256    }
4257  }
4258  return *this;
4259}
4260
4261// Destructor
4262CbcFixVariable::~CbcFixVariable ()
4263{
4264  delete [] states_;
4265  delete [] startLower_;
4266  delete [] startUpper_;
4267  delete [] newBound_;
4268  delete [] variable_;
4269}
4270// Set up a startLower for a single member
4271void 
4272CbcFixVariable::applyToSolver(OsiSolverInterface * solver, int state) const
4273{
4274  assert (state==-9999||state==9999);
4275  // Find state
4276  int find;
4277  for (find=0;find<numberStates_;find++) 
4278    if (states_[find]==state)
4279      break;
4280  if (find==numberStates_)
4281    return;
4282  int i;
4283  // Set new lower bounds
4284  for (i=startLower_[find];i<startUpper_[find];i++) {
4285    int iColumn = variable_[i];
4286    double value = newBound_[i];
4287    double oldValue = solver->getColLower()[iColumn];
4288    //printf("for %d old lower bound %g, new %g",iColumn,oldValue,value);
4289    solver->setColLower(iColumn,CoinMax(value,oldValue));
4290    //printf(" => %g\n",solver->getColLower()[iColumn]);
4291  }
4292  // Set new upper bounds
4293  for (i=startUpper_[find];i<startLower_[find+1];i++) {
4294    int iColumn = variable_[i];
4295    double value = newBound_[i];
4296    double oldValue = solver->getColUpper()[iColumn];
4297    //printf("for %d old upper bound %g, new %g",iColumn,oldValue,value);
4298    solver->setColUpper(iColumn,CoinMin(value,oldValue));
4299    //printf(" => %g\n",solver->getColUpper()[iColumn]);
4300  }
4301}
4302
4303//##############################################################################
4304
4305// Default Constructor
4306CbcDummyBranchingObject::CbcDummyBranchingObject(CbcModel * model)
4307  :CbcBranchingObject(model,0,0,0.5)
4308{
4309  setNumberBranchesLeft(1);
4310}
4311
4312
4313// Copy constructor
4314CbcDummyBranchingObject::CbcDummyBranchingObject ( const CbcDummyBranchingObject & rhs) :CbcBranchingObject(rhs)
4315{
4316}
4317
4318// Assignment operator
4319CbcDummyBranchingObject & 
4320CbcDummyBranchingObject::operator=( const CbcDummyBranchingObject& rhs)
4321{
4322  if (this != &rhs) {
4323    CbcBranchingObject::operator=(rhs);
4324  }
4325  return *this;
4326}
4327CbcBranchingObject * 
4328CbcDummyBranchingObject::clone() const
4329{ 
4330  return (new CbcDummyBranchingObject(*this));
4331}
4332
4333
4334// Destructor
4335CbcDummyBranchingObject::~CbcDummyBranchingObject ()
4336{
4337}
4338
4339/*
4340  Perform a dummy branch
4341*/
4342double
4343CbcDummyBranchingObject::branch()
4344{
4345  decrementNumberBranchesLeft();
4346  return 0.0;
4347}
4348// Print what would happen 
4349void
4350CbcDummyBranchingObject::print()
4351{
4352  printf("Dummy branch\n");
4353}
4354
4355// Default Constructor
4356CbcGeneral::CbcGeneral() 
4357  : CbcObject()
4358{
4359}
4360
4361// Constructor from model
4362CbcGeneral::CbcGeneral(CbcModel * model)
4363  : CbcObject(model)
4364{
4365}
4366
4367
4368// Destructor
4369CbcGeneral::~CbcGeneral ()
4370{
4371}
4372
4373// Copy constructor
4374CbcGeneral::CbcGeneral ( const CbcGeneral & rhs)
4375  : CbcObject(rhs)
4376{
4377}
4378#ifdef COIN_HAS_CLP
4379#include "OsiClpSolverInterface.hpp"
4380#include "CoinWarmStartBasis.hpp"
4381#include "ClpNode.hpp"
4382#include "CbcBranchDynamic.hpp"
4383// Assignment operator
4384CbcGeneral & 
4385CbcGeneral::operator=( const CbcGeneral& rhs)
4386{
4387  if (this!=&rhs) {
4388    CbcObject::operator=(rhs);
4389  }
4390  return *this;
4391}
4392// Infeasibility - large is 0.5
4393double 
4394CbcGeneral::infeasibility(const OsiBranchingInformation * /*info*/,
4395                          int &/*preferredWay*/) const
4396{
4397  abort();
4398  return 0.0;
4399}
4400CbcBranchingObject * 
4401CbcGeneral::createCbcBranch(OsiSolverInterface * /*solver*/,const OsiBranchingInformation * /*info*/, int /*way*/) 
4402{
4403  abort();
4404  return NULL;
4405}
4406
4407// Default Constructor
4408CbcGeneralDepth::CbcGeneralDepth ()
4409  : CbcGeneral(),
4410    maximumDepth_(0),
4411    maximumNodes_(0),
4412    whichSolution_(-1),
4413    numberNodes_(0),
4414    nodeInfo_(NULL)
4415{
4416}
4417
4418// Useful constructor (which are integer indices)
4419CbcGeneralDepth::CbcGeneralDepth (CbcModel * model, int maximumDepth)
4420  : CbcGeneral(model),
4421    maximumDepth_(maximumDepth),
4422    maximumNodes_(0),
4423    whichSolution_(-1),
4424    numberNodes_(0),
4425    nodeInfo_(NULL)
4426{
4427  assert(maximumDepth_<1000000);
4428  if (maximumDepth_>0) 
4429    maximumNodes_ = (1<<maximumDepth_)+1+maximumDepth_;
4430  else if (maximumDepth_<0)
4431    maximumNodes_ = 1+1-maximumDepth_;
4432  else
4433    maximumNodes_ = 0;
4434#define MAX_NODES 100
4435  maximumNodes_ = CoinMin(maximumNodes_,1+maximumDepth_+MAX_NODES);
4436  if (maximumNodes_) {
4437    nodeInfo_ = new ClpNodeStuff();
4438    nodeInfo_->maximumNodes_=maximumNodes_;
4439    ClpNodeStuff * info = nodeInfo_;
4440    // for reduced costs and duals
4441    info->solverOptions_ |= 7;
4442    if (maximumDepth_>0) {
4443      info->nDepth_ = maximumDepth_;
4444    } else {
4445      info->nDepth_ = - maximumDepth_;
4446      info->solverOptions_ |= 32;
4447    }
4448    ClpNode ** nodeInfo = new ClpNode * [maximumNodes_];
4449    for (int i=0;i<maximumNodes_;i++) 
4450      nodeInfo[i]=NULL;
4451    info->nodeInfo_ = nodeInfo;
4452  } else {
4453    nodeInfo_ = NULL;
4454  }
4455}
4456
4457// Copy constructor
4458CbcGeneralDepth::CbcGeneralDepth ( const CbcGeneralDepth & rhs)
4459  :CbcGeneral(rhs)
4460{
4461  maximumDepth_ = rhs.maximumDepth_;
4462  maximumNodes_ = rhs.maximumNodes_;
4463  whichSolution_ = -1;
4464  numberNodes_ = 0;
4465  if (maximumNodes_) {
4466    assert (rhs.nodeInfo_);
4467    nodeInfo_ = new ClpNodeStuff(*rhs.nodeInfo_);
4468    nodeInfo_->maximumNodes_=maximumNodes_;
4469    ClpNodeStuff * info = nodeInfo_;
4470    if (maximumDepth_>0) {
4471      info->nDepth_ = maximumDepth_;
4472    } else {
4473      info->nDepth_ = - maximumDepth_;
4474      info->solverOptions_ |= 32;
4475    }
4476    if (!info->nodeInfo_) {
4477      ClpNode ** nodeInfo = new ClpNode * [maximumNodes_];
4478      for (int i=0;i<maximumNodes_;i++) 
4479        nodeInfo[i]=NULL;
4480      info->nodeInfo_ = nodeInfo;
4481    }
4482  } else {
4483    nodeInfo_ = NULL;
4484  }
4485}
4486
4487// Clone
4488CbcObject *
4489CbcGeneralDepth::clone() const
4490{
4491  return new CbcGeneralDepth(*this);
4492}
4493
4494// Assignment operator
4495CbcGeneralDepth & 
4496CbcGeneralDepth::operator=( const CbcGeneralDepth& rhs)
4497{
4498  if (this!=&rhs) {
4499    CbcGeneral::operator=(rhs);
4500    delete nodeInfo_;
4501    maximumDepth_ = rhs.maximumDepth_;
4502    maximumNodes_ = rhs.maximumNodes_;
4503    whichSolution_ = -1;
4504    numberNodes_ = 0;
4505    if (maximumDepth_) {
4506      assert (rhs.nodeInfo_);
4507      nodeInfo_ = new ClpNodeStuff(*rhs.nodeInfo_);
4508      nodeInfo_->maximumNodes_=maximumNodes_;
4509    } else {
4510      nodeInfo_ = NULL;
4511    }
4512  }
4513  return *this;
4514}
4515
4516// Destructor
4517CbcGeneralDepth::~CbcGeneralDepth ()
4518{
4519  delete nodeInfo_;
4520}
4521// Infeasibility - large is 0.5
4522double 
4523CbcGeneralDepth::infeasibility(const OsiBranchingInformation * /*info*/,
4524                               int &/*preferredWay*/) const
4525{
4526  whichSolution_ = -1;
4527  // should use genuine OsiBranchingInformation usefulInfo = model_->usefulInformation();
4528  // for now assume only called when correct
4529  //if (usefulInfo.depth_>=4&&!model_->parentModel()
4530  //     &&(usefulInfo.depth_%2)==0) {
4531  if (true) {
4532    OsiSolverInterface * solver = model_->solver();
4533    OsiClpSolverInterface * clpSolver
4534      = dynamic_cast<OsiClpSolverInterface *> (solver);
4535    if (clpSolver) {
4536      ClpNodeStuff * info = nodeInfo_;
4537      info->integerTolerance_=model_->getIntegerTolerance();
4538      info->integerIncrement_=model_->getCutoffIncrement();
4539      info->numberBeforeTrust_ = model_->numberBeforeTrust();
4540      info->stateOfSearch_=model_->stateOfSearch();
4541      // Compute "small" change in branch
4542      int nBranches = model_->getIntParam(CbcModel::CbcNumberBranches);
4543      if (nBranches) {
4544        double average = model_->getDblParam(CbcModel::CbcSumChange)/static_cast<double>(nBranches);
4545        info->smallChange_ = 
4546          CoinMax(average*1.0e-5,model_->getDblParam(CbcModel::CbcSmallestChange));
4547        info->smallChange_ = CoinMax(info->smallChange_,1.0e-8);
4548      } else {
4549        info->smallChange_ = 1.0e-8;
4550      }
4551      int numberIntegers = model_->numberIntegers();
4552      double * down = new double[numberIntegers];
4553      double * up = new double[numberIntegers];
4554      int * priority = new int[numberIntegers];
4555      int * numberDown = new int[numberIntegers];
4556      int * numberUp = new int[numberIntegers];
4557      int * numberDownInfeasible = new int[numberIntegers];
4558      int * numberUpInfeasible = new int[numberIntegers];
4559      model_->fillPseudoCosts(down,up,priority,numberDown,numberUp,
4560                      numberDownInfeasible,numberUpInfeasible);
4561      info->fillPseudoCosts(down,up,priority,numberDown,numberUp,
4562                            numberDownInfeasible,
4563                            numberUpInfeasible,numberIntegers);
4564      info->presolveType_= 1; 
4565      delete [] down;
4566      delete [] up;
4567      delete [] numberDown;
4568      delete [] numberUp;
4569      delete [] numberDownInfeasible;
4570      delete [] numberUpInfeasible;
4571      bool takeHint;
4572      OsiHintStrength strength;
4573      solver->getHintParam(OsiDoReducePrint,takeHint,strength);
4574      ClpSimplex * simplex = clpSolver->getModelPtr();
4575      int saveLevel = simplex->logLevel();
4576      if (strength!=OsiHintIgnore&&takeHint&&saveLevel==1)
4577        simplex->setLogLevel(0);
4578      clpSolver->setBasis();
4579      whichSolution_ = simplex->fathomMany(info);
4580      //printf("FAT %d nodes, %d iterations\n",
4581      //info->numberNodesExplored_,info->numberIterations_);
4582      //printf("CbcBranch %d rows, %d columns\n",clpSolver->getNumRows(),
4583      //     clpSolver->getNumCols());
4584      model_->incrementExtra(info->numberNodesExplored_,
4585                             info->numberIterations_);
4586      // update pseudo costs
4587      double smallest=1.0e50;
4588      double largest=-1.0;
4589      OsiObject ** objects = model_->objects();
4590#ifndef NDEBUG
4591      const int * integerVariable = model_->integerVariable();
4592#endif
4593      for (int i=0;i<numberIntegers;i++) {
4594#ifndef NDEBUG
4595        CbcSimpleIntegerDynamicPseudoCost * obj =
4596          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(objects[i]) ;
4597        assert (obj&&obj->columnNumber()==integerVariable[i]);
4598#else
4599        CbcSimpleIntegerDynamicPseudoCost * obj =
4600          static_cast <CbcSimpleIntegerDynamicPseudoCost *>(objects[i]) ;
4601#endif
4602        if (info->numberUp_[i]>0) {
4603          if (info->downPseudo_[i]>largest)
4604            largest=info->downPseudo_[i];
4605          if (info->downPseudo_[i]<smallest) 
4606            smallest=info->downPseudo_[i];
4607          if (info->upPseudo_[i]>largest) 
4608            largest=info->upPseudo_[i];
4609          if (info->upPseudo_[i]<smallest)
4610            smallest=info->upPseudo_[i];
4611          obj->updateAfterMini(info->numberDown_[i],
4612                               info->numberDownInfeasible_[i],
4613                               info->downPseudo_[i],
4614                               info->numberUp_[i],
4615                               info->numberUpInfeasible_[i],
4616                               info->upPseudo_[i]);
4617        }
4618      }
4619      //printf("range of costs %g to %g\n",smallest,largest);
4620      simplex->setLogLevel(saveLevel);
4621      numberNodes_ = info->nNodes_;
4622      int numberDo = numberNodes_;
4623      if (whichSolution_>=0)
4624        numberDo--;
4625      if (numberDo>0) {
4626        return 0.5;
4627      } else {
4628        // no solution
4629        return COIN_DBL_MAX; // say infeasible
4630      }
4631    } else {
4632      return -1.0;
4633    }
4634  } else {
4635    return -1.0;
4636  }
4637}
4638
4639// This looks at solution and sets bounds to contain solution
4640void 
4641CbcGeneralDepth::feasibleRegion()
4642{
4643  // Other stuff should have done this
4644}
4645// Redoes data when sequence numbers change
4646void 
4647CbcGeneralDepth::redoSequenceEtc(CbcModel * /*model*/, 
4648                                 int /*numberColumns*/,
4649                                 const int * /*originalColumns*/)
4650{
4651}
4652
4653//#define CHECK_PATH
4654#ifdef CHECK_PATH
4655extern const double * debuggerSolution_Z;
4656extern int numberColumns_Z;
4657extern int gotGoodNode_Z;
4658#endif
4659CbcBranchingObject * 
4660CbcGeneralDepth::createCbcBranch(OsiSolverInterface * solver,const OsiBranchingInformation * /*info*/, int /*way*/) 
4661{
4662  int numberDo = numberNodes_;
4663  if (whichSolution_>=0)
4664    numberDo--;
4665  assert (numberDo>0);
4666  // create object
4667  CbcGeneralBranchingObject * branch = new CbcGeneralBranchingObject(model_);
4668  // skip solution
4669  branch->numberSubProblems_ = numberDo;
4670  // If parentBranch_ back in then will have to be 2*
4671  branch->numberSubLeft_ = numberDo;
4672  branch->setNumberBranches(numberDo);
4673  CbcSubProblem * sub = new CbcSubProblem[numberDo];
4674  int iProb=0;
4675  branch->subProblems_ = sub;
4676  branch->numberRows_ = model_->solver()->getNumRows();
4677  int iNode;
4678  //OsiSolverInterface * solver = model_->solver();
4679  OsiClpSolverInterface * clpSolver
4680    = dynamic_cast<OsiClpSolverInterface *> (solver);
4681  assert (clpSolver);
4682  ClpSimplex * simplex = clpSolver->getModelPtr();
4683  int numberColumns = simplex->numberColumns();
4684  double * lowerBefore=CoinCopyOfArray(simplex->getColLower(),
4685                                       numberColumns);
4686  double * upperBefore=CoinCopyOfArray(simplex->getColUpper(),
4687                                       numberColumns);
4688  ClpNodeStuff * info = nodeInfo_;
4689  double * weight = new double[numberNodes_];
4690  int * whichNode = new int [numberNodes_];
4691  // Sort
4692  for (iNode=0;iNode<numberNodes_;iNode++) {
4693    if (iNode!=whichSolution_) {
4694      double objectiveValue = info->nodeInfo_[iNode]->objectiveValue();
4695      double sumInfeasibilities = info->nodeInfo_[iNode]->sumInfeasibilities();
4696      int numberInfeasibilities = info->nodeInfo_[iNode]->numberInfeasibilities();
4697      double thisWeight = 0.0;
4698#if 1
4699      // just closest
4700      thisWeight = 1.0e9*numberInfeasibilities;
4701      thisWeight += sumInfeasibilities;
4702      thisWeight += 1.0e-7*objectiveValue;
4703      // Try estimate
4704      thisWeight = info->nodeInfo_[iNode]->estimatedSolution();
4705#else
4706      thisWeight = 1.0e-3*numberInfeasibilities;
4707      thisWeight += 1.0e-5*sumInfeasibilities;
4708      thisWeight += objectiveValue;
4709#endif
4710      whichNode[iProb]=iNode;
4711      weight[iProb++]=thisWeight;
4712    }
4713  }
4714  assert (iProb==numberDo);
4715  CoinSort_2(weight,weight+numberDo,whichNode);
4716  for (iProb=0;iProb<numberDo;iProb++) {
4717    iNode = whichNode[iProb];
4718    ClpNode * node = info->nodeInfo_[iNode];
4719    // move bounds
4720    node->applyNode(simplex,3);
4721    // create subproblem
4722    sub[iProb]=CbcSubProblem(clpSolver,lowerBefore,upperBefore,
4723                             node->statusArray(),node->depth());
4724    sub[iProb].objectiveValue_ = node->objectiveValue();
4725    sub[iProb].sumInfeasibilities_ = node->sumInfeasibilities();
4726    sub[iProb].numberInfeasibilities_ = node->numberInfeasibilities();
4727#ifdef CHECK_PATH
4728    if (simplex->numberColumns()==numberColumns_Z) {
4729      bool onOptimal=true;
4730      const double * columnLower = simplex->columnLower();
4731      const double * columnUpper = simplex->columnUpper();
4732      for (int i=0;i<numberColumns_Z;i++) {
4733        if (iNode==gotGoodNode_Z)
4734          printf("good %d %d %g %g\n",iNode,i,columnLower[i],columnUpper[i]);
4735        if (columnUpper[i]<debuggerSolution_Z[i]||columnLower[i]>debuggerSolution_Z[i]&&simplex->isInteger(i)) {
4736          onOptimal=false;
4737          break;
4738        }
4739      }
4740      if (onOptimal) {
4741        printf("adding to node %x as %d - objs\n",this,iProb);
4742        for (int j=0;j<=iProb;j++)
4743          printf("%d %g\n",j,sub[j].objectiveValue_);
4744      }
4745    }
4746#endif
4747  }
4748  delete [] weight;
4749  delete [] whichNode;
4750  const double * lower = solver->getColLower();
4751  const double * upper = solver->getColUpper();
4752  // restore bounds
4753  for ( int j=0;j<numberColumns;j++) {
4754    if (lowerBefore[j] != lower[j])
4755      solver->setColLower(j,lowerBefore[j]);
4756    if (upperBefore[j] != upper[j])
4757      solver->setColUpper(j,upperBefore[j]);
4758  }
4759  delete [] upperBefore;
4760  delete [] lowerBefore;
4761  return branch;
4762}
4763
4764// Default Constructor
4765CbcGeneralBranchingObject::CbcGeneralBranchingObject()
4766  :CbcBranchingObject(),
4767   subProblems_(NULL),
4768   node_(NULL),
4769   numberSubProblems_(0),
4770   numberSubLeft_(0),
4771   whichNode_(-1),
4772   numberRows_(0)
4773{
4774  //  printf("CbcGeneral %x default constructor\n",this);
4775}
4776
4777// Useful constructor
4778CbcGeneralBranchingObject::CbcGeneralBranchingObject (CbcModel * model)
4779  :CbcBranchingObject(model,-1,-1,0.5),
4780   subProblems_(NULL),
4781   node_(NULL),
4782   numberSubProblems_(0),
4783   numberSubLeft_(0),
4784   whichNode_(-1),
4785   numberRows_(0)
4786{
4787  //printf("CbcGeneral %x useful constructor\n",this);
4788}
4789
4790// Copy constructor
4791CbcGeneralBranchingObject::CbcGeneralBranchingObject ( const CbcGeneralBranchingObject & rhs) 
4792  :CbcBranchingObject(rhs),
4793   subProblems_(NULL),
4794   node_(rhs.node_),
4795   numberSubProblems_(rhs.numberSubProblems_),
4796   numberSubLeft_(rhs.numberSubLeft_),
4797   whichNode_(rhs.whichNode_),
4798   numberRows_(rhs.numberRows_)
4799{
4800  abort();
4801  if (numberSubProblems_) {
4802    subProblems_ = new CbcSubProblem[numberSubProblems_];
4803    for (int i=0;i<numberSubProblems_;i++)
4804      subProblems_[i]=rhs.subProblems_[i];
4805  }
4806}
4807
4808// Assignment operator
4809CbcGeneralBranchingObject & 
4810CbcGeneralBranchingObject::operator=( const CbcGeneralBranchingObject& rhs)
4811{
4812  if (this != &rhs) {
4813    abort();
4814    CbcBranchingObject::operator=(rhs);
4815    delete [] subProblems_;
4816    numberSubProblems_ = rhs.numberSubProblems_;
4817    numberSubLeft_ = rhs.numberSubLeft_;
4818    whichNode_ = rhs.whichNode_;
4819    numberRows_ = rhs.numberRows_;
4820    if (numberSubProblems_) {
4821      subProblems_ = new CbcSubProblem[numberSubProblems_];
4822      for (int i=0;i<numberSubProblems_;i++)
4823        subProblems_[i]=rhs.subProblems_[i];
4824    } else {
4825      subProblems_ = NULL;
4826    }
4827    node_ = rhs.node_;
4828  }
4829  return *this;
4830}
4831CbcBranchingObject * 
4832CbcGeneralBranchingObject::clone() const
4833{ 
4834  return (new CbcGeneralBranchingObject(*this));
4835}
4836
4837
4838// Destructor
4839CbcGeneralBranchingObject::~CbcGeneralBranchingObject ()
4840{
4841  //printf("CbcGeneral %x destructor\n",this);
4842  delete [] subProblems_;
4843}
4844bool doingDoneBranch=false;
4845double
4846CbcGeneralBranchingObject::branch()
4847{
4848  double cutoff=model_->getCutoff();
4849  //printf("GenB %x whichNode %d numberLeft %d which %d\n",
4850  // this,whichNode_,numberBranchesLeft(),branchIndex());
4851  if (whichNode_<0) {
4852    assert (node_);
4853    bool applied=false;
4854    while (numberBranchesLeft()) {
4855      int which = branchIndex();
4856      decrementNumberBranchesLeft();
4857      CbcSubProblem * thisProb = subProblems_+which;
4858      if (thisProb->objectiveValue_<cutoff) {
4859        //printf("branch %x (sub %x) which now %d\n",this,
4860        //     subProblems_,which);
4861        OsiSolverInterface * solver = model_->solver();
4862        thisProb->apply(solver);
4863        OsiClpSolverInterface * clpSolver
4864          = dynamic_cast<OsiClpSolverInterface *> (solver);
4865        assert (clpSolver);
4866        // Move status to basis
4867        clpSolver->setWarmStart(NULL);
4868        //ClpSimplex * simplex = clpSolver->getModelPtr();
4869        node_->setObjectiveValue(thisProb->objectiveValue_);
4870        node_->setSumInfeasibilities(thisProb->sumInfeasibilities_);
4871        node_->setNumberUnsatisfied(thisProb->numberInfeasibilities_);
4872        applied=true;
4873        doingDoneBranch=true;
4874        break;
4875      } else if (numberBranchesLeft()) {
4876        node_->nodeInfo()->branchedOn() ;
4877      }
4878    }
4879    if (!applied) {
4880      // no good one
4881      node_->setObjectiveValue(cutoff+1.0e20);
4882      node_->setSumInfeasibilities(1.0);
4883      node_->setNumberUnsatisfied(1);
4884      assert (whichNode_<0);
4885    }
4886  } else {
4887    decrementNumberBranchesLeft();
4888    CbcSubProblem * thisProb = subProblems_+whichNode_;
4889    assert (thisProb->objectiveValue_<cutoff);
4890    OsiSolverInterface * solver = model_->solver();
4891    thisProb->apply(solver);
4892    //OsiClpSolverInterface * clpSolver
4893    //= dynamic_cast<OsiClpSolverInterface *> (solver);
4894    //assert (clpSolver);
4895    // Move status to basis
4896    //clpSolver->setWarmStart(NULL);
4897  }
4898  return 0.0;
4899}
4900/* Double checks in case node can change its mind!
4901   Can change objective etc */
4902void 
4903CbcGeneralBranchingObject::checkIsCutoff(double cutoff)
4904{
4905  assert (node_);
4906  int first = branchIndex();
4907  int last = first + numberBranchesLeft();
4908  for (int which=first;which<last;which++) {
4909    CbcSubProblem * thisProb = subProblems_+which;
4910    if (thisProb->objectiveValue_<cutoff) {
4911      node_->setObjectiveValue(thisProb->objectiveValue_);
4912      node_->setSumInfeasibilities(thisProb->sumInfeasibilities_);
4913      node_->setNumberUnsatisfied(thisProb->numberInfeasibilities_);
4914      break;
4915    }
4916  }
4917}
4918// Print what would happen 
4919void
4920CbcGeneralBranchingObject::print()
4921{
4922  //printf("CbcGeneralObject has %d subproblems\n",numberSubProblems_);
4923}
4924// Fill in current objective etc
4925void 
4926CbcGeneralBranchingObject::state(double & objectiveValue,
4927                                 double & sumInfeasibilities,
4928                                 int & numberUnsatisfied,int which) const
4929{
4930  assert (which>=0&&which<numberSubProblems_);
4931  const CbcSubProblem * thisProb = subProblems_+which;
4932  objectiveValue = thisProb->objectiveValue_;
4933  sumInfeasibilities = thisProb->sumInfeasibilities_;
4934  numberUnsatisfied = thisProb->numberInfeasibilities_;
4935}
4936/** Compare the original object of \c this with the original object of \c
4937    brObj. Assumes that there is an ordering of the original objects.
4938    This method should be invoked only if \c this and brObj are of the same
4939    type.
4940    Return negative/0/positive depending on whether \c this is
4941    smaller/same/larger than the argument.
4942*/
4943int
4944CbcGeneralBranchingObject::compareOriginalObject
4945(const CbcBranchingObject* /*brObj*/) const
4946{
4947  throw("must implement");
4948}
4949
4950/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
4951    same type and must have the same original object, but they may have
4952    different feasible regions.
4953    Return the appropriate CbcRangeCompare value (first argument being the
4954    sub/superset if that's the case). In case of overlap (and if \c
4955    replaceIfOverlap is true) replace the current branching object with one
4956    whose feasible region is the overlap.
4957*/
4958CbcRangeCompare
4959CbcGeneralBranchingObject::compareBranchingObject
4960(const CbcBranchingObject* /*brObj*/, const bool /*replaceIfOverlap*/)
4961{
4962  throw("must implement");
4963}
4964
4965// Default Constructor
4966CbcOneGeneralBranchingObject::CbcOneGeneralBranchingObject()
4967  :CbcBranchingObject(),
4968   object_(NULL),
4969   whichOne_(-1)
4970{
4971  //printf("CbcOneGeneral %x default constructor\n",this);
4972}
4973
4974// Useful constructor
4975CbcOneGeneralBranchingObject::CbcOneGeneralBranchingObject (CbcModel * model,
4976                                 CbcGeneralBranchingObject * object,
4977                                 int whichOne)
4978  :CbcBranchingObject(model,-1,-1,0.5),
4979   object_(object),
4980   whichOne_(whichOne)
4981{
4982  //printf("CbcOneGeneral %x useful constructor object %x %d left\n",this,
4983  //     object_,object_->numberSubLeft_);
4984  numberBranches_=1;
4985}
4986
4987// Copy constructor
4988CbcOneGeneralBranchingObject::CbcOneGeneralBranchingObject ( const CbcOneGeneralBranchingObject & rhs) 
4989  :CbcBranchingObject(rhs),
4990   object_(rhs.object_),
4991   whichOne_(rhs.whichOne_)
4992{
4993}
4994
4995// Assignment operator
4996CbcOneGeneralBranchingObject & 
4997CbcOneGeneralBranchingObject::operator=( const CbcOneGeneralBranchingObject& rhs)
4998{
4999  if (this != &rhs) {
5000    CbcBranchingObject::operator=(rhs);
5001    object_ = rhs.object_;
5002    whichOne_ = rhs.whichOne_;
5003  }
5004  return *this;
5005}
5006CbcBranchingObject * 
5007CbcOneGeneralBranchingObject::clone() const
5008{ 
5009  return (new CbcOneGeneralBranchingObject(*this));
5010}
5011
5012
5013// Destructor
5014CbcOneGeneralBranchingObject::~CbcOneGeneralBranchingObject ()
5015{
5016  //printf("CbcOneGeneral %x destructor object %x %d left\n",this,
5017  // object_,object_->numberSubLeft_);
5018  assert (object_->numberSubLeft_>0&&
5019          object_->numberSubLeft_<1000000);
5020  if (!object_->decrementNumberLeft()) {
5021    // printf("CbcGeneral %x yy destructor\n",object_);
5022    delete object_;
5023  }
5024}
5025double
5026CbcOneGeneralBranchingObject::branch()
5027{
5028  assert (numberBranchesLeft());
5029  decrementNumberBranchesLeft();
5030  assert (!numberBranchesLeft());
5031  object_->setWhichNode(whichOne_);
5032  object_->branch();
5033  return 0.0;
5034}
5035/* Double checks in case node can change its mind!
5036   Can change objective etc */
5037void 
5038CbcOneGeneralBranchingObject::checkIsCutoff(double /*cutoff*/)
5039{
5040  assert (numberBranchesLeft());
5041}
5042// Print what would happen 
5043void
5044CbcOneGeneralBranchingObject::print()
5045{
5046  //printf("CbcOneGeneralObject has 1 subproblem\n");
5047}
5048/** Compare the original object of \c this with the original object of \c
5049    brObj. Assumes that there is an ordering of the original objects.
5050    This method should be invoked only if \c this and brObj are of the same
5051    type.
5052    Return negative/0/positive depending on whether \c this is
5053    smaller/same/larger than the argument.
5054*/
5055int
5056CbcOneGeneralBranchingObject::compareOriginalObject
5057(const CbcBranchingObject* /*brObj*/) const
5058{
5059  throw("must implement");
5060}
5061
5062/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
5063    same type and must have the same original object, but they may have
5064    different feasible regions.
5065    Return the appropriate CbcRangeCompare value (first argument being the
5066    sub/superset if that's the case). In case of overlap (and if \c
5067    replaceIfOverlap is true) replace the current branching object with one
5068    whose feasible region is the overlap.
5069*/
5070CbcRangeCompare
5071CbcOneGeneralBranchingObject::compareBranchingObject
5072(const CbcBranchingObject* /*brObj*/, const bool /*replaceIfOverlap*/)
5073{
5074  throw("must implement");
5075}
5076// Default Constructor
5077CbcSubProblem::CbcSubProblem()
5078  : objectiveValue_(0.0),
5079    sumInfeasibilities_(0.0),
5080    variables_(NULL),
5081    newBounds_(NULL),
5082    status_(NULL),
5083    depth_(0),
5084    numberChangedBounds_(0),
5085    numberInfeasibilities_(0)
5086{
5087}
5088
5089// Useful constructor
5090CbcSubProblem::CbcSubProblem (const OsiSolverInterface * solver,
5091                              const double * lastLower,
5092                              const double * lastUpper,
5093                              const unsigned char * status,
5094                              int depth)
5095  : objectiveValue_(0.0),
5096    sumInfeasibilities_(0.0),
5097    variables_(NULL),
5098    newBounds_(NULL),
5099    status_(NULL),
5100    depth_(depth),
5101    numberChangedBounds_(0),
5102    numberInfeasibilities_(0)
5103{
5104  const double * lower = solver->getColLower();
5105  const double * upper = solver->getColUpper();
5106
5107  numberChangedBounds_=0;
5108  int numberColumns = solver->getNumCols();
5109  int i;
5110  for (i=0;i<numberColumns;i++) {
5111    if (lower[i]!=lastLower[i]) 
5112      numberChangedBounds_++;
5113    if (upper[i]!=lastUpper[i]) 
5114      numberChangedBounds_++;
5115  }
5116  if (numberChangedBounds_) {
5117    newBounds_ = new double [numberChangedBounds_] ;
5118    variables_ = new int [numberChangedBounds_] ;
5119    numberChangedBounds_=0;
5120    for (i=0;i<numberColumns;i++) {
5121      if (lower[i]!=lastLower[i]) {
5122        variables_[numberChangedBounds_]=i;
5123        newBounds_[numberChangedBounds_++]=lower[i];
5124      }
5125      if (upper[i]!=lastUpper[i]) {
5126        variables_[numberChangedBounds_]=i|0x80000000;
5127        newBounds_[numberChangedBounds_++]=upper[i];
5128      }
5129#ifdef CBC_DEBUG
5130      if (lower[i] != lastLower[i]) {
5131        std::cout
5132          << "lower on " << i << " changed from "
5133          << lastLower[i] << " to " << lower[i] << std::endl ;
5134      }
5135      if (upper[i] != lastUpper[i]) {
5136        std::cout
5137          << "upper on " << i << " changed from "
5138          << lastUpper[i] << " to " << upper[i] << std::endl ;
5139      }
5140#endif
5141    }
5142#ifdef CBC_DEBUG
5143    std::cout << numberChangedBounds_ << " changed bounds." << std::endl ;
5144#endif
5145  }
5146  const OsiClpSolverInterface * clpSolver
5147    = dynamic_cast<const OsiClpSolverInterface *> (solver);
5148  assert (clpSolver);
5149  // Do difference
5150  // Current basis
5151  status_ = clpSolver->getBasis(status);
5152  assert (status_->fullBasis());
5153  //status_->print();
5154}
5155
5156// Copy constructor
5157CbcSubProblem::CbcSubProblem ( const CbcSubProblem & rhs) 
5158  : objectiveValue_(rhs.objectiveValue_),
5159    sumInfeasibilities_(rhs.sumInfeasibilities_),
5160    variables_(NULL),
5161    newBounds_(NULL),
5162    status_(NULL),
5163    depth_(rhs.depth_),
5164    numberChangedBounds_(rhs.numberChangedBounds_),
5165    numberInfeasibilities_(rhs.numberInfeasibilities_)
5166{
5167  if (numberChangedBounds_) {
5168    variables_ = CoinCopyOfArray(rhs.variables_,numberChangedBounds_);
5169    newBounds_ = CoinCopyOfArray(rhs.newBounds_,numberChangedBounds_);
5170  }
5171  if (rhs.status_) {
5172    status_ = new CoinWarmStartBasis(*rhs.status_);
5173  }
5174}
5175
5176// Assignment operator
5177CbcSubProblem & 
5178CbcSubProblem::operator=( const CbcSubProblem& rhs)
5179{
5180  if (this != &rhs) {
5181    delete [] variables_;
5182    delete [] newBounds_;
5183    delete status_;
5184    objectiveValue_ = rhs.objectiveValue_;
5185    sumInfeasibilities_ = rhs.sumInfeasibilities_;
5186    depth_ = rhs.depth_;
5187    numberChangedBounds_ = rhs.numberChangedBounds_;
5188    numberInfeasibilities_ = rhs.numberInfeasibilities_;
5189    if (numberChangedBounds_) {
5190      variables_ = CoinCopyOfArray(rhs.variables_,numberChangedBounds_);
5191      newBounds_ = CoinCopyOfArray(rhs.newBounds_,numberChangedBounds_);
5192    } else {
5193      variables_ = NULL;
5194      newBounds_ = NULL;
5195    }
5196    if (rhs.status_) {
5197      status_ = new CoinWarmStartBasis(*rhs.status_);
5198    } else {
5199      status_ = NULL;
5200    }
5201  }
5202  return *this;
5203}
5204
5205// Destructor
5206CbcSubProblem::~CbcSubProblem ()
5207{
5208  delete [] variables_;
5209  delete [] newBounds_;
5210  delete status_;
5211}
5212// Apply subproblem
5213void 
5214CbcSubProblem::apply(OsiSolverInterface * solver, int what) const
5215{
5216  int i;
5217  if ((what&1)!=0) {
5218    int nSame=0;
5219    for (i=0;i<numberChangedBounds_;i++) {
5220      int variable = variables_[i];
5221      int k = variable&0x3fffffff;
5222      if ((variable&0x80000000)==0) {
5223        // lower bound changing
5224        //#define CBC_PRINT2
5225#ifdef CBC_PRINT2
5226        if(solver->getColLower()[k]!=newBounds_[i])
5227          printf("lower change for column %d - from %g to %g\n",k,solver->getColLower()[k],newBounds_[i]);
5228#endif
5229#ifndef NDEBUG
5230        if ((variable&0x40000000)==0&&true) {
5231          double oldValue = solver->getColLower()[k];
5232          assert (newBounds_[i]>oldValue-1.0e-8);
5233          if (newBounds_[i]<oldValue+1.0e-8) {
5234#ifdef CBC_PRINT2
5235            printf("bad null lower change for column %d - bound %g\n",k,oldValue);
5236#endif
5237            if (newBounds_[i]==oldValue) 
5238              nSame++;
5239          }
5240        }
5241#endif
5242        solver->setColLower(k,newBounds_[i]);
5243      } else {
5244        // upper bound changing
5245#ifdef CBC_PRINT2
5246        if(solver->getColUpper()[k]!=newBounds_[i])
5247          printf("upper change for column %d - from %g to %g\n",k,solver->getColUpper()[k],newBounds_[i]);
5248#endif
5249#ifndef NDEBUG
5250        if ((variable&0x40000000)==0&&true) {
5251          double oldValue = solver->getColUpper()[k];
5252          assert (newBounds_[i]<oldValue+1.0e-8);
5253          if (newBounds_[i]>oldValue-1.0e-8) {
5254#ifdef CBC_PRINT2
5255            printf("bad null upper change for column %d - bound %g\n",k,oldValue);
5256#endif
5257            if (newBounds_[i]==oldValue) 
5258              nSame++;
5259          }
5260        }
5261#endif
5262        solver->setColUpper(k,newBounds_[i]);
5263      }
5264    }
5265    if (nSame&&(nSame<numberChangedBounds_||(what&3)!=3))
5266      printf("%d changes out of %d redundant %d\n",
5267             nSame,numberChangedBounds_,what);
5268    else if (numberChangedBounds_&&what==7&&!nSame)
5269      printf("%d good changes %d\n",
5270             numberChangedBounds_,what);
5271  }
5272#if 0
5273  if ((what&2)!=0) {
5274    OsiClpSolverInterface * clpSolver
5275      = dynamic_cast<OsiClpSolverInterface *> (solver);
5276    assert (clpSolver);
5277    //assert (clpSolver->getNumRows()==numberRows_);
5278    //clpSolver->setBasis(*status_);
5279    // Current basis
5280    CoinWarmStartBasis * basis=clpSolver->getPointerToWarmStart();
5281    printf("BBBB\n");
5282    basis->print();
5283    assert (basis->fullBasis());
5284    basis->applyDiff(status_);
5285    printf("diff applied %x\n",status_);
5286    printf("CCCC\n");
5287    basis->print();
5288    assert (basis->fullBasis());
5289#ifndef NDEBUG
5290    if (!basis->fullBasis())
5291      printf("Debug this basis!!\n");
5292#endif
5293    clpSolver->setBasis(*basis);
5294  }
5295#endif
5296  if ((what&8)!=0) {
5297    OsiClpSolverInterface * clpSolver
5298      = dynamic_cast<OsiClpSolverInterface *> (solver);
5299    assert (clpSolver);
5300    clpSolver->setBasis(*status_);
5301    delete status_;
5302    status_=NULL;
5303  }
5304}
5305#endif
5306
5307/** Compare the original object of \c this with the original object of \c
5308    brObj. Assumes that there is an ordering of the original objects.
5309    This method should be invoked only if \c this and brObj are of the same
5310    type.
5311    Return negative/0/positive depending on whether \c this is
5312    smaller/same/larger than the argument.
5313*/
5314int
5315CbcDummyBranchingObject::compareOriginalObject
5316(const CbcBranchingObject* /*brObj*/) const
5317{
5318  throw("must implement");
5319}
5320
5321/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
5322    same type and must have the same original object, but they may have
5323    different feasible regions.
5324    Return the appropriate CbcRangeCompare value (first argument being the
5325    sub/superset if that's the case). In case of overlap (and if \c
5326    replaceIfOverlap is true) replace the current branching object with one
5327    whose feasible region is the overlap.
5328*/
5329CbcRangeCompare
5330CbcDummyBranchingObject::compareBranchingObject
5331(const CbcBranchingObject* /*brObj*/, const bool /*replaceIfOverlap*/)
5332{
5333  throw("must implement");
5334}
Note: See TracBrowser for help on using the repository browser.