source: trunk/CbcBranchActual.cpp @ 59

Last change on this file since 59 was 59, checked in by forrest, 17 years ago

minor stuff for SOS

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 60.8 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 "CbcModel.hpp"
14#include "CbcMessage.hpp"
15#include "CbcBranchActual.hpp"
16#include "CoinSort.hpp"
17#include "CoinError.hpp"
18
19// Default Constructor
20CbcClique::CbcClique ()
21  : CbcObject(),
22    numberMembers_(0),
23    numberNonSOSMembers_(0),
24    members_(NULL),
25    type_(NULL),
26    cliqueType_(-1),
27    slack_(-1)
28{
29}
30
31// Useful constructor (which are integer indices)
32CbcClique::CbcClique (CbcModel * model, int cliqueType, int numberMembers,
33           const int * which, const char * type, int identifier,int slack)
34  : CbcObject(model)
35{
36  id_=identifier;
37  numberMembers_=numberMembers;
38  if (numberMembers_) {
39    members_ = new int[numberMembers_];
40    memcpy(members_,which,numberMembers_*sizeof(int));
41    type_ = new char[numberMembers_];
42    if (type) {
43      memcpy(type_,type,numberMembers_*sizeof(char));
44    } else {
45      for (int i=0;i<numberMembers_;i++)
46        type_[i]=1;
47    }
48  } else {
49    members_ = NULL;
50    type_ = NULL;
51  }
52  // Find out how many non sos
53  int i;
54  numberNonSOSMembers_=0;
55  for (i=0;i<numberMembers_;i++)
56    if (!type_[i])
57      numberNonSOSMembers_++;
58  cliqueType_ = cliqueType;
59  slack_ = slack;
60}
61
62// Copy constructor
63CbcClique::CbcClique ( const CbcClique & rhs)
64  :CbcObject(rhs)
65{
66  numberMembers_ = rhs.numberMembers_;
67  numberNonSOSMembers_ = rhs.numberNonSOSMembers_;
68  if (numberMembers_) {
69    members_ = new int[numberMembers_];
70    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
71    type_ = new char[numberMembers_];
72    memcpy(type_,rhs.type_,numberMembers_*sizeof(char));
73  } else {
74    members_ = NULL;
75    type_ = NULL;
76  }
77  cliqueType_ = rhs.cliqueType_;
78  slack_ = rhs.slack_;
79}
80
81// Clone
82CbcObject *
83CbcClique::clone() const
84{
85  return new CbcClique(*this);
86}
87
88// Assignment operator
89CbcClique & 
90CbcClique::operator=( const CbcClique& rhs)
91{
92  if (this!=&rhs) {
93    CbcObject::operator=(rhs);
94    delete [] members_;
95    delete [] type_;
96    numberMembers_ = rhs.numberMembers_;
97    numberNonSOSMembers_ = rhs.numberNonSOSMembers_;
98    if (numberMembers_) {
99      members_ = new int[numberMembers_];
100      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
101      type_ = new char[numberMembers_];
102      memcpy(type_,rhs.type_,numberMembers_*sizeof(char));
103    } else {
104      members_ = NULL;
105      type_ = NULL;
106    }
107    cliqueType_ = rhs.cliqueType_;
108    slack_ = rhs.slack_;
109  }
110  return *this;
111}
112
113// Destructor
114CbcClique::~CbcClique ()
115{
116  delete [] members_;
117  delete [] type_;
118}
119
120// Infeasibility - large is 0.5
121double 
122CbcClique::infeasibility(int & preferredWay) const
123{
124  int numberUnsatis=0, numberFree=0;
125  int j;
126  const int * integer = model_->integerVariable();
127  OsiSolverInterface * solver = model_->solver();
128  const double * solution = model_->currentSolution();
129  const double * lower = solver->getColLower();
130  const double * upper = solver->getColUpper();
131  double largestValue=0.0;
132  double integerTolerance = 
133    model_->getDblParam(CbcModel::CbcIntegerTolerance);
134  double * sort = new double[numberMembers_];
135
136  double slackValue=0.0;
137  for (j=0;j<numberMembers_;j++) {
138    int sequence = members_[j];
139    int iColumn = integer[sequence];
140    double value = solution[iColumn];
141    value = CoinMax(value, lower[iColumn]);
142    value = CoinMin(value, upper[iColumn]);
143    double nearest = floor(value+0.5);
144    double distance = fabs(value-nearest);
145    if (distance>integerTolerance) {
146      if (!type_[j])
147        value = 1.0-value; // non SOS
148      // if slack then choose that
149      if (j==slack_&&value>0.05)
150        slackValue = value;
151      largestValue = CoinMax(value,largestValue);
152      sort[numberUnsatis++]=-value;
153    } else if (upper[iColumn]>lower[iColumn]) {
154      numberFree++;
155    }
156  }
157  preferredWay=1;
158  double otherWay = 0.0;
159  if (numberUnsatis) {
160    // sort
161    std::sort(sort,sort+numberUnsatis);
162    for (j=0;j<numberUnsatis;j++) {
163      if ((j&1)!=0)
164        otherWay += -sort[j];
165    }
166    // Need to think more
167    double value = 0.2*numberUnsatis+0.01*(numberMembers_-numberFree);
168    if (fabs(largestValue-0.5)<0.1) {
169      // close to half
170      value +=0.1;
171    }
172    if (slackValue) {
173      // branching on slack
174      value += slackValue;
175    }
176    // scale other way
177    otherWay *= value/(1.0-otherWay);
178    delete [] sort;
179    return value;
180  } else {
181    delete [] sort;
182    return 0.0; // satisfied
183  }
184}
185
186// This looks at solution and sets bounds to contain solution
187void 
188CbcClique::feasibleRegion()
189{
190  int j;
191  const int * integer = model_->integerVariable();
192  OsiSolverInterface * solver = model_->solver();
193  const double * solution = model_->currentSolution();
194  const double * lower = solver->getColLower();
195  const double * upper = solver->getColUpper();
196  double integerTolerance = 
197    model_->getDblParam(CbcModel::CbcIntegerTolerance);
198 
199  for (j=0;j<numberMembers_;j++) {
200    int sequence = members_[j];
201    int iColumn = integer[sequence];
202    double value = solution[iColumn];
203    value = CoinMax(value, lower[iColumn]);
204    value = CoinMin(value, upper[iColumn]);
205    double nearest = floor(value+0.5);
206    double distance = fabs(value-nearest);
207    assert(distance<=integerTolerance);
208    solver->setColLower(iColumn,nearest);
209    solver->setColUpper(iColumn,nearest);
210  }
211}
212
213
214// Creates a branching object
215CbcBranchingObject * 
216CbcClique::createBranch(int way) const
217{
218  int numberUnsatis=0;
219  int j;
220  int nUp=0;
221  int nDown=0;
222  int numberFree=numberMembers_;
223  const int * integer = model_->integerVariable();
224  OsiSolverInterface * solver = model_->solver();
225  const double * solution = model_->currentSolution();
226  const double * lower = solver->getColLower();
227  const double * upper = solver->getColUpper();
228  int * upList = new int[numberMembers_];
229  int * downList = new int[numberMembers_];
230  double * sort = new double[numberMembers_];
231  double integerTolerance = 
232      model_->getDblParam(CbcModel::CbcIntegerTolerance);
233
234  double slackValue=0.0;
235  for (j=0;j<numberMembers_;j++) {
236    int sequence = members_[j];
237    int iColumn = integer[sequence];
238    double value = solution[iColumn];
239    value = CoinMax(value, lower[iColumn]);
240    value = CoinMin(value, upper[iColumn]);
241    double nearest = floor(value+0.5);
242    double distance = fabs(value-nearest);
243    if (distance>integerTolerance) {
244      if (!type_[j])
245        value = 1.0-value; // non SOS
246      // if slack then choose that
247      if (j==slack_&&value>0.05)
248        slackValue = value;
249      value = -value; // for sort
250      upList[numberUnsatis]=j;
251      sort[numberUnsatis++]=value;
252    } else if (upper[iColumn]>lower[iColumn]) {
253      upList[--numberFree]=j;
254    }
255  }
256  assert (numberUnsatis);
257  if (!slackValue) {
258    // sort
259    CoinSort_2(sort,sort+numberUnsatis,upList);
260    // put first in up etc
261    int kWay=1;
262    for (j=0;j<numberUnsatis;j++) {
263      if (kWay>0) 
264        upList[nUp++]=upList[j];
265      else
266        downList[nDown++]=upList[j];
267      kWay = -kWay;
268    }
269    for (j=numberFree;j<numberMembers_;j++) {
270      if (kWay>0)
271        upList[nUp++]=upList[j];
272      else
273        downList[nDown++]=upList[j];
274      kWay = -kWay;
275    }
276  } else {
277    // put slack to 0 in first way
278    nUp = 1;
279    upList[0]=slack_;
280    for (j=0;j<numberUnsatis;j++) {
281      downList[nDown++]=upList[j];
282    }
283    for (j=numberFree;j<numberMembers_;j++) {
284      downList[nDown++]=upList[j];
285    }
286  }
287  // create object
288  CbcBranchingObject * branch;
289  if (numberMembers_ <=64)
290     branch = new CbcCliqueBranchingObject(model_,this,way,
291                                         nDown,downList,nUp,upList);
292  else
293    branch = new CbcLongCliqueBranchingObject(model_,this,way,
294                                            nDown,downList,nUp,upList);
295  delete [] upList;
296  delete [] downList;
297  delete [] sort;
298  return branch;
299}
300
301// Default Constructor
302CbcSOS::CbcSOS ()
303  : CbcObject(),
304    members_(NULL),
305    weights_(NULL),
306    numberMembers_(0),
307    sosType_(-1)
308{
309}
310
311// Useful constructor (which are indices)
312CbcSOS::CbcSOS (CbcModel * model,  int numberMembers,
313           const int * which, const double * weights, int identifier,int type)
314  : CbcObject(model),
315    numberMembers_(numberMembers),
316    sosType_(type)
317{
318  id_=identifier;
319  if (numberMembers_) {
320    members_ = new int[numberMembers_];
321    weights_ = new double[numberMembers_];
322    memcpy(members_,which,numberMembers_*sizeof(int));
323    if (weights) {
324      memcpy(weights_,weights,numberMembers_*sizeof(double));
325    } else {
326      for (int i=0;i<numberMembers_;i++)
327        weights_[i]=i;
328    }
329    // sort so weights increasing
330    CoinSort_2(weights_,weights_+numberMembers_,members_);
331  } else {
332    members_ = NULL;
333    weights_ = NULL;
334  }
335  assert (sosType_>0&&sosType_<3);
336}
337
338// Copy constructor
339CbcSOS::CbcSOS ( const CbcSOS & rhs)
340  :CbcObject(rhs)
341{
342  numberMembers_ = rhs.numberMembers_;
343  sosType_ = rhs.sosType_;
344  if (numberMembers_) {
345    members_ = new int[numberMembers_];
346    weights_ = new double[numberMembers_];
347    memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
348    memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
349    weights_ = new double[numberMembers_];
350    memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
351  } else {
352    members_ = NULL;
353    weights_ = NULL;
354  }
355}
356
357// Clone
358CbcObject *
359CbcSOS::clone() const
360{
361  return new CbcSOS(*this);
362}
363
364// Assignment operator
365CbcSOS & 
366CbcSOS::operator=( const CbcSOS& rhs)
367{
368  if (this!=&rhs) {
369    CbcObject::operator=(rhs);
370    delete [] members_;
371    delete [] weights_;
372    numberMembers_ = rhs.numberMembers_;
373    sosType_ = rhs.sosType_;
374    if (numberMembers_) {
375      members_ = new int[numberMembers_];
376      weights_ = new double[numberMembers_];
377      memcpy(members_,rhs.members_,numberMembers_*sizeof(int));
378      memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
379      weights_ = new double[numberMembers_];
380      memcpy(weights_,rhs.weights_,numberMembers_*sizeof(double));
381    } else {
382      members_ = NULL;
383      weights_ = NULL;
384    }
385  }
386  return *this;
387}
388
389// Destructor
390CbcSOS::~CbcSOS ()
391{
392  delete [] members_;
393  delete [] weights_;
394}
395
396// Infeasibility - large is 0.5
397double 
398CbcSOS::infeasibility(int & preferredWay) const
399{
400  int j;
401  int firstNonZero=-1;
402  int lastNonZero = -1;
403  OsiSolverInterface * solver = model_->solver();
404  const double * solution = model_->currentSolution();
405  const double * lower = solver->getColLower();
406  const double * upper = solver->getColUpper();
407  //double largestValue=0.0;
408  double integerTolerance = 
409    model_->getDblParam(CbcModel::CbcIntegerTolerance);
410  double weight = 0.0;
411  double sum =0.0;
412
413  // check bounds etc
414  double lastWeight=-1.0e100;
415  for (j=0;j<numberMembers_;j++) {
416    int iColumn = members_[j];
417    if (lower[iColumn]&&(lower[iColumn]!=1.0||sosType_!=1))
418      throw CoinError("Non zero lower bound in SOS","constructor","CbcSOS");
419    if (lastWeight>=weights_[j]-1.0e-7)
420      throw CoinError("Weights too close together in SOS","constructor","CbcSOS");
421    double value = CoinMax(0.0,solution[iColumn]);
422    sum += value;
423    if (value>integerTolerance) {
424      // Possibly due to scaling a fixed variable might slip through
425      if (value>upper[iColumn]) {
426        // Could change to #ifdef CBC_DEBUG
427#ifndef NDEBUG
428        if (model_->messageHandler()->logLevel()>1)
429          printf("** Variable %d (%d) has value %g and upper bound of %g\n",
430                 iColumn,j,value,upper[iColumn]);
431#endif
432      } else {
433        weight += weights_[j]*value;
434        if (firstNonZero<0)
435          firstNonZero=j;
436        lastNonZero=j;
437      }
438    }
439  }
440  preferredWay=1;
441  if (lastNonZero-firstNonZero>=sosType_) {
442    // find where to branch
443    assert (sum>0.0);
444    weight /= sum;
445    int iWhere;
446    for (iWhere=firstNonZero;iWhere<lastNonZero;iWhere++) 
447      if (weight<weights_[iWhere+1])
448        break;
449    // probably best to use pseudo duals
450    double value = lastNonZero-firstNonZero+1;
451    value *= 0.5/((double) numberMembers_);
452    return value;
453  } else {
454    return 0.0; // satisfied
455  }
456}
457
458// This looks at solution and sets bounds to contain solution
459void 
460CbcSOS::feasibleRegion()
461{
462  int j;
463  int firstNonZero=-1;
464  int lastNonZero = -1;
465  OsiSolverInterface * solver = model_->solver();
466  const double * solution = model_->currentSolution();
467  //const double * lower = solver->getColLower();
468  const double * upper = solver->getColUpper();
469  double integerTolerance = 
470    model_->getDblParam(CbcModel::CbcIntegerTolerance);
471  double weight = 0.0;
472  double sum =0.0;
473
474  for (j=0;j<numberMembers_;j++) {
475    int iColumn = members_[j];
476    double value = CoinMax(0.0,solution[iColumn]);
477    sum += value;
478    if (value>integerTolerance&&upper[iColumn]) {
479      weight += weights_[j]*value;
480      if (firstNonZero<0)
481        firstNonZero=j;
482      lastNonZero=j;
483    }
484  }
485  assert (lastNonZero-firstNonZero<sosType_) ;
486  for (j=0;j<firstNonZero;j++) {
487    int iColumn = members_[j];
488    solver->setColUpper(iColumn,0.0);
489  }
490  for (j=lastNonZero+1;j<numberMembers_;j++) {
491    int iColumn = members_[j];
492    solver->setColUpper(iColumn,0.0);
493  }
494}
495
496
497// Creates a branching object
498CbcBranchingObject * 
499CbcSOS::createBranch(int way) const
500{
501  int j;
502  const double * solution = model_->currentSolution();
503  double integerTolerance = 
504      model_->getDblParam(CbcModel::CbcIntegerTolerance);
505  OsiSolverInterface * solver = model_->solver();
506  const double * upper = solver->getColUpper();
507  int firstNonFixed=-1;
508  int lastNonFixed=-1;
509  int firstNonZero=-1;
510  int lastNonZero = -1;
511  double weight = 0.0;
512  double sum =0.0;
513  for (j=0;j<numberMembers_;j++) {
514    int iColumn = members_[j];
515    if (upper[iColumn]) {
516      double value = CoinMax(0.0,solution[iColumn]);
517      sum += value;
518      if (firstNonFixed<0)
519        firstNonFixed=j;
520      lastNonFixed=j;
521      if (value>integerTolerance) {
522        weight += weights_[j]*value;
523        if (firstNonZero<0)
524          firstNonZero=j;
525        lastNonZero=j;
526      }
527    }
528  }
529  assert (lastNonZero-firstNonZero>=sosType_) ;
530  // find where to branch
531  assert (sum>0.0);
532  weight /= sum;
533  int iWhere;
534  double separator=0.0;
535  for (iWhere=firstNonZero;iWhere<lastNonZero;iWhere++) 
536    if (weight<weights_[iWhere+1])
537      break;
538  if (sosType_==1) {
539    // SOS 1
540    separator = 0.5 *(weights_[iWhere]+weights_[iWhere+1]);
541  } else {
542    // SOS 2
543    if (iWhere==firstNonFixed)
544      iWhere++;;
545    if (iWhere==lastNonFixed-1)
546      iWhere = lastNonFixed-2;
547    separator = weights_[iWhere+1];
548  }
549  // create object
550  CbcBranchingObject * branch;
551  branch = new CbcSOSBranchingObject(model_,this,way,separator);
552  return branch;
553}
554
555
556
557/** Default Constructor
558
559  Equivalent to an unspecified binary variable.
560*/
561CbcSimpleInteger::CbcSimpleInteger ()
562  : CbcObject(),
563    sequence_(-1),
564    columnNumber_(-1),
565    originalLower_(0.0),
566    originalUpper_(1.0),
567    breakEven_(0.5)
568{
569}
570
571/** Useful constructor
572
573  Loads actual upper & lower bounds for the specified variable.
574*/
575CbcSimpleInteger::CbcSimpleInteger (CbcModel * model, int sequence,
576                                    int iColumn, double breakEven)
577  : CbcObject(model)
578{
579  sequence_ = sequence ;
580  id_ = iColumn; // set as well
581  columnNumber_ = iColumn ;
582  originalLower_ = model_->solver()->getColLower()[columnNumber_] ;
583  originalUpper_ = model_->solver()->getColUpper()[columnNumber_] ;
584  breakEven_ = breakEven;
585  assert (breakEven_>0.0&&breakEven_<1.0);
586}
587
588// Copy constructor
589CbcSimpleInteger::CbcSimpleInteger ( const CbcSimpleInteger & rhs)
590  :CbcObject(rhs)
591
592{
593  sequence_ = rhs.sequence_;
594  columnNumber_ = rhs.columnNumber_;
595  originalLower_ = rhs.originalLower_;
596  originalUpper_ = rhs.originalUpper_;
597  breakEven_ = rhs.breakEven_;
598}
599
600// Clone
601CbcObject *
602CbcSimpleInteger::clone() const
603{
604  return new CbcSimpleInteger(*this);
605}
606
607// Assignment operator
608CbcSimpleInteger & 
609CbcSimpleInteger::operator=( const CbcSimpleInteger& rhs)
610{
611  if (this!=&rhs) {
612    CbcObject::operator=(rhs);
613    columnNumber_ = model_->integerVariable()[sequence_];
614    breakEven_ = rhs.breakEven_;
615  }
616  return *this;
617}
618
619// Destructor
620CbcSimpleInteger::~CbcSimpleInteger ()
621{
622}
623
624// Infeasibility - large is 0.5
625double 
626CbcSimpleInteger::infeasibility(int & preferredWay) const
627{
628  OsiSolverInterface * solver = model_->solver();
629  const double * solution = model_->currentSolution();
630  const double * lower = solver->getColLower();
631  const double * upper = solver->getColUpper();
632  double value = solution[columnNumber_];
633  value = CoinMax(value, lower[columnNumber_]);
634  value = CoinMin(value, upper[columnNumber_]);
635  /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
636    solution[columnNumber_],upper[columnNumber_]);*/
637  double nearest = floor(value+(1.0-breakEven_));
638  double integerTolerance = 
639    model_->getDblParam(CbcModel::CbcIntegerTolerance);
640  if (nearest>value) 
641    preferredWay=1;
642  else
643    preferredWay=-1;
644  double weight = fabs(value-nearest);
645  // normalize so weight is 0.5 at break even
646  if (nearest<value)
647    weight = (0.5/breakEven_)*weight;
648  else
649    weight = (0.5/(1.0-breakEven_))*weight;
650  if (fabs(value-nearest)<=integerTolerance) 
651    return 0.0;
652  else
653    return weight;
654}
655
656// This looks at solution and sets bounds to contain solution
657/** More precisely: it first forces the variable within the existing
658    bounds, and then tightens the bounds to fix the variable at the
659    nearest integer value.
660*/
661void 
662CbcSimpleInteger::feasibleRegion()
663{
664  OsiSolverInterface * solver = model_->solver();
665  const double * lower = solver->getColLower();
666  const double * upper = solver->getColUpper();
667  const double * solution = model_->currentSolution();
668  double value = solution[columnNumber_];
669  value = CoinMax(value, lower[columnNumber_]);
670  value = CoinMin(value, upper[columnNumber_]);
671
672  double nearest = floor(value+0.5);
673  //double integerTolerance =
674  //model_->getDblParam(CbcModel::CbcIntegerTolerance);
675  // Scaling may have moved it a bit
676  //assert (fabs(value-nearest)<=100.0*integerTolerance);
677  assert (fabs(value-nearest)<=0.01);
678  solver->setColLower(columnNumber_,nearest);
679  solver->setColUpper(columnNumber_,nearest);
680}
681
682// Creates a branching object
683CbcBranchingObject * 
684CbcSimpleInteger::createBranch(int way) const
685{
686  OsiSolverInterface * solver = model_->solver();
687  const double * solution = model_->currentSolution();
688  const double * lower = solver->getColLower();
689  const double * upper = solver->getColUpper();
690  double value = solution[columnNumber_];
691  value = CoinMax(value, lower[columnNumber_]);
692  value = CoinMin(value, upper[columnNumber_]);
693  double nearest = floor(value+0.5);
694  double integerTolerance = 
695    model_->getDblParam(CbcModel::CbcIntegerTolerance);
696  assert (upper[columnNumber_]>lower[columnNumber_]);
697  int hotstartStrategy=model_->getHotstartStrategy();
698  if (hotstartStrategy<=0) {
699    assert (fabs(value-nearest)>integerTolerance);
700  } else {
701    const double * bestSolution = model_->bestSolution();
702    double targetValue = bestSolution[columnNumber_];
703    if (way>0)
704      value = targetValue-0.1;
705    else
706      value = targetValue+0.1;
707  }
708  return new CbcIntegerBranchingObject(model_,sequence_,way,
709                                             value);
710}
711
712
713/* Given valid solution (i.e. satisfied) and reduced costs etc
714   returns a branching object which would give a new feasible
715   point in direction reduced cost says would be cheaper.
716   If no feasible point returns null
717*/
718CbcBranchingObject * 
719CbcSimpleInteger::preferredNewFeasible() const
720{
721  OsiSolverInterface * solver = model_->solver();
722  double value = model_->currentSolution()[columnNumber_];
723
724  double nearest = floor(value+0.5);
725  double integerTolerance = 
726    model_->getDblParam(CbcModel::CbcIntegerTolerance);
727  assert (fabs(value-nearest)<=integerTolerance);
728  double dj = solver->getObjSense()*solver->getReducedCost()[columnNumber_];
729  CbcIntegerBranchingObject * object = NULL;
730  if (dj>=0.0) {
731    // can we go down
732    if (nearest>originalLower_+0.5) {
733      // yes
734      object = new CbcIntegerBranchingObject(model_,sequence_,-1,
735                                             nearest-1.0,nearest-1.0);
736    }
737  } else {
738    // can we go up
739    if (nearest<originalUpper_-0.5) {
740      // yes
741      object = new CbcIntegerBranchingObject(model_,sequence_,-1,
742                                             nearest+1.0,nearest+1.0);
743    }
744  }
745  return object;
746}
747 
748/* Given valid solution (i.e. satisfied) and reduced costs etc
749   returns a branching object which would give a new feasible
750   point in direction opposite to one reduced cost says would be cheaper.
751   If no feasible point returns null
752*/
753CbcBranchingObject * 
754CbcSimpleInteger::notPreferredNewFeasible() const 
755{
756  OsiSolverInterface * solver = model_->solver();
757  double value = model_->currentSolution()[columnNumber_];
758
759  double nearest = floor(value+0.5);
760  double integerTolerance = 
761    model_->getDblParam(CbcModel::CbcIntegerTolerance);
762  assert (fabs(value-nearest)<=integerTolerance);
763  double dj = solver->getObjSense()*solver->getReducedCost()[columnNumber_];
764  CbcIntegerBranchingObject * object = NULL;
765  if (dj<=0.0) {
766    // can we go down
767    if (nearest>originalLower_+0.5) {
768      // yes
769      object = new CbcIntegerBranchingObject(model_,sequence_,-1,
770                                             nearest-1.0,nearest-1.0);
771    }
772  } else {
773    // can we go up
774    if (nearest<originalUpper_-0.5) {
775      // yes
776      object = new CbcIntegerBranchingObject(model_,sequence_,-1,
777                                             nearest+1.0,nearest+1.0);
778    }
779  }
780  return object;
781}
782 
783/*
784  Bounds may be tightened, so it may be good to be able to refresh the local
785  copy of the original bounds.
786 */
787void 
788CbcSimpleInteger::resetBounds()
789{
790  originalLower_ = model_->solver()->getColLower()[columnNumber_];
791  originalUpper_ = model_->solver()->getColUpper()[columnNumber_];
792}
793
794
795// Default Constructor
796CbcIntegerBranchingObject::CbcIntegerBranchingObject()
797  :CbcBranchingObject()
798{
799  down_[0] = 0.0;
800  down_[1] = 0.0;
801  up_[0] = 0.0;
802  up_[1] = 0.0;
803}
804
805// Useful constructor
806CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
807                                                      int variable, int way , double value)
808  :CbcBranchingObject(model,variable,way,value)
809{
810  int iColumn = model_->integerVariable()[variable_];
811  down_[0] = model_->solver()->getColLower()[iColumn];
812  down_[1] = floor(value_);
813  up_[0] = ceil(value_);
814  up_[1] = model->getColUpper()[iColumn];
815}
816// Useful constructor for fixing
817CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
818                                                      int variable, int way,
819                                                      double lowerValue, 
820                                                      double upperValue)
821  :CbcBranchingObject(model,variable,way,lowerValue)
822{
823  numberBranchesLeft_=1;
824  down_[0] = lowerValue;
825  down_[1] = upperValue;
826  up_[0] = lowerValue;
827  up_[1] = upperValue;
828}
829 
830
831// Copy constructor
832CbcIntegerBranchingObject::CbcIntegerBranchingObject ( const CbcIntegerBranchingObject & rhs) :CbcBranchingObject(rhs)
833{
834  down_[0] = rhs.down_[0];
835  down_[1] = rhs.down_[1];
836  up_[0] = rhs.up_[0];
837  up_[1] = rhs.up_[1];
838}
839
840// Assignment operator
841CbcIntegerBranchingObject & 
842CbcIntegerBranchingObject::operator=( const CbcIntegerBranchingObject& rhs)
843{
844  if (this != &rhs) {
845    CbcBranchingObject::operator=(rhs);
846    down_[0] = rhs.down_[0];
847    down_[1] = rhs.down_[1];
848    up_[0] = rhs.up_[0];
849    up_[1] = rhs.up_[1];
850  }
851  return *this;
852}
853CbcBranchingObject * 
854CbcIntegerBranchingObject::clone() const
855{ 
856  return (new CbcIntegerBranchingObject(*this));
857}
858
859
860// Destructor
861CbcIntegerBranchingObject::~CbcIntegerBranchingObject ()
862{
863}
864
865/*
866  Perform a branch by adjusting the bounds of the specified variable. Note
867  that each arm of the branch advances the object to the next arm by
868  advancing the value of way_.
869
870  Providing new values for the variable's lower and upper bounds for each
871  branching direction gives a little bit of additional flexibility and will
872  be easily extensible to multi-way branching.
873  Returns change in guessed objective on next branch
874*/
875double
876CbcIntegerBranchingObject::branch(bool normalBranch)
877{
878  if (model_->messageHandler()->logLevel()>2&&normalBranch)
879    print(normalBranch);
880  numberBranchesLeft_--;
881  int iColumn = model_->integerVariable()[variable_];
882  if (way_<0) {
883#ifdef CBC_DEBUG
884  { double olb,oub ;
885    olb = model_->solver()->getColLower()[iColumn] ;
886    oub = model_->solver()->getColUpper()[iColumn] ;
887    printf("branching down on var %d: [%g,%g] => [%g,%g]\n",
888           iColumn,olb,oub,down_[0],down_[1]) ; }
889#endif
890    model_->solver()->setColLower(iColumn,down_[0]);
891    model_->solver()->setColUpper(iColumn,down_[1]);
892    way_=1;
893  } else {
894#ifdef CBC_DEBUG
895  { double olb,oub ;
896    olb = model_->solver()->getColLower()[iColumn] ;
897    oub = model_->solver()->getColUpper()[iColumn] ;
898    printf("branching up on var %d: [%g,%g] => [%g,%g]\n",
899           iColumn,olb,oub,up_[0],up_[1]) ; }
900#endif
901    model_->solver()->setColLower(iColumn,up_[0]);
902    model_->solver()->setColUpper(iColumn,up_[1]);
903    way_=-1;      // Swap direction
904  }
905  return 0.0;
906}
907// Print what would happen 
908void
909CbcIntegerBranchingObject::print(bool normalBranch)
910{
911  int iColumn = model_->integerVariable()[variable_];
912  if (way_<0) {
913  { double olb,oub ;
914    olb = model_->solver()->getColLower()[iColumn] ;
915    oub = model_->solver()->getColUpper()[iColumn] ;
916    printf("CbcInteger would branch down on var %d: [%g,%g] => [%g,%g]\n",
917           iColumn,olb,oub,down_[0],down_[1]) ; }
918  } else {
919  { double olb,oub ;
920    olb = model_->solver()->getColLower()[iColumn] ;
921    oub = model_->solver()->getColUpper()[iColumn] ;
922    printf("CbcInteger would branch up on var %d: [%g,%g] => [%g,%g]\n",
923           iColumn,olb,oub,up_[0],up_[1]) ; }
924  }
925}
926
927
928/** Default Constructor
929
930  Equivalent to an unspecified binary variable.
931*/
932CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ()
933  : CbcSimpleInteger(),
934    downPseudoCost_(1.0e-5),
935    upPseudoCost_(1.0e-5),
936    method_(0)
937{
938}
939
940/** Useful constructor
941
942  Loads actual upper & lower bounds for the specified variable.
943*/
944CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, int sequence,
945                                    int iColumn, double breakEven)
946  : CbcSimpleInteger(model,sequence,iColumn,breakEven)
947{
948  const double * cost = model->getObjCoefficients();
949  double costValue = CoinMax(1.0e-5,fabs(cost[iColumn]));
950  // treat as if will cost what it says up
951  upPseudoCost_=costValue;
952  // and balance at breakeven
953  downPseudoCost_=((1.0-breakEven_)*upPseudoCost_)/breakEven_;
954  method_=0;
955}
956
957/** Useful constructor
958
959  Loads actual upper & lower bounds for the specified variable.
960*/
961CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, int sequence,
962                                    int iColumn, double downPseudoCost,
963                                                        double upPseudoCost)
964  : CbcSimpleInteger(model,sequence,iColumn)
965{
966  downPseudoCost_ = downPseudoCost;
967  upPseudoCost_ = upPseudoCost;
968  breakEven_ = upPseudoCost_/(upPseudoCost_+downPseudoCost_);
969  method_=0;
970}
971
972// Copy constructor
973CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ( const CbcSimpleIntegerPseudoCost & rhs)
974  :CbcSimpleInteger(rhs),
975   downPseudoCost_(rhs.downPseudoCost_),
976   upPseudoCost_(rhs.upPseudoCost_),
977   method_(rhs.method_)
978
979{
980}
981
982// Clone
983CbcObject *
984CbcSimpleIntegerPseudoCost::clone() const
985{
986  return new CbcSimpleIntegerPseudoCost(*this);
987}
988
989// Assignment operator
990CbcSimpleIntegerPseudoCost & 
991CbcSimpleIntegerPseudoCost::operator=( const CbcSimpleIntegerPseudoCost& rhs)
992{
993  if (this!=&rhs) {
994    CbcSimpleInteger::operator=(rhs);
995    downPseudoCost_=rhs.downPseudoCost_;
996    upPseudoCost_=rhs.upPseudoCost_;
997    method_=rhs.method_;
998  }
999  return *this;
1000}
1001
1002// Destructor
1003CbcSimpleIntegerPseudoCost::~CbcSimpleIntegerPseudoCost ()
1004{
1005}
1006// Creates a branching object
1007CbcBranchingObject * 
1008CbcSimpleIntegerPseudoCost::createBranch(int way) const
1009{
1010  OsiSolverInterface * solver = model_->solver();
1011  const double * solution = model_->currentSolution();
1012  const double * lower = solver->getColLower();
1013  const double * upper = solver->getColUpper();
1014  double value = solution[columnNumber_];
1015  value = CoinMax(value, lower[columnNumber_]);
1016  value = CoinMin(value, upper[columnNumber_]);
1017  double nearest = floor(value+0.5);
1018  double integerTolerance = 
1019    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1020  assert (upper[columnNumber_]>lower[columnNumber_]);
1021  int hotstartStrategy=model_->getHotstartStrategy();
1022  if (hotstartStrategy<=0) {
1023    assert (fabs(value-nearest)>integerTolerance);
1024  } else {
1025    const double * bestSolution = model_->bestSolution();
1026    double targetValue = bestSolution[columnNumber_];
1027    if (way>0)
1028      value = targetValue-0.1;
1029    else
1030      value = targetValue+0.1;
1031  }
1032  CbcIntegerPseudoCostBranchingObject * newObject = 
1033    new CbcIntegerPseudoCostBranchingObject(model_,sequence_,way,
1034                                            value);
1035  double up =  upPseudoCost_*(ceil(value)-value);
1036  double down =  downPseudoCost_*(value-floor(value));
1037  double changeInGuessed=up-down;
1038  if (way>0)
1039    changeInGuessed = - changeInGuessed;
1040  changeInGuessed=CoinMax(0.0,changeInGuessed);
1041  //if (way>0)
1042  //changeInGuessed += 1.0e8; // bias to stay up
1043  newObject->setChangeInGuessed(changeInGuessed);
1044  return newObject;
1045}
1046// Infeasibility - large is 0.5
1047double 
1048CbcSimpleIntegerPseudoCost::infeasibility(int & preferredWay) const
1049{
1050  OsiSolverInterface * solver = model_->solver();
1051  const double * solution = model_->currentSolution();
1052  const double * lower = solver->getColLower();
1053  const double * upper = solver->getColUpper();
1054  if (upper[columnNumber_]==lower[columnNumber_]) {
1055    // fixed
1056    preferredWay=1;
1057    return 0.0;
1058  }
1059  double value = solution[columnNumber_];
1060  value = CoinMax(value, lower[columnNumber_]);
1061  value = CoinMin(value, upper[columnNumber_]);
1062  /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
1063    solution[columnNumber_],upper[columnNumber_]);*/
1064  double nearest = floor(value+0.5);
1065  double integerTolerance = 
1066    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1067  double below = floor(value+integerTolerance);
1068  double above = below+1.0;
1069  if (above>upper[columnNumber_]) {
1070    above=below;
1071    below = above -1;
1072  }
1073  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1074  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1075  if (downCost>=upCost)
1076    preferredWay=1;
1077  else
1078    preferredWay=-1;
1079  if (fabs(value-nearest)<=integerTolerance) {
1080    return 0.0;
1081  } else {
1082    // can't get at model so 1,2 don't make sense
1083    assert(method_<1||method_>2);
1084    if (!method_)
1085      return CoinMin(downCost,upCost);
1086    else
1087      return CoinMax(downCost,upCost);
1088  }
1089}
1090
1091// Return "up" estimate
1092double 
1093CbcSimpleIntegerPseudoCost::upEstimate() const
1094{
1095  OsiSolverInterface * solver = model_->solver();
1096  const double * solution = model_->currentSolution();
1097  const double * lower = solver->getColLower();
1098  const double * upper = solver->getColUpper();
1099  double value = solution[columnNumber_];
1100  value = CoinMax(value, lower[columnNumber_]);
1101  value = CoinMin(value, upper[columnNumber_]);
1102  if (upper[columnNumber_]==lower[columnNumber_]) {
1103    // fixed
1104    return 0.0;
1105  }
1106  double integerTolerance = 
1107    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1108  double below = floor(value+integerTolerance);
1109  double above = below+1.0;
1110  if (above>upper[columnNumber_]) {
1111    above=below;
1112    below = above -1;
1113  }
1114  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1115  return upCost;
1116}
1117// Return "down" estimate
1118double 
1119CbcSimpleIntegerPseudoCost::downEstimate() const
1120{
1121  OsiSolverInterface * solver = model_->solver();
1122  const double * solution = model_->currentSolution();
1123  const double * lower = solver->getColLower();
1124  const double * upper = solver->getColUpper();
1125  double value = solution[columnNumber_];
1126  value = CoinMax(value, lower[columnNumber_]);
1127  value = CoinMin(value, upper[columnNumber_]);
1128  if (upper[columnNumber_]==lower[columnNumber_]) {
1129    // fixed
1130    return 0.0;
1131  }
1132  double integerTolerance = 
1133    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1134  double below = floor(value+integerTolerance);
1135  double above = below+1.0;
1136  if (above>upper[columnNumber_]) {
1137    above=below;
1138    below = above -1;
1139  }
1140  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1141  return downCost;
1142}
1143
1144// Default Constructor
1145CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject()
1146  :CbcIntegerBranchingObject()
1147{
1148  changeInGuessed_=1.0e-5;
1149}
1150
1151// Useful constructor
1152CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1153                                                      int variable, int way , double value)
1154  :CbcIntegerBranchingObject(model,variable,way,value)
1155{
1156}
1157// Useful constructor for fixing
1158CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1159                                                      int variable, int way,
1160                                                      double lowerValue, 
1161                                                      double upperValue)
1162  :CbcIntegerBranchingObject(model,variable,way,lowerValue)
1163{
1164  changeInGuessed_=1.0e100;
1165}
1166 
1167
1168// Copy constructor
1169CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject ( 
1170                                 const CbcIntegerPseudoCostBranchingObject & rhs)
1171  :CbcIntegerBranchingObject(rhs)
1172{
1173  changeInGuessed_ = rhs.changeInGuessed_;
1174}
1175
1176// Assignment operator
1177CbcIntegerPseudoCostBranchingObject & 
1178CbcIntegerPseudoCostBranchingObject::operator=( const CbcIntegerPseudoCostBranchingObject& rhs)
1179{
1180  if (this != &rhs) {
1181    CbcIntegerBranchingObject::operator=(rhs);
1182    changeInGuessed_ = rhs.changeInGuessed_;
1183  }
1184  return *this;
1185}
1186CbcBranchingObject * 
1187CbcIntegerPseudoCostBranchingObject::clone() const
1188{ 
1189  return (new CbcIntegerPseudoCostBranchingObject(*this));
1190}
1191
1192
1193// Destructor
1194CbcIntegerPseudoCostBranchingObject::~CbcIntegerPseudoCostBranchingObject ()
1195{
1196}
1197
1198/*
1199  Perform a branch by adjusting the bounds of the specified variable. Note
1200  that each arm of the branch advances the object to the next arm by
1201  advancing the value of way_.
1202
1203  Providing new values for the variable's lower and upper bounds for each
1204  branching direction gives a little bit of additional flexibility and will
1205  be easily extensible to multi-way branching.
1206  Returns change in guessed objective on next branch
1207*/
1208double
1209CbcIntegerPseudoCostBranchingObject::branch(bool normalBranch)
1210{
1211  CbcIntegerBranchingObject::branch(normalBranch);
1212  return changeInGuessed_;
1213}
1214
1215
1216// Default Constructor
1217CbcCliqueBranchingObject::CbcCliqueBranchingObject()
1218  :CbcBranchingObject()
1219{
1220  clique_ = NULL;
1221  downMask_[0]=0;
1222  downMask_[1]=0;
1223  upMask_[0]=0;
1224  upMask_[1]=0;
1225}
1226
1227// Useful constructor
1228CbcCliqueBranchingObject::CbcCliqueBranchingObject (CbcModel * model,
1229                                                    const CbcClique * clique,
1230                                                    int way ,
1231                                                    int numberOnDownSide, const int * down,
1232                                                    int numberOnUpSide, const int * up)
1233  :CbcBranchingObject(model,clique->id(),way,0.5)
1234{
1235  clique_ = clique;
1236  downMask_[0]=0;
1237  downMask_[1]=0;
1238  upMask_[0]=0;
1239  upMask_[1]=0;
1240  int i;
1241  for (i=0;i<numberOnDownSide;i++) {
1242    int sequence = down[i];
1243    int iWord = sequence>>5;
1244    int iBit = sequence - 32*iWord;
1245    unsigned int k = 1<<iBit;
1246    downMask_[iWord] |= k;
1247  }
1248  for (i=0;i<numberOnUpSide;i++) {
1249    int sequence = up[i];
1250    int iWord = sequence>>5;
1251    int iBit = sequence - 32*iWord;
1252    unsigned int k = 1<<iBit;
1253    upMask_[iWord] |= k;
1254  }
1255}
1256
1257// Copy constructor
1258CbcCliqueBranchingObject::CbcCliqueBranchingObject ( const CbcCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
1259{
1260  clique_=rhs.clique_;
1261  downMask_[0]=rhs.downMask_[0];
1262  downMask_[1]=rhs.downMask_[1];
1263  upMask_[0]=rhs.upMask_[0];
1264  upMask_[1]=rhs.upMask_[1];
1265}
1266
1267// Assignment operator
1268CbcCliqueBranchingObject & 
1269CbcCliqueBranchingObject::operator=( const CbcCliqueBranchingObject& rhs)
1270{
1271  if (this != &rhs) {
1272    CbcBranchingObject::operator=(rhs);
1273    clique_=rhs.clique_;
1274    downMask_[0]=rhs.downMask_[0];
1275    downMask_[1]=rhs.downMask_[1];
1276    upMask_[0]=rhs.upMask_[0];
1277    upMask_[1]=rhs.upMask_[1];
1278  }
1279  return *this;
1280}
1281CbcBranchingObject * 
1282CbcCliqueBranchingObject::clone() const
1283{ 
1284  return (new CbcCliqueBranchingObject(*this));
1285}
1286
1287
1288// Destructor
1289CbcCliqueBranchingObject::~CbcCliqueBranchingObject ()
1290{
1291}
1292double
1293CbcCliqueBranchingObject::branch(bool normalBranch)
1294{
1295  if (model_->messageHandler()->logLevel()>2&&normalBranch)
1296    print(normalBranch);
1297  numberBranchesLeft_--;
1298  int iWord;
1299  int numberMembers = clique_->numberMembers();
1300  const int * which = clique_->members();
1301  const int * integerVariables = model_->integerVariable();
1302  int numberWords=(numberMembers+31)>>5;
1303  // *** for way - up means fix all those in down section
1304  if (way_<0) {
1305#ifdef FULL_PRINT
1306    printf("Down Fix ");
1307#endif
1308    for (iWord=0;iWord<numberWords;iWord++) {
1309      int i;
1310      for (i=0;i<32;i++) {
1311        unsigned int k = 1<<i;
1312        if ((upMask_[iWord]&k)!=0) {
1313          int iColumn = which[i+32*iWord];
1314#ifdef FULL_PRINT
1315          printf("%d ",i+32*iWord);
1316#endif
1317          // fix weak way
1318          if (clique_->type(i+32*iWord))
1319            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1320          else
1321            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1322        }
1323      }
1324    }
1325    way_=1;       // Swap direction
1326  } else {
1327#ifdef FULL_PRINT
1328    printf("Up Fix ");
1329#endif
1330    for (iWord=0;iWord<numberWords;iWord++) {
1331      int i;
1332      for (i=0;i<32;i++) {
1333        unsigned int k = 1<<i;
1334        if ((downMask_[iWord]&k)!=0) {
1335          int iColumn = which[i+32*iWord];
1336#ifdef FULL_PRINT
1337          printf("%d ",i+32*iWord);
1338#endif
1339          // fix weak way
1340          if (clique_->type(i+32*iWord))
1341            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1342          else
1343            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1344        }
1345      }
1346    }
1347    way_=-1;      // Swap direction
1348  }
1349#ifdef FULL_PRINT
1350  printf("\n");
1351#endif
1352  return 0.0;
1353}
1354// Print what would happen 
1355void
1356CbcCliqueBranchingObject::print(bool normalBranch)
1357{
1358  int iWord;
1359  int numberMembers = clique_->numberMembers();
1360  const int * which = clique_->members();
1361  const int * integerVariables = model_->integerVariable();
1362  int numberWords=(numberMembers+31)>>5;
1363  // *** for way - up means fix all those in down section
1364  if (way_<0) {
1365    printf("Clique - Down Fix ");
1366    for (iWord=0;iWord<numberWords;iWord++) {
1367      int i;
1368      for (i=0;i<32;i++) {
1369        unsigned int k = 1<<i;
1370        if ((upMask_[iWord]&k)!=0) {
1371          int iColumn = which[i+32*iWord];
1372          printf("%d ",integerVariables[iColumn]);
1373        }
1374      }
1375    }
1376  } else {
1377    printf("Clique - Up Fix ");
1378    for (iWord=0;iWord<numberWords;iWord++) {
1379      int i;
1380      for (i=0;i<32;i++) {
1381        unsigned int k = 1<<i;
1382        if ((downMask_[iWord]&k)!=0) {
1383          int iColumn = which[i+32*iWord];
1384          printf("%d ",integerVariables[iColumn]);
1385        }
1386      }
1387    }
1388  }
1389  printf("\n");
1390}
1391 
1392// Default Constructor
1393CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject()
1394  :CbcBranchingObject()
1395{
1396  clique_=NULL;
1397  downMask_=NULL;
1398  upMask_=NULL;
1399}
1400
1401// Useful constructor
1402CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject (CbcModel * model,
1403                                                            const CbcClique * clique, 
1404                                                            int way ,
1405                                                    int numberOnDownSide, const int * down,
1406                                                    int numberOnUpSide, const int * up)
1407  :CbcBranchingObject(model,clique->id(),way,0.5)
1408{
1409  clique_ = clique;
1410  int numberMembers = clique_->numberMembers();
1411  int numberWords=(numberMembers+31)>>5;
1412  downMask_ = new unsigned int [numberWords];
1413  upMask_ = new unsigned int [numberWords];
1414  memset(downMask_,0,numberWords*sizeof(unsigned int));
1415  memset(upMask_,0,numberWords*sizeof(unsigned int));
1416  int i;
1417  for (i=0;i<numberOnDownSide;i++) {
1418    int sequence = down[i];
1419    int iWord = sequence>>5;
1420    int iBit = sequence - 32*iWord;
1421    unsigned int k = 1<<iBit;
1422    downMask_[iWord] |= k;
1423  }
1424  for (i=0;i<numberOnUpSide;i++) {
1425    int sequence = up[i];
1426    int iWord = sequence>>5;
1427    int iBit = sequence - 32*iWord;
1428    unsigned int k = 1<<iBit;
1429    upMask_[iWord] |= k;
1430  }
1431}
1432
1433// Copy constructor
1434CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject ( const CbcLongCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
1435{
1436  clique_=rhs.clique_;
1437  if (rhs.downMask_) {
1438    int numberMembers = clique_->numberMembers();
1439    int numberWords=(numberMembers+31)>>5;
1440    downMask_ = new unsigned int [numberWords];
1441    memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
1442    upMask_ = new unsigned int [numberWords];
1443    memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
1444  } else {
1445    downMask_=NULL;
1446    upMask_=NULL;
1447  }   
1448}
1449
1450// Assignment operator
1451CbcLongCliqueBranchingObject & 
1452CbcLongCliqueBranchingObject::operator=( const CbcLongCliqueBranchingObject& rhs)
1453{
1454  if (this != &rhs) {
1455    CbcBranchingObject::operator=(rhs);
1456    clique_=rhs.clique_;
1457    delete [] downMask_;
1458    delete [] upMask_;
1459    if (rhs.downMask_) {
1460      int numberMembers = clique_->numberMembers();
1461      int numberWords=(numberMembers+31)>>5;
1462      downMask_ = new unsigned int [numberWords];
1463      memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
1464      upMask_ = new unsigned int [numberWords];
1465      memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
1466    } else {
1467      downMask_=NULL;
1468      upMask_=NULL;
1469    }   
1470  }
1471  return *this;
1472}
1473CbcBranchingObject * 
1474CbcLongCliqueBranchingObject::clone() const
1475{ 
1476  return (new CbcLongCliqueBranchingObject(*this));
1477}
1478
1479
1480// Destructor
1481CbcLongCliqueBranchingObject::~CbcLongCliqueBranchingObject ()
1482{
1483  delete [] downMask_;
1484  delete [] upMask_;
1485}
1486double
1487CbcLongCliqueBranchingObject::branch(bool normalBranch)
1488{
1489  if (model_->messageHandler()->logLevel()>2&&normalBranch)
1490    print(normalBranch);
1491  numberBranchesLeft_--;
1492  int iWord;
1493  int numberMembers = clique_->numberMembers();
1494  const int * which = clique_->members();
1495  const int * integerVariables = model_->integerVariable();
1496  int numberWords=(numberMembers+31)>>5;
1497  // *** for way - up means fix all those in down section
1498  if (way_<0) {
1499#ifdef FULL_PRINT
1500    printf("Down Fix ");
1501#endif
1502    for (iWord=0;iWord<numberWords;iWord++) {
1503      int i;
1504      for (i=0;i<32;i++) {
1505        unsigned int k = 1<<i;
1506        if ((upMask_[iWord]&k)!=0) {
1507          int iColumn = which[i+32*iWord];
1508#ifdef FULL_PRINT
1509          printf("%d ",i+32*iWord);
1510#endif
1511          // fix weak way
1512          if (clique_->type(i+32*iWord))
1513            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1514          else
1515            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1516        }
1517      }
1518    }
1519    way_=1;       // Swap direction
1520  } else {
1521#ifdef FULL_PRINT
1522    printf("Up Fix ");
1523#endif
1524    for (iWord=0;iWord<numberWords;iWord++) {
1525      int i;
1526      for (i=0;i<32;i++) {
1527        unsigned int k = 1<<i;
1528        if ((downMask_[iWord]&k)!=0) {
1529          int iColumn = which[i+32*iWord];
1530#ifdef FULL_PRINT
1531          printf("%d ",i+32*iWord);
1532#endif
1533          // fix weak way
1534          if (clique_->type(i+32*iWord))
1535            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1536          else
1537            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1538        }
1539      }
1540    }
1541    way_=-1;      // Swap direction
1542  }
1543#ifdef FULL_PRINT
1544  printf("\n");
1545#endif
1546  return 0.0;
1547}
1548void
1549CbcLongCliqueBranchingObject::print(bool normalBranch)
1550{
1551  int iWord;
1552  int numberMembers = clique_->numberMembers();
1553  const int * which = clique_->members();
1554  const int * integerVariables = model_->integerVariable();
1555  int numberWords=(numberMembers+31)>>5;
1556  // *** for way - up means fix all those in down section
1557  if (way_<0) {
1558    printf("Clique - Down Fix ");
1559    for (iWord=0;iWord<numberWords;iWord++) {
1560      int i;
1561      for (i=0;i<32;i++) {
1562        unsigned int k = 1<<i;
1563        if ((upMask_[iWord]&k)!=0) {
1564          int iColumn = which[i+32*iWord];
1565          printf("%d ",integerVariables[iColumn]);
1566        }
1567      }
1568    }
1569  } else {
1570    printf("Clique - Up Fix ");
1571    for (iWord=0;iWord<numberWords;iWord++) {
1572      int i;
1573      for (i=0;i<32;i++) {
1574        unsigned int k = 1<<i;
1575        if ((downMask_[iWord]&k)!=0) {
1576          int iColumn = which[i+32*iWord];
1577          printf("%d ",integerVariables[iColumn]);
1578        }
1579      }
1580    }
1581  }
1582  printf("\n");
1583}
1584// Default Constructor
1585CbcSOSBranchingObject::CbcSOSBranchingObject()
1586  :CbcBranchingObject()
1587{
1588  set_ = NULL;
1589  separator_=0.0;
1590}
1591
1592// Useful constructor
1593CbcSOSBranchingObject::CbcSOSBranchingObject (CbcModel * model,
1594                                              const CbcSOS * set,
1595                                              int way ,
1596                                              double separator)
1597  :CbcBranchingObject(model,set->id(),way,0.5)
1598{
1599  set_ = set;
1600  separator_ = separator;
1601}
1602
1603// Copy constructor
1604CbcSOSBranchingObject::CbcSOSBranchingObject ( const CbcSOSBranchingObject & rhs) :CbcBranchingObject(rhs)
1605{
1606  set_=rhs.set_;
1607  separator_ = rhs.separator_;
1608}
1609
1610// Assignment operator
1611CbcSOSBranchingObject & 
1612CbcSOSBranchingObject::operator=( const CbcSOSBranchingObject& rhs)
1613{
1614  if (this != &rhs) {
1615    CbcBranchingObject::operator=(rhs);
1616    set_=rhs.set_;
1617    separator_ = rhs.separator_;
1618  }
1619  return *this;
1620}
1621CbcBranchingObject * 
1622CbcSOSBranchingObject::clone() const
1623{ 
1624  return (new CbcSOSBranchingObject(*this));
1625}
1626
1627
1628// Destructor
1629CbcSOSBranchingObject::~CbcSOSBranchingObject ()
1630{
1631}
1632double
1633CbcSOSBranchingObject::branch(bool normalBranch)
1634{
1635  if (model_->messageHandler()->logLevel()>2&&normalBranch)
1636    print(normalBranch);
1637  numberBranchesLeft_--;
1638  int numberMembers = set_->numberMembers();
1639  const int * which = set_->members();
1640  const double * weights = set_->weights();
1641  OsiSolverInterface * solver = model_->solver();
1642  //const double * lower = solver->getColLower();
1643  //const double * upper = solver->getColUpper();
1644  // *** for way - up means fix all those in down section
1645  if (way_<0) {
1646    int i;
1647    for ( i=0;i<numberMembers;i++) {
1648      if (weights[i] > separator_)
1649        break;
1650    }
1651    assert (i<numberMembers);
1652    for (;i<numberMembers;i++) 
1653      solver->setColUpper(which[i],0.0);
1654    way_=1;       // Swap direction
1655  } else {
1656    int i;
1657    for ( i=0;i<numberMembers;i++) {
1658      if (weights[i] >= separator_)
1659        break;
1660      else
1661        solver->setColUpper(which[i],0.0);
1662    }
1663    assert (i<numberMembers);
1664    way_=-1;      // Swap direction
1665  }
1666  return 0.0;
1667}
1668// Print what would happen 
1669void
1670CbcSOSBranchingObject::print(bool normalBranch)
1671{
1672  int numberMembers = set_->numberMembers();
1673  const int * which = set_->members();
1674  const double * weights = set_->weights();
1675  OsiSolverInterface * solver = model_->solver();
1676  //const double * lower = solver->getColLower();
1677  const double * upper = solver->getColUpper();
1678  int first=numberMembers;
1679  int last=-1;
1680  int numberFixed=0;
1681  int numberOther=0;
1682  int i;
1683  for ( i=0;i<numberMembers;i++) {
1684    double bound = upper[which[i]];
1685    if (bound) {
1686      first = CoinMin(first,i);
1687      last = CoinMax(last,i);
1688    }
1689  }
1690  // *** for way - up means fix all those in down section
1691  if (way_<0) {
1692    printf("SOS Down");
1693    for ( i=0;i<numberMembers;i++) {
1694      double bound = upper[which[i]];
1695      if (weights[i] > separator_)
1696        break;
1697      else if (bound)
1698        numberOther++;
1699    }
1700    assert (i<numberMembers);
1701    for (;i<numberMembers;i++) {
1702      double bound = upper[which[i]];
1703      if (bound)
1704        numberFixed++;
1705    }
1706  } else {
1707    printf("SOS Up");
1708    for ( i=0;i<numberMembers;i++) {
1709      double bound = upper[which[i]];
1710      if (weights[i] >= separator_)
1711        break;
1712      else if (bound)
1713        numberFixed++;
1714    }
1715    assert (i<numberMembers);
1716    for (;i<numberMembers;i++) {
1717      double bound = upper[which[i]];
1718      if (bound)
1719        numberOther++;
1720    }
1721  }
1722  printf(" - at %g, free range %d (%g) => %d (%g), %d would be fixed, %d other way\n",
1723         separator_,which[first],weights[first],which[last],weights[last],numberFixed,numberOther);
1724}
1725 
1726// Default Constructor
1727CbcBranchDefaultDecision::CbcBranchDefaultDecision()
1728  :CbcBranchDecision()
1729{
1730  bestCriterion_ = 0.0;
1731  bestChangeUp_ = 0.0;
1732  bestNumberUp_ = 0;
1733  bestChangeDown_ = 0.0;
1734  bestNumberDown_ = 0;
1735  bestObject_ = NULL;
1736}
1737
1738// Copy constructor
1739CbcBranchDefaultDecision::CbcBranchDefaultDecision (
1740                                    const CbcBranchDefaultDecision & rhs)
1741  :CbcBranchDecision()
1742{
1743  bestCriterion_ = rhs.bestCriterion_;
1744  bestChangeUp_ = rhs.bestChangeUp_;
1745  bestNumberUp_ = rhs.bestNumberUp_;
1746  bestChangeDown_ = rhs.bestChangeDown_;
1747  bestNumberDown_ = rhs.bestNumberDown_;
1748  bestObject_ = rhs.bestObject_;
1749}
1750
1751CbcBranchDefaultDecision::~CbcBranchDefaultDecision()
1752{
1753}
1754
1755// Clone
1756CbcBranchDecision * 
1757CbcBranchDefaultDecision::clone() const
1758{
1759  return new CbcBranchDefaultDecision(*this);
1760}
1761
1762// Initialize i.e. before start of choosing at a node
1763void 
1764CbcBranchDefaultDecision::initialize(CbcModel * model)
1765{
1766  bestCriterion_ = 0.0;
1767  bestChangeUp_ = 0.0;
1768  bestNumberUp_ = 0;
1769  bestChangeDown_ = 0.0;
1770  bestNumberDown_ = 0;
1771  bestObject_ = NULL;
1772}
1773
1774
1775/*
1776  Simple default decision algorithm. Compare based on infeasibility (numInfUp,
1777  numInfDn) until a solution is found by search, then switch to change in
1778  objective (changeUp, changeDn). Note that bestSoFar is remembered in
1779  bestObject_, so the parameter bestSoFar is unused.
1780*/
1781
1782int
1783CbcBranchDefaultDecision::betterBranch(CbcBranchingObject * thisOne,
1784                            CbcBranchingObject * bestSoFar,
1785                            double changeUp, int numInfUp,
1786                            double changeDn, int numInfDn)
1787{
1788  bool beforeSolution = thisOne->model()->getSolutionCount()==
1789    thisOne->model()->getNumberHeuristicSolutions();;
1790  int betterWay=0;
1791  if (beforeSolution) {
1792    if (!bestObject_) {
1793      bestNumberUp_=INT_MAX;
1794      bestNumberDown_=INT_MAX;
1795    }
1796    // before solution - choose smallest number
1797    // could add in depth as well
1798    int bestNumber = CoinMin(bestNumberUp_,bestNumberDown_);
1799    if (numInfUp<numInfDn) {
1800      if (numInfUp<bestNumber) {
1801        betterWay = 1;
1802      } else if (numInfUp==bestNumber) {
1803        if (changeUp<bestCriterion_)
1804          betterWay=1;
1805      }
1806    } else if (numInfUp>numInfDn) {
1807      if (numInfDn<bestNumber) {
1808        betterWay = -1;
1809      } else if (numInfDn==bestNumber) {
1810        if (changeDn<bestCriterion_)
1811          betterWay=-1;
1812      }
1813    } else {
1814      // up and down have same number
1815      bool better=false;
1816      if (numInfUp<bestNumber) {
1817        better=true;
1818      } else if (numInfUp==bestNumber) {
1819        if (min(changeUp,changeDn)<bestCriterion_)
1820          better=true;;
1821      }
1822      if (better) {
1823        // see which way
1824        if (changeUp<=changeDn)
1825          betterWay=1;
1826        else
1827          betterWay=-1;
1828      }
1829    }
1830  } else {
1831    if (!bestObject_) {
1832      bestCriterion_=-1.0;
1833    }
1834    // got a solution
1835    if (changeUp<=changeDn) {
1836      if (changeUp>bestCriterion_)
1837        betterWay=1;
1838    } else {
1839      if (changeDn>bestCriterion_)
1840        betterWay=-1;
1841    }
1842  }
1843  if (betterWay) {
1844    bestCriterion_ = CoinMin(changeUp,changeDn);
1845    bestChangeUp_ = changeUp;
1846    bestNumberUp_ = numInfUp;
1847    bestChangeDown_ = changeDn;
1848    bestNumberDown_ = numInfDn;
1849    bestObject_=thisOne;
1850  }
1851  return betterWay;
1852}
1853// Default Constructor
1854CbcFollowOn::CbcFollowOn ()
1855  : CbcObject(),
1856    rhs_(NULL)
1857{
1858}
1859
1860// Useful constructor
1861CbcFollowOn::CbcFollowOn (CbcModel * model)
1862  : CbcObject(model)
1863{
1864  assert (model);
1865  OsiSolverInterface * solver = model_->solver();
1866  matrix_ = *solver->getMatrixByCol();
1867  matrix_.removeGaps();
1868  matrixByRow_ = *solver->getMatrixByRow();
1869  int numberRows = matrix_.getNumRows();
1870 
1871  rhs_ = new int[numberRows];
1872  int i;
1873  const double * rowLower = solver->getRowLower();
1874  const double * rowUpper = solver->getRowUpper();
1875  // Row copy
1876  const double * elementByRow = matrixByRow_.getElements();
1877  const int * column = matrixByRow_.getIndices();
1878  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
1879  const int * rowLength = matrixByRow_.getVectorLengths();
1880  for (i=0;i<numberRows;i++) {
1881    rhs_[i]=0;
1882    double value = rowLower[i];
1883    if (value==rowUpper[i]) {
1884      if (floor(value)==value&&value>=1.0&&value<10.0) {
1885        // check elements
1886        bool good=true;
1887        for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
1888          int iColumn = column[j];
1889          if (!solver->isBinary(iColumn))
1890            good=false;
1891          double elValue = elementByRow[j];
1892          if (floor(elValue)!=elValue||value<1.0)
1893            good=false;
1894        }
1895        if (good)
1896          rhs_[i]=(int) value;
1897      }
1898    }
1899  }
1900}
1901
1902// Copy constructor
1903CbcFollowOn::CbcFollowOn ( const CbcFollowOn & rhs)
1904  :CbcObject(rhs),
1905   matrix_(rhs.matrix_),
1906   matrixByRow_(rhs.matrixByRow_)
1907{
1908  int numberRows = matrix_.getNumRows();
1909  rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
1910}
1911
1912// Clone
1913CbcObject *
1914CbcFollowOn::clone() const
1915{
1916  return new CbcFollowOn(*this);
1917}
1918
1919// Assignment operator
1920CbcFollowOn & 
1921CbcFollowOn::operator=( const CbcFollowOn& rhs)
1922{
1923  if (this!=&rhs) {
1924    CbcObject::operator=(rhs);
1925    delete [] rhs_;
1926    matrix_ = rhs.matrix_;
1927    matrixByRow_ = rhs.matrixByRow_;
1928    int numberRows = matrix_.getNumRows();
1929    rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
1930  }
1931  return *this;
1932}
1933
1934// Destructor
1935CbcFollowOn::~CbcFollowOn ()
1936{
1937  delete [] rhs_;
1938}
1939// As some computation is needed in more than one place - returns row
1940int 
1941CbcFollowOn::gutsOfFollowOn(int & otherRow, int & preferredWay) const
1942{
1943  int whichRow=-1;
1944  otherRow=-1;
1945  int numberRows = matrix_.getNumRows();
1946 
1947  int i;
1948  // For sorting
1949  int * sort = new int [numberRows];
1950  int * isort = new int [numberRows];
1951  // Column copy
1952  //const double * element = matrix_.getElements();
1953  const int * row = matrix_.getIndices();
1954  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
1955  const int * columnLength = matrix_.getVectorLengths();
1956  // Row copy
1957  const double * elementByRow = matrixByRow_.getElements();
1958  const int * column = matrixByRow_.getIndices();
1959  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
1960  const int * rowLength = matrixByRow_.getVectorLengths();
1961  OsiSolverInterface * solver = model_->solver();
1962  const double * columnLower = solver->getColLower();
1963  const double * columnUpper = solver->getColUpper();
1964  const double * solution = solver->getColSolution();
1965  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
1966  int nSort=0;
1967  for (i=0;i<numberRows;i++) {
1968    if (rhs_[i]) {
1969      // check elements
1970      double smallest=1.0e10;
1971      double largest=0.0;
1972      int rhsValue=rhs_[i];
1973      int number1=0;
1974      int numberUnsatisfied=0;
1975      for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
1976        int iColumn = column[j];
1977        double value = elementByRow[j];
1978        double solValue = solution[iColumn];
1979        if (columnLower[iColumn]!=columnUpper[iColumn]) {
1980          smallest = CoinMin(smallest,value);
1981          largest = CoinMax(largest,value);
1982          if (value==1.0)
1983            number1++;
1984          if (solValue<1.0-integerTolerance&&solValue>integerTolerance)
1985            numberUnsatisfied++;
1986        } else {
1987          rhsValue -= (int)(value*floor(solValue+0.5));
1988        }
1989      }
1990      if (numberUnsatisfied>1) {
1991        if (smallest<largest) {
1992          // probably no good but check a few things
1993          assert (largest<=rhsValue);
1994          if (number1==1&&largest==rhsValue)
1995            printf("could fix\n");
1996        } else if (largest==rhsValue) {
1997          sort[nSort]=i;
1998          isort[nSort++]=-numberUnsatisfied;
1999        }
2000      }
2001    }
2002  }
2003  if (nSort>1) {
2004    CoinSort_2(isort,isort+nSort,sort);
2005    CoinZeroN(isort,numberRows);
2006    double * other = new double[numberRows];
2007    CoinZeroN(other,numberRows);
2008    int * which = new int[numberRows];
2009    //#define COUNT
2010#ifndef COUNT
2011    bool beforeSolution = model_->getSolutionCount()==0;
2012#endif
2013    for (int k=0;k<nSort-1;k++) {
2014      i=sort[k];
2015      int numberUnsatisfied = 0;
2016      int n=0;
2017      int j;
2018      for (j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
2019        int iColumn = column[j];
2020        if (columnLower[iColumn]!=columnUpper[iColumn]) {
2021          double solValue = solution[iColumn]-columnLower[iColumn];
2022          if (solValue<1.0-integerTolerance&&solValue>integerTolerance) {
2023            numberUnsatisfied++;
2024            for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
2025              int iRow = row[jj];
2026              if (rhs_[iRow]) {
2027                other[iRow]+=solValue;
2028                if (isort[iRow]) {
2029                  isort[iRow]++;
2030                } else {
2031                  isort[iRow]=1;
2032                  which[n++]=iRow;
2033                }
2034              }
2035            }
2036          }
2037        }
2038      }
2039      double total=0.0;
2040      // Take out row
2041      double sumThis=other[i];
2042      other[i]=0.0;
2043      assert (numberUnsatisfied==isort[i]);
2044      // find one nearest half if solution, one if before solution
2045      int iBest=-1;
2046      double dtarget=0.5*total;
2047#ifdef COUNT
2048      int target = (numberUnsatisfied+1)>>1;
2049      int best=numberUnsatisfied;
2050#else
2051      double best;
2052      if (beforeSolution)
2053        best=dtarget;
2054      else
2055        best=1.0e30;
2056#endif
2057      for (j=0;j<n;j++) {
2058        int iRow = which[j];
2059        double dvalue=other[iRow];
2060        other[iRow]=0.0;
2061#ifdef COUNT
2062        int value = isort[iRow];
2063#endif
2064        isort[iRow]=0;
2065        if (fabs(dvalue)<1.0e-8||fabs(sumThis-dvalue)<1.0e-8)
2066          continue;
2067        if (dvalue<integerTolerance||dvalue>1.0-integerTolerance)
2068          continue;
2069#ifdef COUNT
2070        if (abs(value-target)<best&&value!=numberUnsatisfied) {
2071          best=abs(value-target);
2072          iBest=iRow;
2073          if (dvalue<dtarget)
2074            preferredWay=1;
2075          else
2076            preferredWay=-1;
2077        }
2078#else
2079        if (beforeSolution) {
2080          if (fabs(dvalue-dtarget)>best) {
2081            best = fabs(dvalue-dtarget);
2082            iBest=iRow;
2083            if (dvalue<dtarget)
2084              preferredWay=1;
2085            else
2086              preferredWay=-1;
2087          }
2088        } else {
2089          if (fabs(dvalue-dtarget)<best) {
2090            best = fabs(dvalue-dtarget);
2091            iBest=iRow;
2092            if (dvalue<dtarget)
2093              preferredWay=1;
2094            else
2095              preferredWay=-1;
2096          }
2097        }
2098#endif
2099      }
2100      if (iBest>=0) {
2101        whichRow=i;
2102        otherRow=iBest;
2103        break;
2104      }
2105    }
2106    delete [] which;
2107    delete [] other;
2108  }
2109  delete [] sort;
2110  delete [] isort;
2111  return whichRow;
2112}
2113
2114// Infeasibility - large is 0.5
2115double 
2116CbcFollowOn::infeasibility(int & preferredWay) const
2117{
2118  int otherRow=0;
2119  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
2120  if (whichRow<0)
2121    return 0.0;
2122  else
2123  return 2.0* model_->getDblParam(CbcModel::CbcIntegerTolerance);
2124}
2125
2126// This looks at solution and sets bounds to contain solution
2127void 
2128CbcFollowOn::feasibleRegion()
2129{
2130}
2131
2132
2133// Creates a branching object
2134CbcBranchingObject * 
2135CbcFollowOn::createBranch(int way) const
2136{
2137  int otherRow=0;
2138  int preferredWay;
2139  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
2140  assert(way==preferredWay);
2141  assert (whichRow>=0);
2142  int numberColumns = matrix_.getNumCols();
2143 
2144  // Column copy
2145  //const double * element = matrix_.getElements();
2146  const int * row = matrix_.getIndices();
2147  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
2148  const int * columnLength = matrix_.getVectorLengths();
2149  // Row copy
2150  //const double * elementByRow = matrixByRow_.getElements();
2151  const int * column = matrixByRow_.getIndices();
2152  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
2153  const int * rowLength = matrixByRow_.getVectorLengths();
2154  OsiSolverInterface * solver = model_->solver();
2155  const double * columnLower = solver->getColLower();
2156  const double * columnUpper = solver->getColUpper();
2157  //const double * solution = solver->getColSolution();
2158  int nUp=0;
2159  int nDown=0;
2160  int * upList = new int[numberColumns];
2161  int * downList = new int[numberColumns];
2162  int j;
2163  for (j=rowStart[whichRow];j<rowStart[whichRow]+rowLength[whichRow];j++) {
2164    int iColumn = column[j];
2165    if (columnLower[iColumn]!=columnUpper[iColumn]) {
2166      bool up=true;
2167      for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
2168        int iRow = row[jj];
2169        if (iRow==otherRow) {
2170          up=false;
2171          break;
2172        }
2173      }
2174      if (up)
2175        upList[nUp++]=iColumn;
2176      else
2177        downList[nDown++]=iColumn;
2178    }
2179  }
2180  //printf("way %d\n",way);
2181  // create object
2182  CbcBranchingObject * branch
2183     = new CbcFixingBranchingObject(model_,way,
2184                                         nDown,downList,nUp,upList);
2185  delete [] upList;
2186  delete [] downList;
2187  return branch;
2188}
2189// Default Constructor
2190CbcFixingBranchingObject::CbcFixingBranchingObject()
2191  :CbcBranchingObject()
2192{
2193  numberDown_=0;
2194  numberUp_=0;
2195  downList_=NULL;
2196  upList_=NULL;
2197}
2198
2199// Useful constructor
2200CbcFixingBranchingObject::CbcFixingBranchingObject (CbcModel * model,
2201                                                    int way ,
2202                                                    int numberOnDownSide, const int * down,
2203                                                    int numberOnUpSide, const int * up)
2204  :CbcBranchingObject(model,0,way,0.5)
2205{
2206  numberDown_=numberOnDownSide;
2207  numberUp_=numberOnUpSide;
2208  downList_ = CoinCopyOfArray(down,numberDown_);
2209  upList_ = CoinCopyOfArray(up,numberUp_);
2210}
2211
2212// Copy constructor
2213CbcFixingBranchingObject::CbcFixingBranchingObject ( const CbcFixingBranchingObject & rhs) :CbcBranchingObject(rhs)
2214{
2215  numberDown_=rhs.numberDown_;
2216  numberUp_=rhs.numberUp_;
2217  downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
2218  upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
2219}
2220
2221// Assignment operator
2222CbcFixingBranchingObject & 
2223CbcFixingBranchingObject::operator=( const CbcFixingBranchingObject& rhs)
2224{
2225  if (this != &rhs) {
2226    CbcBranchingObject::operator=(rhs);
2227    delete [] downList_;
2228    delete [] upList_;
2229    numberDown_=rhs.numberDown_;
2230    numberUp_=rhs.numberUp_;
2231    downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
2232    upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
2233  }
2234  return *this;
2235}
2236CbcBranchingObject * 
2237CbcFixingBranchingObject::clone() const
2238{ 
2239  return (new CbcFixingBranchingObject(*this));
2240}
2241
2242
2243// Destructor
2244CbcFixingBranchingObject::~CbcFixingBranchingObject ()
2245{
2246  delete [] downList_;
2247  delete [] upList_;
2248}
2249double
2250CbcFixingBranchingObject::branch(bool normalBranch)
2251{
2252  if (model_->messageHandler()->logLevel()>2&&normalBranch)
2253    print(normalBranch);
2254  numberBranchesLeft_--;
2255  OsiSolverInterface * solver = model_->solver();
2256  const double * columnLower = solver->getColLower();
2257  int i;
2258  // *** for way - up means fix all those in up section
2259  if (way_<0) {
2260#ifdef FULL_PRINT
2261    printf("Down Fix ");
2262#endif
2263    for (i=0;i<numberDown_;i++) {
2264      int iColumn = downList_[i];
2265      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
2266#ifdef FULL_PRINT
2267      printf("Setting bound on %d to lower bound\n",iColumn);
2268#endif
2269    }
2270    way_=1;       // Swap direction
2271  } else {
2272#ifdef FULL_PRINT
2273    printf("Up Fix ");
2274#endif
2275    for (i=0;i<numberUp_;i++) {
2276      int iColumn = upList_[i];
2277      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
2278#ifdef FULL_PRINT
2279      printf("Setting bound on %d to lower bound\n",iColumn);
2280#endif
2281    }
2282    way_=-1;      // Swap direction
2283  }
2284#ifdef FULL_PRINT
2285  printf("\n");
2286#endif
2287  return 0.0;
2288}
2289void
2290CbcFixingBranchingObject::print(bool normalBranch)
2291{
2292  int i;
2293  // *** for way - up means fix all those in up section
2294  if (way_<0) {
2295    printf("Down Fix ");
2296    for (i=0;i<numberDown_;i++) {
2297      int iColumn = downList_[i];
2298      printf("%d ",iColumn);
2299    }
2300  } else {
2301    printf("Up Fix ");
2302    for (i=0;i<numberUp_;i++) {
2303      int iColumn = upList_[i];
2304      printf("%d ",iColumn);
2305    }
2306  }
2307  printf("\n");
2308}
Note: See TracBrowser for help on using the repository browser.