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

Last change on this file since 848 was 848, checked in by forrest, 14 years ago

try slightly different branching

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 94.0 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  int iColumn;
902  for (iColumn=0;iColumn<numberColumns;iColumn++) {
903    if (columnNumber_==originalColumns[iColumn])
904      break;
905  }
906  assert (iColumn<numberColumns);
907  columnNumber_ = iColumn;
908}
909
910// Infeasibility - large is 0.5
911double 
912CbcSimpleInteger::infeasibility(int & preferredWay) const
913{
914  OsiBranchingInformation info(model_->solver(),model_->normalSolver(),false);
915  return infeasibility(model_->solver(),&info,preferredWay);
916}
917
918// This looks at solution and sets bounds to contain solution
919/** More precisely: it first forces the variable within the existing
920    bounds, and then tightens the bounds to fix the variable at the
921    nearest integer value.
922*/
923void 
924CbcSimpleInteger::feasibleRegion()
925{
926  abort();
927}
928CbcBranchingObject * 
929CbcSimpleInteger::createBranch( int way) 
930{
931  abort();
932  return NULL;
933}
934// Default Constructor
935CbcIntegerBranchingObject::CbcIntegerBranchingObject()
936  :CbcBranchingObject()
937{
938  down_[0] = 0.0;
939  down_[1] = 0.0;
940  up_[0] = 0.0;
941  up_[1] = 0.0;
942#ifdef FUNNY_BRANCHING
943  variables_ = NULL;
944  newBounds_ = NULL;
945  numberExtraChangedBounds_ = 0;
946#endif
947}
948// Useful constructor
949CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
950                                                      int variable, int way , double value)
951  :CbcBranchingObject(model,variable,way,value)
952{
953  int iColumn = variable;
954  assert (model_->solver()->getNumCols()>0);
955  down_[0] = model_->solver()->getColLower()[iColumn];
956  down_[1] = floor(value_);
957  up_[0] = ceil(value_);
958  up_[1] = model->getColUpper()[iColumn];
959#ifdef FUNNY_BRANCHING
960  variables_ = NULL;
961  newBounds_ = NULL;
962  numberExtraChangedBounds_ = 0;
963#endif
964}
965// Does part of constructor
966void 
967CbcIntegerBranchingObject::fillPart (int variable,
968                                 int way , double value) 
969{
970  //originalObject_=NULL;
971  branchIndex_=0;
972  value_=value;
973  numberBranches_=2;
974  //model_= model;
975  //originalCbcObject_=NULL;
976  variable_=variable;
977  way_=way;
978  int iColumn = variable;
979  down_[0] = model_->solver()->getColLower()[iColumn];
980  down_[1] = floor(value_);
981  up_[0] = ceil(value_);
982  up_[1] = model_->getColUpper()[iColumn];
983}
984// Useful constructor for fixing
985CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
986                                                      int variable, int way,
987                                                      double lowerValue, 
988                                                      double upperValue)
989  :CbcBranchingObject(model,variable,way,lowerValue)
990{
991  setNumberBranchesLeft(1);
992  down_[0] = lowerValue;
993  down_[1] = upperValue;
994  up_[0] = lowerValue;
995  up_[1] = upperValue;
996#ifdef FUNNY_BRANCHING
997  variables_ = NULL;
998  newBounds_ = NULL;
999  numberExtraChangedBounds_ = 0;
1000#endif
1001}
1002 
1003
1004// Copy constructor
1005CbcIntegerBranchingObject::CbcIntegerBranchingObject ( const CbcIntegerBranchingObject & rhs) :CbcBranchingObject(rhs)
1006{
1007  down_[0] = rhs.down_[0];
1008  down_[1] = rhs.down_[1];
1009  up_[0] = rhs.up_[0];
1010  up_[1] = rhs.up_[1];
1011#ifdef FUNNY_BRANCHING
1012  numberExtraChangedBounds_ = rhs.numberExtraChangedBounds_;
1013  int size = numberExtraChangedBounds_*(sizeof(double)+sizeof(int));
1014  char * temp = new char [size];
1015  newBounds_ = (double *) temp;
1016  variables_ = (int *) (newBounds_+numberExtraChangedBounds_);
1017
1018  int i ;
1019  for (i=0;i<numberExtraChangedBounds_;i++) {
1020    variables_[i]=rhs.variables_[i];
1021    newBounds_[i]=rhs.newBounds_[i];
1022  }
1023#endif
1024}
1025
1026// Assignment operator
1027CbcIntegerBranchingObject & 
1028CbcIntegerBranchingObject::operator=( const CbcIntegerBranchingObject& rhs)
1029{
1030  if (this != &rhs) {
1031    CbcBranchingObject::operator=(rhs);
1032    down_[0] = rhs.down_[0];
1033    down_[1] = rhs.down_[1];
1034    up_[0] = rhs.up_[0];
1035    up_[1] = rhs.up_[1];
1036#ifdef FUNNY_BRANCHING
1037    delete [] newBounds_;
1038    numberExtraChangedBounds_ = rhs.numberExtraChangedBounds_;
1039    int size = numberExtraChangedBounds_*(sizeof(double)+sizeof(int));
1040    char * temp = new char [size];
1041    newBounds_ = (double *) temp;
1042    variables_ = (int *) (newBounds_+numberExtraChangedBounds_);
1043   
1044    int i ;
1045    for (i=0;i<numberExtraChangedBounds_;i++) {
1046      variables_[i]=rhs.variables_[i];
1047      newBounds_[i]=rhs.newBounds_[i];
1048    }
1049#endif
1050  }
1051  return *this;
1052}
1053CbcBranchingObject * 
1054CbcIntegerBranchingObject::clone() const
1055{ 
1056  return (new CbcIntegerBranchingObject(*this));
1057}
1058
1059
1060// Destructor
1061CbcIntegerBranchingObject::~CbcIntegerBranchingObject ()
1062{
1063  // for debugging threads
1064  way_=-23456789;
1065#ifdef FUNNY_BRANCHING
1066  delete [] newBounds_;
1067#endif
1068}
1069
1070/*
1071  Perform a branch by adjusting the bounds of the specified variable. Note
1072  that each arm of the branch advances the object to the next arm by
1073  advancing the value of way_.
1074
1075  Providing new values for the variable's lower and upper bounds for each
1076  branching direction gives a little bit of additional flexibility and will
1077  be easily extensible to multi-way branching.
1078  Returns change in guessed objective on next branch
1079*/
1080double
1081CbcIntegerBranchingObject::branch()
1082{
1083  // for debugging threads
1084  if (way_<-1||way_>100000) {
1085    printf("way %d, left %d, iCol %d, variable %d\n",
1086           way_,numberBranchesLeft(),
1087           originalCbcObject_->columnNumber(),variable_);
1088    assert (way_!=-23456789);
1089  }
1090  decrementNumberBranchesLeft();
1091  if (down_[1]==-COIN_DBL_MAX)
1092    return 0.0;
1093  int iColumn = originalCbcObject_->columnNumber();
1094  assert (variable_==iColumn);
1095  double olb,oub ;
1096  olb = model_->solver()->getColLower()[iColumn] ;
1097  oub = model_->solver()->getColUpper()[iColumn] ;
1098#ifdef COIN_DEVELOP
1099  if (olb!=down_[0]||oub!=up_[1]) {
1100    if (way_>0)
1101      printf("branching up on var %d: [%g,%g] => [%g,%g] - other [%g,%g]\n",
1102             iColumn,olb,oub,up_[0],up_[1],down_[0],down_[1]) ; 
1103    else
1104      printf("branching down on var %d: [%g,%g] => [%g,%g] - other [%g,%g]\n",
1105             iColumn,olb,oub,down_[0],down_[1],up_[0],up_[1]) ; 
1106  }
1107#endif
1108  if (way_<0) {
1109#ifdef CBC_DEBUG
1110  { double olb,oub ;
1111    olb = model_->solver()->getColLower()[iColumn] ;
1112    oub = model_->solver()->getColUpper()[iColumn] ;
1113    printf("branching down on var %d: [%g,%g] => [%g,%g]\n",
1114           iColumn,olb,oub,down_[0],down_[1]) ; }
1115#endif
1116    model_->solver()->setColLower(iColumn,down_[0]);
1117    model_->solver()->setColUpper(iColumn,down_[1]);
1118    //#define CBC_PRINT2
1119#ifdef CBC_PRINT2
1120    printf("%d branching down has bounds %g %g",iColumn,down_[0],down_[1]);
1121#endif
1122#ifdef FUNNY_BRANCHING
1123    // branch - do extra bounds
1124    for (int i=0;i<numberExtraChangedBounds_;i++) {
1125      int variable = variables_[i];
1126      if ((variable&0x40000000)!=0) {
1127        // for going down
1128        int k = variable&0x3fffffff;
1129        assert (k!=iColumn);
1130        if ((variable&0x80000000)==0) {
1131          // lower bound changing
1132#ifdef CBC_PRINT2
1133          printf(" extra for %d changes lower from %g to %g",
1134                 k,model_->solver()->getColLower()[k],newBounds_[i]);
1135#endif
1136          model_->solver()->setColLower(k,newBounds_[i]);
1137        } else {
1138          // upper bound changing
1139#ifdef CBC_PRINT2
1140          printf(" extra for %d changes upper from %g to %g",
1141                 k,model_->solver()->getColUpper()[k],newBounds_[i]);
1142#endif
1143          model_->solver()->setColUpper(k,newBounds_[i]);
1144        }
1145      }
1146    }
1147#endif
1148#ifdef CBC_PRINT2
1149    printf("\n");
1150#endif
1151    way_=1;
1152  } else {
1153#ifdef CBC_DEBUG
1154  { double olb,oub ;
1155    olb = model_->solver()->getColLower()[iColumn] ;
1156    oub = model_->solver()->getColUpper()[iColumn] ;
1157    printf("branching up on var %d: [%g,%g] => [%g,%g]\n",
1158           iColumn,olb,oub,up_[0],up_[1]) ; }
1159#endif
1160    model_->solver()->setColLower(iColumn,up_[0]);
1161    model_->solver()->setColUpper(iColumn,up_[1]);
1162#ifdef CBC_PRINT2
1163    printf("%d branching up has bounds %g %g",iColumn,up_[0],up_[1]);
1164#endif
1165#ifdef FUNNY_BRANCHING
1166    // branch - do extra bounds
1167    for (int i=0;i<numberExtraChangedBounds_;i++) {
1168      int variable = variables_[i];
1169      if ((variable&0x40000000)==0) {
1170        // for going up
1171        int k = variable&0x3fffffff;
1172        assert (k!=iColumn);
1173        if ((variable&0x80000000)==0) {
1174          // lower bound changing
1175#ifdef CBC_PRINT2
1176          printf(" extra for %d changes lower from %g to %g",
1177                 k,model_->solver()->getColLower()[k],newBounds_[i]);
1178#endif
1179          model_->solver()->setColLower(k,newBounds_[i]);
1180        } else {
1181          // upper bound changing
1182#ifdef CBC_PRINT2
1183          printf(" extra for %d changes upper from %g to %g",
1184                 k,model_->solver()->getColUpper()[k],newBounds_[i]);
1185#endif
1186          model_->solver()->setColUpper(k,newBounds_[i]);
1187        }
1188      }
1189    }
1190#endif
1191#ifdef CBC_PRINT2
1192    printf("\n");
1193#endif
1194    way_=-1;      // Swap direction
1195  }
1196  double nlb = model_->solver()->getColLower()[iColumn];
1197  double nub = model_->solver()->getColUpper()[iColumn];
1198  if (nlb<olb) {
1199#ifndef NDEBUG
1200    printf("bad lb change for column %d from %g to %g\n",iColumn,olb,nlb);
1201#endif
1202    model_->solver()->setColLower(iColumn,CoinMin(olb,nub));
1203    nlb=olb;
1204  }
1205  if (nub>oub) {
1206#ifndef NDEBUG
1207    printf("bad ub change for column %d from %g to %g\n",iColumn,oub,nub);
1208#endif
1209    model_->solver()->setColUpper(iColumn,CoinMax(oub,nlb));
1210  }
1211#ifndef NDEBUG
1212  if (nlb<olb+1.0e-8&&nub>oub-1.0e-8&&false)
1213    printf("bad null change for column %d - bounds %g,%g\n",iColumn,olb,oub);
1214#endif
1215  return 0.0;
1216}
1217#ifdef FUNNY_BRANCHING
1218// Deactivate bounds for branching
1219void 
1220CbcIntegerBranchingObject::deactivate()
1221{
1222  down_[1]=-COIN_DBL_MAX;
1223}
1224int
1225CbcIntegerBranchingObject::applyExtraBounds(int iColumn, double lower, double upper, int way)
1226{
1227  // branch - do bounds
1228
1229  int i;
1230  int found=0;
1231  if (variable_==iColumn) {
1232    printf("odd applyExtra %d\n",iColumn);
1233    if (way<0) {
1234      down_[0]=CoinMax(lower,down_[0]);
1235      down_[1]=CoinMin(upper,down_[1]);
1236      assert (down_[0]<=down_[1]);
1237    } else {
1238      up_[0]=CoinMax(lower,up_[0]);
1239      up_[1]=CoinMin(upper,up_[1]);
1240      assert (up_[0]<=up_[1]);
1241    }
1242    return 0;
1243  }
1244  int check = (way<0) ? 0x40000000 : 0;
1245  double newLower=lower;
1246  double newUpper=upper;
1247  for (i=0;i<numberExtraChangedBounds_;i++) {
1248    int variable = variables_[i];
1249    if ((variable&0x40000000)==check) {
1250      int k = variable&0x3fffffff;
1251      if (k==iColumn) {
1252        if ((variable&0x80000000)==0) {
1253          // lower bound changing
1254          found |= 1;
1255          newBounds_[i] = CoinMax(lower,newBounds_[i]);
1256          newLower = newBounds_[i];
1257        } else {
1258          // upper bound changing
1259          found |= 2;
1260          newBounds_[i] = CoinMin(upper,newBounds_[i]);
1261          newUpper = newBounds_[i];
1262        }
1263      }
1264    }
1265  }
1266  int nAdd=0;
1267  if ((found&2)==0) {
1268    // need to add new upper
1269    nAdd++;
1270  }
1271  if ((found&1)==0) {
1272    // need to add new lower
1273    nAdd++;
1274  }
1275  if (nAdd) { 
1276    int size = (numberExtraChangedBounds_+nAdd)*(sizeof(double)+sizeof(int));
1277    char * temp = new char [size];
1278    double * newBounds = (double *) temp;
1279    int * variables = (int *) (newBounds+numberExtraChangedBounds_+nAdd);
1280
1281    int i ;
1282    for (i=0;i<numberExtraChangedBounds_;i++) {
1283      variables[i]=variables_[i];
1284      newBounds[i]=newBounds_[i];
1285    }
1286    delete [] newBounds_;
1287    newBounds_ = newBounds;
1288    variables_ = variables;
1289    if ((found&2)==0) {
1290      // need to add new upper
1291      int variable = iColumn | 0x80000000;
1292      variables_[numberExtraChangedBounds_]=variable;
1293      newBounds_[numberExtraChangedBounds_++]=newUpper;
1294    }
1295    if ((found&1)==0) {
1296      // need to add new lower
1297      int variable = iColumn;
1298      variables_[numberExtraChangedBounds_]=variable;
1299      newBounds_[numberExtraChangedBounds_++]=newLower;
1300    }
1301  }
1302 
1303  return (newUpper>=newLower) ? 0 : 1;
1304}
1305#endif
1306// Print what would happen 
1307void
1308CbcIntegerBranchingObject::print()
1309{
1310  int iColumn = originalCbcObject_->columnNumber();
1311  assert (variable_==iColumn);
1312  if (way_<0) {
1313  { double olb,oub ;
1314    olb = model_->solver()->getColLower()[iColumn] ;
1315    oub = model_->solver()->getColUpper()[iColumn] ;
1316    printf("CbcInteger would branch down on var %d (int var %d): [%g,%g] => [%g,%g]\n",
1317           iColumn,variable_,olb,oub,down_[0],down_[1]) ; }
1318  } else {
1319  { double olb,oub ;
1320    olb = model_->solver()->getColLower()[iColumn] ;
1321    oub = model_->solver()->getColUpper()[iColumn] ;
1322    printf("CbcInteger would branch up on var %d (int var %d): [%g,%g] => [%g,%g]\n",
1323           iColumn,variable_,olb,oub,up_[0],up_[1]) ; }
1324  }
1325}
1326
1327
1328/** Default Constructor
1329
1330  Equivalent to an unspecified binary variable.
1331*/
1332CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ()
1333  : CbcSimpleInteger(),
1334    downPseudoCost_(1.0e-5),
1335    upPseudoCost_(1.0e-5),
1336    upDownSeparator_(-1.0),
1337    method_(0)
1338{
1339}
1340
1341/** Useful constructor
1342
1343  Loads actual upper & lower bounds for the specified variable.
1344*/
1345CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model,
1346                                    int iColumn, double breakEven)
1347  : CbcSimpleInteger(model,iColumn,breakEven)
1348{
1349  const double * cost = model->getObjCoefficients();
1350  double costValue = CoinMax(1.0e-5,fabs(cost[iColumn]));
1351  // treat as if will cost what it says up
1352  upPseudoCost_=costValue;
1353  // and balance at breakeven
1354  downPseudoCost_=((1.0-breakEven_)*upPseudoCost_)/breakEven_;
1355  upDownSeparator_ = -1.0;
1356  method_=0;
1357}
1358
1359/** Useful constructor
1360
1361  Loads actual upper & lower bounds for the specified variable.
1362*/
1363CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model,
1364                                    int iColumn, double downPseudoCost,
1365                                                        double upPseudoCost)
1366  : CbcSimpleInteger(model,iColumn)
1367{
1368  downPseudoCost_ = CoinMax(1.0e-10,downPseudoCost);
1369  upPseudoCost_ = CoinMax(1.0e-10,upPseudoCost);
1370  breakEven_ = upPseudoCost_/(upPseudoCost_+downPseudoCost_);
1371  upDownSeparator_ = -1.0;
1372  method_=0;
1373}
1374// Useful constructor - passed and model index and pseudo costs
1375CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, int dummy,int iColumn, 
1376                                                        double downPseudoCost, double upPseudoCost)
1377{
1378  CbcSimpleIntegerPseudoCost(model,iColumn,downPseudoCost,upPseudoCost);
1379  columnNumber_=iColumn;
1380}
1381
1382// Copy constructor
1383CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ( const CbcSimpleIntegerPseudoCost & rhs)
1384  :CbcSimpleInteger(rhs),
1385   downPseudoCost_(rhs.downPseudoCost_),
1386   upPseudoCost_(rhs.upPseudoCost_),
1387   upDownSeparator_(rhs.upDownSeparator_),
1388   method_(rhs.method_)
1389
1390{
1391}
1392
1393// Clone
1394CbcObject *
1395CbcSimpleIntegerPseudoCost::clone() const
1396{
1397  return new CbcSimpleIntegerPseudoCost(*this);
1398}
1399
1400// Assignment operator
1401CbcSimpleIntegerPseudoCost & 
1402CbcSimpleIntegerPseudoCost::operator=( const CbcSimpleIntegerPseudoCost& rhs)
1403{
1404  if (this!=&rhs) {
1405    CbcSimpleInteger::operator=(rhs);
1406    downPseudoCost_=rhs.downPseudoCost_;
1407    upPseudoCost_=rhs.upPseudoCost_;
1408    upDownSeparator_=rhs.upDownSeparator_;
1409    method_=rhs.method_;
1410  }
1411  return *this;
1412}
1413
1414// Destructor
1415CbcSimpleIntegerPseudoCost::~CbcSimpleIntegerPseudoCost ()
1416{
1417}
1418// Creates a branching object
1419CbcBranchingObject * 
1420CbcSimpleIntegerPseudoCost::createBranch(int way) 
1421{
1422  OsiSolverInterface * solver = model_->solver();
1423  const double * solution = model_->testSolution();
1424  const double * lower = solver->getColLower();
1425  const double * upper = solver->getColUpper();
1426  double value = solution[columnNumber_];
1427  value = CoinMax(value, lower[columnNumber_]);
1428  value = CoinMin(value, upper[columnNumber_]);
1429#ifndef NDEBUG
1430  double nearest = floor(value+0.5);
1431  double integerTolerance = 
1432    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1433  assert (upper[columnNumber_]>lower[columnNumber_]);
1434#endif
1435  if (!model_->hotstartSolution()) {
1436    assert (fabs(value-nearest)>integerTolerance);
1437  } else {
1438    const double * hotstartSolution = model_->hotstartSolution();
1439    double targetValue = hotstartSolution[columnNumber_];
1440    if (way>0)
1441      value = targetValue-0.1;
1442    else
1443      value = targetValue+0.1;
1444  }
1445  CbcIntegerPseudoCostBranchingObject * newObject = 
1446    new CbcIntegerPseudoCostBranchingObject(model_,columnNumber_,way,
1447                                            value);
1448  double up =  upPseudoCost_*(ceil(value)-value);
1449  double down =  downPseudoCost_*(value-floor(value));
1450  double changeInGuessed=up-down;
1451  if (way>0)
1452    changeInGuessed = - changeInGuessed;
1453  changeInGuessed=CoinMax(0.0,changeInGuessed);
1454  //if (way>0)
1455  //changeInGuessed += 1.0e8; // bias to stay up
1456  newObject->setChangeInGuessed(changeInGuessed);
1457  newObject->setOriginalObject(this);
1458  return newObject;
1459}
1460// Infeasibility - large is 0.5
1461double 
1462CbcSimpleIntegerPseudoCost::infeasibility(int & preferredWay) const
1463{
1464  OsiSolverInterface * solver = model_->solver();
1465  const double * solution = model_->testSolution();
1466  const double * lower = solver->getColLower();
1467  const double * upper = solver->getColUpper();
1468  if (upper[columnNumber_]==lower[columnNumber_]) {
1469    // fixed
1470    preferredWay=1;
1471    return 0.0;
1472  }
1473  double value = solution[columnNumber_];
1474  value = CoinMax(value, lower[columnNumber_]);
1475  value = CoinMin(value, upper[columnNumber_]);
1476  /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
1477    solution[columnNumber_],upper[columnNumber_]);*/
1478  double nearest = floor(value+0.5);
1479  double integerTolerance = 
1480    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1481  double below = floor(value+integerTolerance);
1482  double above = below+1.0;
1483  if (above>upper[columnNumber_]) {
1484    above=below;
1485    below = above -1;
1486  }
1487  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1488  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1489  if (downCost>=upCost)
1490    preferredWay=1;
1491  else
1492    preferredWay=-1;
1493  // See if up down choice set
1494  if (upDownSeparator_>0.0) {
1495    preferredWay = (value-below>=upDownSeparator_) ? 1 : -1;
1496  }
1497  if (preferredWay_)
1498    preferredWay=preferredWay_;
1499  if (fabs(value-nearest)<=integerTolerance) {
1500    return 0.0;
1501  } else {
1502    // can't get at model so 1,2 don't make sense
1503    assert(method_<1||method_>2);
1504    if (!method_)
1505      return CoinMin(downCost,upCost);
1506    else
1507      return CoinMax(downCost,upCost);
1508  }
1509}
1510
1511// Return "up" estimate
1512double 
1513CbcSimpleIntegerPseudoCost::upEstimate() const
1514{
1515  OsiSolverInterface * solver = model_->solver();
1516  const double * solution = model_->testSolution();
1517  const double * lower = solver->getColLower();
1518  const double * upper = solver->getColUpper();
1519  double value = solution[columnNumber_];
1520  value = CoinMax(value, lower[columnNumber_]);
1521  value = CoinMin(value, upper[columnNumber_]);
1522  if (upper[columnNumber_]==lower[columnNumber_]) {
1523    // fixed
1524    return 0.0;
1525  }
1526  double integerTolerance = 
1527    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1528  double below = floor(value+integerTolerance);
1529  double above = below+1.0;
1530  if (above>upper[columnNumber_]) {
1531    above=below;
1532    below = above -1;
1533  }
1534  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1535  return upCost;
1536}
1537// Return "down" estimate
1538double 
1539CbcSimpleIntegerPseudoCost::downEstimate() const
1540{
1541  OsiSolverInterface * solver = model_->solver();
1542  const double * solution = model_->testSolution();
1543  const double * lower = solver->getColLower();
1544  const double * upper = solver->getColUpper();
1545  double value = solution[columnNumber_];
1546  value = CoinMax(value, lower[columnNumber_]);
1547  value = CoinMin(value, upper[columnNumber_]);
1548  if (upper[columnNumber_]==lower[columnNumber_]) {
1549    // fixed
1550    return 0.0;
1551  }
1552  double integerTolerance = 
1553    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1554  double below = floor(value+integerTolerance);
1555  double above = below+1.0;
1556  if (above>upper[columnNumber_]) {
1557    above=below;
1558    below = above -1;
1559  }
1560  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1561  return downCost;
1562}
1563
1564// Default Constructor
1565CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject()
1566  :CbcIntegerBranchingObject()
1567{
1568  changeInGuessed_=1.0e-5;
1569}
1570
1571// Useful constructor
1572CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1573                                                      int variable, int way , double value)
1574  :CbcIntegerBranchingObject(model,variable,way,value)
1575{
1576}
1577// Useful constructor for fixing
1578CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1579                                                      int variable, int way,
1580                                                      double lowerValue, 
1581                                                      double upperValue)
1582  :CbcIntegerBranchingObject(model,variable,way,lowerValue)
1583{
1584  changeInGuessed_=1.0e100;
1585}
1586 
1587
1588// Copy constructor
1589CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject ( 
1590                                 const CbcIntegerPseudoCostBranchingObject & rhs)
1591  :CbcIntegerBranchingObject(rhs)
1592{
1593  changeInGuessed_ = rhs.changeInGuessed_;
1594}
1595
1596// Assignment operator
1597CbcIntegerPseudoCostBranchingObject & 
1598CbcIntegerPseudoCostBranchingObject::operator=( const CbcIntegerPseudoCostBranchingObject& rhs)
1599{
1600  if (this != &rhs) {
1601    CbcIntegerBranchingObject::operator=(rhs);
1602    changeInGuessed_ = rhs.changeInGuessed_;
1603  }
1604  return *this;
1605}
1606CbcBranchingObject * 
1607CbcIntegerPseudoCostBranchingObject::clone() const
1608{ 
1609  return (new CbcIntegerPseudoCostBranchingObject(*this));
1610}
1611
1612
1613// Destructor
1614CbcIntegerPseudoCostBranchingObject::~CbcIntegerPseudoCostBranchingObject ()
1615{
1616}
1617
1618/*
1619  Perform a branch by adjusting the bounds of the specified variable. Note
1620  that each arm of the branch advances the object to the next arm by
1621  advancing the value of way_.
1622
1623  Providing new values for the variable's lower and upper bounds for each
1624  branching direction gives a little bit of additional flexibility and will
1625  be easily extensible to multi-way branching.
1626  Returns change in guessed objective on next branch
1627*/
1628double
1629CbcIntegerPseudoCostBranchingObject::branch()
1630{
1631  CbcIntegerBranchingObject::branch();
1632  return changeInGuessed_;
1633}
1634
1635
1636// Default Constructor
1637CbcCliqueBranchingObject::CbcCliqueBranchingObject()
1638  :CbcBranchingObject()
1639{
1640  clique_ = NULL;
1641  downMask_[0]=0;
1642  downMask_[1]=0;
1643  upMask_[0]=0;
1644  upMask_[1]=0;
1645}
1646
1647// Useful constructor
1648CbcCliqueBranchingObject::CbcCliqueBranchingObject (CbcModel * model,
1649                                                    const CbcClique * clique,
1650                                                    int way ,
1651                                                    int numberOnDownSide, const int * down,
1652                                                    int numberOnUpSide, const int * up)
1653  :CbcBranchingObject(model,clique->id(),way,0.5)
1654{
1655  clique_ = clique;
1656  downMask_[0]=0;
1657  downMask_[1]=0;
1658  upMask_[0]=0;
1659  upMask_[1]=0;
1660  int i;
1661  for (i=0;i<numberOnDownSide;i++) {
1662    int sequence = down[i];
1663    int iWord = sequence>>5;
1664    int iBit = sequence - 32*iWord;
1665    unsigned int k = 1<<iBit;
1666    downMask_[iWord] |= k;
1667  }
1668  for (i=0;i<numberOnUpSide;i++) {
1669    int sequence = up[i];
1670    int iWord = sequence>>5;
1671    int iBit = sequence - 32*iWord;
1672    unsigned int k = 1<<iBit;
1673    upMask_[iWord] |= k;
1674  }
1675}
1676
1677// Copy constructor
1678CbcCliqueBranchingObject::CbcCliqueBranchingObject ( const CbcCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
1679{
1680  clique_=rhs.clique_;
1681  downMask_[0]=rhs.downMask_[0];
1682  downMask_[1]=rhs.downMask_[1];
1683  upMask_[0]=rhs.upMask_[0];
1684  upMask_[1]=rhs.upMask_[1];
1685}
1686
1687// Assignment operator
1688CbcCliqueBranchingObject & 
1689CbcCliqueBranchingObject::operator=( const CbcCliqueBranchingObject& rhs)
1690{
1691  if (this != &rhs) {
1692    CbcBranchingObject::operator=(rhs);
1693    clique_=rhs.clique_;
1694    downMask_[0]=rhs.downMask_[0];
1695    downMask_[1]=rhs.downMask_[1];
1696    upMask_[0]=rhs.upMask_[0];
1697    upMask_[1]=rhs.upMask_[1];
1698  }
1699  return *this;
1700}
1701CbcBranchingObject * 
1702CbcCliqueBranchingObject::clone() const
1703{ 
1704  return (new CbcCliqueBranchingObject(*this));
1705}
1706
1707
1708// Destructor
1709CbcCliqueBranchingObject::~CbcCliqueBranchingObject ()
1710{
1711}
1712double
1713CbcCliqueBranchingObject::branch()
1714{
1715  decrementNumberBranchesLeft();
1716  int iWord;
1717  int numberMembers = clique_->numberMembers();
1718  const int * which = clique_->members();
1719  const int * integerVariables = model_->integerVariable();
1720  int numberWords=(numberMembers+31)>>5;
1721  // *** for way - up means fix all those in down section
1722  if (way_<0) {
1723#ifdef FULL_PRINT
1724    printf("Down Fix ");
1725#endif
1726    for (iWord=0;iWord<numberWords;iWord++) {
1727      int i;
1728      for (i=0;i<32;i++) {
1729        unsigned int k = 1<<i;
1730        if ((upMask_[iWord]&k)!=0) {
1731          int iColumn = which[i+32*iWord];
1732#ifdef FULL_PRINT
1733          printf("%d ",i+32*iWord);
1734#endif
1735          // fix weak way
1736          if (clique_->type(i+32*iWord))
1737            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1738          else
1739            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1740        }
1741      }
1742    }
1743    way_=1;       // Swap direction
1744  } else {
1745#ifdef FULL_PRINT
1746    printf("Up Fix ");
1747#endif
1748    for (iWord=0;iWord<numberWords;iWord++) {
1749      int i;
1750      for (i=0;i<32;i++) {
1751        unsigned int k = 1<<i;
1752        if ((downMask_[iWord]&k)!=0) {
1753          int iColumn = which[i+32*iWord];
1754#ifdef FULL_PRINT
1755          printf("%d ",i+32*iWord);
1756#endif
1757          // fix weak way
1758          if (clique_->type(i+32*iWord))
1759            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1760          else
1761            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1762        }
1763      }
1764    }
1765    way_=-1;      // Swap direction
1766  }
1767#ifdef FULL_PRINT
1768  printf("\n");
1769#endif
1770  return 0.0;
1771}
1772// Print what would happen 
1773void
1774CbcCliqueBranchingObject::print()
1775{
1776  int iWord;
1777  int numberMembers = clique_->numberMembers();
1778  const int * which = clique_->members();
1779  const int * integerVariables = model_->integerVariable();
1780  int numberWords=(numberMembers+31)>>5;
1781  // *** for way - up means fix all those in down section
1782  if (way_<0) {
1783    printf("Clique - Down Fix ");
1784    for (iWord=0;iWord<numberWords;iWord++) {
1785      int i;
1786      for (i=0;i<32;i++) {
1787        unsigned int k = 1<<i;
1788        if ((upMask_[iWord]&k)!=0) {
1789          int iColumn = which[i+32*iWord];
1790          printf("%d ",integerVariables[iColumn]);
1791        }
1792      }
1793    }
1794  } else {
1795    printf("Clique - Up Fix ");
1796    for (iWord=0;iWord<numberWords;iWord++) {
1797      int i;
1798      for (i=0;i<32;i++) {
1799        unsigned int k = 1<<i;
1800        if ((downMask_[iWord]&k)!=0) {
1801          int iColumn = which[i+32*iWord];
1802          printf("%d ",integerVariables[iColumn]);
1803        }
1804      }
1805    }
1806  }
1807  printf("\n");
1808}
1809 
1810// Default Constructor
1811CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject()
1812  :CbcBranchingObject()
1813{
1814  clique_=NULL;
1815  downMask_=NULL;
1816  upMask_=NULL;
1817}
1818
1819// Useful constructor
1820CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject (CbcModel * model,
1821                                                            const CbcClique * clique, 
1822                                                            int way ,
1823                                                    int numberOnDownSide, const int * down,
1824                                                    int numberOnUpSide, const int * up)
1825  :CbcBranchingObject(model,clique->id(),way,0.5)
1826{
1827  clique_ = clique;
1828  int numberMembers = clique_->numberMembers();
1829  int numberWords=(numberMembers+31)>>5;
1830  downMask_ = new unsigned int [numberWords];
1831  upMask_ = new unsigned int [numberWords];
1832  memset(downMask_,0,numberWords*sizeof(unsigned int));
1833  memset(upMask_,0,numberWords*sizeof(unsigned int));
1834  int i;
1835  for (i=0;i<numberOnDownSide;i++) {
1836    int sequence = down[i];
1837    int iWord = sequence>>5;
1838    int iBit = sequence - 32*iWord;
1839    unsigned int k = 1<<iBit;
1840    downMask_[iWord] |= k;
1841  }
1842  for (i=0;i<numberOnUpSide;i++) {
1843    int sequence = up[i];
1844    int iWord = sequence>>5;
1845    int iBit = sequence - 32*iWord;
1846    unsigned int k = 1<<iBit;
1847    upMask_[iWord] |= k;
1848  }
1849}
1850
1851// Copy constructor
1852CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject ( const CbcLongCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
1853{
1854  clique_=rhs.clique_;
1855  if (rhs.downMask_) {
1856    int numberMembers = clique_->numberMembers();
1857    int numberWords=(numberMembers+31)>>5;
1858    downMask_ = new unsigned int [numberWords];
1859    memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
1860    upMask_ = new unsigned int [numberWords];
1861    memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
1862  } else {
1863    downMask_=NULL;
1864    upMask_=NULL;
1865  }   
1866}
1867
1868// Assignment operator
1869CbcLongCliqueBranchingObject & 
1870CbcLongCliqueBranchingObject::operator=( const CbcLongCliqueBranchingObject& rhs)
1871{
1872  if (this != &rhs) {
1873    CbcBranchingObject::operator=(rhs);
1874    clique_=rhs.clique_;
1875    delete [] downMask_;
1876    delete [] upMask_;
1877    if (rhs.downMask_) {
1878      int numberMembers = clique_->numberMembers();
1879      int numberWords=(numberMembers+31)>>5;
1880      downMask_ = new unsigned int [numberWords];
1881      memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
1882      upMask_ = new unsigned int [numberWords];
1883      memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
1884    } else {
1885      downMask_=NULL;
1886      upMask_=NULL;
1887    }   
1888  }
1889  return *this;
1890}
1891CbcBranchingObject * 
1892CbcLongCliqueBranchingObject::clone() const
1893{ 
1894  return (new CbcLongCliqueBranchingObject(*this));
1895}
1896
1897
1898// Destructor
1899CbcLongCliqueBranchingObject::~CbcLongCliqueBranchingObject ()
1900{
1901  delete [] downMask_;
1902  delete [] upMask_;
1903}
1904double
1905CbcLongCliqueBranchingObject::branch()
1906{
1907  decrementNumberBranchesLeft();
1908  int iWord;
1909  int numberMembers = clique_->numberMembers();
1910  const int * which = clique_->members();
1911  const int * integerVariables = model_->integerVariable();
1912  int numberWords=(numberMembers+31)>>5;
1913  // *** for way - up means fix all those in down section
1914  if (way_<0) {
1915#ifdef FULL_PRINT
1916    printf("Down Fix ");
1917#endif
1918    for (iWord=0;iWord<numberWords;iWord++) {
1919      int i;
1920      for (i=0;i<32;i++) {
1921        unsigned int k = 1<<i;
1922        if ((upMask_[iWord]&k)!=0) {
1923          int iColumn = which[i+32*iWord];
1924#ifdef FULL_PRINT
1925          printf("%d ",i+32*iWord);
1926#endif
1927          // fix weak way
1928          if (clique_->type(i+32*iWord))
1929            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1930          else
1931            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1932        }
1933      }
1934    }
1935    way_=1;       // Swap direction
1936  } else {
1937#ifdef FULL_PRINT
1938    printf("Up Fix ");
1939#endif
1940    for (iWord=0;iWord<numberWords;iWord++) {
1941      int i;
1942      for (i=0;i<32;i++) {
1943        unsigned int k = 1<<i;
1944        if ((downMask_[iWord]&k)!=0) {
1945          int iColumn = which[i+32*iWord];
1946#ifdef FULL_PRINT
1947          printf("%d ",i+32*iWord);
1948#endif
1949          // fix weak way
1950          if (clique_->type(i+32*iWord))
1951            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1952          else
1953            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1954        }
1955      }
1956    }
1957    way_=-1;      // Swap direction
1958  }
1959#ifdef FULL_PRINT
1960  printf("\n");
1961#endif
1962  return 0.0;
1963}
1964void
1965CbcLongCliqueBranchingObject::print()
1966{
1967  int iWord;
1968  int numberMembers = clique_->numberMembers();
1969  const int * which = clique_->members();
1970  const int * integerVariables = model_->integerVariable();
1971  int numberWords=(numberMembers+31)>>5;
1972  // *** for way - up means fix all those in down section
1973  if (way_<0) {
1974    printf("Clique - Down Fix ");
1975    for (iWord=0;iWord<numberWords;iWord++) {
1976      int i;
1977      for (i=0;i<32;i++) {
1978        unsigned int k = 1<<i;
1979        if ((upMask_[iWord]&k)!=0) {
1980          int iColumn = which[i+32*iWord];
1981          printf("%d ",integerVariables[iColumn]);
1982        }
1983      }
1984    }
1985  } else {
1986    printf("Clique - Up Fix ");
1987    for (iWord=0;iWord<numberWords;iWord++) {
1988      int i;
1989      for (i=0;i<32;i++) {
1990        unsigned int k = 1<<i;
1991        if ((downMask_[iWord]&k)!=0) {
1992          int iColumn = which[i+32*iWord];
1993          printf("%d ",integerVariables[iColumn]);
1994        }
1995      }
1996    }
1997  }
1998  printf("\n");
1999}
2000// Default Constructor
2001CbcSOSBranchingObject::CbcSOSBranchingObject()
2002  :CbcBranchingObject()
2003{
2004  set_ = NULL;
2005  separator_=0.0;
2006}
2007
2008// Useful constructor
2009CbcSOSBranchingObject::CbcSOSBranchingObject (CbcModel * model,
2010                                              const CbcSOS * set,
2011                                              int way ,
2012                                              double separator)
2013  :CbcBranchingObject(model,set->id(),way,0.5)
2014{
2015  set_ = set;
2016  separator_ = separator;
2017}
2018
2019// Copy constructor
2020CbcSOSBranchingObject::CbcSOSBranchingObject ( const CbcSOSBranchingObject & rhs) :CbcBranchingObject(rhs)
2021{
2022  set_=rhs.set_;
2023  separator_ = rhs.separator_;
2024}
2025
2026// Assignment operator
2027CbcSOSBranchingObject & 
2028CbcSOSBranchingObject::operator=( const CbcSOSBranchingObject& rhs)
2029{
2030  if (this != &rhs) {
2031    CbcBranchingObject::operator=(rhs);
2032    set_=rhs.set_;
2033    separator_ = rhs.separator_;
2034  }
2035  return *this;
2036}
2037CbcBranchingObject * 
2038CbcSOSBranchingObject::clone() const
2039{ 
2040  return (new CbcSOSBranchingObject(*this));
2041}
2042
2043
2044// Destructor
2045CbcSOSBranchingObject::~CbcSOSBranchingObject ()
2046{
2047}
2048double
2049CbcSOSBranchingObject::branch()
2050{
2051  decrementNumberBranchesLeft();
2052  int numberMembers = set_->numberMembers();
2053  const int * which = set_->members();
2054  const double * weights = set_->weights();
2055  OsiSolverInterface * solver = model_->solver();
2056  //const double * lower = solver->getColLower();
2057  //const double * upper = solver->getColUpper();
2058  // *** for way - up means fix all those in down section
2059  if (way_<0) {
2060    int i;
2061    for ( i=0;i<numberMembers;i++) {
2062      if (weights[i] > separator_)
2063        break;
2064    }
2065    assert (i<numberMembers);
2066    for (;i<numberMembers;i++) 
2067      solver->setColUpper(which[i],0.0);
2068    way_=1;       // Swap direction
2069  } else {
2070    int i;
2071    for ( i=0;i<numberMembers;i++) {
2072      if (weights[i] >= separator_)
2073        break;
2074      else
2075        solver->setColUpper(which[i],0.0);
2076    }
2077    assert (i<numberMembers);
2078    way_=-1;      // Swap direction
2079  }
2080  return 0.0;
2081}
2082// Print what would happen 
2083void
2084CbcSOSBranchingObject::print()
2085{
2086  int numberMembers = set_->numberMembers();
2087  const int * which = set_->members();
2088  const double * weights = set_->weights();
2089  OsiSolverInterface * solver = model_->solver();
2090  //const double * lower = solver->getColLower();
2091  const double * upper = solver->getColUpper();
2092  int first=numberMembers;
2093  int last=-1;
2094  int numberFixed=0;
2095  int numberOther=0;
2096  int i;
2097  for ( i=0;i<numberMembers;i++) {
2098    double bound = upper[which[i]];
2099    if (bound) {
2100      first = CoinMin(first,i);
2101      last = CoinMax(last,i);
2102    }
2103  }
2104  // *** for way - up means fix all those in down section
2105  if (way_<0) {
2106    printf("SOS Down");
2107    for ( i=0;i<numberMembers;i++) {
2108      double bound = upper[which[i]];
2109      if (weights[i] > separator_)
2110        break;
2111      else if (bound)
2112        numberOther++;
2113    }
2114    assert (i<numberMembers);
2115    for (;i<numberMembers;i++) {
2116      double bound = upper[which[i]];
2117      if (bound)
2118        numberFixed++;
2119    }
2120  } else {
2121    printf("SOS Up");
2122    for ( i=0;i<numberMembers;i++) {
2123      double bound = upper[which[i]];
2124      if (weights[i] >= separator_)
2125        break;
2126      else if (bound)
2127        numberFixed++;
2128    }
2129    assert (i<numberMembers);
2130    for (;i<numberMembers;i++) {
2131      double bound = upper[which[i]];
2132      if (bound)
2133        numberOther++;
2134    }
2135  }
2136  printf(" - at %g, free range %d (%g) => %d (%g), %d would be fixed, %d other way\n",
2137         separator_,which[first],weights[first],which[last],weights[last],numberFixed,numberOther);
2138}
2139 
2140// Default Constructor
2141CbcBranchDefaultDecision::CbcBranchDefaultDecision()
2142  :CbcBranchDecision()
2143{
2144  bestCriterion_ = 0.0;
2145  bestChangeUp_ = 0.0;
2146  bestNumberUp_ = 0;
2147  bestChangeDown_ = 0.0;
2148  bestObject_ = NULL;
2149  bestNumberDown_ = 0;
2150}
2151
2152// Copy constructor
2153CbcBranchDefaultDecision::CbcBranchDefaultDecision (
2154                                    const CbcBranchDefaultDecision & rhs)
2155  :CbcBranchDecision(rhs)
2156{
2157  bestCriterion_ = rhs.bestCriterion_;
2158  bestChangeUp_ = rhs.bestChangeUp_;
2159  bestNumberUp_ = rhs.bestNumberUp_;
2160  bestChangeDown_ = rhs.bestChangeDown_;
2161  bestNumberDown_ = rhs.bestNumberDown_;
2162  bestObject_ = rhs.bestObject_;
2163  model_ = rhs.model_;
2164}
2165
2166CbcBranchDefaultDecision::~CbcBranchDefaultDecision()
2167{
2168}
2169
2170// Clone
2171CbcBranchDecision * 
2172CbcBranchDefaultDecision::clone() const
2173{
2174  return new CbcBranchDefaultDecision(*this);
2175}
2176
2177// Initialize i.e. before start of choosing at a node
2178void 
2179CbcBranchDefaultDecision::initialize(CbcModel * model)
2180{
2181  bestCriterion_ = 0.0;
2182  bestChangeUp_ = 0.0;
2183  bestNumberUp_ = 0;
2184  bestChangeDown_ = 0.0;
2185  bestNumberDown_ = 0;
2186  bestObject_ = NULL;
2187  model_ = model;
2188}
2189
2190
2191/*
2192  Simple default decision algorithm. Compare based on infeasibility (numInfUp,
2193  numInfDn) until a solution is found by search, then switch to change in
2194  objective (changeUp, changeDn). Note that bestSoFar is remembered in
2195  bestObject_, so the parameter bestSoFar is unused.
2196*/
2197
2198int
2199CbcBranchDefaultDecision::betterBranch(CbcBranchingObject * thisOne,
2200                            CbcBranchingObject * bestSoFar,
2201                            double changeUp, int numInfUp,
2202                            double changeDn, int numInfDn)
2203{
2204  bool beforeSolution = cbcModel()->getSolutionCount()==
2205    cbcModel()->getNumberHeuristicSolutions();;
2206  int betterWay=0;
2207  if (beforeSolution) {
2208    if (!bestObject_) {
2209      bestNumberUp_=COIN_INT_MAX;
2210      bestNumberDown_=COIN_INT_MAX;
2211    }
2212    // before solution - choose smallest number
2213    // could add in depth as well
2214    int bestNumber = CoinMin(bestNumberUp_,bestNumberDown_);
2215    if (numInfUp<numInfDn) {
2216      if (numInfUp<bestNumber) {
2217        betterWay = 1;
2218      } else if (numInfUp==bestNumber) {
2219        if (changeUp<bestCriterion_)
2220          betterWay=1;
2221      }
2222    } else if (numInfUp>numInfDn) {
2223      if (numInfDn<bestNumber) {
2224        betterWay = -1;
2225      } else if (numInfDn==bestNumber) {
2226        if (changeDn<bestCriterion_)
2227          betterWay=-1;
2228      }
2229    } else {
2230      // up and down have same number
2231      bool better=false;
2232      if (numInfUp<bestNumber) {
2233        better=true;
2234      } else if (numInfUp==bestNumber) {
2235        if (min(changeUp,changeDn)<bestCriterion_)
2236          better=true;;
2237      }
2238      if (better) {
2239        // see which way
2240        if (changeUp<=changeDn)
2241          betterWay=1;
2242        else
2243          betterWay=-1;
2244      }
2245    }
2246  } else {
2247    if (!bestObject_) {
2248      bestCriterion_=-1.0;
2249    }
2250    // got a solution
2251    if (changeUp<=changeDn) {
2252      if (changeUp>bestCriterion_)
2253        betterWay=1;
2254    } else {
2255      if (changeDn>bestCriterion_)
2256        betterWay=-1;
2257    }
2258  }
2259  if (betterWay) {
2260    bestCriterion_ = CoinMin(changeUp,changeDn);
2261    bestChangeUp_ = changeUp;
2262    bestNumberUp_ = numInfUp;
2263    bestChangeDown_ = changeDn;
2264    bestNumberDown_ = numInfDn;
2265    bestObject_=thisOne;
2266    // See if user is overriding way
2267    if (thisOne->object()&&thisOne->object()->preferredWay())
2268      betterWay = thisOne->object()->preferredWay();
2269  }
2270  return betterWay;
2271}
2272/* Sets or gets best criterion so far */
2273void 
2274CbcBranchDefaultDecision::setBestCriterion(double value)
2275{ 
2276  bestCriterion_ = value;
2277}
2278double 
2279CbcBranchDefaultDecision::getBestCriterion() const
2280{ 
2281  return bestCriterion_;
2282}
2283
2284/* Compare N branching objects. Return index of best
2285   and sets way of branching in chosen object.
2286   
2287   This routine is used only after strong branching.
2288*/
2289
2290int
2291CbcBranchDefaultDecision::bestBranch (CbcBranchingObject ** objects, int numberObjects,
2292                                   int numberUnsatisfied,
2293                                   double * changeUp, int * numberInfeasibilitiesUp,
2294                                   double * changeDown, int * numberInfeasibilitiesDown,
2295                                   double objectiveValue) 
2296{
2297
2298  int bestWay=0;
2299  int whichObject = -1;
2300  if (numberObjects) {
2301    CbcModel * model = cbcModel();
2302    // at continuous
2303    //double continuousObjective = model->getContinuousObjective();
2304    //int continuousInfeasibilities = model->getContinuousInfeasibilities();
2305   
2306    // average cost to get rid of infeasibility
2307    //double averageCostPerInfeasibility =
2308    //(objectiveValue-continuousObjective)/
2309    //(double) (abs(continuousInfeasibilities-numberUnsatisfied)+1);
2310    /* beforeSolution is :
2311       0 - before any solution
2312       n - n heuristic solutions but no branched one
2313       -1 - branched solution found
2314    */
2315    int numberSolutions = model->getSolutionCount();
2316    double cutoff = model->getCutoff();
2317    int method=0;
2318    int i;
2319    if (numberSolutions) {
2320      int numberHeuristic = model->getNumberHeuristicSolutions();
2321      if (numberHeuristic<numberSolutions) {
2322        method = 1;
2323      } else {
2324        method = 2;
2325        // look further
2326        for ( i = 0 ; i < numberObjects ; i++) {
2327          int numberNext = numberInfeasibilitiesUp[i];
2328         
2329          if (numberNext<numberUnsatisfied) {
2330            int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
2331            double perUnsatisfied = changeUp[i]/(double) numberUp;
2332            double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
2333            if (estimatedObjective<cutoff) 
2334              method=3;
2335          }
2336          numberNext = numberInfeasibilitiesDown[i];
2337          if (numberNext<numberUnsatisfied) {
2338            int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
2339            double perUnsatisfied = changeDown[i]/(double) numberDown;
2340            double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
2341            if (estimatedObjective<cutoff) 
2342              method=3;
2343          }
2344        }
2345      }
2346      method=2;
2347    } else {
2348      method = 0;
2349    }
2350    // Uncomment next to force method 4
2351    //method=4;
2352    /* Methods :
2353       0 - fewest infeasibilities
2354       1 - largest min change in objective
2355       2 - as 1 but use sum of changes if min close
2356       3 - predicted best solution
2357       4 - take cheapest up branch if infeasibilities same
2358    */
2359    int bestNumber=COIN_INT_MAX;
2360    double bestCriterion=-1.0e50;
2361    double alternativeCriterion = -1.0;
2362    double bestEstimate = 1.0e100;
2363    switch (method) {
2364    case 0:
2365      // could add in depth as well
2366      for ( i = 0 ; i < numberObjects ; i++) {
2367        int thisNumber = min(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
2368        if (thisNumber<=bestNumber) {
2369          int betterWay=0;
2370          if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
2371            if (numberInfeasibilitiesUp[i]<bestNumber) {
2372              betterWay = 1;
2373            } else {
2374              if (changeUp[i]<bestCriterion)
2375                betterWay=1;
2376            }
2377          } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
2378            if (numberInfeasibilitiesDown[i]<bestNumber) {
2379              betterWay = -1;
2380            } else {
2381              if (changeDown[i]<bestCriterion)
2382                betterWay=-1;
2383            }
2384          } else {
2385            // up and down have same number
2386            bool better=false;
2387            if (numberInfeasibilitiesUp[i]<bestNumber) {
2388              better=true;
2389            } else if (numberInfeasibilitiesUp[i]==bestNumber) {
2390              if (min(changeUp[i],changeDown[i])<bestCriterion)
2391                better=true;;
2392            }
2393            if (better) {
2394              // see which way
2395              if (changeUp[i]<=changeDown[i])
2396                betterWay=1;
2397              else
2398                betterWay=-1;
2399            }
2400          }
2401          if (betterWay) {
2402            bestCriterion = min(changeUp[i],changeDown[i]);
2403            bestNumber = thisNumber;
2404            whichObject = i;
2405            bestWay = betterWay;
2406          }
2407        }
2408      }
2409      break;
2410    case 1:
2411      for ( i = 0 ; i < numberObjects ; i++) {
2412        int betterWay=0;
2413        if (changeUp[i]<=changeDown[i]) {
2414          if (changeUp[i]>bestCriterion)
2415            betterWay=1;
2416        } else {
2417          if (changeDown[i]>bestCriterion)
2418            betterWay=-1;
2419        }
2420        if (betterWay) {
2421          bestCriterion = min(changeUp[i],changeDown[i]);
2422          whichObject = i;
2423          bestWay = betterWay;
2424        }
2425      }
2426      break;
2427    case 2:
2428      for ( i = 0 ; i < numberObjects ; i++) {
2429        double change = min(changeUp[i],changeDown[i]);
2430        double sum = changeUp[i] + changeDown[i];
2431        bool take=false;
2432        if (change>1.1*bestCriterion) 
2433          take=true;
2434        else if (change>0.9*bestCriterion&&sum+change>bestCriterion+alternativeCriterion) 
2435          take=true;
2436        if (take) {
2437          if (changeUp[i]<=changeDown[i]) {
2438            if (changeUp[i]>bestCriterion)
2439              bestWay=1;
2440          } else {
2441            if (changeDown[i]>bestCriterion)
2442              bestWay=-1;
2443          }
2444          bestCriterion = change;
2445          alternativeCriterion = sum;
2446          whichObject = i;
2447        }
2448      }
2449      break;
2450    case 3:
2451      for ( i = 0 ; i < numberObjects ; i++) {
2452        int numberNext = numberInfeasibilitiesUp[i];
2453       
2454        if (numberNext<numberUnsatisfied) {
2455          int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
2456          double perUnsatisfied = changeUp[i]/(double) numberUp;
2457          double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
2458          if (estimatedObjective<bestEstimate) {
2459            bestEstimate = estimatedObjective;
2460            bestWay=1;
2461            whichObject=i;
2462          }
2463        }
2464        numberNext = numberInfeasibilitiesDown[i];
2465        if (numberNext<numberUnsatisfied) {
2466          int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
2467          double perUnsatisfied = changeDown[i]/(double) numberDown;
2468          double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
2469          if (estimatedObjective<bestEstimate) {
2470            bestEstimate = estimatedObjective;
2471            bestWay=-1;
2472            whichObject=i;
2473          }
2474        }
2475      }
2476      break;
2477    case 4:
2478      // if number infeas same then cheapest up
2479      // first get best number or when going down
2480      // now choose smallest change up amongst equal number infeas
2481      for ( i = 0 ; i < numberObjects ; i++) {
2482        int thisNumber = min(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
2483        if (thisNumber<=bestNumber) {
2484          int betterWay=0;
2485          if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
2486            if (numberInfeasibilitiesUp[i]<bestNumber) {
2487              betterWay = 1;
2488            } else {
2489              if (changeUp[i]<bestCriterion)
2490                betterWay=1;
2491            }
2492          } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
2493            if (numberInfeasibilitiesDown[i]<bestNumber) {
2494              betterWay = -1;
2495            } else {
2496              if (changeDown[i]<bestCriterion)
2497                betterWay=-1;
2498            }
2499          } else {
2500            // up and down have same number
2501            bool better=false;
2502            if (numberInfeasibilitiesUp[i]<bestNumber) {
2503              better=true;
2504            } else if (numberInfeasibilitiesUp[i]==bestNumber) {
2505              if (min(changeUp[i],changeDown[i])<bestCriterion)
2506                better=true;;
2507            }
2508            if (better) {
2509              // see which way
2510              if (changeUp[i]<=changeDown[i])
2511                betterWay=1;
2512              else
2513                betterWay=-1;
2514            }
2515          }
2516          if (betterWay) {
2517            bestCriterion = min(changeUp[i],changeDown[i]);
2518            bestNumber = thisNumber;
2519            whichObject = i;
2520            bestWay = betterWay;
2521          }
2522        }
2523      }
2524      bestCriterion=1.0e50;
2525      for ( i = 0 ; i < numberObjects ; i++) {
2526        int thisNumber = numberInfeasibilitiesUp[i];
2527        if (thisNumber==bestNumber&&changeUp) {
2528          if (changeUp[i]<bestCriterion) {
2529            bestCriterion = changeUp[i];
2530            whichObject = i;
2531            bestWay = 1;
2532          }
2533        }
2534      }
2535      break;
2536    }
2537    // set way in best
2538    if (whichObject>=0) {
2539      CbcBranchingObject * bestObject = objects[whichObject];
2540      if (bestObject->object()&&bestObject->object()->preferredWay()) 
2541        bestWay = bestObject->object()->preferredWay();
2542      bestObject->way(bestWay);
2543    } else {
2544      printf("debug\n");
2545    }
2546  }
2547  return whichObject;
2548}
2549
2550// Default Constructor
2551CbcFollowOn::CbcFollowOn ()
2552  : CbcObject(),
2553    rhs_(NULL)
2554{
2555}
2556
2557// Useful constructor
2558CbcFollowOn::CbcFollowOn (CbcModel * model)
2559  : CbcObject(model)
2560{
2561  assert (model);
2562  OsiSolverInterface * solver = model_->solver();
2563  matrix_ = *solver->getMatrixByCol();
2564  matrix_.removeGaps();
2565  matrix_.setExtraGap(0.0);
2566  matrixByRow_ = *solver->getMatrixByRow();
2567  int numberRows = matrix_.getNumRows();
2568 
2569  rhs_ = new int[numberRows];
2570  int i;
2571  const double * rowLower = solver->getRowLower();
2572  const double * rowUpper = solver->getRowUpper();
2573  // Row copy
2574  const double * elementByRow = matrixByRow_.getElements();
2575  const int * column = matrixByRow_.getIndices();
2576  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
2577  const int * rowLength = matrixByRow_.getVectorLengths();
2578  for (i=0;i<numberRows;i++) {
2579    rhs_[i]=0;
2580    double value = rowLower[i];
2581    if (value==rowUpper[i]) {
2582      if (floor(value)==value&&value>=1.0&&value<10.0) {
2583        // check elements
2584        bool good=true;
2585        for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
2586          int iColumn = column[j];
2587          if (!solver->isBinary(iColumn))
2588            good=false;
2589          double elValue = elementByRow[j];
2590          if (floor(elValue)!=elValue||value<1.0)
2591            good=false;
2592        }
2593        if (good)
2594          rhs_[i]=(int) value;
2595      }
2596    }
2597  }
2598}
2599
2600// Copy constructor
2601CbcFollowOn::CbcFollowOn ( const CbcFollowOn & rhs)
2602  :CbcObject(rhs),
2603   matrix_(rhs.matrix_),
2604   matrixByRow_(rhs.matrixByRow_)
2605{
2606  int numberRows = matrix_.getNumRows();
2607  rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
2608}
2609
2610// Clone
2611CbcObject *
2612CbcFollowOn::clone() const
2613{
2614  return new CbcFollowOn(*this);
2615}
2616
2617// Assignment operator
2618CbcFollowOn & 
2619CbcFollowOn::operator=( const CbcFollowOn& rhs)
2620{
2621  if (this!=&rhs) {
2622    CbcObject::operator=(rhs);
2623    delete [] rhs_;
2624    matrix_ = rhs.matrix_;
2625    matrixByRow_ = rhs.matrixByRow_;
2626    int numberRows = matrix_.getNumRows();
2627    rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
2628  }
2629  return *this;
2630}
2631
2632// Destructor
2633CbcFollowOn::~CbcFollowOn ()
2634{
2635  delete [] rhs_;
2636}
2637// As some computation is needed in more than one place - returns row
2638int 
2639CbcFollowOn::gutsOfFollowOn(int & otherRow, int & preferredWay) const
2640{
2641  int whichRow=-1;
2642  otherRow=-1;
2643  int numberRows = matrix_.getNumRows();
2644 
2645  int i;
2646  // For sorting
2647  int * sort = new int [numberRows];
2648  int * isort = new int [numberRows];
2649  // Column copy
2650  //const double * element = matrix_.getElements();
2651  const int * row = matrix_.getIndices();
2652  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
2653  const int * columnLength = matrix_.getVectorLengths();
2654  // Row copy
2655  const double * elementByRow = matrixByRow_.getElements();
2656  const int * column = matrixByRow_.getIndices();
2657  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
2658  const int * rowLength = matrixByRow_.getVectorLengths();
2659  OsiSolverInterface * solver = model_->solver();
2660  const double * columnLower = solver->getColLower();
2661  const double * columnUpper = solver->getColUpper();
2662  const double * solution = solver->getColSolution();
2663  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
2664  int nSort=0;
2665  for (i=0;i<numberRows;i++) {
2666    if (rhs_[i]) {
2667      // check elements
2668      double smallest=1.0e10;
2669      double largest=0.0;
2670      int rhsValue=rhs_[i];
2671      int number1=0;
2672      int numberUnsatisfied=0;
2673      for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
2674        int iColumn = column[j];
2675        double value = elementByRow[j];
2676        double solValue = solution[iColumn];
2677        if (columnLower[iColumn]!=columnUpper[iColumn]) {
2678          smallest = CoinMin(smallest,value);
2679          largest = CoinMax(largest,value);
2680          if (value==1.0)
2681            number1++;
2682          if (solValue<1.0-integerTolerance&&solValue>integerTolerance)
2683            numberUnsatisfied++;
2684        } else {
2685          rhsValue -= (int)(value*floor(solValue+0.5));
2686        }
2687      }
2688      if (numberUnsatisfied>1) {
2689        if (smallest<largest) {
2690          // probably no good but check a few things
2691          assert (largest<=rhsValue);
2692          if (number1==1&&largest==rhsValue)
2693            printf("could fix\n");
2694        } else if (largest==rhsValue) {
2695          sort[nSort]=i;
2696          isort[nSort++]=-numberUnsatisfied;
2697        }
2698      }
2699    }
2700  }
2701  if (nSort>1) {
2702    CoinSort_2(isort,isort+nSort,sort);
2703    CoinZeroN(isort,numberRows);
2704    double * other = new double[numberRows];
2705    CoinZeroN(other,numberRows);
2706    int * which = new int[numberRows];
2707    //#define COUNT
2708#ifndef COUNT
2709    bool beforeSolution = model_->getSolutionCount()==0;
2710#endif
2711    for (int k=0;k<nSort-1;k++) {
2712      i=sort[k];
2713      int numberUnsatisfied = 0;
2714      int n=0;
2715      int j;
2716      for (j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
2717        int iColumn = column[j];
2718        if (columnLower[iColumn]!=columnUpper[iColumn]) {
2719          double solValue = solution[iColumn]-columnLower[iColumn];
2720          if (solValue<1.0-integerTolerance&&solValue>integerTolerance) {
2721            numberUnsatisfied++;
2722            for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
2723              int iRow = row[jj];
2724              if (rhs_[iRow]) {
2725                other[iRow]+=solValue;
2726                if (isort[iRow]) {
2727                  isort[iRow]++;
2728                } else {
2729                  isort[iRow]=1;
2730                  which[n++]=iRow;
2731                }
2732              }
2733            }
2734          }
2735        }
2736      }
2737      double total=0.0;
2738      // Take out row
2739      double sumThis=other[i];
2740      other[i]=0.0;
2741      assert (numberUnsatisfied==isort[i]);
2742      // find one nearest half if solution, one if before solution
2743      int iBest=-1;
2744      double dtarget=0.5*total;
2745#ifdef COUNT
2746      int target = (numberUnsatisfied+1)>>1;
2747      int best=numberUnsatisfied;
2748#else
2749      double best;
2750      if (beforeSolution)
2751        best=dtarget;
2752      else
2753        best=1.0e30;
2754#endif
2755      for (j=0;j<n;j++) {
2756        int iRow = which[j];
2757        double dvalue=other[iRow];
2758        other[iRow]=0.0;
2759#ifdef COUNT
2760        int value = isort[iRow];
2761#endif
2762        isort[iRow]=0;
2763        if (fabs(dvalue)<1.0e-8||fabs(sumThis-dvalue)<1.0e-8)
2764          continue;
2765        if (dvalue<integerTolerance||dvalue>1.0-integerTolerance)
2766          continue;
2767#ifdef COUNT
2768        if (abs(value-target)<best&&value!=numberUnsatisfied) {
2769          best=abs(value-target);
2770          iBest=iRow;
2771          if (dvalue<dtarget)
2772            preferredWay=1;
2773          else
2774            preferredWay=-1;
2775        }
2776#else
2777        if (beforeSolution) {
2778          if (fabs(dvalue-dtarget)>best) {
2779            best = fabs(dvalue-dtarget);
2780            iBest=iRow;
2781            if (dvalue<dtarget)
2782              preferredWay=1;
2783            else
2784              preferredWay=-1;
2785          }
2786        } else {
2787          if (fabs(dvalue-dtarget)<best) {
2788            best = fabs(dvalue-dtarget);
2789            iBest=iRow;
2790            if (dvalue<dtarget)
2791              preferredWay=1;
2792            else
2793              preferredWay=-1;
2794          }
2795        }
2796#endif
2797      }
2798      if (iBest>=0) {
2799        whichRow=i;
2800        otherRow=iBest;
2801        break;
2802      }
2803    }
2804    delete [] which;
2805    delete [] other;
2806  }
2807  delete [] sort;
2808  delete [] isort;
2809  return whichRow;
2810}
2811
2812// Infeasibility - large is 0.5
2813double 
2814CbcFollowOn::infeasibility(int & preferredWay) const
2815{
2816  int otherRow=0;
2817  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
2818  if (whichRow<0)
2819    return 0.0;
2820  else
2821  return 2.0* model_->getDblParam(CbcModel::CbcIntegerTolerance);
2822}
2823
2824// This looks at solution and sets bounds to contain solution
2825void 
2826CbcFollowOn::feasibleRegion()
2827{
2828}
2829
2830
2831// Creates a branching object
2832CbcBranchingObject * 
2833CbcFollowOn::createBranch(int way) 
2834{
2835  int otherRow=0;
2836  int preferredWay;
2837  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
2838  assert(way==preferredWay);
2839  assert (whichRow>=0);
2840  int numberColumns = matrix_.getNumCols();
2841 
2842  // Column copy
2843  //const double * element = matrix_.getElements();
2844  const int * row = matrix_.getIndices();
2845  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
2846  const int * columnLength = matrix_.getVectorLengths();
2847  // Row copy
2848  //const double * elementByRow = matrixByRow_.getElements();
2849  const int * column = matrixByRow_.getIndices();
2850  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
2851  const int * rowLength = matrixByRow_.getVectorLengths();
2852  OsiSolverInterface * solver = model_->solver();
2853  const double * columnLower = solver->getColLower();
2854  const double * columnUpper = solver->getColUpper();
2855  //const double * solution = solver->getColSolution();
2856  int nUp=0;
2857  int nDown=0;
2858  int * upList = new int[numberColumns];
2859  int * downList = new int[numberColumns];
2860  int j;
2861  for (j=rowStart[whichRow];j<rowStart[whichRow]+rowLength[whichRow];j++) {
2862    int iColumn = column[j];
2863    if (columnLower[iColumn]!=columnUpper[iColumn]) {
2864      bool up=true;
2865      for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
2866        int iRow = row[jj];
2867        if (iRow==otherRow) {
2868          up=false;
2869          break;
2870        }
2871      }
2872      if (up)
2873        upList[nUp++]=iColumn;
2874      else
2875        downList[nDown++]=iColumn;
2876    }
2877  }
2878  //printf("way %d\n",way);
2879  // create object
2880  //printf("would fix %d down and %d up\n",nDown,nUp);
2881  CbcBranchingObject * branch
2882     = new CbcFixingBranchingObject(model_,way,
2883                                         nDown,downList,nUp,upList);
2884  delete [] upList;
2885  delete [] downList;
2886  return branch;
2887}
2888// Default Constructor
2889CbcFixingBranchingObject::CbcFixingBranchingObject()
2890  :CbcBranchingObject()
2891{
2892  numberDown_=0;
2893  numberUp_=0;
2894  downList_=NULL;
2895  upList_=NULL;
2896}
2897
2898// Useful constructor
2899CbcFixingBranchingObject::CbcFixingBranchingObject (CbcModel * model,
2900                                                    int way ,
2901                                                    int numberOnDownSide, const int * down,
2902                                                    int numberOnUpSide, const int * up)
2903  :CbcBranchingObject(model,0,way,0.5)
2904{
2905  numberDown_=numberOnDownSide;
2906  numberUp_=numberOnUpSide;
2907  downList_ = CoinCopyOfArray(down,numberDown_);
2908  upList_ = CoinCopyOfArray(up,numberUp_);
2909}
2910
2911// Copy constructor
2912CbcFixingBranchingObject::CbcFixingBranchingObject ( const CbcFixingBranchingObject & rhs) :CbcBranchingObject(rhs)
2913{
2914  numberDown_=rhs.numberDown_;
2915  numberUp_=rhs.numberUp_;
2916  downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
2917  upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
2918}
2919
2920// Assignment operator
2921CbcFixingBranchingObject & 
2922CbcFixingBranchingObject::operator=( const CbcFixingBranchingObject& rhs)
2923{
2924  if (this != &rhs) {
2925    CbcBranchingObject::operator=(rhs);
2926    delete [] downList_;
2927    delete [] upList_;
2928    numberDown_=rhs.numberDown_;
2929    numberUp_=rhs.numberUp_;
2930    downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
2931    upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
2932  }
2933  return *this;
2934}
2935CbcBranchingObject * 
2936CbcFixingBranchingObject::clone() const
2937{ 
2938  return (new CbcFixingBranchingObject(*this));
2939}
2940
2941
2942// Destructor
2943CbcFixingBranchingObject::~CbcFixingBranchingObject ()
2944{
2945  delete [] downList_;
2946  delete [] upList_;
2947}
2948double
2949CbcFixingBranchingObject::branch()
2950{
2951  decrementNumberBranchesLeft();
2952  OsiSolverInterface * solver = model_->solver();
2953  const double * columnLower = solver->getColLower();
2954  int i;
2955  // *** for way - up means fix all those in up section
2956  if (way_<0) {
2957#ifdef FULL_PRINT
2958    printf("Down Fix ");
2959#endif
2960    //printf("Down Fix %d\n",numberDown_);
2961    for (i=0;i<numberDown_;i++) {
2962      int iColumn = downList_[i];
2963      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
2964#ifdef FULL_PRINT
2965      printf("Setting bound on %d to lower bound\n",iColumn);
2966#endif
2967    }
2968    way_=1;       // Swap direction
2969  } else {
2970#ifdef FULL_PRINT
2971    printf("Up Fix ");
2972#endif
2973    //printf("Up Fix %d\n",numberUp_);
2974    for (i=0;i<numberUp_;i++) {
2975      int iColumn = upList_[i];
2976      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
2977#ifdef FULL_PRINT
2978      printf("Setting bound on %d to lower bound\n",iColumn);
2979#endif
2980    }
2981    way_=-1;      // Swap direction
2982  }
2983#ifdef FULL_PRINT
2984  printf("\n");
2985#endif
2986  return 0.0;
2987}
2988void
2989CbcFixingBranchingObject::print()
2990{
2991  int i;
2992  // *** for way - up means fix all those in up section
2993  if (way_<0) {
2994    printf("Down Fix ");
2995    for (i=0;i<numberDown_;i++) {
2996      int iColumn = downList_[i];
2997      printf("%d ",iColumn);
2998    }
2999  } else {
3000    printf("Up Fix ");
3001    for (i=0;i<numberUp_;i++) {
3002      int iColumn = upList_[i];
3003      printf("%d ",iColumn);
3004    }
3005  }
3006  printf("\n");
3007}
3008// Default Constructor
3009CbcNWay::CbcNWay ()
3010  : CbcObject(),
3011    numberMembers_(0),
3012    members_(NULL),
3013    consequence_(NULL)
3014{
3015}
3016
3017// Useful constructor (which are integer indices)
3018CbcNWay::CbcNWay (CbcModel * model, int numberMembers,
3019                  const int * which, int identifier)
3020  : CbcObject(model)
3021{
3022  id_=identifier;
3023  numberMembers_=numberMembers;
3024  if (numberMembers_) {
3025    members_ = new int[numberMembers_];
3026    memcpy(members_,which,numberMembers_*sizeof(int));
3027  } else {
3028    members_ = NULL;
3029  }
3030  consequence_ = NULL;
3031}
3032
3033// Copy constructor
3034CbcNWay::CbcNWay ( const CbcNWay & rhs)
3035  :CbcObject(rhs)
3036{
3037  numberMembers_ = rhs.numberMembers_;
3038  consequence_ = NULL;
3039  if (numberMembers_) {
3040    members_ = new int[numberMembers_];
3041    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
3042    if (rhs.consequence_) {
3043      consequence_ = new CbcConsequence * [numberMembers_];
3044      for (int i=0;i<numberMembers_;i++) {
3045        if (rhs.consequence_[i])
3046          consequence_[i]= rhs.consequence_[i]->clone();
3047        else
3048          consequence_[i]=NULL;
3049      }
3050    }
3051  } else {
3052    members_ = NULL;
3053  }
3054}
3055
3056// Clone
3057CbcObject *
3058CbcNWay::clone() const
3059{
3060  return new CbcNWay(*this);
3061}
3062
3063// Assignment operator
3064CbcNWay & 
3065CbcNWay::operator=( const CbcNWay& rhs)
3066{
3067  if (this!=&rhs) {
3068    CbcObject::operator=(rhs);
3069    delete [] members_;
3070    numberMembers_ = rhs.numberMembers_;
3071    if (consequence_) {
3072      for (int i=0;i<numberMembers_;i++) 
3073        delete consequence_[i];
3074      delete [] consequence_;
3075      consequence_=NULL;
3076    }
3077    if (numberMembers_) {
3078      members_ = new int[numberMembers_];
3079      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
3080    } else {
3081      members_ = NULL;
3082    }
3083    if (rhs.consequence_) {
3084      consequence_ = new CbcConsequence * [numberMembers_];
3085      for (int i=0;i<numberMembers_;i++) {
3086        if (rhs.consequence_[i])
3087          consequence_[i]= rhs.consequence_[i]->clone();
3088        else
3089          consequence_[i]=NULL;
3090      }
3091    }
3092  }
3093  return *this;
3094}
3095
3096// Destructor
3097CbcNWay::~CbcNWay ()
3098{
3099  delete [] members_;
3100  if (consequence_) {
3101    for (int i=0;i<numberMembers_;i++) 
3102      delete consequence_[i];
3103    delete [] consequence_;
3104  }
3105}
3106// Set up a consequence for a single member
3107void 
3108CbcNWay::setConsequence(int iColumn, const CbcConsequence & consequence)
3109{
3110  if (!consequence_) {
3111    consequence_ = new CbcConsequence * [numberMembers_];
3112    for (int i=0;i<numberMembers_;i++) 
3113      consequence_[i]=NULL;
3114  }
3115  for (int i=0;i<numberMembers_;i++) {
3116    if (members_[i]==iColumn) {
3117      consequence_[i]=consequence.clone();
3118      break;
3119    }
3120  }
3121}
3122
3123// Applies a consequence for a single member
3124void 
3125CbcNWay::applyConsequence(int iSequence, int state) const
3126{
3127  assert (state==-9999||state==9999);
3128  if (consequence_) {
3129    CbcConsequence * consequence = consequence_[iSequence];
3130    if (consequence) 
3131      consequence->applyToSolver(model_->solver(),state);
3132  }
3133}
3134 
3135// Infeasibility - large is 0.5
3136double 
3137CbcNWay::infeasibility(int & preferredWay) const
3138{
3139  int numberUnsatis=0;
3140  int j;
3141  OsiSolverInterface * solver = model_->solver();
3142  const double * solution = model_->testSolution();
3143  const double * lower = solver->getColLower();
3144  const double * upper = solver->getColUpper();
3145  double largestValue=0.0;
3146 
3147  double integerTolerance = 
3148    model_->getDblParam(CbcModel::CbcIntegerTolerance);
3149
3150  for (j=0;j<numberMembers_;j++) {
3151    int iColumn = members_[j];
3152    double value = solution[iColumn];
3153    value = CoinMax(value, lower[iColumn]);
3154    value = CoinMin(value, upper[iColumn]);
3155    double distance = CoinMin(value-lower[iColumn],upper[iColumn]-value);
3156    if (distance>integerTolerance) {
3157      numberUnsatis++;
3158      largestValue = CoinMax(distance,largestValue);
3159    }
3160  }
3161  preferredWay=1;
3162  if (numberUnsatis) {
3163    return largestValue;
3164  } else {
3165    return 0.0; // satisfied
3166  }
3167}
3168
3169// This looks at solution and sets bounds to contain solution
3170void 
3171CbcNWay::feasibleRegion()
3172{
3173  int j;
3174  OsiSolverInterface * solver = model_->solver();
3175  const double * solution = model_->testSolution();
3176  const double * lower = solver->getColLower();
3177  const double * upper = solver->getColUpper();
3178  double integerTolerance = 
3179    model_->getDblParam(CbcModel::CbcIntegerTolerance);
3180  for (j=0;j<numberMembers_;j++) {
3181    int iColumn = members_[j];
3182    double value = solution[iColumn];
3183    value = CoinMax(value, lower[iColumn]);
3184    value = CoinMin(value, upper[iColumn]);
3185    if (value>=upper[iColumn]-integerTolerance) {
3186      solver->setColLower(iColumn,upper[iColumn]);
3187    } else {
3188      assert (value<=lower[iColumn]+integerTolerance);
3189      solver->setColUpper(iColumn,lower[iColumn]);
3190    }
3191  }
3192}
3193// Redoes data when sequence numbers change
3194void 
3195CbcNWay::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
3196{
3197  model_=model;
3198  int n2=0;
3199  for (int j=0;j<numberMembers_;j++) {
3200    int iColumn = members_[j];
3201    int i;
3202    for (i=0;i<numberColumns;i++) {
3203      if (originalColumns[i]==iColumn)
3204        break;
3205    }
3206    if (i<numberColumns) {
3207      members_[n2]=i;
3208      consequence_[n2++]=consequence_[j];
3209    } else {
3210      delete consequence_[j];
3211    }
3212  }
3213  if (n2<numberMembers_) {
3214    printf("** NWay number of members reduced from %d to %d!\n",numberMembers_,n2);
3215    numberMembers_=n2;
3216  }
3217}
3218
3219
3220// Creates a branching object
3221CbcBranchingObject * 
3222CbcNWay::createBranch(int way) 
3223{
3224  int numberFree=0;
3225  int j;
3226
3227  OsiSolverInterface * solver = model_->solver();
3228  const double * solution = model_->testSolution();
3229  const double * lower = solver->getColLower();
3230  const double * upper = solver->getColUpper();
3231  int * list = new int[numberMembers_];
3232  double * sort = new double[numberMembers_];
3233
3234  for (j=0;j<numberMembers_;j++) {
3235    int iColumn = members_[j];
3236    double value = solution[iColumn];
3237    value = CoinMax(value, lower[iColumn]);
3238    value = CoinMin(value, upper[iColumn]);
3239    if (upper[iColumn]>lower[iColumn]) {
3240      double distance = upper[iColumn]-value;
3241      list[numberFree]=j;
3242      sort[numberFree++]=distance;
3243    }
3244  }
3245  assert (numberFree);
3246  // sort
3247  CoinSort_2(sort,sort+numberFree,list);
3248  // create object
3249  CbcBranchingObject * branch;
3250  branch = new CbcNWayBranchingObject(model_,this,numberFree,list);
3251  branch->setOriginalObject(this);
3252  delete [] list;
3253  delete [] sort;
3254  return branch;
3255}
3256 
3257// Default Constructor
3258CbcNWayBranchingObject::CbcNWayBranchingObject()
3259  :CbcBranchingObject()
3260{
3261  order_=NULL;
3262  object_=NULL;
3263  numberInSet_=0;
3264  way_=0;
3265}
3266
3267// Useful constructor
3268CbcNWayBranchingObject::CbcNWayBranchingObject (CbcModel * model,
3269                                                const CbcNWay * nway, 
3270                                                int number, const int * order)
3271  :CbcBranchingObject(model,nway->id(),-1,0.5)
3272{
3273  numberBranches_ = number;
3274  order_ = new int [number];
3275  object_=nway;
3276  numberInSet_=number;
3277  memcpy(order_,order,number*sizeof(int));
3278}
3279
3280// Copy constructor
3281CbcNWayBranchingObject::CbcNWayBranchingObject ( const CbcNWayBranchingObject & rhs) :CbcBranchingObject(rhs)
3282{
3283  numberInSet_=rhs.numberInSet_;
3284  object_=rhs.object_;
3285  if (numberInSet_) {
3286    order_ = new int [numberInSet_];
3287    memcpy(order_,rhs.order_,numberInSet_*sizeof(int));
3288  } else {
3289    order_=NULL;
3290  }   
3291}
3292
3293// Assignment operator
3294CbcNWayBranchingObject & 
3295CbcNWayBranchingObject::operator=( const CbcNWayBranchingObject& rhs)
3296{
3297  if (this != &rhs) {
3298    CbcBranchingObject::operator=(rhs);
3299    object_=rhs.object_;
3300    delete [] order_;
3301    numberInSet_=rhs.numberInSet_;
3302    if (numberInSet_) {
3303      order_ = new int [numberInSet_];
3304      memcpy(order_,rhs.order_,numberInSet_*sizeof(int));
3305    } else {
3306      order_=NULL;
3307    }   
3308  }
3309  return *this;
3310}
3311CbcBranchingObject * 
3312CbcNWayBranchingObject::clone() const
3313{ 
3314  return (new CbcNWayBranchingObject(*this));
3315}
3316
3317
3318// Destructor
3319CbcNWayBranchingObject::~CbcNWayBranchingObject ()
3320{
3321  delete [] order_;
3322}
3323double
3324CbcNWayBranchingObject::branch()
3325{
3326  int which = branchIndex_;
3327  branchIndex_++;
3328  assert (numberBranchesLeft()>=0);
3329  if (which==0) {
3330    // first branch so way_ may mean something
3331    assert (way_==-1||way_==1);
3332    if (way_==-1)
3333      which++;
3334  } else if (which==1) {
3335    // second branch so way_ may mean something
3336    assert (way_==-1||way_==1);
3337    if (way_==-1)
3338      which--;
3339    // switch way off
3340    way_=0;
3341  }
3342  const double * lower = model_->solver()->getColLower();
3343  const double * upper = model_->solver()->getColUpper();
3344  const int * members = object_->members();
3345  for (int j=0;j<numberInSet_;j++) {
3346    int iSequence = order_[j];
3347    int iColumn = members[iSequence];
3348    if (j!=which) {
3349      model_->solver()->setColUpper(iColumn,lower[iColumn]);
3350      //model_->solver()->setColLower(iColumn,lower[iColumn]);
3351      assert (lower[iColumn]>-1.0e20);
3352      // apply any consequences
3353      object_->applyConsequence(iSequence,-9999);
3354    } else {
3355      model_->solver()->setColLower(iColumn,upper[iColumn]);
3356      //model_->solver()->setColUpper(iColumn,upper[iColumn]);
3357#ifdef FULL_PRINT
3358      printf("Up Fix %d to %g\n",iColumn,upper[iColumn]);
3359#endif
3360      assert (upper[iColumn]<1.0e20);
3361      // apply any consequences
3362      object_->applyConsequence(iSequence,9999);
3363    }
3364  }
3365  return 0.0;
3366}
3367void
3368CbcNWayBranchingObject::print()
3369{
3370  printf("NWay - Up Fix ");
3371  const int * members = object_->members();
3372  for (int j=0;j<way_;j++) {
3373    int iColumn = members[order_[j]];
3374    printf("%d ",iColumn);
3375  }
3376  printf("\n");
3377}
3378
3379// Default Constructor
3380CbcFixVariable::CbcFixVariable ()
3381  : CbcConsequence(),
3382    numberStates_(0),
3383    states_(NULL),
3384    startLower_(NULL),
3385    startUpper_(NULL),
3386    newBound_(NULL),
3387    variable_(NULL)
3388{
3389}
3390
3391// One useful Constructor
3392CbcFixVariable::CbcFixVariable (int numberStates,const int * states, const int * numberNewLower, 
3393                                const int ** newLowerValue,
3394                                const int ** lowerColumn,
3395                                const int * numberNewUpper, const int ** newUpperValue,
3396                                const int ** upperColumn)
3397  : CbcConsequence(),
3398    states_(NULL),
3399    startLower_(NULL),
3400    startUpper_(NULL),
3401    newBound_(NULL),
3402    variable_(NULL)
3403{
3404  // How much space
3405  numberStates_ = numberStates;
3406  if (numberStates_) {
3407    states_ = new int[numberStates_];
3408    memcpy(states_,states,numberStates_*sizeof(int));
3409    int i;
3410    int n=0;
3411    startLower_ = new int[numberStates_+1];
3412    startUpper_ = new int[numberStates_+1];
3413    startLower_[0]=0;
3414    //count
3415    for (i=0;i<numberStates_;i++) {
3416      n += numberNewLower[i];
3417      startUpper_[i]=n;
3418      n += numberNewUpper[i];
3419      startLower_[i+1]=n;
3420    }
3421    newBound_ = new double [n];
3422    variable_ = new int [n];
3423    n=0;
3424    for (i=0;i<numberStates_;i++) {
3425      int j;
3426      int k;
3427      const int * bound;
3428      const int * variable;
3429      k=numberNewLower[i];
3430      bound = newLowerValue[i];
3431      variable = lowerColumn[i];
3432      for (j=0;j<k;j++) {
3433        newBound_[n]=bound[j];
3434        variable_[n++]=variable[j];
3435      }
3436      k=numberNewUpper[i];
3437      bound = newUpperValue[i];
3438      variable = upperColumn[i];
3439      for (j=0;j<k;j++) {
3440        newBound_[n]=bound[j];
3441        variable_[n++]=variable[j];
3442      }
3443    }
3444  }
3445}
3446
3447// Copy constructor
3448CbcFixVariable::CbcFixVariable ( const CbcFixVariable & rhs)
3449  :CbcConsequence(rhs)
3450{
3451  numberStates_ = rhs.numberStates_;
3452  states_ = NULL;
3453  startLower_ = NULL;
3454  startUpper_ = NULL;
3455  newBound_ = NULL;
3456  variable_ = NULL;
3457  if (numberStates_) {
3458    states_ = CoinCopyOfArray(rhs.states_,numberStates_);
3459    startLower_ = CoinCopyOfArray(rhs.startLower_,numberStates_+1);
3460    startUpper_ = CoinCopyOfArray(rhs.startUpper_,numberStates_+1);
3461    int n=startLower_[numberStates_];
3462    newBound_ = CoinCopyOfArray(rhs.newBound_,n);
3463    variable_ = CoinCopyOfArray(rhs.variable_,n);
3464  }
3465}
3466
3467// Clone
3468CbcConsequence *
3469CbcFixVariable::clone() const
3470{
3471  return new CbcFixVariable(*this);
3472}
3473
3474// Assignment operator
3475CbcFixVariable & 
3476CbcFixVariable::operator=( const CbcFixVariable& rhs)
3477{
3478  if (this!=&rhs) {
3479    CbcConsequence::operator=(rhs);
3480    delete [] states_;
3481    delete [] startLower_;
3482    delete [] startUpper_;
3483    delete [] newBound_;
3484    delete [] variable_;
3485    states_ = NULL;
3486    startLower_ = NULL;
3487    startUpper_ = NULL;
3488    newBound_ = NULL;
3489    variable_ = NULL;
3490    numberStates_ = rhs.numberStates_;
3491    if (numberStates_) {
3492      states_ = CoinCopyOfArray(rhs.states_,numberStates_);
3493      startLower_ = CoinCopyOfArray(rhs.startLower_,numberStates_+1);
3494      startUpper_ = CoinCopyOfArray(rhs.startUpper_,numberStates_+1);
3495      int n=startLower_[numberStates_];
3496      newBound_ = CoinCopyOfArray(rhs.newBound_,n);
3497      variable_ = CoinCopyOfArray(rhs.variable_,n);
3498    }
3499  }
3500  return *this;
3501}
3502
3503// Destructor
3504CbcFixVariable::~CbcFixVariable ()
3505{
3506  delete [] states_;
3507  delete [] startLower_;
3508  delete [] startUpper_;
3509  delete [] newBound_;
3510  delete [] variable_;
3511}
3512// Set up a startLower for a single member
3513void 
3514CbcFixVariable::applyToSolver(OsiSolverInterface * solver, int state) const
3515{
3516  assert (state==-9999||state==9999);
3517  // Find state
3518  int find;
3519  for (find=0;find<numberStates_;find++) 
3520    if (states_[find]==state)
3521      break;
3522  if (find==numberStates_)
3523    return;
3524  int i;
3525  // Set new lower bounds
3526  for (i=startLower_[find];i<startUpper_[find];i++) {
3527    int iColumn = variable_[i];
3528    double value = newBound_[i];
3529    double oldValue = solver->getColLower()[iColumn];
3530    //printf("for %d old lower bound %g, new %g",iColumn,oldValue,value);
3531    solver->setColLower(iColumn,CoinMax(value,oldValue));
3532    //printf(" => %g\n",solver->getColLower()[iColumn]);
3533  }
3534  // Set new upper bounds
3535  for (i=startUpper_[find];i<startLower_[find+1];i++) {
3536    int iColumn = variable_[i];
3537    double value = newBound_[i];
3538    double oldValue = solver->getColUpper()[iColumn];
3539    //printf("for %d old upper bound %g, new %g",iColumn,oldValue,value);
3540    solver->setColUpper(iColumn,CoinMin(value,oldValue));
3541    //printf(" => %g\n",solver->getColUpper()[iColumn]);
3542  }
3543}
3544
3545// Default Constructor
3546CbcDummyBranchingObject::CbcDummyBranchingObject(CbcModel * model)
3547  :CbcBranchingObject(model,0,0,0.5)
3548{
3549  setNumberBranchesLeft(1);
3550}
3551
3552
3553// Copy constructor
3554CbcDummyBranchingObject::CbcDummyBranchingObject ( const CbcDummyBranchingObject & rhs) :CbcBranchingObject(rhs)
3555{
3556}
3557
3558// Assignment operator
3559CbcDummyBranchingObject & 
3560CbcDummyBranchingObject::operator=( const CbcDummyBranchingObject& rhs)
3561{
3562  if (this != &rhs) {
3563    CbcBranchingObject::operator=(rhs);
3564  }
3565  return *this;
3566}
3567CbcBranchingObject * 
3568CbcDummyBranchingObject::clone() const
3569{ 
3570  return (new CbcDummyBranchingObject(*this));
3571}
3572
3573
3574// Destructor
3575CbcDummyBranchingObject::~CbcDummyBranchingObject ()
3576{
3577}
3578
3579/*
3580  Perform a dummy branch
3581*/
3582double
3583CbcDummyBranchingObject::branch()
3584{
3585  decrementNumberBranchesLeft();
3586  return 0.0;
3587}
3588// Print what would happen 
3589void
3590CbcDummyBranchingObject::print()
3591{
3592  printf("Dummy branch\n");
3593}
Note: See TracBrowser for help on using the repository browser.