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

Last change on this file since 904 was 904, checked in by ladanyi, 13 years ago

include cstdlib before cmath to get things to compile on AIX with xlC

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 94.1 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 "OsiSolverInterface.hpp"
14#include "OsiSolverBranch.hpp"
15#include "CbcModel.hpp"
16#include "CbcMessage.hpp"
17#include "CbcBranchActual.hpp"
18#include "CoinSort.hpp"
19#include "CoinError.hpp"
20
21// Default Constructor
22CbcClique::CbcClique ()
23  : CbcObject(),
24    numberMembers_(0),
25    numberNonSOSMembers_(0),
26    members_(NULL),
27    type_(NULL),
28    cliqueType_(-1),
29    slack_(-1)
30{
31}
32
33// Useful constructor (which are integer indices)
34CbcClique::CbcClique (CbcModel * model, int cliqueType, int numberMembers,
35           const int * which, const char * type, int identifier,int slack)
36  : CbcObject(model)
37{
38  id_=identifier;
39  numberMembers_=numberMembers;
40  if (numberMembers_) {
41    members_ = new int[numberMembers_];
42    memcpy(members_,which,numberMembers_*sizeof(int));
43    type_ = new char[numberMembers_];
44    if (type) {
45      memcpy(type_,type,numberMembers_*sizeof(char));
46    } else {
47      for (int i=0;i<numberMembers_;i++)
48        type_[i]=1;
49    }
50  } else {
51    members_ = NULL;
52    type_ = NULL;
53  }
54  // Find out how many non sos
55  int i;
56  numberNonSOSMembers_=0;
57  for (i=0;i<numberMembers_;i++)
58    if (!type_[i])
59      numberNonSOSMembers_++;
60  cliqueType_ = cliqueType;
61  slack_ = slack;
62}
63
64// Copy constructor
65CbcClique::CbcClique ( const CbcClique & rhs)
66  :CbcObject(rhs)
67{
68  numberMembers_ = rhs.numberMembers_;
69  numberNonSOSMembers_ = rhs.numberNonSOSMembers_;
70  if (numberMembers_) {
71    members_ = new int[numberMembers_];
72    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
73    type_ = new char[numberMembers_];
74    memcpy(type_,rhs.type_,numberMembers_*sizeof(char));
75  } else {
76    members_ = NULL;
77    type_ = NULL;
78  }
79  cliqueType_ = rhs.cliqueType_;
80  slack_ = rhs.slack_;
81}
82
83// Clone
84CbcObject *
85CbcClique::clone() const
86{
87  return new CbcClique(*this);
88}
89
90// Assignment operator
91CbcClique & 
92CbcClique::operator=( const CbcClique& rhs)
93{
94  if (this!=&rhs) {
95    CbcObject::operator=(rhs);
96    delete [] members_;
97    delete [] type_;
98    numberMembers_ = rhs.numberMembers_;
99    numberNonSOSMembers_ = rhs.numberNonSOSMembers_;
100    if (numberMembers_) {
101      members_ = new int[numberMembers_];
102      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
103      type_ = new char[numberMembers_];
104      memcpy(type_,rhs.type_,numberMembers_*sizeof(char));
105    } else {
106      members_ = NULL;
107      type_ = NULL;
108    }
109    cliqueType_ = rhs.cliqueType_;
110    slack_ = rhs.slack_;
111  }
112  return *this;
113}
114
115// Destructor
116CbcClique::~CbcClique ()
117{
118  delete [] members_;
119  delete [] type_;
120}
121
122// Infeasibility - large is 0.5
123double 
124CbcClique::infeasibility(int & preferredWay) const
125{
126  int numberUnsatis=0, numberFree=0;
127  int j;
128  const int * integer = model_->integerVariable();
129  OsiSolverInterface * solver = model_->solver();
130  const double * solution = model_->testSolution();
131  const double * lower = solver->getColLower();
132  const double * upper = solver->getColUpper();
133  double largestValue=0.0;
134  double integerTolerance = 
135    model_->getDblParam(CbcModel::CbcIntegerTolerance);
136  double * sort = new double[numberMembers_];
137
138  double slackValue=0.0;
139  for (j=0;j<numberMembers_;j++) {
140    int sequence = members_[j];
141    int iColumn = integer[sequence];
142    double value = solution[iColumn];
143    value = CoinMax(value, lower[iColumn]);
144    value = CoinMin(value, upper[iColumn]);
145    double nearest = floor(value+0.5);
146    double distance = fabs(value-nearest);
147    if (distance>integerTolerance) {
148      if (!type_[j])
149        value = 1.0-value; // non SOS
150      // if slack then choose that
151      if (j==slack_&&value>0.05)
152        slackValue = value;
153      largestValue = CoinMax(value,largestValue);
154      sort[numberUnsatis++]=-value;
155    } else if (upper[iColumn]>lower[iColumn]) {
156      numberFree++;
157    }
158  }
159  preferredWay=1;
160  double otherWay = 0.0;
161  if (numberUnsatis) {
162    // sort
163    std::sort(sort,sort+numberUnsatis);
164    for (j=0;j<numberUnsatis;j++) {
165      if ((j&1)!=0)
166        otherWay += -sort[j];
167    }
168    // Need to think more
169    double value = 0.2*numberUnsatis+0.01*(numberMembers_-numberFree);
170    if (fabs(largestValue-0.5)<0.1) {
171      // close to half
172      value +=0.1;
173    }
174    if (slackValue) {
175      // branching on slack
176      value += slackValue;
177    }
178    // scale other way
179    otherWay *= value/(1.0-otherWay);
180    delete [] sort;
181    return value;
182  } else {
183    delete [] sort;
184    return 0.0; // satisfied
185  }
186}
187
188// This looks at solution and sets bounds to contain solution
189void 
190CbcClique::feasibleRegion()
191{
192  int j;
193  const int * integer = model_->integerVariable();
194  OsiSolverInterface * solver = model_->solver();
195  const double * solution = model_->testSolution();
196  const double * lower = solver->getColLower();
197  const double * upper = solver->getColUpper();
198#ifndef NDEBUG
199  double integerTolerance = 
200    model_->getDblParam(CbcModel::CbcIntegerTolerance);
201#endif 
202  for (j=0;j<numberMembers_;j++) {
203    int sequence = members_[j];
204    int iColumn = integer[sequence];
205    double value = solution[iColumn];
206    value = CoinMax(value, lower[iColumn]);
207    value = CoinMin(value, upper[iColumn]);
208    double nearest = floor(value+0.5);
209#ifndef NDEBUG
210    double distance = fabs(value-nearest);
211    assert(distance<=integerTolerance);
212#endif
213    solver->setColLower(iColumn,nearest);
214    solver->setColUpper(iColumn,nearest);
215  }
216}
217// Redoes data when sequence numbers change
218void 
219CbcClique::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
220{
221  model_=model;
222  int n2=0;
223  for (int j=0;j<numberMembers_;j++) {
224    int iColumn = members_[j];
225    int i;
226    for (i=0;i<numberColumns;i++) {
227      if (originalColumns[i]==iColumn)
228        break;
229    }
230    if (i<numberColumns) {
231      members_[n2]=i;
232      type_[n2++]=type_[j];
233    }
234  }
235  if (n2<numberMembers_) {
236    //printf("** SOS number of members reduced from %d to %d!\n",numberMembers_,n2);
237    numberMembers_=n2;
238  }
239  // Find out how many non sos
240  int i;
241  numberNonSOSMembers_=0;
242  for (i=0;i<numberMembers_;i++)
243    if (!type_[i])
244      numberNonSOSMembers_++;
245}
246
247
248// Creates a branching object
249CbcBranchingObject * 
250CbcClique::createBranch(int way) 
251{
252  int numberUnsatis=0;
253  int j;
254  int nUp=0;
255  int nDown=0;
256  int numberFree=numberMembers_;
257  const int * integer = model_->integerVariable();
258  OsiSolverInterface * solver = model_->solver();
259  const double * solution = model_->testSolution();
260  const double * lower = solver->getColLower();
261  const double * upper = solver->getColUpper();
262  int * upList = new int[numberMembers_];
263  int * downList = new int[numberMembers_];
264  double * sort = new double[numberMembers_];
265  double integerTolerance = 
266      model_->getDblParam(CbcModel::CbcIntegerTolerance);
267
268  double slackValue=0.0;
269  for (j=0;j<numberMembers_;j++) {
270    int sequence = members_[j];
271    int iColumn = integer[sequence];
272    double value = solution[iColumn];
273    value = CoinMax(value, lower[iColumn]);
274    value = CoinMin(value, upper[iColumn]);
275    double nearest = floor(value+0.5);
276    double distance = fabs(value-nearest);
277    if (distance>integerTolerance) {
278      if (!type_[j])
279        value = 1.0-value; // non SOS
280      // if slack then choose that
281      if (j==slack_&&value>0.05)
282        slackValue = value;
283      value = -value; // for sort
284      upList[numberUnsatis]=j;
285      sort[numberUnsatis++]=value;
286    } else if (upper[iColumn]>lower[iColumn]) {
287      upList[--numberFree]=j;
288    }
289  }
290  assert (numberUnsatis);
291  if (!slackValue) {
292    // sort
293    CoinSort_2(sort,sort+numberUnsatis,upList);
294    // put first in up etc
295    int kWay=1;
296    for (j=0;j<numberUnsatis;j++) {
297      if (kWay>0) 
298        upList[nUp++]=upList[j];
299      else
300        downList[nDown++]=upList[j];
301      kWay = -kWay;
302    }
303    for (j=numberFree;j<numberMembers_;j++) {
304      if (kWay>0)
305        upList[nUp++]=upList[j];
306      else
307        downList[nDown++]=upList[j];
308      kWay = -kWay;
309    }
310  } else {
311    // put slack to 0 in first way
312    nUp = 1;
313    upList[0]=slack_;
314    for (j=0;j<numberUnsatis;j++) {
315      downList[nDown++]=upList[j];
316    }
317    for (j=numberFree;j<numberMembers_;j++) {
318      downList[nDown++]=upList[j];
319    }
320  }
321  // create object
322  CbcBranchingObject * branch;
323  if (numberMembers_ <=64)
324     branch = new CbcCliqueBranchingObject(model_,this,way,
325                                         nDown,downList,nUp,upList);
326  else
327    branch = new CbcLongCliqueBranchingObject(model_,this,way,
328                                            nDown,downList,nUp,upList);
329  delete [] upList;
330  delete [] downList;
331  delete [] sort;
332  return branch;
333}
334
335// Default Constructor
336CbcSOS::CbcSOS ()
337  : CbcObject(),
338    members_(NULL),
339    weights_(NULL),
340    numberMembers_(0),
341    sosType_(-1),
342    integerValued_(false)
343{
344}
345
346// Useful constructor (which are indices)
347CbcSOS::CbcSOS (CbcModel * model,  int numberMembers,
348           const int * which, const double * weights, int identifier,int type)
349  : CbcObject(model),
350    numberMembers_(numberMembers),
351    sosType_(type)
352{
353  id_=identifier;
354  integerValued_ = type==1;
355  if (integerValued_) {
356    // check all members integer
357    OsiSolverInterface * solver = model->solver();
358    if (solver) {
359      for (int i=0;i<numberMembers_;i++) {
360        if (!solver->isInteger(which[i]))
361          integerValued_=false;
362      }
363    } else {
364      // can't tell
365      integerValued_=false;
366    }
367  }
368  if (numberMembers_) {
369    members_ = new int[numberMembers_];
370    weights_ = new double[numberMembers_];
371    memcpy(members_,which,numberMembers_*sizeof(int));
372    if (weights) {
373      memcpy(weights_,weights,numberMembers_*sizeof(double));
374    } else {
375      for (int i=0;i<numberMembers_;i++)
376        weights_[i]=i;
377    }
378    // sort so weights increasing
379    CoinSort_2(weights_,weights_+numberMembers_,members_);
380    double last = -COIN_DBL_MAX;
381    int i;
382    for (i=0;i<numberMembers_;i++) {
383      double possible = CoinMax(last+1.0e-10,weights_[i]);
384      weights_[i] = possible;
385      last=possible;
386    }
387  } else {
388    members_ = NULL;
389    weights_ = NULL;
390  }
391  assert (sosType_>0&&sosType_<3);
392}
393
394// Copy constructor
395CbcSOS::CbcSOS ( const CbcSOS & rhs)
396  :CbcObject(rhs)
397{
398  numberMembers_ = rhs.numberMembers_;
399  sosType_ = rhs.sosType_;
400  integerValued_ = rhs.integerValued_;
401  if (numberMembers_) {
402    members_ = new int[numberMembers_];
403    weights_ = new double[numberMembers_];
404    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
405    memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
406  } else {
407    members_ = NULL;
408    weights_ = NULL;
409  }
410}
411
412// Clone
413CbcObject *
414CbcSOS::clone() const
415{
416  return new CbcSOS(*this);
417}
418
419// Assignment operator
420CbcSOS & 
421CbcSOS::operator=( const CbcSOS& rhs)
422{
423  if (this!=&rhs) {
424    CbcObject::operator=(rhs);
425    delete [] members_;
426    delete [] weights_;
427    numberMembers_ = rhs.numberMembers_;
428    sosType_ = rhs.sosType_;
429    integerValued_ = rhs.integerValued_;
430    if (numberMembers_) {
431      members_ = new int[numberMembers_];
432      weights_ = new double[numberMembers_];
433      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
434      memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
435    } else {
436      members_ = NULL;
437      weights_ = NULL;
438    }
439  }
440  return *this;
441}
442
443// Destructor
444CbcSOS::~CbcSOS ()
445{
446  delete [] members_;
447  delete [] weights_;
448}
449
450// Infeasibility - large is 0.5
451double 
452CbcSOS::infeasibility(int & preferredWay) const
453{
454  int j;
455  int firstNonZero=-1;
456  int lastNonZero = -1;
457  OsiSolverInterface * solver = model_->solver();
458  const double * solution = model_->testSolution();
459  //const double * lower = solver->getColLower();
460  const double * upper = solver->getColUpper();
461  //double largestValue=0.0;
462  double integerTolerance = 
463    model_->getDblParam(CbcModel::CbcIntegerTolerance);
464  double weight = 0.0;
465  double sum =0.0;
466
467  // check bounds etc
468  double lastWeight=-1.0e100;
469  for (j=0;j<numberMembers_;j++) {
470    int iColumn = members_[j];
471    if (lastWeight>=weights_[j]-1.0e-7)
472      throw CoinError("Weights too close together in SOS","infeasibility","CbcSOS");
473    double value = CoinMax(0.0,solution[iColumn]);
474    sum += value;
475    if (value>integerTolerance&&upper[iColumn]) {
476      // Possibly due to scaling a fixed variable might slip through
477      if (value>upper[iColumn]) {
478        value=upper[iColumn];
479        // Could change to #ifdef CBC_DEBUG
480#ifndef NDEBUG
481        if (model_->messageHandler()->logLevel()>2)
482          printf("** Variable %d (%d) has value %g and upper bound of %g\n",
483                 iColumn,j,value,upper[iColumn]);
484#endif
485      } 
486      weight += weights_[j]*value;
487      if (firstNonZero<0)
488        firstNonZero=j;
489      lastNonZero=j;
490    }
491  }
492  preferredWay=1;
493  if (lastNonZero-firstNonZero>=sosType_) {
494    // find where to branch
495    assert (sum>0.0);
496    weight /= sum;
497    //int iWhere;
498    //for (iWhere=firstNonZero;iWhere<lastNonZero;iWhere++)
499    //if (weight<weights_[iWhere+1])
500    //break;
501    // probably best to use pseudo duals
502    double value = lastNonZero-firstNonZero+1;
503    value *= 0.5/((double) numberMembers_);
504    return value;
505  } else {
506    return 0.0; // satisfied
507  }
508}
509
510// This looks at solution and sets bounds to contain solution
511void 
512CbcSOS::feasibleRegion()
513{
514  int j;
515  int firstNonZero=-1;
516  int lastNonZero = -1;
517  OsiSolverInterface * solver = model_->solver();
518  const double * solution = model_->testSolution();
519  //const double * lower = solver->getColLower();
520  const double * upper = solver->getColUpper();
521  double integerTolerance = 
522    model_->getDblParam(CbcModel::CbcIntegerTolerance);
523  double weight = 0.0;
524  double sum =0.0;
525
526  for (j=0;j<numberMembers_;j++) {
527    int iColumn = members_[j];
528    double value = CoinMax(0.0,solution[iColumn]);
529    sum += value;
530    if (value>integerTolerance&&upper[iColumn]) {
531      weight += weights_[j]*value;
532      if (firstNonZero<0)
533        firstNonZero=j;
534      lastNonZero=j;
535    }
536  }
537  assert (lastNonZero-firstNonZero<sosType_) ;
538  for (j=0;j<firstNonZero;j++) {
539    int iColumn = members_[j];
540    solver->setColUpper(iColumn,0.0);
541  }
542  for (j=lastNonZero+1;j<numberMembers_;j++) {
543    int iColumn = members_[j];
544    solver->setColUpper(iColumn,0.0);
545  }
546}
547// Redoes data when sequence numbers change
548void 
549CbcSOS::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
550{
551  model_=model;
552  int n2=0;
553  for (int j=0;j<numberMembers_;j++) {
554    int iColumn = members_[j];
555    int i;
556    for (i=0;i<numberColumns;i++) {
557      if (originalColumns[i]==iColumn)
558        break;
559    }
560    if (i<numberColumns) {
561      members_[n2]=i;
562      weights_[n2++]=weights_[j];
563    }
564  }
565  if (n2<numberMembers_) {
566    //printf("** SOS number of members reduced from %d to %d!\n",numberMembers_,n2);
567    numberMembers_=n2;
568  }
569}
570
571
572// Creates a branching object
573CbcBranchingObject * 
574CbcSOS::createBranch(int way) 
575{
576  int j;
577  const double * solution = model_->testSolution();
578  double integerTolerance = 
579      model_->getDblParam(CbcModel::CbcIntegerTolerance);
580  OsiSolverInterface * solver = model_->solver();
581  const double * upper = solver->getColUpper();
582  int firstNonFixed=-1;
583  int lastNonFixed=-1;
584  int firstNonZero=-1;
585  int lastNonZero = -1;
586  double weight = 0.0;
587  double sum =0.0;
588  for (j=0;j<numberMembers_;j++) {
589    int iColumn = members_[j];
590    if (upper[iColumn]) {
591      double value = CoinMax(0.0,solution[iColumn]);
592      sum += value;
593      if (firstNonFixed<0)
594        firstNonFixed=j;
595      lastNonFixed=j;
596      if (value>integerTolerance) {
597        weight += weights_[j]*value;
598        if (firstNonZero<0)
599          firstNonZero=j;
600        lastNonZero=j;
601      }
602    }
603  }
604  assert (lastNonZero-firstNonZero>=sosType_) ;
605  // find where to branch
606  assert (sum>0.0);
607  weight /= sum;
608  int iWhere;
609  double separator=0.0;
610  for (iWhere=firstNonZero;iWhere<lastNonZero;iWhere++) 
611    if (weight<weights_[iWhere+1])
612      break;
613  if (sosType_==1) {
614    // SOS 1
615    separator = 0.5 *(weights_[iWhere]+weights_[iWhere+1]);
616  } else {
617    // SOS 2
618    if (iWhere==firstNonFixed)
619      iWhere++;;
620    if (iWhere==lastNonFixed-1)
621      iWhere = lastNonFixed-2;
622    separator = weights_[iWhere+1];
623  }
624  // create object
625  CbcBranchingObject * branch;
626  branch = new CbcSOSBranchingObject(model_,this,way,separator);
627  return branch;
628}
629
630/* Create an OsiSolverBranch object
631   
632This returns NULL if branch not represented by bound changes
633*/
634OsiSolverBranch * 
635CbcSOS::solverBranch() const
636{
637  int j;
638  const double * solution = model_->testSolution();
639  double integerTolerance = 
640      model_->getDblParam(CbcModel::CbcIntegerTolerance);
641  OsiSolverInterface * solver = model_->solver();
642  const double * upper = solver->getColUpper();
643  int firstNonFixed=-1;
644  int lastNonFixed=-1;
645  int firstNonZero=-1;
646  int lastNonZero = -1;
647  double weight = 0.0;
648  double sum =0.0;
649  double * fix = new double[numberMembers_];
650  int * which = new int[numberMembers_];
651  for (j=0;j<numberMembers_;j++) {
652    int iColumn = members_[j];
653    // fix all on one side or other (even if fixed)
654    fix[j]=0.0;
655    which[j]=iColumn;
656    if (upper[iColumn]) {
657      double value = CoinMax(0.0,solution[iColumn]);
658      sum += value;
659      if (firstNonFixed<0)
660        firstNonFixed=j;
661      lastNonFixed=j;
662      if (value>integerTolerance) {
663        weight += weights_[j]*value;
664        if (firstNonZero<0)
665          firstNonZero=j;
666        lastNonZero=j;
667      }
668    }
669  }
670  assert (lastNonZero-firstNonZero>=sosType_) ;
671  // find where to branch
672  assert (sum>0.0);
673  weight /= sum;
674  // down branch fixes ones above weight to 0
675  int iWhere;
676  int iDownStart=0;
677  int iUpEnd=0;
678  for (iWhere=firstNonZero;iWhere<lastNonZero;iWhere++) 
679    if (weight<weights_[iWhere+1])
680      break;
681  if (sosType_==1) {
682    // SOS 1
683    iUpEnd=iWhere+1;
684    iDownStart=iUpEnd;
685  } else {
686    // SOS 2
687    if (iWhere==firstNonFixed)
688      iWhere++;;
689    if (iWhere==lastNonFixed-1)
690      iWhere = lastNonFixed-2;
691    iUpEnd=iWhere+1;
692    iDownStart=iUpEnd+1;
693  }
694  //
695  OsiSolverBranch * branch = new OsiSolverBranch();
696  branch->addBranch(-1,0,NULL,NULL,numberMembers_-iDownStart,which+iDownStart,fix);
697  branch->addBranch(1,0,NULL,NULL,iUpEnd,which,fix);
698  delete [] fix;
699  delete [] which;
700  return branch;
701}
702// Construct an OsiSOS object
703OsiSOS * 
704CbcSOS::osiObject(const OsiSolverInterface * solver) const
705{
706  OsiSOS * obj = new OsiSOS(solver,numberMembers_,members_,weights_,sosType_);
707  obj->setPriority(priority());
708  return obj;
709}
710
711/** Default Constructor
712
713  Equivalent to an unspecified binary variable.
714*/
715CbcSimpleInteger::CbcSimpleInteger ()
716  : CbcObject(),
717    originalLower_(0.0),
718    originalUpper_(1.0),
719    breakEven_(0.5),
720    columnNumber_(-1),
721    preferredWay_(0)
722{
723}
724
725/** Useful constructor
726
727  Loads actual upper & lower bounds for the specified variable.
728*/
729CbcSimpleInteger::CbcSimpleInteger ( CbcModel * model, int iColumn, double breakEven)
730  : CbcObject(model)
731{
732  columnNumber_ = iColumn ;
733  originalLower_ = model->solver()->getColLower()[columnNumber_] ;
734  originalUpper_ = model->solver()->getColUpper()[columnNumber_] ;
735  breakEven_ = breakEven;
736  assert (breakEven_>0.0&&breakEven_<1.0);
737  preferredWay_ = 0;
738}
739
740
741// Copy constructor
742CbcSimpleInteger::CbcSimpleInteger ( const CbcSimpleInteger & rhs)
743  :CbcObject(rhs)
744
745{
746  columnNumber_ = rhs.columnNumber_;
747  originalLower_ = rhs.originalLower_;
748  originalUpper_ = rhs.originalUpper_;
749  breakEven_ = rhs.breakEven_;
750  preferredWay_ = rhs.preferredWay_;
751}
752
753// Clone
754CbcObject *
755CbcSimpleInteger::clone() const
756{
757  return new CbcSimpleInteger(*this);
758}
759
760// Assignment operator
761CbcSimpleInteger & 
762CbcSimpleInteger::operator=( const CbcSimpleInteger& rhs)
763{
764  if (this!=&rhs) {
765    CbcObject::operator=(rhs);
766    columnNumber_ = rhs.columnNumber_;
767    originalLower_ = rhs.originalLower_;
768    originalUpper_ = rhs.originalUpper_;
769    breakEven_ = rhs.breakEven_;
770    preferredWay_ = rhs.preferredWay_;
771  }
772  return *this;
773}
774
775// Destructor
776CbcSimpleInteger::~CbcSimpleInteger ()
777{
778}
779// Construct an OsiSimpleInteger object
780OsiSimpleInteger * 
781CbcSimpleInteger::osiObject() const
782{
783  OsiSimpleInteger * obj = new OsiSimpleInteger(columnNumber_,
784                                                originalLower_,originalUpper_);
785  obj->setPriority(priority());
786  return obj;
787}
788
789double
790CbcSimpleInteger::infeasibility(const OsiSolverInterface * solver, const OsiBranchingInformation * info,
791                         int & preferredWay) const
792{
793  double value = info->solution_[columnNumber_];
794  value = CoinMax(value, info->lower_[columnNumber_]);
795  value = CoinMin(value, info->upper_[columnNumber_]);
796  double nearest = floor(value+(1.0-breakEven_));
797  assert (breakEven_>0.0&&breakEven_<1.0);
798  if (nearest>value) 
799    preferredWay=1;
800  else
801    preferredWay=-1;
802  if (preferredWay_)
803    preferredWay=preferredWay_;
804  double weight = fabs(value-nearest);
805  // normalize so weight is 0.5 at break even
806  if (nearest<value)
807    weight = (0.5/breakEven_)*weight;
808  else
809    weight = (0.5/(1.0-breakEven_))*weight;
810  if (fabs(value-nearest)<=info->integerTolerance_) 
811    return 0.0;
812  else
813    return weight;
814}
815double 
816CbcSimpleInteger::feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const 
817{
818  double value = info->solution_[columnNumber_];
819  double newValue = CoinMax(value, info->lower_[columnNumber_]);
820  newValue = CoinMin(newValue, info->upper_[columnNumber_]);
821  newValue = floor(newValue+0.5);
822  solver->setColLower(columnNumber_,newValue);
823  solver->setColUpper(columnNumber_,newValue);
824  return fabs(value-newValue);
825}
826
827/* Create an OsiSolverBranch object
828   
829This returns NULL if branch not represented by bound changes
830*/
831OsiSolverBranch * 
832CbcSimpleInteger::solverBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info) const
833{
834  double value = info->solution_[columnNumber_];
835  value = CoinMax(value, info->lower_[columnNumber_]);
836  value = CoinMin(value, info->upper_[columnNumber_]);
837  assert (info->upper_[columnNumber_]>info->lower_[columnNumber_]);
838#ifndef NDEBUG
839  double nearest = floor(value+0.5);
840  assert (fabs(value-nearest)>info->integerTolerance_);
841#endif
842  OsiSolverBranch * branch = new OsiSolverBranch();
843  branch->addBranch(columnNumber_,value);
844  return branch;
845}
846// Creates a branching object
847CbcBranchingObject * 
848CbcSimpleInteger::createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) 
849{
850  CbcIntegerBranchingObject * branch = new CbcIntegerBranchingObject(model_,0,-1,0.5);
851  fillCreateBranch(branch,info,way);
852  return branch;
853}
854// Fills in a created branching object
855void 
856CbcSimpleInteger::fillCreateBranch(CbcIntegerBranchingObject * branch, const OsiBranchingInformation * info, int way) 
857{
858  branch->setOriginalObject(this);
859  double value = info->solution_[columnNumber_];
860  value = CoinMax(value, info->lower_[columnNumber_]);
861  value = CoinMin(value, info->upper_[columnNumber_]);
862  assert (info->upper_[columnNumber_]>info->lower_[columnNumber_]);
863  if (!info->hotstartSolution_) {
864#ifndef NDEBUG
865    double nearest = floor(value+0.5);
866    assert (fabs(value-nearest)>info->integerTolerance_);
867#endif
868  } else {
869    double targetValue = info->hotstartSolution_[columnNumber_];
870    if (way>0)
871      value = targetValue-0.1;
872    else
873      value = targetValue+0.1;
874  }
875  branch->fillPart(columnNumber_,way,value);
876}
877/* Column number if single column object -1 otherwise,
878   so returns >= 0
879   Used by heuristics
880*/
881int 
882CbcSimpleInteger::columnNumber() const
883{
884  return columnNumber_;
885}
886/* Reset variable bounds to their original values.
887 
888    Bounds may be tightened, so it may be good to be able to set this info in object.
889*/
890void 
891CbcSimpleInteger::resetBounds(const OsiSolverInterface * solver) 
892{
893  originalLower_ = solver->getColLower()[columnNumber_] ;
894  originalUpper_ = solver->getColUpper()[columnNumber_] ;
895}
896
897/*  Change column numbers after preprocessing
898 */
899void 
900CbcSimpleInteger::resetSequenceEtc(int numberColumns, const int * originalColumns) 
901{
902  assert (numberColumns>0);
903  int iColumn;
904#if 0
905  for (iColumn=0;iColumn<numberColumns;iColumn++) {
906    if (columnNumber_==originalColumns[iColumn])
907      break;
908  }
909  assert (iColumn<numberColumns);
910#else
911  iColumn=originalColumns[columnNumber_];
912  assert (iColumn>=0);
913#endif
914  columnNumber_ = iColumn;
915}
916
917// Infeasibility - large is 0.5
918double 
919CbcSimpleInteger::infeasibility(int & preferredWay) const
920{
921  OsiBranchingInformation info(model_->solver(),model_->normalSolver(),false);
922  return infeasibility(model_->solver(),&info,preferredWay);
923}
924
925// This looks at solution and sets bounds to contain solution
926/** More precisely: it first forces the variable within the existing
927    bounds, and then tightens the bounds to fix the variable at the
928    nearest integer value.
929*/
930void 
931CbcSimpleInteger::feasibleRegion()
932{
933  abort();
934}
935CbcBranchingObject * 
936CbcSimpleInteger::createBranch( int way) 
937{
938  abort();
939  return NULL;
940}
941// Default Constructor
942CbcIntegerBranchingObject::CbcIntegerBranchingObject()
943  :CbcBranchingObject()
944{
945  down_[0] = 0.0;
946  down_[1] = 0.0;
947  up_[0] = 0.0;
948  up_[1] = 0.0;
949#ifdef FUNNY_BRANCHING
950  variables_ = NULL;
951  newBounds_ = NULL;
952  numberExtraChangedBounds_ = 0;
953#endif
954}
955// Useful constructor
956CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
957                                                      int variable, int way , double value)
958  :CbcBranchingObject(model,variable,way,value)
959{
960  int iColumn = variable;
961  assert (model_->solver()->getNumCols()>0);
962  down_[0] = model_->solver()->getColLower()[iColumn];
963  down_[1] = floor(value_);
964  up_[0] = ceil(value_);
965  up_[1] = model->getColUpper()[iColumn];
966#ifdef FUNNY_BRANCHING
967  variables_ = NULL;
968  newBounds_ = NULL;
969  numberExtraChangedBounds_ = 0;
970#endif
971}
972// Does part of constructor
973void 
974CbcIntegerBranchingObject::fillPart (int variable,
975                                 int way , double value) 
976{
977  //originalObject_=NULL;
978  branchIndex_=0;
979  value_=value;
980  numberBranches_=2;
981  //model_= model;
982  //originalCbcObject_=NULL;
983  variable_=variable;
984  way_=way;
985  int iColumn = variable;
986  down_[0] = model_->solver()->getColLower()[iColumn];
987  down_[1] = floor(value_);
988  up_[0] = ceil(value_);
989  up_[1] = model_->getColUpper()[iColumn];
990}
991// Useful constructor for fixing
992CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
993                                                      int variable, int way,
994                                                      double lowerValue, 
995                                                      double upperValue)
996  :CbcBranchingObject(model,variable,way,lowerValue)
997{
998  setNumberBranchesLeft(1);
999  down_[0] = lowerValue;
1000  down_[1] = upperValue;
1001  up_[0] = lowerValue;
1002  up_[1] = upperValue;
1003#ifdef FUNNY_BRANCHING
1004  variables_ = NULL;
1005  newBounds_ = NULL;
1006  numberExtraChangedBounds_ = 0;
1007#endif
1008}
1009 
1010
1011// Copy constructor
1012CbcIntegerBranchingObject::CbcIntegerBranchingObject ( const CbcIntegerBranchingObject & rhs) :CbcBranchingObject(rhs)
1013{
1014  down_[0] = rhs.down_[0];
1015  down_[1] = rhs.down_[1];
1016  up_[0] = rhs.up_[0];
1017  up_[1] = rhs.up_[1];
1018#ifdef FUNNY_BRANCHING
1019  numberExtraChangedBounds_ = rhs.numberExtraChangedBounds_;
1020  int size = numberExtraChangedBounds_*(sizeof(double)+sizeof(int));
1021  char * temp = new char [size];
1022  newBounds_ = (double *) temp;
1023  variables_ = (int *) (newBounds_+numberExtraChangedBounds_);
1024
1025  int i ;
1026  for (i=0;i<numberExtraChangedBounds_;i++) {
1027    variables_[i]=rhs.variables_[i];
1028    newBounds_[i]=rhs.newBounds_[i];
1029  }
1030#endif
1031}
1032
1033// Assignment operator
1034CbcIntegerBranchingObject & 
1035CbcIntegerBranchingObject::operator=( const CbcIntegerBranchingObject& rhs)
1036{
1037  if (this != &rhs) {
1038    CbcBranchingObject::operator=(rhs);
1039    down_[0] = rhs.down_[0];
1040    down_[1] = rhs.down_[1];
1041    up_[0] = rhs.up_[0];
1042    up_[1] = rhs.up_[1];
1043#ifdef FUNNY_BRANCHING
1044    delete [] newBounds_;
1045    numberExtraChangedBounds_ = rhs.numberExtraChangedBounds_;
1046    int size = numberExtraChangedBounds_*(sizeof(double)+sizeof(int));
1047    char * temp = new char [size];
1048    newBounds_ = (double *) temp;
1049    variables_ = (int *) (newBounds_+numberExtraChangedBounds_);
1050   
1051    int i ;
1052    for (i=0;i<numberExtraChangedBounds_;i++) {
1053      variables_[i]=rhs.variables_[i];
1054      newBounds_[i]=rhs.newBounds_[i];
1055    }
1056#endif
1057  }
1058  return *this;
1059}
1060CbcBranchingObject * 
1061CbcIntegerBranchingObject::clone() const
1062{ 
1063  return (new CbcIntegerBranchingObject(*this));
1064}
1065
1066
1067// Destructor
1068CbcIntegerBranchingObject::~CbcIntegerBranchingObject ()
1069{
1070  // for debugging threads
1071  way_=-23456789;
1072#ifdef FUNNY_BRANCHING
1073  delete [] newBounds_;
1074#endif
1075}
1076
1077/*
1078  Perform a branch by adjusting the bounds of the specified variable. Note
1079  that each arm of the branch advances the object to the next arm by
1080  advancing the value of way_.
1081
1082  Providing new values for the variable's lower and upper bounds for each
1083  branching direction gives a little bit of additional flexibility and will
1084  be easily extensible to multi-way branching.
1085  Returns change in guessed objective on next branch
1086*/
1087double
1088CbcIntegerBranchingObject::branch()
1089{
1090  // for debugging threads
1091  if (way_<-1||way_>100000) {
1092    printf("way %d, left %d, iCol %d, variable %d\n",
1093           way_,numberBranchesLeft(),
1094           originalCbcObject_->columnNumber(),variable_);
1095    assert (way_!=-23456789);
1096  }
1097  decrementNumberBranchesLeft();
1098  if (down_[1]==-COIN_DBL_MAX)
1099    return 0.0;
1100  int iColumn = originalCbcObject_->columnNumber();
1101  assert (variable_==iColumn);
1102  double olb,oub ;
1103  olb = model_->solver()->getColLower()[iColumn] ;
1104  oub = model_->solver()->getColUpper()[iColumn] ;
1105#ifdef COIN_DEVELOP
1106  if (olb!=down_[0]||oub!=up_[1]) {
1107    if (way_>0)
1108      printf("branching up on var %d: [%g,%g] => [%g,%g] - other [%g,%g]\n",
1109             iColumn,olb,oub,up_[0],up_[1],down_[0],down_[1]) ; 
1110    else
1111      printf("branching down on var %d: [%g,%g] => [%g,%g] - other [%g,%g]\n",
1112             iColumn,olb,oub,down_[0],down_[1],up_[0],up_[1]) ; 
1113  }
1114#endif
1115  if (way_<0) {
1116#ifdef CBC_DEBUG
1117  { double olb,oub ;
1118    olb = model_->solver()->getColLower()[iColumn] ;
1119    oub = model_->solver()->getColUpper()[iColumn] ;
1120    printf("branching down on var %d: [%g,%g] => [%g,%g]\n",
1121           iColumn,olb,oub,down_[0],down_[1]) ; }
1122#endif
1123    model_->solver()->setColLower(iColumn,down_[0]);
1124    model_->solver()->setColUpper(iColumn,down_[1]);
1125    //#define CBC_PRINT2
1126#ifdef CBC_PRINT2
1127    printf("%d branching down has bounds %g %g",iColumn,down_[0],down_[1]);
1128#endif
1129#ifdef FUNNY_BRANCHING
1130    // branch - do extra bounds
1131    for (int i=0;i<numberExtraChangedBounds_;i++) {
1132      int variable = variables_[i];
1133      if ((variable&0x40000000)!=0) {
1134        // for going down
1135        int k = variable&0x3fffffff;
1136        assert (k!=iColumn);
1137        if ((variable&0x80000000)==0) {
1138          // lower bound changing
1139#ifdef CBC_PRINT2
1140          printf(" extra for %d changes lower from %g to %g",
1141                 k,model_->solver()->getColLower()[k],newBounds_[i]);
1142#endif
1143          model_->solver()->setColLower(k,newBounds_[i]);
1144        } else {
1145          // upper bound changing
1146#ifdef CBC_PRINT2
1147          printf(" extra for %d changes upper from %g to %g",
1148                 k,model_->solver()->getColUpper()[k],newBounds_[i]);
1149#endif
1150          model_->solver()->setColUpper(k,newBounds_[i]);
1151        }
1152      }
1153    }
1154#endif
1155#ifdef CBC_PRINT2
1156    printf("\n");
1157#endif
1158    way_=1;
1159  } else {
1160#ifdef CBC_DEBUG
1161  { double olb,oub ;
1162    olb = model_->solver()->getColLower()[iColumn] ;
1163    oub = model_->solver()->getColUpper()[iColumn] ;
1164    printf("branching up on var %d: [%g,%g] => [%g,%g]\n",
1165           iColumn,olb,oub,up_[0],up_[1]) ; }
1166#endif
1167    model_->solver()->setColLower(iColumn,up_[0]);
1168    model_->solver()->setColUpper(iColumn,up_[1]);
1169#ifdef CBC_PRINT2
1170    printf("%d branching up has bounds %g %g",iColumn,up_[0],up_[1]);
1171#endif
1172#ifdef FUNNY_BRANCHING
1173    // branch - do extra bounds
1174    for (int i=0;i<numberExtraChangedBounds_;i++) {
1175      int variable = variables_[i];
1176      if ((variable&0x40000000)==0) {
1177        // for going up
1178        int k = variable&0x3fffffff;
1179        assert (k!=iColumn);
1180        if ((variable&0x80000000)==0) {
1181          // lower bound changing
1182#ifdef CBC_PRINT2
1183          printf(" extra for %d changes lower from %g to %g",
1184                 k,model_->solver()->getColLower()[k],newBounds_[i]);
1185#endif
1186          model_->solver()->setColLower(k,newBounds_[i]);
1187        } else {
1188          // upper bound changing
1189#ifdef CBC_PRINT2
1190          printf(" extra for %d changes upper from %g to %g",
1191                 k,model_->solver()->getColUpper()[k],newBounds_[i]);
1192#endif
1193          model_->solver()->setColUpper(k,newBounds_[i]);
1194        }
1195      }
1196    }
1197#endif
1198#ifdef CBC_PRINT2
1199    printf("\n");
1200#endif
1201    way_=-1;      // Swap direction
1202  }
1203  double nlb = model_->solver()->getColLower()[iColumn];
1204  double nub = model_->solver()->getColUpper()[iColumn];
1205  if (nlb<olb) {
1206#ifndef NDEBUG
1207    printf("bad lb change for column %d from %g to %g\n",iColumn,olb,nlb);
1208#endif
1209    model_->solver()->setColLower(iColumn,CoinMin(olb,nub));
1210    nlb=olb;
1211  }
1212  if (nub>oub) {
1213#ifndef NDEBUG
1214    printf("bad ub change for column %d from %g to %g\n",iColumn,oub,nub);
1215#endif
1216    model_->solver()->setColUpper(iColumn,CoinMax(oub,nlb));
1217  }
1218#ifndef NDEBUG
1219  if (nlb<olb+1.0e-8&&nub>oub-1.0e-8&&false)
1220    printf("bad null change for column %d - bounds %g,%g\n",iColumn,olb,oub);
1221#endif
1222  return 0.0;
1223}
1224#ifdef FUNNY_BRANCHING
1225// Deactivate bounds for branching
1226void 
1227CbcIntegerBranchingObject::deactivate()
1228{
1229  down_[1]=-COIN_DBL_MAX;
1230}
1231int
1232CbcIntegerBranchingObject::applyExtraBounds(int iColumn, double lower, double upper, int way)
1233{
1234  // branch - do bounds
1235
1236  int i;
1237  int found=0;
1238  if (variable_==iColumn) {
1239    printf("odd applyExtra %d\n",iColumn);
1240    if (way<0) {
1241      down_[0]=CoinMax(lower,down_[0]);
1242      down_[1]=CoinMin(upper,down_[1]);
1243      assert (down_[0]<=down_[1]);
1244    } else {
1245      up_[0]=CoinMax(lower,up_[0]);
1246      up_[1]=CoinMin(upper,up_[1]);
1247      assert (up_[0]<=up_[1]);
1248    }
1249    return 0;
1250  }
1251  int check = (way<0) ? 0x40000000 : 0;
1252  double newLower=lower;
1253  double newUpper=upper;
1254  for (i=0;i<numberExtraChangedBounds_;i++) {
1255    int variable = variables_[i];
1256    if ((variable&0x40000000)==check) {
1257      int k = variable&0x3fffffff;
1258      if (k==iColumn) {
1259        if ((variable&0x80000000)==0) {
1260          // lower bound changing
1261          found |= 1;
1262          newBounds_[i] = CoinMax(lower,newBounds_[i]);
1263          newLower = newBounds_[i];
1264        } else {
1265          // upper bound changing
1266          found |= 2;
1267          newBounds_[i] = CoinMin(upper,newBounds_[i]);
1268          newUpper = newBounds_[i];
1269        }
1270      }
1271    }
1272  }
1273  int nAdd=0;
1274  if ((found&2)==0) {
1275    // need to add new upper
1276    nAdd++;
1277  }
1278  if ((found&1)==0) {
1279    // need to add new lower
1280    nAdd++;
1281  }
1282  if (nAdd) { 
1283    int size = (numberExtraChangedBounds_+nAdd)*(sizeof(double)+sizeof(int));
1284    char * temp = new char [size];
1285    double * newBounds = (double *) temp;
1286    int * variables = (int *) (newBounds+numberExtraChangedBounds_+nAdd);
1287
1288    int i ;
1289    for (i=0;i<numberExtraChangedBounds_;i++) {
1290      variables[i]=variables_[i];
1291      newBounds[i]=newBounds_[i];
1292    }
1293    delete [] newBounds_;
1294    newBounds_ = newBounds;
1295    variables_ = variables;
1296    if ((found&2)==0) {
1297      // need to add new upper
1298      int variable = iColumn | 0x80000000;
1299      variables_[numberExtraChangedBounds_]=variable;
1300      newBounds_[numberExtraChangedBounds_++]=newUpper;
1301    }
1302    if ((found&1)==0) {
1303      // need to add new lower
1304      int variable = iColumn;
1305      variables_[numberExtraChangedBounds_]=variable;
1306      newBounds_[numberExtraChangedBounds_++]=newLower;
1307    }
1308  }
1309 
1310  return (newUpper>=newLower) ? 0 : 1;
1311}
1312#endif
1313// Print what would happen 
1314void
1315CbcIntegerBranchingObject::print()
1316{
1317  int iColumn = originalCbcObject_->columnNumber();
1318  assert (variable_==iColumn);
1319  if (way_<0) {
1320  { double olb,oub ;
1321    olb = model_->solver()->getColLower()[iColumn] ;
1322    oub = model_->solver()->getColUpper()[iColumn] ;
1323    printf("CbcInteger would branch down on var %d (int var %d): [%g,%g] => [%g,%g]\n",
1324           iColumn,variable_,olb,oub,down_[0],down_[1]) ; }
1325  } else {
1326  { double olb,oub ;
1327    olb = model_->solver()->getColLower()[iColumn] ;
1328    oub = model_->solver()->getColUpper()[iColumn] ;
1329    printf("CbcInteger would branch up on var %d (int var %d): [%g,%g] => [%g,%g]\n",
1330           iColumn,variable_,olb,oub,up_[0],up_[1]) ; }
1331  }
1332}
1333
1334
1335/** Default Constructor
1336
1337  Equivalent to an unspecified binary variable.
1338*/
1339CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ()
1340  : CbcSimpleInteger(),
1341    downPseudoCost_(1.0e-5),
1342    upPseudoCost_(1.0e-5),
1343    upDownSeparator_(-1.0),
1344    method_(0)
1345{
1346}
1347
1348/** Useful constructor
1349
1350  Loads actual upper & lower bounds for the specified variable.
1351*/
1352CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model,
1353                                    int iColumn, double breakEven)
1354  : CbcSimpleInteger(model,iColumn,breakEven)
1355{
1356  const double * cost = model->getObjCoefficients();
1357  double costValue = CoinMax(1.0e-5,fabs(cost[iColumn]));
1358  // treat as if will cost what it says up
1359  upPseudoCost_=costValue;
1360  // and balance at breakeven
1361  downPseudoCost_=((1.0-breakEven_)*upPseudoCost_)/breakEven_;
1362  upDownSeparator_ = -1.0;
1363  method_=0;
1364}
1365
1366/** Useful constructor
1367
1368  Loads actual upper & lower bounds for the specified variable.
1369*/
1370CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model,
1371                                    int iColumn, double downPseudoCost,
1372                                                        double upPseudoCost)
1373  : CbcSimpleInteger(model,iColumn)
1374{
1375  downPseudoCost_ = CoinMax(1.0e-10,downPseudoCost);
1376  upPseudoCost_ = CoinMax(1.0e-10,upPseudoCost);
1377  breakEven_ = upPseudoCost_/(upPseudoCost_+downPseudoCost_);
1378  upDownSeparator_ = -1.0;
1379  method_=0;
1380}
1381// Useful constructor - passed and model index and pseudo costs
1382CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, int dummy,int iColumn, 
1383                                                        double downPseudoCost, double upPseudoCost)
1384{
1385  *this=CbcSimpleIntegerPseudoCost(model,iColumn,downPseudoCost,upPseudoCost);
1386  columnNumber_=iColumn;
1387}
1388
1389// Copy constructor
1390CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ( const CbcSimpleIntegerPseudoCost & rhs)
1391  :CbcSimpleInteger(rhs),
1392   downPseudoCost_(rhs.downPseudoCost_),
1393   upPseudoCost_(rhs.upPseudoCost_),
1394   upDownSeparator_(rhs.upDownSeparator_),
1395   method_(rhs.method_)
1396
1397{
1398}
1399
1400// Clone
1401CbcObject *
1402CbcSimpleIntegerPseudoCost::clone() const
1403{
1404  return new CbcSimpleIntegerPseudoCost(*this);
1405}
1406
1407// Assignment operator
1408CbcSimpleIntegerPseudoCost & 
1409CbcSimpleIntegerPseudoCost::operator=( const CbcSimpleIntegerPseudoCost& rhs)
1410{
1411  if (this!=&rhs) {
1412    CbcSimpleInteger::operator=(rhs);
1413    downPseudoCost_=rhs.downPseudoCost_;
1414    upPseudoCost_=rhs.upPseudoCost_;
1415    upDownSeparator_=rhs.upDownSeparator_;
1416    method_=rhs.method_;
1417  }
1418  return *this;
1419}
1420
1421// Destructor
1422CbcSimpleIntegerPseudoCost::~CbcSimpleIntegerPseudoCost ()
1423{
1424}
1425// Creates a branching object
1426CbcBranchingObject * 
1427CbcSimpleIntegerPseudoCost::createBranch(int way) 
1428{
1429  OsiSolverInterface * solver = model_->solver();
1430  const double * solution = model_->testSolution();
1431  const double * lower = solver->getColLower();
1432  const double * upper = solver->getColUpper();
1433  double value = solution[columnNumber_];
1434  value = CoinMax(value, lower[columnNumber_]);
1435  value = CoinMin(value, upper[columnNumber_]);
1436#ifndef NDEBUG
1437  double nearest = floor(value+0.5);
1438  double integerTolerance = 
1439    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1440  assert (upper[columnNumber_]>lower[columnNumber_]);
1441#endif
1442  if (!model_->hotstartSolution()) {
1443    assert (fabs(value-nearest)>integerTolerance);
1444  } else {
1445    const double * hotstartSolution = model_->hotstartSolution();
1446    double targetValue = hotstartSolution[columnNumber_];
1447    if (way>0)
1448      value = targetValue-0.1;
1449    else
1450      value = targetValue+0.1;
1451  }
1452  CbcIntegerPseudoCostBranchingObject * newObject = 
1453    new CbcIntegerPseudoCostBranchingObject(model_,columnNumber_,way,
1454                                            value);
1455  double up =  upPseudoCost_*(ceil(value)-value);
1456  double down =  downPseudoCost_*(value-floor(value));
1457  double changeInGuessed=up-down;
1458  if (way>0)
1459    changeInGuessed = - changeInGuessed;
1460  changeInGuessed=CoinMax(0.0,changeInGuessed);
1461  //if (way>0)
1462  //changeInGuessed += 1.0e8; // bias to stay up
1463  newObject->setChangeInGuessed(changeInGuessed);
1464  newObject->setOriginalObject(this);
1465  return newObject;
1466}
1467// Infeasibility - large is 0.5
1468double 
1469CbcSimpleIntegerPseudoCost::infeasibility(int & preferredWay) const
1470{
1471  OsiSolverInterface * solver = model_->solver();
1472  const double * solution = model_->testSolution();
1473  const double * lower = solver->getColLower();
1474  const double * upper = solver->getColUpper();
1475  if (upper[columnNumber_]==lower[columnNumber_]) {
1476    // fixed
1477    preferredWay=1;
1478    return 0.0;
1479  }
1480  double value = solution[columnNumber_];
1481  value = CoinMax(value, lower[columnNumber_]);
1482  value = CoinMin(value, upper[columnNumber_]);
1483  /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
1484    solution[columnNumber_],upper[columnNumber_]);*/
1485  double nearest = floor(value+0.5);
1486  double integerTolerance = 
1487    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1488  double below = floor(value+integerTolerance);
1489  double above = below+1.0;
1490  if (above>upper[columnNumber_]) {
1491    above=below;
1492    below = above -1;
1493  }
1494  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1495  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1496  if (downCost>=upCost)
1497    preferredWay=1;
1498  else
1499    preferredWay=-1;
1500  // See if up down choice set
1501  if (upDownSeparator_>0.0) {
1502    preferredWay = (value-below>=upDownSeparator_) ? 1 : -1;
1503  }
1504  if (preferredWay_)
1505    preferredWay=preferredWay_;
1506  if (fabs(value-nearest)<=integerTolerance) {
1507    return 0.0;
1508  } else {
1509    // can't get at model so 1,2 don't make sense
1510    assert(method_<1||method_>2);
1511    if (!method_)
1512      return CoinMin(downCost,upCost);
1513    else
1514      return CoinMax(downCost,upCost);
1515  }
1516}
1517
1518// Return "up" estimate
1519double 
1520CbcSimpleIntegerPseudoCost::upEstimate() const
1521{
1522  OsiSolverInterface * solver = model_->solver();
1523  const double * solution = model_->testSolution();
1524  const double * lower = solver->getColLower();
1525  const double * upper = solver->getColUpper();
1526  double value = solution[columnNumber_];
1527  value = CoinMax(value, lower[columnNumber_]);
1528  value = CoinMin(value, upper[columnNumber_]);
1529  if (upper[columnNumber_]==lower[columnNumber_]) {
1530    // fixed
1531    return 0.0;
1532  }
1533  double integerTolerance = 
1534    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1535  double below = floor(value+integerTolerance);
1536  double above = below+1.0;
1537  if (above>upper[columnNumber_]) {
1538    above=below;
1539    below = above -1;
1540  }
1541  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1542  return upCost;
1543}
1544// Return "down" estimate
1545double 
1546CbcSimpleIntegerPseudoCost::downEstimate() const
1547{
1548  OsiSolverInterface * solver = model_->solver();
1549  const double * solution = model_->testSolution();
1550  const double * lower = solver->getColLower();
1551  const double * upper = solver->getColUpper();
1552  double value = solution[columnNumber_];
1553  value = CoinMax(value, lower[columnNumber_]);
1554  value = CoinMin(value, upper[columnNumber_]);
1555  if (upper[columnNumber_]==lower[columnNumber_]) {
1556    // fixed
1557    return 0.0;
1558  }
1559  double integerTolerance = 
1560    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1561  double below = floor(value+integerTolerance);
1562  double above = below+1.0;
1563  if (above>upper[columnNumber_]) {
1564    above=below;
1565    below = above -1;
1566  }
1567  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1568  return downCost;
1569}
1570
1571// Default Constructor
1572CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject()
1573  :CbcIntegerBranchingObject()
1574{
1575  changeInGuessed_=1.0e-5;
1576}
1577
1578// Useful constructor
1579CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1580                                                      int variable, int way , double value)
1581  :CbcIntegerBranchingObject(model,variable,way,value)
1582{
1583}
1584// Useful constructor for fixing
1585CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1586                                                      int variable, int way,
1587                                                      double lowerValue, 
1588                                                      double upperValue)
1589  :CbcIntegerBranchingObject(model,variable,way,lowerValue)
1590{
1591  changeInGuessed_=1.0e100;
1592}
1593 
1594
1595// Copy constructor
1596CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject ( 
1597                                 const CbcIntegerPseudoCostBranchingObject & rhs)
1598  :CbcIntegerBranchingObject(rhs)
1599{
1600  changeInGuessed_ = rhs.changeInGuessed_;
1601}
1602
1603// Assignment operator
1604CbcIntegerPseudoCostBranchingObject & 
1605CbcIntegerPseudoCostBranchingObject::operator=( const CbcIntegerPseudoCostBranchingObject& rhs)
1606{
1607  if (this != &rhs) {
1608    CbcIntegerBranchingObject::operator=(rhs);
1609    changeInGuessed_ = rhs.changeInGuessed_;
1610  }
1611  return *this;
1612}
1613CbcBranchingObject * 
1614CbcIntegerPseudoCostBranchingObject::clone() const
1615{ 
1616  return (new CbcIntegerPseudoCostBranchingObject(*this));
1617}
1618
1619
1620// Destructor
1621CbcIntegerPseudoCostBranchingObject::~CbcIntegerPseudoCostBranchingObject ()
1622{
1623}
1624
1625/*
1626  Perform a branch by adjusting the bounds of the specified variable. Note
1627  that each arm of the branch advances the object to the next arm by
1628  advancing the value of way_.
1629
1630  Providing new values for the variable's lower and upper bounds for each
1631  branching direction gives a little bit of additional flexibility and will
1632  be easily extensible to multi-way branching.
1633  Returns change in guessed objective on next branch
1634*/
1635double
1636CbcIntegerPseudoCostBranchingObject::branch()
1637{
1638  CbcIntegerBranchingObject::branch();
1639  return changeInGuessed_;
1640}
1641
1642
1643// Default Constructor
1644CbcCliqueBranchingObject::CbcCliqueBranchingObject()
1645  :CbcBranchingObject()
1646{
1647  clique_ = NULL;
1648  downMask_[0]=0;
1649  downMask_[1]=0;
1650  upMask_[0]=0;
1651  upMask_[1]=0;
1652}
1653
1654// Useful constructor
1655CbcCliqueBranchingObject::CbcCliqueBranchingObject (CbcModel * model,
1656                                                    const CbcClique * clique,
1657                                                    int way ,
1658                                                    int numberOnDownSide, const int * down,
1659                                                    int numberOnUpSide, const int * up)
1660  :CbcBranchingObject(model,clique->id(),way,0.5)
1661{
1662  clique_ = clique;
1663  downMask_[0]=0;
1664  downMask_[1]=0;
1665  upMask_[0]=0;
1666  upMask_[1]=0;
1667  int i;
1668  for (i=0;i<numberOnDownSide;i++) {
1669    int sequence = down[i];
1670    int iWord = sequence>>5;
1671    int iBit = sequence - 32*iWord;
1672    unsigned int k = 1<<iBit;
1673    downMask_[iWord] |= k;
1674  }
1675  for (i=0;i<numberOnUpSide;i++) {
1676    int sequence = up[i];
1677    int iWord = sequence>>5;
1678    int iBit = sequence - 32*iWord;
1679    unsigned int k = 1<<iBit;
1680    upMask_[iWord] |= k;
1681  }
1682}
1683
1684// Copy constructor
1685CbcCliqueBranchingObject::CbcCliqueBranchingObject ( const CbcCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
1686{
1687  clique_=rhs.clique_;
1688  downMask_[0]=rhs.downMask_[0];
1689  downMask_[1]=rhs.downMask_[1];
1690  upMask_[0]=rhs.upMask_[0];
1691  upMask_[1]=rhs.upMask_[1];
1692}
1693
1694// Assignment operator
1695CbcCliqueBranchingObject & 
1696CbcCliqueBranchingObject::operator=( const CbcCliqueBranchingObject& rhs)
1697{
1698  if (this != &rhs) {
1699    CbcBranchingObject::operator=(rhs);
1700    clique_=rhs.clique_;
1701    downMask_[0]=rhs.downMask_[0];
1702    downMask_[1]=rhs.downMask_[1];
1703    upMask_[0]=rhs.upMask_[0];
1704    upMask_[1]=rhs.upMask_[1];
1705  }
1706  return *this;
1707}
1708CbcBranchingObject * 
1709CbcCliqueBranchingObject::clone() const
1710{ 
1711  return (new CbcCliqueBranchingObject(*this));
1712}
1713
1714
1715// Destructor
1716CbcCliqueBranchingObject::~CbcCliqueBranchingObject ()
1717{
1718}
1719double
1720CbcCliqueBranchingObject::branch()
1721{
1722  decrementNumberBranchesLeft();
1723  int iWord;
1724  int numberMembers = clique_->numberMembers();
1725  const int * which = clique_->members();
1726  const int * integerVariables = model_->integerVariable();
1727  int numberWords=(numberMembers+31)>>5;
1728  // *** for way - up means fix all those in down section
1729  if (way_<0) {
1730#ifdef FULL_PRINT
1731    printf("Down Fix ");
1732#endif
1733    for (iWord=0;iWord<numberWords;iWord++) {
1734      int i;
1735      for (i=0;i<32;i++) {
1736        unsigned int k = 1<<i;
1737        if ((upMask_[iWord]&k)!=0) {
1738          int iColumn = which[i+32*iWord];
1739#ifdef FULL_PRINT
1740          printf("%d ",i+32*iWord);
1741#endif
1742          // fix weak way
1743          if (clique_->type(i+32*iWord))
1744            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1745          else
1746            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1747        }
1748      }
1749    }
1750    way_=1;       // Swap direction
1751  } else {
1752#ifdef FULL_PRINT
1753    printf("Up Fix ");
1754#endif
1755    for (iWord=0;iWord<numberWords;iWord++) {
1756      int i;
1757      for (i=0;i<32;i++) {
1758        unsigned int k = 1<<i;
1759        if ((downMask_[iWord]&k)!=0) {
1760          int iColumn = which[i+32*iWord];
1761#ifdef FULL_PRINT
1762          printf("%d ",i+32*iWord);
1763#endif
1764          // fix weak way
1765          if (clique_->type(i+32*iWord))
1766            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1767          else
1768            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1769        }
1770      }
1771    }
1772    way_=-1;      // Swap direction
1773  }
1774#ifdef FULL_PRINT
1775  printf("\n");
1776#endif
1777  return 0.0;
1778}
1779// Print what would happen 
1780void
1781CbcCliqueBranchingObject::print()
1782{
1783  int iWord;
1784  int numberMembers = clique_->numberMembers();
1785  const int * which = clique_->members();
1786  const int * integerVariables = model_->integerVariable();
1787  int numberWords=(numberMembers+31)>>5;
1788  // *** for way - up means fix all those in down section
1789  if (way_<0) {
1790    printf("Clique - Down Fix ");
1791    for (iWord=0;iWord<numberWords;iWord++) {
1792      int i;
1793      for (i=0;i<32;i++) {
1794        unsigned int k = 1<<i;
1795        if ((upMask_[iWord]&k)!=0) {
1796          int iColumn = which[i+32*iWord];
1797          printf("%d ",integerVariables[iColumn]);
1798        }
1799      }
1800    }
1801  } else {
1802    printf("Clique - Up Fix ");
1803    for (iWord=0;iWord<numberWords;iWord++) {
1804      int i;
1805      for (i=0;i<32;i++) {
1806        unsigned int k = 1<<i;
1807        if ((downMask_[iWord]&k)!=0) {
1808          int iColumn = which[i+32*iWord];
1809          printf("%d ",integerVariables[iColumn]);
1810        }
1811      }
1812    }
1813  }
1814  printf("\n");
1815}
1816 
1817// Default Constructor
1818CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject()
1819  :CbcBranchingObject()
1820{
1821  clique_=NULL;
1822  downMask_=NULL;
1823  upMask_=NULL;
1824}
1825
1826// Useful constructor
1827CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject (CbcModel * model,
1828                                                            const CbcClique * clique, 
1829                                                            int way ,
1830                                                    int numberOnDownSide, const int * down,
1831                                                    int numberOnUpSide, const int * up)
1832  :CbcBranchingObject(model,clique->id(),way,0.5)
1833{
1834  clique_ = clique;
1835  int numberMembers = clique_->numberMembers();
1836  int numberWords=(numberMembers+31)>>5;
1837  downMask_ = new unsigned int [numberWords];
1838  upMask_ = new unsigned int [numberWords];
1839  memset(downMask_,0,numberWords*sizeof(unsigned int));
1840  memset(upMask_,0,numberWords*sizeof(unsigned int));
1841  int i;
1842  for (i=0;i<numberOnDownSide;i++) {
1843    int sequence = down[i];
1844    int iWord = sequence>>5;
1845    int iBit = sequence - 32*iWord;
1846    unsigned int k = 1<<iBit;
1847    downMask_[iWord] |= k;
1848  }
1849  for (i=0;i<numberOnUpSide;i++) {
1850    int sequence = up[i];
1851    int iWord = sequence>>5;
1852    int iBit = sequence - 32*iWord;
1853    unsigned int k = 1<<iBit;
1854    upMask_[iWord] |= k;
1855  }
1856}
1857
1858// Copy constructor
1859CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject ( const CbcLongCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
1860{
1861  clique_=rhs.clique_;
1862  if (rhs.downMask_) {
1863    int numberMembers = clique_->numberMembers();
1864    int numberWords=(numberMembers+31)>>5;
1865    downMask_ = new unsigned int [numberWords];
1866    memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
1867    upMask_ = new unsigned int [numberWords];
1868    memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
1869  } else {
1870    downMask_=NULL;
1871    upMask_=NULL;
1872  }   
1873}
1874
1875// Assignment operator
1876CbcLongCliqueBranchingObject & 
1877CbcLongCliqueBranchingObject::operator=( const CbcLongCliqueBranchingObject& rhs)
1878{
1879  if (this != &rhs) {
1880    CbcBranchingObject::operator=(rhs);
1881    clique_=rhs.clique_;
1882    delete [] downMask_;
1883    delete [] upMask_;
1884    if (rhs.downMask_) {
1885      int numberMembers = clique_->numberMembers();
1886      int numberWords=(numberMembers+31)>>5;
1887      downMask_ = new unsigned int [numberWords];
1888      memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
1889      upMask_ = new unsigned int [numberWords];
1890      memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
1891    } else {
1892      downMask_=NULL;
1893      upMask_=NULL;
1894    }   
1895  }
1896  return *this;
1897}
1898CbcBranchingObject * 
1899CbcLongCliqueBranchingObject::clone() const
1900{ 
1901  return (new CbcLongCliqueBranchingObject(*this));
1902}
1903
1904
1905// Destructor
1906CbcLongCliqueBranchingObject::~CbcLongCliqueBranchingObject ()
1907{
1908  delete [] downMask_;
1909  delete [] upMask_;
1910}
1911double
1912CbcLongCliqueBranchingObject::branch()
1913{
1914  decrementNumberBranchesLeft();
1915  int iWord;
1916  int numberMembers = clique_->numberMembers();
1917  const int * which = clique_->members();
1918  const int * integerVariables = model_->integerVariable();
1919  int numberWords=(numberMembers+31)>>5;
1920  // *** for way - up means fix all those in down section
1921  if (way_<0) {
1922#ifdef FULL_PRINT
1923    printf("Down Fix ");
1924#endif
1925    for (iWord=0;iWord<numberWords;iWord++) {
1926      int i;
1927      for (i=0;i<32;i++) {
1928        unsigned int k = 1<<i;
1929        if ((upMask_[iWord]&k)!=0) {
1930          int iColumn = which[i+32*iWord];
1931#ifdef FULL_PRINT
1932          printf("%d ",i+32*iWord);
1933#endif
1934          // fix weak way
1935          if (clique_->type(i+32*iWord))
1936            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1937          else
1938            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1939        }
1940      }
1941    }
1942    way_=1;       // Swap direction
1943  } else {
1944#ifdef FULL_PRINT
1945    printf("Up Fix ");
1946#endif
1947    for (iWord=0;iWord<numberWords;iWord++) {
1948      int i;
1949      for (i=0;i<32;i++) {
1950        unsigned int k = 1<<i;
1951        if ((downMask_[iWord]&k)!=0) {
1952          int iColumn = which[i+32*iWord];
1953#ifdef FULL_PRINT
1954          printf("%d ",i+32*iWord);
1955#endif
1956          // fix weak way
1957          if (clique_->type(i+32*iWord))
1958            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1959          else
1960            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1961        }
1962      }
1963    }
1964    way_=-1;      // Swap direction
1965  }
1966#ifdef FULL_PRINT
1967  printf("\n");
1968#endif
1969  return 0.0;
1970}
1971void
1972CbcLongCliqueBranchingObject::print()
1973{
1974  int iWord;
1975  int numberMembers = clique_->numberMembers();
1976  const int * which = clique_->members();
1977  const int * integerVariables = model_->integerVariable();
1978  int numberWords=(numberMembers+31)>>5;
1979  // *** for way - up means fix all those in down section
1980  if (way_<0) {
1981    printf("Clique - Down Fix ");
1982    for (iWord=0;iWord<numberWords;iWord++) {
1983      int i;
1984      for (i=0;i<32;i++) {
1985        unsigned int k = 1<<i;
1986        if ((upMask_[iWord]&k)!=0) {
1987          int iColumn = which[i+32*iWord];
1988          printf("%d ",integerVariables[iColumn]);
1989        }
1990      }
1991    }
1992  } else {
1993    printf("Clique - Up Fix ");
1994    for (iWord=0;iWord<numberWords;iWord++) {
1995      int i;
1996      for (i=0;i<32;i++) {
1997        unsigned int k = 1<<i;
1998        if ((downMask_[iWord]&k)!=0) {
1999          int iColumn = which[i+32*iWord];
2000          printf("%d ",integerVariables[iColumn]);
2001        }
2002      }
2003    }
2004  }
2005  printf("\n");
2006}
2007// Default Constructor
2008CbcSOSBranchingObject::CbcSOSBranchingObject()
2009  :CbcBranchingObject()
2010{
2011  set_ = NULL;
2012  separator_=0.0;
2013}
2014
2015// Useful constructor
2016CbcSOSBranchingObject::CbcSOSBranchingObject (CbcModel * model,
2017                                              const CbcSOS * set,
2018                                              int way ,
2019                                              double separator)
2020  :CbcBranchingObject(model,set->id(),way,0.5)
2021{
2022  set_ = set;
2023  separator_ = separator;
2024}
2025
2026// Copy constructor
2027CbcSOSBranchingObject::CbcSOSBranchingObject ( const CbcSOSBranchingObject & rhs) :CbcBranchingObject(rhs)
2028{
2029  set_=rhs.set_;
2030  separator_ = rhs.separator_;
2031}
2032
2033// Assignment operator
2034CbcSOSBranchingObject & 
2035CbcSOSBranchingObject::operator=( const CbcSOSBranchingObject& rhs)
2036{
2037  if (this != &rhs) {
2038    CbcBranchingObject::operator=(rhs);
2039    set_=rhs.set_;
2040    separator_ = rhs.separator_;
2041  }
2042  return *this;
2043}
2044CbcBranchingObject * 
2045CbcSOSBranchingObject::clone() const
2046{ 
2047  return (new CbcSOSBranchingObject(*this));
2048}
2049
2050
2051// Destructor
2052CbcSOSBranchingObject::~CbcSOSBranchingObject ()
2053{
2054}
2055double
2056CbcSOSBranchingObject::branch()
2057{
2058  decrementNumberBranchesLeft();
2059  int numberMembers = set_->numberMembers();
2060  const int * which = set_->members();
2061  const double * weights = set_->weights();
2062  OsiSolverInterface * solver = model_->solver();
2063  //const double * lower = solver->getColLower();
2064  //const double * upper = solver->getColUpper();
2065  // *** for way - up means fix all those in down section
2066  if (way_<0) {
2067    int i;
2068    for ( i=0;i<numberMembers;i++) {
2069      if (weights[i] > separator_)
2070        break;
2071    }
2072    assert (i<numberMembers);
2073    for (;i<numberMembers;i++) 
2074      solver->setColUpper(which[i],0.0);
2075    way_=1;       // Swap direction
2076  } else {
2077    int i;
2078    for ( i=0;i<numberMembers;i++) {
2079      if (weights[i] >= separator_)
2080        break;
2081      else
2082        solver->setColUpper(which[i],0.0);
2083    }
2084    assert (i<numberMembers);
2085    way_=-1;      // Swap direction
2086  }
2087  return 0.0;
2088}
2089// Print what would happen 
2090void
2091CbcSOSBranchingObject::print()
2092{
2093  int numberMembers = set_->numberMembers();
2094  const int * which = set_->members();
2095  const double * weights = set_->weights();
2096  OsiSolverInterface * solver = model_->solver();
2097  //const double * lower = solver->getColLower();
2098  const double * upper = solver->getColUpper();
2099  int first=numberMembers;
2100  int last=-1;
2101  int numberFixed=0;
2102  int numberOther=0;
2103  int i;
2104  for ( i=0;i<numberMembers;i++) {
2105    double bound = upper[which[i]];
2106    if (bound) {
2107      first = CoinMin(first,i);
2108      last = CoinMax(last,i);
2109    }
2110  }
2111  // *** for way - up means fix all those in down section
2112  if (way_<0) {
2113    printf("SOS Down");
2114    for ( i=0;i<numberMembers;i++) {
2115      double bound = upper[which[i]];
2116      if (weights[i] > separator_)
2117        break;
2118      else if (bound)
2119        numberOther++;
2120    }
2121    assert (i<numberMembers);
2122    for (;i<numberMembers;i++) {
2123      double bound = upper[which[i]];
2124      if (bound)
2125        numberFixed++;
2126    }
2127  } else {
2128    printf("SOS Up");
2129    for ( i=0;i<numberMembers;i++) {
2130      double bound = upper[which[i]];
2131      if (weights[i] >= separator_)
2132        break;
2133      else if (bound)
2134        numberFixed++;
2135    }
2136    assert (i<numberMembers);
2137    for (;i<numberMembers;i++) {
2138      double bound = upper[which[i]];
2139      if (bound)
2140        numberOther++;
2141    }
2142  }
2143  printf(" - at %g, free range %d (%g) => %d (%g), %d would be fixed, %d other way\n",
2144         separator_,which[first],weights[first],which[last],weights[last],numberFixed,numberOther);
2145}
2146 
2147// Default Constructor
2148CbcBranchDefaultDecision::CbcBranchDefaultDecision()
2149  :CbcBranchDecision()
2150{
2151  bestCriterion_ = 0.0;
2152  bestChangeUp_ = 0.0;
2153  bestNumberUp_ = 0;
2154  bestChangeDown_ = 0.0;
2155  bestObject_ = NULL;
2156  bestNumberDown_ = 0;
2157}
2158
2159// Copy constructor
2160CbcBranchDefaultDecision::CbcBranchDefaultDecision (
2161                                    const CbcBranchDefaultDecision & rhs)
2162  :CbcBranchDecision(rhs)
2163{
2164  bestCriterion_ = rhs.bestCriterion_;
2165  bestChangeUp_ = rhs.bestChangeUp_;
2166  bestNumberUp_ = rhs.bestNumberUp_;
2167  bestChangeDown_ = rhs.bestChangeDown_;
2168  bestNumberDown_ = rhs.bestNumberDown_;
2169  bestObject_ = rhs.bestObject_;
2170  model_ = rhs.model_;
2171}
2172
2173CbcBranchDefaultDecision::~CbcBranchDefaultDecision()
2174{
2175}
2176
2177// Clone
2178CbcBranchDecision * 
2179CbcBranchDefaultDecision::clone() const
2180{
2181  return new CbcBranchDefaultDecision(*this);
2182}
2183
2184// Initialize i.e. before start of choosing at a node
2185void 
2186CbcBranchDefaultDecision::initialize(CbcModel * model)
2187{
2188  bestCriterion_ = 0.0;
2189  bestChangeUp_ = 0.0;
2190  bestNumberUp_ = 0;
2191  bestChangeDown_ = 0.0;
2192  bestNumberDown_ = 0;
2193  bestObject_ = NULL;
2194  model_ = model;
2195}
2196
2197
2198/*
2199  Simple default decision algorithm. Compare based on infeasibility (numInfUp,
2200  numInfDn) until a solution is found by search, then switch to change in
2201  objective (changeUp, changeDn). Note that bestSoFar is remembered in
2202  bestObject_, so the parameter bestSoFar is unused.
2203*/
2204
2205int
2206CbcBranchDefaultDecision::betterBranch(CbcBranchingObject * thisOne,
2207                            CbcBranchingObject * bestSoFar,
2208                            double changeUp, int numInfUp,
2209                            double changeDn, int numInfDn)
2210{
2211  bool beforeSolution = cbcModel()->getSolutionCount()==
2212    cbcModel()->getNumberHeuristicSolutions();;
2213  int betterWay=0;
2214  if (beforeSolution) {
2215    if (!bestObject_) {
2216      bestNumberUp_=COIN_INT_MAX;
2217      bestNumberDown_=COIN_INT_MAX;
2218    }
2219    // before solution - choose smallest number
2220    // could add in depth as well
2221    int bestNumber = CoinMin(bestNumberUp_,bestNumberDown_);
2222    if (numInfUp<numInfDn) {
2223      if (numInfUp<bestNumber) {
2224        betterWay = 1;
2225      } else if (numInfUp==bestNumber) {
2226        if (changeUp<bestCriterion_)
2227          betterWay=1;
2228      }
2229    } else if (numInfUp>numInfDn) {
2230      if (numInfDn<bestNumber) {
2231        betterWay = -1;
2232      } else if (numInfDn==bestNumber) {
2233        if (changeDn<bestCriterion_)
2234          betterWay=-1;
2235      }
2236    } else {
2237      // up and down have same number
2238      bool better=false;
2239      if (numInfUp<bestNumber) {
2240        better=true;
2241      } else if (numInfUp==bestNumber) {
2242        if (min(changeUp,changeDn)<bestCriterion_)
2243          better=true;;
2244      }
2245      if (better) {
2246        // see which way
2247        if (changeUp<=changeDn)
2248          betterWay=1;
2249        else
2250          betterWay=-1;
2251      }
2252    }
2253  } else {
2254    if (!bestObject_) {
2255      bestCriterion_=-1.0;
2256    }
2257    // got a solution
2258    if (changeUp<=changeDn) {
2259      if (changeUp>bestCriterion_)
2260        betterWay=1;
2261    } else {
2262      if (changeDn>bestCriterion_)
2263        betterWay=-1;
2264    }
2265  }
2266  if (betterWay) {
2267    bestCriterion_ = CoinMin(changeUp,changeDn);
2268    bestChangeUp_ = changeUp;
2269    bestNumberUp_ = numInfUp;
2270    bestChangeDown_ = changeDn;
2271    bestNumberDown_ = numInfDn;
2272    bestObject_=thisOne;
2273    // See if user is overriding way
2274    if (thisOne->object()&&thisOne->object()->preferredWay())
2275      betterWay = thisOne->object()->preferredWay();
2276  }
2277  return betterWay;
2278}
2279/* Sets or gets best criterion so far */
2280void 
2281CbcBranchDefaultDecision::setBestCriterion(double value)
2282{ 
2283  bestCriterion_ = value;
2284}
2285double 
2286CbcBranchDefaultDecision::getBestCriterion() const
2287{ 
2288  return bestCriterion_;
2289}
2290
2291/* Compare N branching objects. Return index of best
2292   and sets way of branching in chosen object.
2293   
2294   This routine is used only after strong branching.
2295*/
2296
2297int
2298CbcBranchDefaultDecision::bestBranch (CbcBranchingObject ** objects, int numberObjects,
2299                                   int numberUnsatisfied,
2300                                   double * changeUp, int * numberInfeasibilitiesUp,
2301                                   double * changeDown, int * numberInfeasibilitiesDown,
2302                                   double objectiveValue) 
2303{
2304
2305  int bestWay=0;
2306  int whichObject = -1;
2307  if (numberObjects) {
2308    CbcModel * model = cbcModel();
2309    // at continuous
2310    //double continuousObjective = model->getContinuousObjective();
2311    //int continuousInfeasibilities = model->getContinuousInfeasibilities();
2312   
2313    // average cost to get rid of infeasibility
2314    //double averageCostPerInfeasibility =
2315    //(objectiveValue-continuousObjective)/
2316    //(double) (abs(continuousInfeasibilities-numberUnsatisfied)+1);
2317    /* beforeSolution is :
2318       0 - before any solution
2319       n - n heuristic solutions but no branched one
2320       -1 - branched solution found
2321    */
2322    int numberSolutions = model->getSolutionCount();
2323    double cutoff = model->getCutoff();
2324    int method=0;
2325    int i;
2326    if (numberSolutions) {
2327      int numberHeuristic = model->getNumberHeuristicSolutions();
2328      if (numberHeuristic<numberSolutions) {
2329        method = 1;
2330      } else {
2331        method = 2;
2332        // look further
2333        for ( i = 0 ; i < numberObjects ; i++) {
2334          int numberNext = numberInfeasibilitiesUp[i];
2335         
2336          if (numberNext<numberUnsatisfied) {
2337            int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
2338            double perUnsatisfied = changeUp[i]/(double) numberUp;
2339            double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
2340            if (estimatedObjective<cutoff) 
2341              method=3;
2342          }
2343          numberNext = numberInfeasibilitiesDown[i];
2344          if (numberNext<numberUnsatisfied) {
2345            int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
2346            double perUnsatisfied = changeDown[i]/(double) numberDown;
2347            double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
2348            if (estimatedObjective<cutoff) 
2349              method=3;
2350          }
2351        }
2352      }
2353      method=2;
2354    } else {
2355      method = 0;
2356    }
2357    // Uncomment next to force method 4
2358    //method=4;
2359    /* Methods :
2360       0 - fewest infeasibilities
2361       1 - largest min change in objective
2362       2 - as 1 but use sum of changes if min close
2363       3 - predicted best solution
2364       4 - take cheapest up branch if infeasibilities same
2365    */
2366    int bestNumber=COIN_INT_MAX;
2367    double bestCriterion=-1.0e50;
2368    double alternativeCriterion = -1.0;
2369    double bestEstimate = 1.0e100;
2370    switch (method) {
2371    case 0:
2372      // could add in depth as well
2373      for ( i = 0 ; i < numberObjects ; i++) {
2374        int thisNumber = min(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
2375        if (thisNumber<=bestNumber) {
2376          int betterWay=0;
2377          if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
2378            if (numberInfeasibilitiesUp[i]<bestNumber) {
2379              betterWay = 1;
2380            } else {
2381              if (changeUp[i]<bestCriterion)
2382                betterWay=1;
2383            }
2384          } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
2385            if (numberInfeasibilitiesDown[i]<bestNumber) {
2386              betterWay = -1;
2387            } else {
2388              if (changeDown[i]<bestCriterion)
2389                betterWay=-1;
2390            }
2391          } else {
2392            // up and down have same number
2393            bool better=false;
2394            if (numberInfeasibilitiesUp[i]<bestNumber) {
2395              better=true;
2396            } else if (numberInfeasibilitiesUp[i]==bestNumber) {
2397              if (min(changeUp[i],changeDown[i])<bestCriterion)
2398                better=true;;
2399            }
2400            if (better) {
2401              // see which way
2402              if (changeUp[i]<=changeDown[i])
2403                betterWay=1;
2404              else
2405                betterWay=-1;
2406            }
2407          }
2408          if (betterWay) {
2409            bestCriterion = min(changeUp[i],changeDown[i]);
2410            bestNumber = thisNumber;
2411            whichObject = i;
2412            bestWay = betterWay;
2413          }
2414        }
2415      }
2416      break;
2417    case 1:
2418      for ( i = 0 ; i < numberObjects ; i++) {
2419        int betterWay=0;
2420        if (changeUp[i]<=changeDown[i]) {
2421          if (changeUp[i]>bestCriterion)
2422            betterWay=1;
2423        } else {
2424          if (changeDown[i]>bestCriterion)
2425            betterWay=-1;
2426        }
2427        if (betterWay) {
2428          bestCriterion = min(changeUp[i],changeDown[i]);
2429          whichObject = i;
2430          bestWay = betterWay;
2431        }
2432      }
2433      break;
2434    case 2:
2435      for ( i = 0 ; i < numberObjects ; i++) {
2436        double change = min(changeUp[i],changeDown[i]);
2437        double sum = changeUp[i] + changeDown[i];
2438        bool take=false;
2439        if (change>1.1*bestCriterion) 
2440          take=true;
2441        else if (change>0.9*bestCriterion&&sum+change>bestCriterion+alternativeCriterion) 
2442          take=true;
2443        if (take) {
2444          if (changeUp[i]<=changeDown[i]) {
2445            if (changeUp[i]>bestCriterion)
2446              bestWay=1;
2447          } else {
2448            if (changeDown[i]>bestCriterion)
2449              bestWay=-1;
2450          }
2451          bestCriterion = change;
2452          alternativeCriterion = sum;
2453          whichObject = i;
2454        }
2455      }
2456      break;
2457    case 3:
2458      for ( i = 0 ; i < numberObjects ; i++) {
2459        int numberNext = numberInfeasibilitiesUp[i];
2460       
2461        if (numberNext<numberUnsatisfied) {
2462          int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
2463          double perUnsatisfied = changeUp[i]/(double) numberUp;
2464          double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
2465          if (estimatedObjective<bestEstimate) {
2466            bestEstimate = estimatedObjective;
2467            bestWay=1;
2468            whichObject=i;
2469          }
2470        }
2471        numberNext = numberInfeasibilitiesDown[i];
2472        if (numberNext<numberUnsatisfied) {
2473          int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
2474          double perUnsatisfied = changeDown[i]/(double) numberDown;
2475          double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
2476          if (estimatedObjective<bestEstimate) {
2477            bestEstimate = estimatedObjective;
2478            bestWay=-1;
2479            whichObject=i;
2480          }
2481        }
2482      }
2483      break;
2484    case 4:
2485      // if number infeas same then cheapest up
2486      // first get best number or when going down
2487      // now choose smallest change up amongst equal number infeas
2488      for ( i = 0 ; i < numberObjects ; i++) {
2489        int thisNumber = min(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
2490        if (thisNumber<=bestNumber) {
2491          int betterWay=0;
2492          if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
2493            if (numberInfeasibilitiesUp[i]<bestNumber) {
2494              betterWay = 1;
2495            } else {
2496              if (changeUp[i]<bestCriterion)
2497                betterWay=1;
2498            }
2499          } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
2500            if (numberInfeasibilitiesDown[i]<bestNumber) {
2501              betterWay = -1;
2502            } else {
2503              if (changeDown[i]<bestCriterion)
2504                betterWay=-1;
2505            }
2506          } else {
2507            // up and down have same number
2508            bool better=false;
2509            if (numberInfeasibilitiesUp[i]<bestNumber) {
2510              better=true;
2511            } else if (numberInfeasibilitiesUp[i]==bestNumber) {
2512              if (min(changeUp[i],changeDown[i])<bestCriterion)
2513                better=true;;
2514            }
2515            if (better) {
2516              // see which way
2517              if (changeUp[i]<=changeDown[i])
2518                betterWay=1;
2519              else
2520                betterWay=-1;
2521            }
2522          }
2523          if (betterWay) {
2524            bestCriterion = min(changeUp[i],changeDown[i]);
2525            bestNumber = thisNumber;
2526            whichObject = i;
2527            bestWay = betterWay;
2528          }
2529        }
2530      }
2531      bestCriterion=1.0e50;
2532      for ( i = 0 ; i < numberObjects ; i++) {
2533        int thisNumber = numberInfeasibilitiesUp[i];
2534        if (thisNumber==bestNumber&&changeUp) {
2535          if (changeUp[i]<bestCriterion) {
2536            bestCriterion = changeUp[i];
2537            whichObject = i;
2538            bestWay = 1;
2539          }
2540        }
2541      }
2542      break;
2543    }
2544    // set way in best
2545    if (whichObject>=0) {
2546      CbcBranchingObject * bestObject = objects[whichObject];
2547      if (bestObject->object()&&bestObject->object()->preferredWay()) 
2548        bestWay = bestObject->object()->preferredWay();
2549      bestObject->way(bestWay);
2550    } else {
2551      printf("debug\n");
2552    }
2553  }
2554  return whichObject;
2555}
2556
2557// Default Constructor
2558CbcFollowOn::CbcFollowOn ()
2559  : CbcObject(),
2560    rhs_(NULL)
2561{
2562}
2563
2564// Useful constructor
2565CbcFollowOn::CbcFollowOn (CbcModel * model)
2566  : CbcObject(model)
2567{
2568  assert (model);
2569  OsiSolverInterface * solver = model_->solver();
2570  matrix_ = *solver->getMatrixByCol();
2571  matrix_.removeGaps();
2572  matrix_.setExtraGap(0.0);
2573  matrixByRow_ = *solver->getMatrixByRow();
2574  int numberRows = matrix_.getNumRows();
2575 
2576  rhs_ = new int[numberRows];
2577  int i;
2578  const double * rowLower = solver->getRowLower();
2579  const double * rowUpper = solver->getRowUpper();
2580  // Row copy
2581  const double * elementByRow = matrixByRow_.getElements();
2582  const int * column = matrixByRow_.getIndices();
2583  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
2584  const int * rowLength = matrixByRow_.getVectorLengths();
2585  for (i=0;i<numberRows;i++) {
2586    rhs_[i]=0;
2587    double value = rowLower[i];
2588    if (value==rowUpper[i]) {
2589      if (floor(value)==value&&value>=1.0&&value<10.0) {
2590        // check elements
2591        bool good=true;
2592        for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
2593          int iColumn = column[j];
2594          if (!solver->isBinary(iColumn))
2595            good=false;
2596          double elValue = elementByRow[j];
2597          if (floor(elValue)!=elValue||value<1.0)
2598            good=false;
2599        }
2600        if (good)
2601          rhs_[i]=(int) value;
2602      }
2603    }
2604  }
2605}
2606
2607// Copy constructor
2608CbcFollowOn::CbcFollowOn ( const CbcFollowOn & rhs)
2609  :CbcObject(rhs),
2610   matrix_(rhs.matrix_),
2611   matrixByRow_(rhs.matrixByRow_)
2612{
2613  int numberRows = matrix_.getNumRows();
2614  rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
2615}
2616
2617// Clone
2618CbcObject *
2619CbcFollowOn::clone() const
2620{
2621  return new CbcFollowOn(*this);
2622}
2623
2624// Assignment operator
2625CbcFollowOn & 
2626CbcFollowOn::operator=( const CbcFollowOn& rhs)
2627{
2628  if (this!=&rhs) {
2629    CbcObject::operator=(rhs);
2630    delete [] rhs_;
2631    matrix_ = rhs.matrix_;
2632    matrixByRow_ = rhs.matrixByRow_;
2633    int numberRows = matrix_.getNumRows();
2634    rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
2635  }
2636  return *this;
2637}
2638
2639// Destructor
2640CbcFollowOn::~CbcFollowOn ()
2641{
2642  delete [] rhs_;
2643}
2644// As some computation is needed in more than one place - returns row
2645int 
2646CbcFollowOn::gutsOfFollowOn(int & otherRow, int & preferredWay) const
2647{
2648  int whichRow=-1;
2649  otherRow=-1;
2650  int numberRows = matrix_.getNumRows();
2651 
2652  int i;
2653  // For sorting
2654  int * sort = new int [numberRows];
2655  int * isort = new int [numberRows];
2656  // Column copy
2657  //const double * element = matrix_.getElements();
2658  const int * row = matrix_.getIndices();
2659  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
2660  const int * columnLength = matrix_.getVectorLengths();
2661  // Row copy
2662  const double * elementByRow = matrixByRow_.getElements();
2663  const int * column = matrixByRow_.getIndices();
2664  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
2665  const int * rowLength = matrixByRow_.getVectorLengths();
2666  OsiSolverInterface * solver = model_->solver();
2667  const double * columnLower = solver->getColLower();
2668  const double * columnUpper = solver->getColUpper();
2669  const double * solution = solver->getColSolution();
2670  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
2671  int nSort=0;
2672  for (i=0;i<numberRows;i++) {
2673    if (rhs_[i]) {
2674      // check elements
2675      double smallest=1.0e10;
2676      double largest=0.0;
2677      int rhsValue=rhs_[i];
2678      int number1=0;
2679      int numberUnsatisfied=0;
2680      for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
2681        int iColumn = column[j];
2682        double value = elementByRow[j];
2683        double solValue = solution[iColumn];
2684        if (columnLower[iColumn]!=columnUpper[iColumn]) {
2685          smallest = CoinMin(smallest,value);
2686          largest = CoinMax(largest,value);
2687          if (value==1.0)
2688            number1++;
2689          if (solValue<1.0-integerTolerance&&solValue>integerTolerance)
2690            numberUnsatisfied++;
2691        } else {
2692          rhsValue -= (int)(value*floor(solValue+0.5));
2693        }
2694      }
2695      if (numberUnsatisfied>1) {
2696        if (smallest<largest) {
2697          // probably no good but check a few things
2698          assert (largest<=rhsValue);
2699          if (number1==1&&largest==rhsValue)
2700            printf("could fix\n");
2701        } else if (largest==rhsValue) {
2702          sort[nSort]=i;
2703          isort[nSort++]=-numberUnsatisfied;
2704        }
2705      }
2706    }
2707  }
2708  if (nSort>1) {
2709    CoinSort_2(isort,isort+nSort,sort);
2710    CoinZeroN(isort,numberRows);
2711    double * other = new double[numberRows];
2712    CoinZeroN(other,numberRows);
2713    int * which = new int[numberRows];
2714    //#define COUNT
2715#ifndef COUNT
2716    bool beforeSolution = model_->getSolutionCount()==0;
2717#endif
2718    for (int k=0;k<nSort-1;k++) {
2719      i=sort[k];
2720      int numberUnsatisfied = 0;
2721      int n=0;
2722      int j;
2723      for (j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
2724        int iColumn = column[j];
2725        if (columnLower[iColumn]!=columnUpper[iColumn]) {
2726          double solValue = solution[iColumn]-columnLower[iColumn];
2727          if (solValue<1.0-integerTolerance&&solValue>integerTolerance) {
2728            numberUnsatisfied++;
2729            for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
2730              int iRow = row[jj];
2731              if (rhs_[iRow]) {
2732                other[iRow]+=solValue;
2733                if (isort[iRow]) {
2734                  isort[iRow]++;
2735                } else {
2736                  isort[iRow]=1;
2737                  which[n++]=iRow;
2738                }
2739              }
2740            }
2741          }
2742        }
2743      }
2744      double total=0.0;
2745      // Take out row
2746      double sumThis=other[i];
2747      other[i]=0.0;
2748      assert (numberUnsatisfied==isort[i]);
2749      // find one nearest half if solution, one if before solution
2750      int iBest=-1;
2751      double dtarget=0.5*total;
2752#ifdef COUNT
2753      int target = (numberUnsatisfied+1)>>1;
2754      int best=numberUnsatisfied;
2755#else
2756      double best;
2757      if (beforeSolution)
2758        best=dtarget;
2759      else
2760        best=1.0e30;
2761#endif
2762      for (j=0;j<n;j++) {
2763        int iRow = which[j];
2764        double dvalue=other[iRow];
2765        other[iRow]=0.0;
2766#ifdef COUNT
2767        int value = isort[iRow];
2768#endif
2769        isort[iRow]=0;
2770        if (fabs(dvalue)<1.0e-8||fabs(sumThis-dvalue)<1.0e-8)
2771          continue;
2772        if (dvalue<integerTolerance||dvalue>1.0-integerTolerance)
2773          continue;
2774#ifdef COUNT
2775        if (abs(value-target)<best&&value!=numberUnsatisfied) {
2776          best=abs(value-target);
2777          iBest=iRow;
2778          if (dvalue<dtarget)
2779            preferredWay=1;
2780          else
2781            preferredWay=-1;
2782        }
2783#else
2784        if (beforeSolution) {
2785          if (fabs(dvalue-dtarget)>best) {
2786            best = fabs(dvalue-dtarget);
2787            iBest=iRow;
2788            if (dvalue<dtarget)
2789              preferredWay=1;
2790            else
2791              preferredWay=-1;
2792          }
2793        } else {
2794          if (fabs(dvalue-dtarget)<best) {
2795            best = fabs(dvalue-dtarget);
2796            iBest=iRow;
2797            if (dvalue<dtarget)
2798              preferredWay=1;
2799            else
2800              preferredWay=-1;
2801          }
2802        }
2803#endif
2804      }
2805      if (iBest>=0) {
2806        whichRow=i;
2807        otherRow=iBest;
2808        break;
2809      }
2810    }
2811    delete [] which;
2812    delete [] other;
2813  }
2814  delete [] sort;
2815  delete [] isort;
2816  return whichRow;
2817}
2818
2819// Infeasibility - large is 0.5
2820double 
2821CbcFollowOn::infeasibility(int & preferredWay) const
2822{
2823  int otherRow=0;
2824  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
2825  if (whichRow<0)
2826    return 0.0;
2827  else
2828  return 2.0* model_->getDblParam(CbcModel::CbcIntegerTolerance);
2829}
2830
2831// This looks at solution and sets bounds to contain solution
2832void 
2833CbcFollowOn::feasibleRegion()
2834{
2835}
2836
2837
2838// Creates a branching object
2839CbcBranchingObject * 
2840CbcFollowOn::createBranch(int way) 
2841{
2842  int otherRow=0;
2843  int preferredWay;
2844  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
2845  assert(way==preferredWay);
2846  assert (whichRow>=0);
2847  int numberColumns = matrix_.getNumCols();
2848 
2849  // Column copy
2850  //const double * element = matrix_.getElements();
2851  const int * row = matrix_.getIndices();
2852  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
2853  const int * columnLength = matrix_.getVectorLengths();
2854  // Row copy
2855  //const double * elementByRow = matrixByRow_.getElements();
2856  const int * column = matrixByRow_.getIndices();
2857  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
2858  const int * rowLength = matrixByRow_.getVectorLengths();
2859  OsiSolverInterface * solver = model_->solver();
2860  const double * columnLower = solver->getColLower();
2861  const double * columnUpper = solver->getColUpper();
2862  //const double * solution = solver->getColSolution();
2863  int nUp=0;
2864  int nDown=0;
2865  int * upList = new int[numberColumns];
2866  int * downList = new int[numberColumns];
2867  int j;
2868  for (j=rowStart[whichRow];j<rowStart[whichRow]+rowLength[whichRow];j++) {
2869    int iColumn = column[j];
2870    if (columnLower[iColumn]!=columnUpper[iColumn]) {
2871      bool up=true;
2872      for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
2873        int iRow = row[jj];
2874        if (iRow==otherRow) {
2875          up=false;
2876          break;
2877        }
2878      }
2879      if (up)
2880        upList[nUp++]=iColumn;
2881      else
2882        downList[nDown++]=iColumn;
2883    }
2884  }
2885  //printf("way %d\n",way);
2886  // create object
2887  //printf("would fix %d down and %d up\n",nDown,nUp);
2888  CbcBranchingObject * branch
2889     = new CbcFixingBranchingObject(model_,way,
2890                                         nDown,downList,nUp,upList);
2891  delete [] upList;
2892  delete [] downList;
2893  return branch;
2894}
2895// Default Constructor
2896CbcFixingBranchingObject::CbcFixingBranchingObject()
2897  :CbcBranchingObject()
2898{
2899  numberDown_=0;
2900  numberUp_=0;
2901  downList_=NULL;
2902  upList_=NULL;
2903}
2904
2905// Useful constructor
2906CbcFixingBranchingObject::CbcFixingBranchingObject (CbcModel * model,
2907                                                    int way ,
2908                                                    int numberOnDownSide, const int * down,
2909                                                    int numberOnUpSide, const int * up)
2910  :CbcBranchingObject(model,0,way,0.5)
2911{
2912  numberDown_=numberOnDownSide;
2913  numberUp_=numberOnUpSide;
2914  downList_ = CoinCopyOfArray(down,numberDown_);
2915  upList_ = CoinCopyOfArray(up,numberUp_);
2916}
2917
2918// Copy constructor
2919CbcFixingBranchingObject::CbcFixingBranchingObject ( const CbcFixingBranchingObject & rhs) :CbcBranchingObject(rhs)
2920{
2921  numberDown_=rhs.numberDown_;
2922  numberUp_=rhs.numberUp_;
2923  downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
2924  upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
2925}
2926
2927// Assignment operator
2928CbcFixingBranchingObject & 
2929CbcFixingBranchingObject::operator=( const CbcFixingBranchingObject& rhs)
2930{
2931  if (this != &rhs) {
2932    CbcBranchingObject::operator=(rhs);
2933    delete [] downList_;
2934    delete [] upList_;
2935    numberDown_=rhs.numberDown_;
2936    numberUp_=rhs.numberUp_;
2937    downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
2938    upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
2939  }
2940  return *this;
2941}
2942CbcBranchingObject * 
2943CbcFixingBranchingObject::clone() const
2944{ 
2945  return (new CbcFixingBranchingObject(*this));
2946}
2947
2948
2949// Destructor
2950CbcFixingBranchingObject::~CbcFixingBranchingObject ()
2951{
2952  delete [] downList_;
2953  delete [] upList_;
2954}
2955double
2956CbcFixingBranchingObject::branch()
2957{
2958  decrementNumberBranchesLeft();
2959  OsiSolverInterface * solver = model_->solver();
2960  const double * columnLower = solver->getColLower();
2961  int i;
2962  // *** for way - up means fix all those in up section
2963  if (way_<0) {
2964#ifdef FULL_PRINT
2965    printf("Down Fix ");
2966#endif
2967    //printf("Down Fix %d\n",numberDown_);
2968    for (i=0;i<numberDown_;i++) {
2969      int iColumn = downList_[i];
2970      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
2971#ifdef FULL_PRINT
2972      printf("Setting bound on %d to lower bound\n",iColumn);
2973#endif
2974    }
2975    way_=1;       // Swap direction
2976  } else {
2977#ifdef FULL_PRINT
2978    printf("Up Fix ");
2979#endif
2980    //printf("Up Fix %d\n",numberUp_);
2981    for (i=0;i<numberUp_;i++) {
2982      int iColumn = upList_[i];
2983      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
2984#ifdef FULL_PRINT
2985      printf("Setting bound on %d to lower bound\n",iColumn);
2986#endif
2987    }
2988    way_=-1;      // Swap direction
2989  }
2990#ifdef FULL_PRINT
2991  printf("\n");
2992#endif
2993  return 0.0;
2994}
2995void
2996CbcFixingBranchingObject::print()
2997{
2998  int i;
2999  // *** for way - up means fix all those in up section
3000  if (way_<0) {
3001    printf("Down Fix ");
3002    for (i=0;i<numberDown_;i++) {
3003      int iColumn = downList_[i];
3004      printf("%d ",iColumn);
3005    }
3006  } else {
3007    printf("Up Fix ");
3008    for (i=0;i<numberUp_;i++) {
3009      int iColumn = upList_[i];
3010      printf("%d ",iColumn);
3011    }
3012  }
3013  printf("\n");
3014}
3015// Default Constructor
3016CbcNWay::CbcNWay ()
3017  : CbcObject(),
3018    numberMembers_(0),
3019    members_(NULL),
3020    consequence_(NULL)
3021{
3022}
3023
3024// Useful constructor (which are integer indices)
3025CbcNWay::CbcNWay (CbcModel * model, int numberMembers,
3026                  const int * which, int identifier)
3027  : CbcObject(model)
3028{
3029  id_=identifier;
3030  numberMembers_=numberMembers;
3031  if (numberMembers_) {
3032    members_ = new int[numberMembers_];
3033    memcpy(members_,which,numberMembers_*sizeof(int));
3034  } else {
3035    members_ = NULL;
3036  }
3037  consequence_ = NULL;
3038}
3039
3040// Copy constructor
3041CbcNWay::CbcNWay ( const CbcNWay & rhs)
3042  :CbcObject(rhs)
3043{
3044  numberMembers_ = rhs.numberMembers_;
3045  consequence_ = NULL;
3046  if (numberMembers_) {
3047    members_ = new int[numberMembers_];
3048    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
3049    if (rhs.consequence_) {
3050      consequence_ = new CbcConsequence * [numberMembers_];
3051      for (int i=0;i<numberMembers_;i++) {
3052        if (rhs.consequence_[i])
3053          consequence_[i]= rhs.consequence_[i]->clone();
3054        else
3055          consequence_[i]=NULL;
3056      }
3057    }
3058  } else {
3059    members_ = NULL;
3060  }
3061}
3062
3063// Clone
3064CbcObject *
3065CbcNWay::clone() const
3066{
3067  return new CbcNWay(*this);
3068}
3069
3070// Assignment operator
3071CbcNWay & 
3072CbcNWay::operator=( const CbcNWay& rhs)
3073{
3074  if (this!=&rhs) {
3075    CbcObject::operator=(rhs);
3076    delete [] members_;
3077    numberMembers_ = rhs.numberMembers_;
3078    if (consequence_) {
3079      for (int i=0;i<numberMembers_;i++) 
3080        delete consequence_[i];
3081      delete [] consequence_;
3082      consequence_=NULL;
3083    }
3084    if (numberMembers_) {
3085      members_ = new int[numberMembers_];
3086      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
3087    } else {
3088      members_ = NULL;
3089    }
3090    if (rhs.consequence_) {
3091      consequence_ = new CbcConsequence * [numberMembers_];
3092      for (int i=0;i<numberMembers_;i++) {
3093        if (rhs.consequence_[i])
3094          consequence_[i]= rhs.consequence_[i]->clone();
3095        else
3096          consequence_[i]=NULL;
3097      }
3098    }
3099  }
3100  return *this;
3101}
3102
3103// Destructor
3104CbcNWay::~CbcNWay ()
3105{
3106  delete [] members_;
3107  if (consequence_) {
3108    for (int i=0;i<numberMembers_;i++) 
3109      delete consequence_[i];
3110    delete [] consequence_;
3111  }
3112}
3113// Set up a consequence for a single member
3114void 
3115CbcNWay::setConsequence(int iColumn, const CbcConsequence & consequence)
3116{
3117  if (!consequence_) {
3118    consequence_ = new CbcConsequence * [numberMembers_];
3119    for (int i=0;i<numberMembers_;i++) 
3120      consequence_[i]=NULL;
3121  }
3122  for (int i=0;i<numberMembers_;i++) {
3123    if (members_[i]==iColumn) {
3124      consequence_[i]=consequence.clone();
3125      break;
3126    }
3127  }
3128}
3129
3130// Applies a consequence for a single member
3131void 
3132CbcNWay::applyConsequence(int iSequence, int state) const
3133{
3134  assert (state==-9999||state==9999);
3135  if (consequence_) {
3136    CbcConsequence * consequence = consequence_[iSequence];
3137    if (consequence) 
3138      consequence->applyToSolver(model_->solver(),state);
3139  }
3140}
3141 
3142// Infeasibility - large is 0.5
3143double 
3144CbcNWay::infeasibility(int & preferredWay) const
3145{
3146  int numberUnsatis=0;
3147  int j;
3148  OsiSolverInterface * solver = model_->solver();
3149  const double * solution = model_->testSolution();
3150  const double * lower = solver->getColLower();
3151  const double * upper = solver->getColUpper();
3152  double largestValue=0.0;
3153 
3154  double integerTolerance = 
3155    model_->getDblParam(CbcModel::CbcIntegerTolerance);
3156
3157  for (j=0;j<numberMembers_;j++) {
3158    int iColumn = members_[j];
3159    double value = solution[iColumn];
3160    value = CoinMax(value, lower[iColumn]);
3161    value = CoinMin(value, upper[iColumn]);
3162    double distance = CoinMin(value-lower[iColumn],upper[iColumn]-value);
3163    if (distance>integerTolerance) {
3164      numberUnsatis++;
3165      largestValue = CoinMax(distance,largestValue);
3166    }
3167  }
3168  preferredWay=1;
3169  if (numberUnsatis) {
3170    return largestValue;
3171  } else {
3172    return 0.0; // satisfied
3173  }
3174}
3175
3176// This looks at solution and sets bounds to contain solution
3177void 
3178CbcNWay::feasibleRegion()
3179{
3180  int j;
3181  OsiSolverInterface * solver = model_->solver();
3182  const double * solution = model_->testSolution();
3183  const double * lower = solver->getColLower();
3184  const double * upper = solver->getColUpper();
3185  double integerTolerance = 
3186    model_->getDblParam(CbcModel::CbcIntegerTolerance);
3187  for (j=0;j<numberMembers_;j++) {
3188    int iColumn = members_[j];
3189    double value = solution[iColumn];
3190    value = CoinMax(value, lower[iColumn]);
3191    value = CoinMin(value, upper[iColumn]);
3192    if (value>=upper[iColumn]-integerTolerance) {
3193      solver->setColLower(iColumn,upper[iColumn]);
3194    } else {
3195      assert (value<=lower[iColumn]+integerTolerance);
3196      solver->setColUpper(iColumn,lower[iColumn]);
3197    }
3198  }
3199}
3200// Redoes data when sequence numbers change
3201void 
3202CbcNWay::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
3203{
3204  model_=model;
3205  int n2=0;
3206  for (int j=0;j<numberMembers_;j++) {
3207    int iColumn = members_[j];
3208    int i;
3209    for (i=0;i<numberColumns;i++) {
3210      if (originalColumns[i]==iColumn)
3211        break;
3212    }
3213    if (i<numberColumns) {
3214      members_[n2]=i;
3215      consequence_[n2++]=consequence_[j];
3216    } else {
3217      delete consequence_[j];
3218    }
3219  }
3220  if (n2<numberMembers_) {
3221    printf("** NWay number of members reduced from %d to %d!\n",numberMembers_,n2);
3222    numberMembers_=n2;
3223  }
3224}
3225
3226
3227// Creates a branching object
3228CbcBranchingObject * 
3229CbcNWay::createBranch(int way) 
3230{
3231  int numberFree=0;
3232  int j;
3233
3234  OsiSolverInterface * solver = model_->solver();
3235  const double * solution = model_->testSolution();
3236  const double * lower = solver->getColLower();
3237  const double * upper = solver->getColUpper();
3238  int * list = new int[numberMembers_];
3239  double * sort = new double[numberMembers_];
3240
3241  for (j=0;j<numberMembers_;j++) {
3242    int iColumn = members_[j];
3243    double value = solution[iColumn];
3244    value = CoinMax(value, lower[iColumn]);
3245    value = CoinMin(value, upper[iColumn]);
3246    if (upper[iColumn]>lower[iColumn]) {
3247      double distance = upper[iColumn]-value;
3248      list[numberFree]=j;
3249      sort[numberFree++]=distance;
3250    }
3251  }
3252  assert (numberFree);
3253  // sort
3254  CoinSort_2(sort,sort+numberFree,list);
3255  // create object
3256  CbcBranchingObject * branch;
3257  branch = new CbcNWayBranchingObject(model_,this,numberFree,list);
3258  branch->setOriginalObject(this);
3259  delete [] list;
3260  delete [] sort;
3261  return branch;
3262}
3263 
3264// Default Constructor
3265CbcNWayBranchingObject::CbcNWayBranchingObject()
3266  :CbcBranchingObject()
3267{
3268  order_=NULL;
3269  object_=NULL;
3270  numberInSet_=0;
3271  way_=0;
3272}
3273
3274// Useful constructor
3275CbcNWayBranchingObject::CbcNWayBranchingObject (CbcModel * model,
3276                                                const CbcNWay * nway, 
3277                                                int number, const int * order)
3278  :CbcBranchingObject(model,nway->id(),-1,0.5)
3279{
3280  numberBranches_ = number;
3281  order_ = new int [number];
3282  object_=nway;
3283  numberInSet_=number;
3284  memcpy(order_,order,number*sizeof(int));
3285}
3286
3287// Copy constructor
3288CbcNWayBranchingObject::CbcNWayBranchingObject ( const CbcNWayBranchingObject & rhs) :CbcBranchingObject(rhs)
3289{
3290  numberInSet_=rhs.numberInSet_;
3291  object_=rhs.object_;
3292  if (numberInSet_) {
3293    order_ = new int [numberInSet_];
3294    memcpy(order_,rhs.order_,numberInSet_*sizeof(int));
3295  } else {
3296    order_=NULL;
3297  }   
3298}
3299
3300// Assignment operator
3301CbcNWayBranchingObject & 
3302CbcNWayBranchingObject::operator=( const CbcNWayBranchingObject& rhs)
3303{
3304  if (this != &rhs) {
3305    CbcBranchingObject::operator=(rhs);
3306    object_=rhs.object_;
3307    delete [] order_;
3308    numberInSet_=rhs.numberInSet_;
3309    if (numberInSet_) {
3310      order_ = new int [numberInSet_];
3311      memcpy(order_,rhs.order_,numberInSet_*sizeof(int));
3312    } else {
3313      order_=NULL;
3314    }   
3315  }
3316  return *this;
3317}
3318CbcBranchingObject * 
3319CbcNWayBranchingObject::clone() const
3320{ 
3321  return (new CbcNWayBranchingObject(*this));
3322}
3323
3324
3325// Destructor
3326CbcNWayBranchingObject::~CbcNWayBranchingObject ()
3327{
3328  delete [] order_;
3329}
3330double
3331CbcNWayBranchingObject::branch()
3332{
3333  int which = branchIndex_;
3334  branchIndex_++;
3335  assert (numberBranchesLeft()>=0);
3336  if (which==0) {
3337    // first branch so way_ may mean something
3338    assert (way_==-1||way_==1);
3339    if (way_==-1)
3340      which++;
3341  } else if (which==1) {
3342    // second branch so way_ may mean something
3343    assert (way_==-1||way_==1);
3344    if (way_==-1)
3345      which--;
3346    // switch way off
3347    way_=0;
3348  }
3349  const double * lower = model_->solver()->getColLower();
3350  const double * upper = model_->solver()->getColUpper();
3351  const int * members = object_->members();
3352  for (int j=0;j<numberInSet_;j++) {
3353    int iSequence = order_[j];
3354    int iColumn = members[iSequence];
3355    if (j!=which) {
3356      model_->solver()->setColUpper(iColumn,lower[iColumn]);
3357      //model_->solver()->setColLower(iColumn,lower[iColumn]);
3358      assert (lower[iColumn]>-1.0e20);
3359      // apply any consequences
3360      object_->applyConsequence(iSequence,-9999);
3361    } else {
3362      model_->solver()->setColLower(iColumn,upper[iColumn]);
3363      //model_->solver()->setColUpper(iColumn,upper[iColumn]);
3364#ifdef FULL_PRINT
3365      printf("Up Fix %d to %g\n",iColumn,upper[iColumn]);
3366#endif
3367      assert (upper[iColumn]<1.0e20);
3368      // apply any consequences
3369      object_->applyConsequence(iSequence,9999);
3370    }
3371  }
3372  return 0.0;
3373}
3374void
3375CbcNWayBranchingObject::print()
3376{
3377  printf("NWay - Up Fix ");
3378  const int * members = object_->members();
3379  for (int j=0;j<way_;j++) {
3380    int iColumn = members[order_[j]];
3381    printf("%d ",iColumn);
3382  }
3383  printf("\n");
3384}
3385
3386// Default Constructor
3387CbcFixVariable::CbcFixVariable ()
3388  : CbcConsequence(),
3389    numberStates_(0),
3390    states_(NULL),
3391    startLower_(NULL),
3392    startUpper_(NULL),
3393    newBound_(NULL),
3394    variable_(NULL)
3395{
3396}
3397
3398// One useful Constructor
3399CbcFixVariable::CbcFixVariable (int numberStates,const int * states, const int * numberNewLower, 
3400                                const int ** newLowerValue,
3401                                const int ** lowerColumn,
3402                                const int * numberNewUpper, const int ** newUpperValue,
3403                                const int ** upperColumn)
3404  : CbcConsequence(),
3405    states_(NULL),
3406    startLower_(NULL),
3407    startUpper_(NULL),
3408    newBound_(NULL),
3409    variable_(NULL)
3410{
3411  // How much space
3412  numberStates_ = numberStates;
3413  if (numberStates_) {
3414    states_ = new int[numberStates_];
3415    memcpy(states_,states,numberStates_*sizeof(int));
3416    int i;
3417    int n=0;
3418    startLower_ = new int[numberStates_+1];
3419    startUpper_ = new int[numberStates_+1];
3420    startLower_[0]=0;
3421    //count
3422    for (i=0;i<numberStates_;i++) {
3423      n += numberNewLower[i];
3424      startUpper_[i]=n;
3425      n += numberNewUpper[i];
3426      startLower_[i+1]=n;
3427    }
3428    newBound_ = new double [n];
3429    variable_ = new int [n];
3430    n=0;
3431    for (i=0;i<numberStates_;i++) {
3432      int j;
3433      int k;
3434      const int * bound;
3435      const int * variable;
3436      k=numberNewLower[i];
3437      bound = newLowerValue[i];
3438      variable = lowerColumn[i];
3439      for (j=0;j<k;j++) {
3440        newBound_[n]=bound[j];
3441        variable_[n++]=variable[j];
3442      }
3443      k=numberNewUpper[i];
3444      bound = newUpperValue[i];
3445      variable = upperColumn[i];
3446      for (j=0;j<k;j++) {
3447        newBound_[n]=bound[j];
3448        variable_[n++]=variable[j];
3449      }
3450    }
3451  }
3452}
3453
3454// Copy constructor
3455CbcFixVariable::CbcFixVariable ( const CbcFixVariable & rhs)
3456  :CbcConsequence(rhs)
3457{
3458  numberStates_ = rhs.numberStates_;
3459  states_ = NULL;
3460  startLower_ = NULL;
3461  startUpper_ = NULL;
3462  newBound_ = NULL;
3463  variable_ = NULL;
3464  if (numberStates_) {
3465    states_ = CoinCopyOfArray(rhs.states_,numberStates_);
3466    startLower_ = CoinCopyOfArray(rhs.startLower_,numberStates_+1);
3467    startUpper_ = CoinCopyOfArray(rhs.startUpper_,numberStates_+1);
3468    int n=startLower_[numberStates_];
3469    newBound_ = CoinCopyOfArray(rhs.newBound_,n);
3470    variable_ = CoinCopyOfArray(rhs.variable_,n);
3471  }
3472}
3473
3474// Clone
3475CbcConsequence *
3476CbcFixVariable::clone() const
3477{
3478  return new CbcFixVariable(*this);
3479}
3480
3481// Assignment operator
3482CbcFixVariable & 
3483CbcFixVariable::operator=( const CbcFixVariable& rhs)
3484{
3485  if (this!=&rhs) {
3486    CbcConsequence::operator=(rhs);
3487    delete [] states_;
3488    delete [] startLower_;
3489    delete [] startUpper_;
3490    delete [] newBound_;
3491    delete [] variable_;
3492    states_ = NULL;
3493    startLower_ = NULL;
3494    startUpper_ = NULL;
3495    newBound_ = NULL;
3496    variable_ = NULL;
3497    numberStates_ = rhs.numberStates_;
3498    if (numberStates_) {
3499      states_ = CoinCopyOfArray(rhs.states_,numberStates_);
3500      startLower_ = CoinCopyOfArray(rhs.startLower_,numberStates_+1);
3501      startUpper_ = CoinCopyOfArray(rhs.startUpper_,numberStates_+1);
3502      int n=startLower_[numberStates_];
3503      newBound_ = CoinCopyOfArray(rhs.newBound_,n);
3504      variable_ = CoinCopyOfArray(rhs.variable_,n);
3505    }
3506  }
3507  return *this;
3508}
3509
3510// Destructor
3511CbcFixVariable::~CbcFixVariable ()
3512{
3513  delete [] states_;
3514  delete [] startLower_;
3515  delete [] startUpper_;
3516  delete [] newBound_;
3517  delete [] variable_;
3518}
3519// Set up a startLower for a single member
3520void 
3521CbcFixVariable::applyToSolver(OsiSolverInterface * solver, int state) const
3522{
3523  assert (state==-9999||state==9999);
3524  // Find state
3525  int find;
3526  for (find=0;find<numberStates_;find++) 
3527    if (states_[find]==state)
3528      break;
3529  if (find==numberStates_)
3530    return;
3531  int i;
3532  // Set new lower bounds
3533  for (i=startLower_[find];i<startUpper_[find];i++) {
3534    int iColumn = variable_[i];
3535    double value = newBound_[i];
3536    double oldValue = solver->getColLower()[iColumn];
3537    //printf("for %d old lower bound %g, new %g",iColumn,oldValue,value);
3538    solver->setColLower(iColumn,CoinMax(value,oldValue));
3539    //printf(" => %g\n",solver->getColLower()[iColumn]);
3540  }
3541  // Set new upper bounds
3542  for (i=startUpper_[find];i<startLower_[find+1];i++) {
3543    int iColumn = variable_[i];
3544    double value = newBound_[i];
3545    double oldValue = solver->getColUpper()[iColumn];
3546    //printf("for %d old upper bound %g, new %g",iColumn,oldValue,value);
3547    solver->setColUpper(iColumn,CoinMin(value,oldValue));
3548    //printf(" => %g\n",solver->getColUpper()[iColumn]);
3549  }
3550}
3551
3552// Default Constructor
3553CbcDummyBranchingObject::CbcDummyBranchingObject(CbcModel * model)
3554  :CbcBranchingObject(model,0,0,0.5)
3555{
3556  setNumberBranchesLeft(1);
3557}
3558
3559
3560// Copy constructor
3561CbcDummyBranchingObject::CbcDummyBranchingObject ( const CbcDummyBranchingObject & rhs) :CbcBranchingObject(rhs)
3562{
3563}
3564
3565// Assignment operator
3566CbcDummyBranchingObject & 
3567CbcDummyBranchingObject::operator=( const CbcDummyBranchingObject& rhs)
3568{
3569  if (this != &rhs) {
3570    CbcBranchingObject::operator=(rhs);
3571  }
3572  return *this;
3573}
3574CbcBranchingObject * 
3575CbcDummyBranchingObject::clone() const
3576{ 
3577  return (new CbcDummyBranchingObject(*this));
3578}
3579
3580
3581// Destructor
3582CbcDummyBranchingObject::~CbcDummyBranchingObject ()
3583{
3584}
3585
3586/*
3587  Perform a dummy branch
3588*/
3589double
3590CbcDummyBranchingObject::branch()
3591{
3592  decrementNumberBranchesLeft();
3593  return 0.0;
3594}
3595// Print what would happen 
3596void
3597CbcDummyBranchingObject::print()
3598{
3599  printf("Dummy branch\n");
3600}
Note: See TracBrowser for help on using the repository browser.