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

Last change on this file since 862 was 854, checked in by forrest, 12 years ago

try and make a bit faster

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