source: trunk/Cbc/src/CbcBranchActual.cpp @ 1121

Last change on this file since 1121 was 1121, checked in by forrest, 11 years ago

compiler warnings, deterministic parallel and stability

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