source: trunk/CbcBranchActual.cpp @ 74

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

adding something to say if object a column

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 61.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 "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/* Column number if single column object -1 otherwise,
682   so returns >= 0
683   Used by heuristics
684*/
685int 
686CbcSimpleInteger::columnNumber() const
687{
688  return columnNumber_;
689}
690
691// Creates a branching object
692CbcBranchingObject * 
693CbcSimpleInteger::createBranch(int way) const
694{
695  OsiSolverInterface * solver = model_->solver();
696  const double * solution = model_->currentSolution();
697  const double * lower = solver->getColLower();
698  const double * upper = solver->getColUpper();
699  double value = solution[columnNumber_];
700  value = CoinMax(value, lower[columnNumber_]);
701  value = CoinMin(value, upper[columnNumber_]);
702  double nearest = floor(value+0.5);
703  double integerTolerance = 
704    model_->getDblParam(CbcModel::CbcIntegerTolerance);
705  assert (upper[columnNumber_]>lower[columnNumber_]);
706  int hotstartStrategy=model_->getHotstartStrategy();
707  if (hotstartStrategy<=0) {
708    assert (fabs(value-nearest)>integerTolerance);
709  } else {
710    const double * bestSolution = model_->bestSolution();
711    double targetValue = bestSolution[columnNumber_];
712    if (way>0)
713      value = targetValue-0.1;
714    else
715      value = targetValue+0.1;
716  }
717  return new CbcIntegerBranchingObject(model_,sequence_,way,
718                                             value);
719}
720
721
722/* Given valid solution (i.e. satisfied) and reduced costs etc
723   returns a branching object which would give a new feasible
724   point in direction reduced cost says would be cheaper.
725   If no feasible point returns null
726*/
727CbcBranchingObject * 
728CbcSimpleInteger::preferredNewFeasible() const
729{
730  OsiSolverInterface * solver = model_->solver();
731  double value = model_->currentSolution()[columnNumber_];
732
733  double nearest = floor(value+0.5);
734  double integerTolerance = 
735    model_->getDblParam(CbcModel::CbcIntegerTolerance);
736  assert (fabs(value-nearest)<=integerTolerance);
737  double dj = solver->getObjSense()*solver->getReducedCost()[columnNumber_];
738  CbcIntegerBranchingObject * object = NULL;
739  if (dj>=0.0) {
740    // can we go down
741    if (nearest>originalLower_+0.5) {
742      // yes
743      object = new CbcIntegerBranchingObject(model_,sequence_,-1,
744                                             nearest-1.0,nearest-1.0);
745    }
746  } else {
747    // can we go up
748    if (nearest<originalUpper_-0.5) {
749      // yes
750      object = new CbcIntegerBranchingObject(model_,sequence_,-1,
751                                             nearest+1.0,nearest+1.0);
752    }
753  }
754  return object;
755}
756 
757/* Given valid solution (i.e. satisfied) and reduced costs etc
758   returns a branching object which would give a new feasible
759   point in direction opposite to one reduced cost says would be cheaper.
760   If no feasible point returns null
761*/
762CbcBranchingObject * 
763CbcSimpleInteger::notPreferredNewFeasible() const 
764{
765  OsiSolverInterface * solver = model_->solver();
766  double value = model_->currentSolution()[columnNumber_];
767
768  double nearest = floor(value+0.5);
769  double integerTolerance = 
770    model_->getDblParam(CbcModel::CbcIntegerTolerance);
771  assert (fabs(value-nearest)<=integerTolerance);
772  double dj = solver->getObjSense()*solver->getReducedCost()[columnNumber_];
773  CbcIntegerBranchingObject * object = NULL;
774  if (dj<=0.0) {
775    // can we go down
776    if (nearest>originalLower_+0.5) {
777      // yes
778      object = new CbcIntegerBranchingObject(model_,sequence_,-1,
779                                             nearest-1.0,nearest-1.0);
780    }
781  } else {
782    // can we go up
783    if (nearest<originalUpper_-0.5) {
784      // yes
785      object = new CbcIntegerBranchingObject(model_,sequence_,-1,
786                                             nearest+1.0,nearest+1.0);
787    }
788  }
789  return object;
790}
791 
792/*
793  Bounds may be tightened, so it may be good to be able to refresh the local
794  copy of the original bounds.
795 */
796void 
797CbcSimpleInteger::resetBounds()
798{
799  originalLower_ = model_->solver()->getColLower()[columnNumber_];
800  originalUpper_ = model_->solver()->getColUpper()[columnNumber_];
801}
802
803
804// Default Constructor
805CbcIntegerBranchingObject::CbcIntegerBranchingObject()
806  :CbcBranchingObject()
807{
808  down_[0] = 0.0;
809  down_[1] = 0.0;
810  up_[0] = 0.0;
811  up_[1] = 0.0;
812}
813
814// Useful constructor
815CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
816                                                      int variable, int way , double value)
817  :CbcBranchingObject(model,variable,way,value)
818{
819  int iColumn = model_->integerVariable()[variable_];
820  down_[0] = model_->solver()->getColLower()[iColumn];
821  down_[1] = floor(value_);
822  up_[0] = ceil(value_);
823  up_[1] = model->getColUpper()[iColumn];
824}
825// Useful constructor for fixing
826CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, 
827                                                      int variable, int way,
828                                                      double lowerValue, 
829                                                      double upperValue)
830  :CbcBranchingObject(model,variable,way,lowerValue)
831{
832  numberBranchesLeft_=1;
833  down_[0] = lowerValue;
834  down_[1] = upperValue;
835  up_[0] = lowerValue;
836  up_[1] = upperValue;
837}
838 
839
840// Copy constructor
841CbcIntegerBranchingObject::CbcIntegerBranchingObject ( const CbcIntegerBranchingObject & rhs) :CbcBranchingObject(rhs)
842{
843  down_[0] = rhs.down_[0];
844  down_[1] = rhs.down_[1];
845  up_[0] = rhs.up_[0];
846  up_[1] = rhs.up_[1];
847}
848
849// Assignment operator
850CbcIntegerBranchingObject & 
851CbcIntegerBranchingObject::operator=( const CbcIntegerBranchingObject& rhs)
852{
853  if (this != &rhs) {
854    CbcBranchingObject::operator=(rhs);
855    down_[0] = rhs.down_[0];
856    down_[1] = rhs.down_[1];
857    up_[0] = rhs.up_[0];
858    up_[1] = rhs.up_[1];
859  }
860  return *this;
861}
862CbcBranchingObject * 
863CbcIntegerBranchingObject::clone() const
864{ 
865  return (new CbcIntegerBranchingObject(*this));
866}
867
868
869// Destructor
870CbcIntegerBranchingObject::~CbcIntegerBranchingObject ()
871{
872}
873
874/*
875  Perform a branch by adjusting the bounds of the specified variable. Note
876  that each arm of the branch advances the object to the next arm by
877  advancing the value of way_.
878
879  Providing new values for the variable's lower and upper bounds for each
880  branching direction gives a little bit of additional flexibility and will
881  be easily extensible to multi-way branching.
882  Returns change in guessed objective on next branch
883*/
884double
885CbcIntegerBranchingObject::branch(bool normalBranch)
886{
887  if (model_->messageHandler()->logLevel()>2&&normalBranch)
888    print(normalBranch);
889  numberBranchesLeft_--;
890  int iColumn = model_->integerVariable()[variable_];
891  if (way_<0) {
892#ifdef CBC_DEBUG
893  { double olb,oub ;
894    olb = model_->solver()->getColLower()[iColumn] ;
895    oub = model_->solver()->getColUpper()[iColumn] ;
896    printf("branching down on var %d: [%g,%g] => [%g,%g]\n",
897           iColumn,olb,oub,down_[0],down_[1]) ; }
898#endif
899    model_->solver()->setColLower(iColumn,down_[0]);
900    model_->solver()->setColUpper(iColumn,down_[1]);
901    way_=1;
902  } else {
903#ifdef CBC_DEBUG
904  { double olb,oub ;
905    olb = model_->solver()->getColLower()[iColumn] ;
906    oub = model_->solver()->getColUpper()[iColumn] ;
907    printf("branching up on var %d: [%g,%g] => [%g,%g]\n",
908           iColumn,olb,oub,up_[0],up_[1]) ; }
909#endif
910    model_->solver()->setColLower(iColumn,up_[0]);
911    model_->solver()->setColUpper(iColumn,up_[1]);
912    way_=-1;      // Swap direction
913  }
914  return 0.0;
915}
916// Print what would happen 
917void
918CbcIntegerBranchingObject::print(bool normalBranch)
919{
920  int iColumn = model_->integerVariable()[variable_];
921  if (way_<0) {
922  { double olb,oub ;
923    olb = model_->solver()->getColLower()[iColumn] ;
924    oub = model_->solver()->getColUpper()[iColumn] ;
925    printf("CbcInteger would branch down on var %d: [%g,%g] => [%g,%g]\n",
926           iColumn,olb,oub,down_[0],down_[1]) ; }
927  } else {
928  { double olb,oub ;
929    olb = model_->solver()->getColLower()[iColumn] ;
930    oub = model_->solver()->getColUpper()[iColumn] ;
931    printf("CbcInteger would branch up on var %d: [%g,%g] => [%g,%g]\n",
932           iColumn,olb,oub,up_[0],up_[1]) ; }
933  }
934}
935
936
937/** Default Constructor
938
939  Equivalent to an unspecified binary variable.
940*/
941CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ()
942  : CbcSimpleInteger(),
943    downPseudoCost_(1.0e-5),
944    upPseudoCost_(1.0e-5),
945    method_(0)
946{
947}
948
949/** Useful constructor
950
951  Loads actual upper & lower bounds for the specified variable.
952*/
953CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, int sequence,
954                                    int iColumn, double breakEven)
955  : CbcSimpleInteger(model,sequence,iColumn,breakEven)
956{
957  const double * cost = model->getObjCoefficients();
958  double costValue = CoinMax(1.0e-5,fabs(cost[iColumn]));
959  // treat as if will cost what it says up
960  upPseudoCost_=costValue;
961  // and balance at breakeven
962  downPseudoCost_=((1.0-breakEven_)*upPseudoCost_)/breakEven_;
963  method_=0;
964}
965
966/** Useful constructor
967
968  Loads actual upper & lower bounds for the specified variable.
969*/
970CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost (CbcModel * model, int sequence,
971                                    int iColumn, double downPseudoCost,
972                                                        double upPseudoCost)
973  : CbcSimpleInteger(model,sequence,iColumn)
974{
975  downPseudoCost_ = downPseudoCost;
976  upPseudoCost_ = upPseudoCost;
977  breakEven_ = upPseudoCost_/(upPseudoCost_+downPseudoCost_);
978  method_=0;
979}
980
981// Copy constructor
982CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost ( const CbcSimpleIntegerPseudoCost & rhs)
983  :CbcSimpleInteger(rhs),
984   downPseudoCost_(rhs.downPseudoCost_),
985   upPseudoCost_(rhs.upPseudoCost_),
986   method_(rhs.method_)
987
988{
989}
990
991// Clone
992CbcObject *
993CbcSimpleIntegerPseudoCost::clone() const
994{
995  return new CbcSimpleIntegerPseudoCost(*this);
996}
997
998// Assignment operator
999CbcSimpleIntegerPseudoCost & 
1000CbcSimpleIntegerPseudoCost::operator=( const CbcSimpleIntegerPseudoCost& rhs)
1001{
1002  if (this!=&rhs) {
1003    CbcSimpleInteger::operator=(rhs);
1004    downPseudoCost_=rhs.downPseudoCost_;
1005    upPseudoCost_=rhs.upPseudoCost_;
1006    method_=rhs.method_;
1007  }
1008  return *this;
1009}
1010
1011// Destructor
1012CbcSimpleIntegerPseudoCost::~CbcSimpleIntegerPseudoCost ()
1013{
1014}
1015// Creates a branching object
1016CbcBranchingObject * 
1017CbcSimpleIntegerPseudoCost::createBranch(int way) const
1018{
1019  OsiSolverInterface * solver = model_->solver();
1020  const double * solution = model_->currentSolution();
1021  const double * lower = solver->getColLower();
1022  const double * upper = solver->getColUpper();
1023  double value = solution[columnNumber_];
1024  value = CoinMax(value, lower[columnNumber_]);
1025  value = CoinMin(value, upper[columnNumber_]);
1026  double nearest = floor(value+0.5);
1027  double integerTolerance = 
1028    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1029  assert (upper[columnNumber_]>lower[columnNumber_]);
1030  int hotstartStrategy=model_->getHotstartStrategy();
1031  if (hotstartStrategy<=0) {
1032    assert (fabs(value-nearest)>integerTolerance);
1033  } else {
1034    const double * bestSolution = model_->bestSolution();
1035    double targetValue = bestSolution[columnNumber_];
1036    if (way>0)
1037      value = targetValue-0.1;
1038    else
1039      value = targetValue+0.1;
1040  }
1041  CbcIntegerPseudoCostBranchingObject * newObject = 
1042    new CbcIntegerPseudoCostBranchingObject(model_,sequence_,way,
1043                                            value);
1044  double up =  upPseudoCost_*(ceil(value)-value);
1045  double down =  downPseudoCost_*(value-floor(value));
1046  double changeInGuessed=up-down;
1047  if (way>0)
1048    changeInGuessed = - changeInGuessed;
1049  changeInGuessed=CoinMax(0.0,changeInGuessed);
1050  //if (way>0)
1051  //changeInGuessed += 1.0e8; // bias to stay up
1052  newObject->setChangeInGuessed(changeInGuessed);
1053  return newObject;
1054}
1055// Infeasibility - large is 0.5
1056double 
1057CbcSimpleIntegerPseudoCost::infeasibility(int & preferredWay) const
1058{
1059  OsiSolverInterface * solver = model_->solver();
1060  const double * solution = model_->currentSolution();
1061  const double * lower = solver->getColLower();
1062  const double * upper = solver->getColUpper();
1063  if (upper[columnNumber_]==lower[columnNumber_]) {
1064    // fixed
1065    preferredWay=1;
1066    return 0.0;
1067  }
1068  double value = solution[columnNumber_];
1069  value = CoinMax(value, lower[columnNumber_]);
1070  value = CoinMin(value, upper[columnNumber_]);
1071  /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
1072    solution[columnNumber_],upper[columnNumber_]);*/
1073  double nearest = floor(value+0.5);
1074  double integerTolerance = 
1075    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1076  double below = floor(value+integerTolerance);
1077  double above = below+1.0;
1078  if (above>upper[columnNumber_]) {
1079    above=below;
1080    below = above -1;
1081  }
1082  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1083  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1084  if (downCost>=upCost)
1085    preferredWay=1;
1086  else
1087    preferredWay=-1;
1088  if (fabs(value-nearest)<=integerTolerance) {
1089    return 0.0;
1090  } else {
1091    // can't get at model so 1,2 don't make sense
1092    assert(method_<1||method_>2);
1093    if (!method_)
1094      return CoinMin(downCost,upCost);
1095    else
1096      return CoinMax(downCost,upCost);
1097  }
1098}
1099
1100// Return "up" estimate
1101double 
1102CbcSimpleIntegerPseudoCost::upEstimate() const
1103{
1104  OsiSolverInterface * solver = model_->solver();
1105  const double * solution = model_->currentSolution();
1106  const double * lower = solver->getColLower();
1107  const double * upper = solver->getColUpper();
1108  double value = solution[columnNumber_];
1109  value = CoinMax(value, lower[columnNumber_]);
1110  value = CoinMin(value, upper[columnNumber_]);
1111  if (upper[columnNumber_]==lower[columnNumber_]) {
1112    // fixed
1113    return 0.0;
1114  }
1115  double integerTolerance = 
1116    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1117  double below = floor(value+integerTolerance);
1118  double above = below+1.0;
1119  if (above>upper[columnNumber_]) {
1120    above=below;
1121    below = above -1;
1122  }
1123  double upCost = CoinMax((above-value)*upPseudoCost_,0.0);
1124  return upCost;
1125}
1126// Return "down" estimate
1127double 
1128CbcSimpleIntegerPseudoCost::downEstimate() const
1129{
1130  OsiSolverInterface * solver = model_->solver();
1131  const double * solution = model_->currentSolution();
1132  const double * lower = solver->getColLower();
1133  const double * upper = solver->getColUpper();
1134  double value = solution[columnNumber_];
1135  value = CoinMax(value, lower[columnNumber_]);
1136  value = CoinMin(value, upper[columnNumber_]);
1137  if (upper[columnNumber_]==lower[columnNumber_]) {
1138    // fixed
1139    return 0.0;
1140  }
1141  double integerTolerance = 
1142    model_->getDblParam(CbcModel::CbcIntegerTolerance);
1143  double below = floor(value+integerTolerance);
1144  double above = below+1.0;
1145  if (above>upper[columnNumber_]) {
1146    above=below;
1147    below = above -1;
1148  }
1149  double downCost = CoinMax((value-below)*downPseudoCost_,0.0);
1150  return downCost;
1151}
1152
1153// Default Constructor
1154CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject()
1155  :CbcIntegerBranchingObject()
1156{
1157  changeInGuessed_=1.0e-5;
1158}
1159
1160// Useful constructor
1161CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1162                                                      int variable, int way , double value)
1163  :CbcIntegerBranchingObject(model,variable,way,value)
1164{
1165}
1166// Useful constructor for fixing
1167CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject (CbcModel * model, 
1168                                                      int variable, int way,
1169                                                      double lowerValue, 
1170                                                      double upperValue)
1171  :CbcIntegerBranchingObject(model,variable,way,lowerValue)
1172{
1173  changeInGuessed_=1.0e100;
1174}
1175 
1176
1177// Copy constructor
1178CbcIntegerPseudoCostBranchingObject::CbcIntegerPseudoCostBranchingObject ( 
1179                                 const CbcIntegerPseudoCostBranchingObject & rhs)
1180  :CbcIntegerBranchingObject(rhs)
1181{
1182  changeInGuessed_ = rhs.changeInGuessed_;
1183}
1184
1185// Assignment operator
1186CbcIntegerPseudoCostBranchingObject & 
1187CbcIntegerPseudoCostBranchingObject::operator=( const CbcIntegerPseudoCostBranchingObject& rhs)
1188{
1189  if (this != &rhs) {
1190    CbcIntegerBranchingObject::operator=(rhs);
1191    changeInGuessed_ = rhs.changeInGuessed_;
1192  }
1193  return *this;
1194}
1195CbcBranchingObject * 
1196CbcIntegerPseudoCostBranchingObject::clone() const
1197{ 
1198  return (new CbcIntegerPseudoCostBranchingObject(*this));
1199}
1200
1201
1202// Destructor
1203CbcIntegerPseudoCostBranchingObject::~CbcIntegerPseudoCostBranchingObject ()
1204{
1205}
1206
1207/*
1208  Perform a branch by adjusting the bounds of the specified variable. Note
1209  that each arm of the branch advances the object to the next arm by
1210  advancing the value of way_.
1211
1212  Providing new values for the variable's lower and upper bounds for each
1213  branching direction gives a little bit of additional flexibility and will
1214  be easily extensible to multi-way branching.
1215  Returns change in guessed objective on next branch
1216*/
1217double
1218CbcIntegerPseudoCostBranchingObject::branch(bool normalBranch)
1219{
1220  CbcIntegerBranchingObject::branch(normalBranch);
1221  return changeInGuessed_;
1222}
1223
1224
1225// Default Constructor
1226CbcCliqueBranchingObject::CbcCliqueBranchingObject()
1227  :CbcBranchingObject()
1228{
1229  clique_ = NULL;
1230  downMask_[0]=0;
1231  downMask_[1]=0;
1232  upMask_[0]=0;
1233  upMask_[1]=0;
1234}
1235
1236// Useful constructor
1237CbcCliqueBranchingObject::CbcCliqueBranchingObject (CbcModel * model,
1238                                                    const CbcClique * clique,
1239                                                    int way ,
1240                                                    int numberOnDownSide, const int * down,
1241                                                    int numberOnUpSide, const int * up)
1242  :CbcBranchingObject(model,clique->id(),way,0.5)
1243{
1244  clique_ = clique;
1245  downMask_[0]=0;
1246  downMask_[1]=0;
1247  upMask_[0]=0;
1248  upMask_[1]=0;
1249  int i;
1250  for (i=0;i<numberOnDownSide;i++) {
1251    int sequence = down[i];
1252    int iWord = sequence>>5;
1253    int iBit = sequence - 32*iWord;
1254    unsigned int k = 1<<iBit;
1255    downMask_[iWord] |= k;
1256  }
1257  for (i=0;i<numberOnUpSide;i++) {
1258    int sequence = up[i];
1259    int iWord = sequence>>5;
1260    int iBit = sequence - 32*iWord;
1261    unsigned int k = 1<<iBit;
1262    upMask_[iWord] |= k;
1263  }
1264}
1265
1266// Copy constructor
1267CbcCliqueBranchingObject::CbcCliqueBranchingObject ( const CbcCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
1268{
1269  clique_=rhs.clique_;
1270  downMask_[0]=rhs.downMask_[0];
1271  downMask_[1]=rhs.downMask_[1];
1272  upMask_[0]=rhs.upMask_[0];
1273  upMask_[1]=rhs.upMask_[1];
1274}
1275
1276// Assignment operator
1277CbcCliqueBranchingObject & 
1278CbcCliqueBranchingObject::operator=( const CbcCliqueBranchingObject& rhs)
1279{
1280  if (this != &rhs) {
1281    CbcBranchingObject::operator=(rhs);
1282    clique_=rhs.clique_;
1283    downMask_[0]=rhs.downMask_[0];
1284    downMask_[1]=rhs.downMask_[1];
1285    upMask_[0]=rhs.upMask_[0];
1286    upMask_[1]=rhs.upMask_[1];
1287  }
1288  return *this;
1289}
1290CbcBranchingObject * 
1291CbcCliqueBranchingObject::clone() const
1292{ 
1293  return (new CbcCliqueBranchingObject(*this));
1294}
1295
1296
1297// Destructor
1298CbcCliqueBranchingObject::~CbcCliqueBranchingObject ()
1299{
1300}
1301double
1302CbcCliqueBranchingObject::branch(bool normalBranch)
1303{
1304  if (model_->messageHandler()->logLevel()>2&&normalBranch)
1305    print(normalBranch);
1306  numberBranchesLeft_--;
1307  int iWord;
1308  int numberMembers = clique_->numberMembers();
1309  const int * which = clique_->members();
1310  const int * integerVariables = model_->integerVariable();
1311  int numberWords=(numberMembers+31)>>5;
1312  // *** for way - up means fix all those in down section
1313  if (way_<0) {
1314#ifdef FULL_PRINT
1315    printf("Down Fix ");
1316#endif
1317    for (iWord=0;iWord<numberWords;iWord++) {
1318      int i;
1319      for (i=0;i<32;i++) {
1320        unsigned int k = 1<<i;
1321        if ((upMask_[iWord]&k)!=0) {
1322          int iColumn = which[i+32*iWord];
1323#ifdef FULL_PRINT
1324          printf("%d ",i+32*iWord);
1325#endif
1326          // fix weak way
1327          if (clique_->type(i+32*iWord))
1328            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1329          else
1330            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1331        }
1332      }
1333    }
1334    way_=1;       // Swap direction
1335  } else {
1336#ifdef FULL_PRINT
1337    printf("Up Fix ");
1338#endif
1339    for (iWord=0;iWord<numberWords;iWord++) {
1340      int i;
1341      for (i=0;i<32;i++) {
1342        unsigned int k = 1<<i;
1343        if ((downMask_[iWord]&k)!=0) {
1344          int iColumn = which[i+32*iWord];
1345#ifdef FULL_PRINT
1346          printf("%d ",i+32*iWord);
1347#endif
1348          // fix weak way
1349          if (clique_->type(i+32*iWord))
1350            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1351          else
1352            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1353        }
1354      }
1355    }
1356    way_=-1;      // Swap direction
1357  }
1358#ifdef FULL_PRINT
1359  printf("\n");
1360#endif
1361  return 0.0;
1362}
1363// Print what would happen 
1364void
1365CbcCliqueBranchingObject::print(bool normalBranch)
1366{
1367  int iWord;
1368  int numberMembers = clique_->numberMembers();
1369  const int * which = clique_->members();
1370  const int * integerVariables = model_->integerVariable();
1371  int numberWords=(numberMembers+31)>>5;
1372  // *** for way - up means fix all those in down section
1373  if (way_<0) {
1374    printf("Clique - Down Fix ");
1375    for (iWord=0;iWord<numberWords;iWord++) {
1376      int i;
1377      for (i=0;i<32;i++) {
1378        unsigned int k = 1<<i;
1379        if ((upMask_[iWord]&k)!=0) {
1380          int iColumn = which[i+32*iWord];
1381          printf("%d ",integerVariables[iColumn]);
1382        }
1383      }
1384    }
1385  } else {
1386    printf("Clique - Up Fix ");
1387    for (iWord=0;iWord<numberWords;iWord++) {
1388      int i;
1389      for (i=0;i<32;i++) {
1390        unsigned int k = 1<<i;
1391        if ((downMask_[iWord]&k)!=0) {
1392          int iColumn = which[i+32*iWord];
1393          printf("%d ",integerVariables[iColumn]);
1394        }
1395      }
1396    }
1397  }
1398  printf("\n");
1399}
1400 
1401// Default Constructor
1402CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject()
1403  :CbcBranchingObject()
1404{
1405  clique_=NULL;
1406  downMask_=NULL;
1407  upMask_=NULL;
1408}
1409
1410// Useful constructor
1411CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject (CbcModel * model,
1412                                                            const CbcClique * clique, 
1413                                                            int way ,
1414                                                    int numberOnDownSide, const int * down,
1415                                                    int numberOnUpSide, const int * up)
1416  :CbcBranchingObject(model,clique->id(),way,0.5)
1417{
1418  clique_ = clique;
1419  int numberMembers = clique_->numberMembers();
1420  int numberWords=(numberMembers+31)>>5;
1421  downMask_ = new unsigned int [numberWords];
1422  upMask_ = new unsigned int [numberWords];
1423  memset(downMask_,0,numberWords*sizeof(unsigned int));
1424  memset(upMask_,0,numberWords*sizeof(unsigned int));
1425  int i;
1426  for (i=0;i<numberOnDownSide;i++) {
1427    int sequence = down[i];
1428    int iWord = sequence>>5;
1429    int iBit = sequence - 32*iWord;
1430    unsigned int k = 1<<iBit;
1431    downMask_[iWord] |= k;
1432  }
1433  for (i=0;i<numberOnUpSide;i++) {
1434    int sequence = up[i];
1435    int iWord = sequence>>5;
1436    int iBit = sequence - 32*iWord;
1437    unsigned int k = 1<<iBit;
1438    upMask_[iWord] |= k;
1439  }
1440}
1441
1442// Copy constructor
1443CbcLongCliqueBranchingObject::CbcLongCliqueBranchingObject ( const CbcLongCliqueBranchingObject & rhs) :CbcBranchingObject(rhs)
1444{
1445  clique_=rhs.clique_;
1446  if (rhs.downMask_) {
1447    int numberMembers = clique_->numberMembers();
1448    int numberWords=(numberMembers+31)>>5;
1449    downMask_ = new unsigned int [numberWords];
1450    memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
1451    upMask_ = new unsigned int [numberWords];
1452    memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
1453  } else {
1454    downMask_=NULL;
1455    upMask_=NULL;
1456  }   
1457}
1458
1459// Assignment operator
1460CbcLongCliqueBranchingObject & 
1461CbcLongCliqueBranchingObject::operator=( const CbcLongCliqueBranchingObject& rhs)
1462{
1463  if (this != &rhs) {
1464    CbcBranchingObject::operator=(rhs);
1465    clique_=rhs.clique_;
1466    delete [] downMask_;
1467    delete [] upMask_;
1468    if (rhs.downMask_) {
1469      int numberMembers = clique_->numberMembers();
1470      int numberWords=(numberMembers+31)>>5;
1471      downMask_ = new unsigned int [numberWords];
1472      memcpy(downMask_,rhs.downMask_,numberWords*sizeof(unsigned int));
1473      upMask_ = new unsigned int [numberWords];
1474      memcpy(upMask_,rhs.upMask_,numberWords*sizeof(unsigned int));
1475    } else {
1476      downMask_=NULL;
1477      upMask_=NULL;
1478    }   
1479  }
1480  return *this;
1481}
1482CbcBranchingObject * 
1483CbcLongCliqueBranchingObject::clone() const
1484{ 
1485  return (new CbcLongCliqueBranchingObject(*this));
1486}
1487
1488
1489// Destructor
1490CbcLongCliqueBranchingObject::~CbcLongCliqueBranchingObject ()
1491{
1492  delete [] downMask_;
1493  delete [] upMask_;
1494}
1495double
1496CbcLongCliqueBranchingObject::branch(bool normalBranch)
1497{
1498  if (model_->messageHandler()->logLevel()>2&&normalBranch)
1499    print(normalBranch);
1500  numberBranchesLeft_--;
1501  int iWord;
1502  int numberMembers = clique_->numberMembers();
1503  const int * which = clique_->members();
1504  const int * integerVariables = model_->integerVariable();
1505  int numberWords=(numberMembers+31)>>5;
1506  // *** for way - up means fix all those in down section
1507  if (way_<0) {
1508#ifdef FULL_PRINT
1509    printf("Down Fix ");
1510#endif
1511    for (iWord=0;iWord<numberWords;iWord++) {
1512      int i;
1513      for (i=0;i<32;i++) {
1514        unsigned int k = 1<<i;
1515        if ((upMask_[iWord]&k)!=0) {
1516          int iColumn = which[i+32*iWord];
1517#ifdef FULL_PRINT
1518          printf("%d ",i+32*iWord);
1519#endif
1520          // fix weak way
1521          if (clique_->type(i+32*iWord))
1522            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1523          else
1524            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1525        }
1526      }
1527    }
1528    way_=1;       // Swap direction
1529  } else {
1530#ifdef FULL_PRINT
1531    printf("Up Fix ");
1532#endif
1533    for (iWord=0;iWord<numberWords;iWord++) {
1534      int i;
1535      for (i=0;i<32;i++) {
1536        unsigned int k = 1<<i;
1537        if ((downMask_[iWord]&k)!=0) {
1538          int iColumn = which[i+32*iWord];
1539#ifdef FULL_PRINT
1540          printf("%d ",i+32*iWord);
1541#endif
1542          // fix weak way
1543          if (clique_->type(i+32*iWord))
1544            model_->solver()->setColUpper(integerVariables[iColumn],0.0);
1545          else
1546            model_->solver()->setColLower(integerVariables[iColumn],1.0);
1547        }
1548      }
1549    }
1550    way_=-1;      // Swap direction
1551  }
1552#ifdef FULL_PRINT
1553  printf("\n");
1554#endif
1555  return 0.0;
1556}
1557void
1558CbcLongCliqueBranchingObject::print(bool normalBranch)
1559{
1560  int iWord;
1561  int numberMembers = clique_->numberMembers();
1562  const int * which = clique_->members();
1563  const int * integerVariables = model_->integerVariable();
1564  int numberWords=(numberMembers+31)>>5;
1565  // *** for way - up means fix all those in down section
1566  if (way_<0) {
1567    printf("Clique - Down Fix ");
1568    for (iWord=0;iWord<numberWords;iWord++) {
1569      int i;
1570      for (i=0;i<32;i++) {
1571        unsigned int k = 1<<i;
1572        if ((upMask_[iWord]&k)!=0) {
1573          int iColumn = which[i+32*iWord];
1574          printf("%d ",integerVariables[iColumn]);
1575        }
1576      }
1577    }
1578  } else {
1579    printf("Clique - Up Fix ");
1580    for (iWord=0;iWord<numberWords;iWord++) {
1581      int i;
1582      for (i=0;i<32;i++) {
1583        unsigned int k = 1<<i;
1584        if ((downMask_[iWord]&k)!=0) {
1585          int iColumn = which[i+32*iWord];
1586          printf("%d ",integerVariables[iColumn]);
1587        }
1588      }
1589    }
1590  }
1591  printf("\n");
1592}
1593// Default Constructor
1594CbcSOSBranchingObject::CbcSOSBranchingObject()
1595  :CbcBranchingObject()
1596{
1597  set_ = NULL;
1598  separator_=0.0;
1599}
1600
1601// Useful constructor
1602CbcSOSBranchingObject::CbcSOSBranchingObject (CbcModel * model,
1603                                              const CbcSOS * set,
1604                                              int way ,
1605                                              double separator)
1606  :CbcBranchingObject(model,set->id(),way,0.5)
1607{
1608  set_ = set;
1609  separator_ = separator;
1610}
1611
1612// Copy constructor
1613CbcSOSBranchingObject::CbcSOSBranchingObject ( const CbcSOSBranchingObject & rhs) :CbcBranchingObject(rhs)
1614{
1615  set_=rhs.set_;
1616  separator_ = rhs.separator_;
1617}
1618
1619// Assignment operator
1620CbcSOSBranchingObject & 
1621CbcSOSBranchingObject::operator=( const CbcSOSBranchingObject& rhs)
1622{
1623  if (this != &rhs) {
1624    CbcBranchingObject::operator=(rhs);
1625    set_=rhs.set_;
1626    separator_ = rhs.separator_;
1627  }
1628  return *this;
1629}
1630CbcBranchingObject * 
1631CbcSOSBranchingObject::clone() const
1632{ 
1633  return (new CbcSOSBranchingObject(*this));
1634}
1635
1636
1637// Destructor
1638CbcSOSBranchingObject::~CbcSOSBranchingObject ()
1639{
1640}
1641double
1642CbcSOSBranchingObject::branch(bool normalBranch)
1643{
1644  if (model_->messageHandler()->logLevel()>2&&normalBranch)
1645    print(normalBranch);
1646  numberBranchesLeft_--;
1647  int numberMembers = set_->numberMembers();
1648  const int * which = set_->members();
1649  const double * weights = set_->weights();
1650  OsiSolverInterface * solver = model_->solver();
1651  //const double * lower = solver->getColLower();
1652  //const double * upper = solver->getColUpper();
1653  // *** for way - up means fix all those in down section
1654  if (way_<0) {
1655    int i;
1656    for ( i=0;i<numberMembers;i++) {
1657      if (weights[i] > separator_)
1658        break;
1659    }
1660    assert (i<numberMembers);
1661    for (;i<numberMembers;i++) 
1662      solver->setColUpper(which[i],0.0);
1663    way_=1;       // Swap direction
1664  } else {
1665    int i;
1666    for ( i=0;i<numberMembers;i++) {
1667      if (weights[i] >= separator_)
1668        break;
1669      else
1670        solver->setColUpper(which[i],0.0);
1671    }
1672    assert (i<numberMembers);
1673    way_=-1;      // Swap direction
1674  }
1675  return 0.0;
1676}
1677// Print what would happen 
1678void
1679CbcSOSBranchingObject::print(bool normalBranch)
1680{
1681  int numberMembers = set_->numberMembers();
1682  const int * which = set_->members();
1683  const double * weights = set_->weights();
1684  OsiSolverInterface * solver = model_->solver();
1685  //const double * lower = solver->getColLower();
1686  const double * upper = solver->getColUpper();
1687  int first=numberMembers;
1688  int last=-1;
1689  int numberFixed=0;
1690  int numberOther=0;
1691  int i;
1692  for ( i=0;i<numberMembers;i++) {
1693    double bound = upper[which[i]];
1694    if (bound) {
1695      first = CoinMin(first,i);
1696      last = CoinMax(last,i);
1697    }
1698  }
1699  // *** for way - up means fix all those in down section
1700  if (way_<0) {
1701    printf("SOS Down");
1702    for ( i=0;i<numberMembers;i++) {
1703      double bound = upper[which[i]];
1704      if (weights[i] > separator_)
1705        break;
1706      else if (bound)
1707        numberOther++;
1708    }
1709    assert (i<numberMembers);
1710    for (;i<numberMembers;i++) {
1711      double bound = upper[which[i]];
1712      if (bound)
1713        numberFixed++;
1714    }
1715  } else {
1716    printf("SOS Up");
1717    for ( i=0;i<numberMembers;i++) {
1718      double bound = upper[which[i]];
1719      if (weights[i] >= separator_)
1720        break;
1721      else if (bound)
1722        numberFixed++;
1723    }
1724    assert (i<numberMembers);
1725    for (;i<numberMembers;i++) {
1726      double bound = upper[which[i]];
1727      if (bound)
1728        numberOther++;
1729    }
1730  }
1731  printf(" - at %g, free range %d (%g) => %d (%g), %d would be fixed, %d other way\n",
1732         separator_,which[first],weights[first],which[last],weights[last],numberFixed,numberOther);
1733}
1734 
1735// Default Constructor
1736CbcBranchDefaultDecision::CbcBranchDefaultDecision()
1737  :CbcBranchDecision()
1738{
1739  bestCriterion_ = 0.0;
1740  bestChangeUp_ = 0.0;
1741  bestNumberUp_ = 0;
1742  bestChangeDown_ = 0.0;
1743  bestNumberDown_ = 0;
1744  bestObject_ = NULL;
1745}
1746
1747// Copy constructor
1748CbcBranchDefaultDecision::CbcBranchDefaultDecision (
1749                                    const CbcBranchDefaultDecision & rhs)
1750  :CbcBranchDecision()
1751{
1752  bestCriterion_ = rhs.bestCriterion_;
1753  bestChangeUp_ = rhs.bestChangeUp_;
1754  bestNumberUp_ = rhs.bestNumberUp_;
1755  bestChangeDown_ = rhs.bestChangeDown_;
1756  bestNumberDown_ = rhs.bestNumberDown_;
1757  bestObject_ = rhs.bestObject_;
1758}
1759
1760CbcBranchDefaultDecision::~CbcBranchDefaultDecision()
1761{
1762}
1763
1764// Clone
1765CbcBranchDecision * 
1766CbcBranchDefaultDecision::clone() const
1767{
1768  return new CbcBranchDefaultDecision(*this);
1769}
1770
1771// Initialize i.e. before start of choosing at a node
1772void 
1773CbcBranchDefaultDecision::initialize(CbcModel * model)
1774{
1775  bestCriterion_ = 0.0;
1776  bestChangeUp_ = 0.0;
1777  bestNumberUp_ = 0;
1778  bestChangeDown_ = 0.0;
1779  bestNumberDown_ = 0;
1780  bestObject_ = NULL;
1781}
1782
1783
1784/*
1785  Simple default decision algorithm. Compare based on infeasibility (numInfUp,
1786  numInfDn) until a solution is found by search, then switch to change in
1787  objective (changeUp, changeDn). Note that bestSoFar is remembered in
1788  bestObject_, so the parameter bestSoFar is unused.
1789*/
1790
1791int
1792CbcBranchDefaultDecision::betterBranch(CbcBranchingObject * thisOne,
1793                            CbcBranchingObject * bestSoFar,
1794                            double changeUp, int numInfUp,
1795                            double changeDn, int numInfDn)
1796{
1797  bool beforeSolution = thisOne->model()->getSolutionCount()==
1798    thisOne->model()->getNumberHeuristicSolutions();;
1799  int betterWay=0;
1800  if (beforeSolution) {
1801    if (!bestObject_) {
1802      bestNumberUp_=INT_MAX;
1803      bestNumberDown_=INT_MAX;
1804    }
1805    // before solution - choose smallest number
1806    // could add in depth as well
1807    int bestNumber = CoinMin(bestNumberUp_,bestNumberDown_);
1808    if (numInfUp<numInfDn) {
1809      if (numInfUp<bestNumber) {
1810        betterWay = 1;
1811      } else if (numInfUp==bestNumber) {
1812        if (changeUp<bestCriterion_)
1813          betterWay=1;
1814      }
1815    } else if (numInfUp>numInfDn) {
1816      if (numInfDn<bestNumber) {
1817        betterWay = -1;
1818      } else if (numInfDn==bestNumber) {
1819        if (changeDn<bestCriterion_)
1820          betterWay=-1;
1821      }
1822    } else {
1823      // up and down have same number
1824      bool better=false;
1825      if (numInfUp<bestNumber) {
1826        better=true;
1827      } else if (numInfUp==bestNumber) {
1828        if (min(changeUp,changeDn)<bestCriterion_)
1829          better=true;;
1830      }
1831      if (better) {
1832        // see which way
1833        if (changeUp<=changeDn)
1834          betterWay=1;
1835        else
1836          betterWay=-1;
1837      }
1838    }
1839  } else {
1840    if (!bestObject_) {
1841      bestCriterion_=-1.0;
1842    }
1843    // got a solution
1844    if (changeUp<=changeDn) {
1845      if (changeUp>bestCriterion_)
1846        betterWay=1;
1847    } else {
1848      if (changeDn>bestCriterion_)
1849        betterWay=-1;
1850    }
1851  }
1852  if (betterWay) {
1853    bestCriterion_ = CoinMin(changeUp,changeDn);
1854    bestChangeUp_ = changeUp;
1855    bestNumberUp_ = numInfUp;
1856    bestChangeDown_ = changeDn;
1857    bestNumberDown_ = numInfDn;
1858    bestObject_=thisOne;
1859  }
1860  return betterWay;
1861}
1862// Default Constructor
1863CbcFollowOn::CbcFollowOn ()
1864  : CbcObject(),
1865    rhs_(NULL)
1866{
1867}
1868
1869// Useful constructor
1870CbcFollowOn::CbcFollowOn (CbcModel * model)
1871  : CbcObject(model)
1872{
1873  assert (model);
1874  OsiSolverInterface * solver = model_->solver();
1875  matrix_ = *solver->getMatrixByCol();
1876  matrix_.removeGaps();
1877  matrixByRow_ = *solver->getMatrixByRow();
1878  int numberRows = matrix_.getNumRows();
1879 
1880  rhs_ = new int[numberRows];
1881  int i;
1882  const double * rowLower = solver->getRowLower();
1883  const double * rowUpper = solver->getRowUpper();
1884  // Row copy
1885  const double * elementByRow = matrixByRow_.getElements();
1886  const int * column = matrixByRow_.getIndices();
1887  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
1888  const int * rowLength = matrixByRow_.getVectorLengths();
1889  for (i=0;i<numberRows;i++) {
1890    rhs_[i]=0;
1891    double value = rowLower[i];
1892    if (value==rowUpper[i]) {
1893      if (floor(value)==value&&value>=1.0&&value<10.0) {
1894        // check elements
1895        bool good=true;
1896        for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
1897          int iColumn = column[j];
1898          if (!solver->isBinary(iColumn))
1899            good=false;
1900          double elValue = elementByRow[j];
1901          if (floor(elValue)!=elValue||value<1.0)
1902            good=false;
1903        }
1904        if (good)
1905          rhs_[i]=(int) value;
1906      }
1907    }
1908  }
1909}
1910
1911// Copy constructor
1912CbcFollowOn::CbcFollowOn ( const CbcFollowOn & rhs)
1913  :CbcObject(rhs),
1914   matrix_(rhs.matrix_),
1915   matrixByRow_(rhs.matrixByRow_)
1916{
1917  int numberRows = matrix_.getNumRows();
1918  rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
1919}
1920
1921// Clone
1922CbcObject *
1923CbcFollowOn::clone() const
1924{
1925  return new CbcFollowOn(*this);
1926}
1927
1928// Assignment operator
1929CbcFollowOn & 
1930CbcFollowOn::operator=( const CbcFollowOn& rhs)
1931{
1932  if (this!=&rhs) {
1933    CbcObject::operator=(rhs);
1934    delete [] rhs_;
1935    matrix_ = rhs.matrix_;
1936    matrixByRow_ = rhs.matrixByRow_;
1937    int numberRows = matrix_.getNumRows();
1938    rhs_= CoinCopyOfArray(rhs.rhs_,numberRows);
1939  }
1940  return *this;
1941}
1942
1943// Destructor
1944CbcFollowOn::~CbcFollowOn ()
1945{
1946  delete [] rhs_;
1947}
1948// As some computation is needed in more than one place - returns row
1949int 
1950CbcFollowOn::gutsOfFollowOn(int & otherRow, int & preferredWay) const
1951{
1952  int whichRow=-1;
1953  otherRow=-1;
1954  int numberRows = matrix_.getNumRows();
1955 
1956  int i;
1957  // For sorting
1958  int * sort = new int [numberRows];
1959  int * isort = new int [numberRows];
1960  // Column copy
1961  //const double * element = matrix_.getElements();
1962  const int * row = matrix_.getIndices();
1963  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
1964  const int * columnLength = matrix_.getVectorLengths();
1965  // Row copy
1966  const double * elementByRow = matrixByRow_.getElements();
1967  const int * column = matrixByRow_.getIndices();
1968  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
1969  const int * rowLength = matrixByRow_.getVectorLengths();
1970  OsiSolverInterface * solver = model_->solver();
1971  const double * columnLower = solver->getColLower();
1972  const double * columnUpper = solver->getColUpper();
1973  const double * solution = solver->getColSolution();
1974  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
1975  int nSort=0;
1976  for (i=0;i<numberRows;i++) {
1977    if (rhs_[i]) {
1978      // check elements
1979      double smallest=1.0e10;
1980      double largest=0.0;
1981      int rhsValue=rhs_[i];
1982      int number1=0;
1983      int numberUnsatisfied=0;
1984      for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
1985        int iColumn = column[j];
1986        double value = elementByRow[j];
1987        double solValue = solution[iColumn];
1988        if (columnLower[iColumn]!=columnUpper[iColumn]) {
1989          smallest = CoinMin(smallest,value);
1990          largest = CoinMax(largest,value);
1991          if (value==1.0)
1992            number1++;
1993          if (solValue<1.0-integerTolerance&&solValue>integerTolerance)
1994            numberUnsatisfied++;
1995        } else {
1996          rhsValue -= (int)(value*floor(solValue+0.5));
1997        }
1998      }
1999      if (numberUnsatisfied>1) {
2000        if (smallest<largest) {
2001          // probably no good but check a few things
2002          assert (largest<=rhsValue);
2003          if (number1==1&&largest==rhsValue)
2004            printf("could fix\n");
2005        } else if (largest==rhsValue) {
2006          sort[nSort]=i;
2007          isort[nSort++]=-numberUnsatisfied;
2008        }
2009      }
2010    }
2011  }
2012  if (nSort>1) {
2013    CoinSort_2(isort,isort+nSort,sort);
2014    CoinZeroN(isort,numberRows);
2015    double * other = new double[numberRows];
2016    CoinZeroN(other,numberRows);
2017    int * which = new int[numberRows];
2018    //#define COUNT
2019#ifndef COUNT
2020    bool beforeSolution = model_->getSolutionCount()==0;
2021#endif
2022    for (int k=0;k<nSort-1;k++) {
2023      i=sort[k];
2024      int numberUnsatisfied = 0;
2025      int n=0;
2026      int j;
2027      for (j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
2028        int iColumn = column[j];
2029        if (columnLower[iColumn]!=columnUpper[iColumn]) {
2030          double solValue = solution[iColumn]-columnLower[iColumn];
2031          if (solValue<1.0-integerTolerance&&solValue>integerTolerance) {
2032            numberUnsatisfied++;
2033            for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
2034              int iRow = row[jj];
2035              if (rhs_[iRow]) {
2036                other[iRow]+=solValue;
2037                if (isort[iRow]) {
2038                  isort[iRow]++;
2039                } else {
2040                  isort[iRow]=1;
2041                  which[n++]=iRow;
2042                }
2043              }
2044            }
2045          }
2046        }
2047      }
2048      double total=0.0;
2049      // Take out row
2050      double sumThis=other[i];
2051      other[i]=0.0;
2052      assert (numberUnsatisfied==isort[i]);
2053      // find one nearest half if solution, one if before solution
2054      int iBest=-1;
2055      double dtarget=0.5*total;
2056#ifdef COUNT
2057      int target = (numberUnsatisfied+1)>>1;
2058      int best=numberUnsatisfied;
2059#else
2060      double best;
2061      if (beforeSolution)
2062        best=dtarget;
2063      else
2064        best=1.0e30;
2065#endif
2066      for (j=0;j<n;j++) {
2067        int iRow = which[j];
2068        double dvalue=other[iRow];
2069        other[iRow]=0.0;
2070#ifdef COUNT
2071        int value = isort[iRow];
2072#endif
2073        isort[iRow]=0;
2074        if (fabs(dvalue)<1.0e-8||fabs(sumThis-dvalue)<1.0e-8)
2075          continue;
2076        if (dvalue<integerTolerance||dvalue>1.0-integerTolerance)
2077          continue;
2078#ifdef COUNT
2079        if (abs(value-target)<best&&value!=numberUnsatisfied) {
2080          best=abs(value-target);
2081          iBest=iRow;
2082          if (dvalue<dtarget)
2083            preferredWay=1;
2084          else
2085            preferredWay=-1;
2086        }
2087#else
2088        if (beforeSolution) {
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        } else {
2098          if (fabs(dvalue-dtarget)<best) {
2099            best = fabs(dvalue-dtarget);
2100            iBest=iRow;
2101            if (dvalue<dtarget)
2102              preferredWay=1;
2103            else
2104              preferredWay=-1;
2105          }
2106        }
2107#endif
2108      }
2109      if (iBest>=0) {
2110        whichRow=i;
2111        otherRow=iBest;
2112        break;
2113      }
2114    }
2115    delete [] which;
2116    delete [] other;
2117  }
2118  delete [] sort;
2119  delete [] isort;
2120  return whichRow;
2121}
2122
2123// Infeasibility - large is 0.5
2124double 
2125CbcFollowOn::infeasibility(int & preferredWay) const
2126{
2127  int otherRow=0;
2128  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
2129  if (whichRow<0)
2130    return 0.0;
2131  else
2132  return 2.0* model_->getDblParam(CbcModel::CbcIntegerTolerance);
2133}
2134
2135// This looks at solution and sets bounds to contain solution
2136void 
2137CbcFollowOn::feasibleRegion()
2138{
2139}
2140
2141
2142// Creates a branching object
2143CbcBranchingObject * 
2144CbcFollowOn::createBranch(int way) const
2145{
2146  int otherRow=0;
2147  int preferredWay;
2148  int whichRow = gutsOfFollowOn(otherRow,preferredWay);
2149  assert(way==preferredWay);
2150  assert (whichRow>=0);
2151  int numberColumns = matrix_.getNumCols();
2152 
2153  // Column copy
2154  //const double * element = matrix_.getElements();
2155  const int * row = matrix_.getIndices();
2156  const CoinBigIndex * columnStart = matrix_.getVectorStarts();
2157  const int * columnLength = matrix_.getVectorLengths();
2158  // Row copy
2159  //const double * elementByRow = matrixByRow_.getElements();
2160  const int * column = matrixByRow_.getIndices();
2161  const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
2162  const int * rowLength = matrixByRow_.getVectorLengths();
2163  OsiSolverInterface * solver = model_->solver();
2164  const double * columnLower = solver->getColLower();
2165  const double * columnUpper = solver->getColUpper();
2166  //const double * solution = solver->getColSolution();
2167  int nUp=0;
2168  int nDown=0;
2169  int * upList = new int[numberColumns];
2170  int * downList = new int[numberColumns];
2171  int j;
2172  for (j=rowStart[whichRow];j<rowStart[whichRow]+rowLength[whichRow];j++) {
2173    int iColumn = column[j];
2174    if (columnLower[iColumn]!=columnUpper[iColumn]) {
2175      bool up=true;
2176      for (int jj=columnStart[iColumn];jj<columnStart[iColumn]+columnLength[iColumn];jj++) {
2177        int iRow = row[jj];
2178        if (iRow==otherRow) {
2179          up=false;
2180          break;
2181        }
2182      }
2183      if (up)
2184        upList[nUp++]=iColumn;
2185      else
2186        downList[nDown++]=iColumn;
2187    }
2188  }
2189  //printf("way %d\n",way);
2190  // create object
2191  CbcBranchingObject * branch
2192     = new CbcFixingBranchingObject(model_,way,
2193                                         nDown,downList,nUp,upList);
2194  delete [] upList;
2195  delete [] downList;
2196  return branch;
2197}
2198// Default Constructor
2199CbcFixingBranchingObject::CbcFixingBranchingObject()
2200  :CbcBranchingObject()
2201{
2202  numberDown_=0;
2203  numberUp_=0;
2204  downList_=NULL;
2205  upList_=NULL;
2206}
2207
2208// Useful constructor
2209CbcFixingBranchingObject::CbcFixingBranchingObject (CbcModel * model,
2210                                                    int way ,
2211                                                    int numberOnDownSide, const int * down,
2212                                                    int numberOnUpSide, const int * up)
2213  :CbcBranchingObject(model,0,way,0.5)
2214{
2215  numberDown_=numberOnDownSide;
2216  numberUp_=numberOnUpSide;
2217  downList_ = CoinCopyOfArray(down,numberDown_);
2218  upList_ = CoinCopyOfArray(up,numberUp_);
2219}
2220
2221// Copy constructor
2222CbcFixingBranchingObject::CbcFixingBranchingObject ( const CbcFixingBranchingObject & rhs) :CbcBranchingObject(rhs)
2223{
2224  numberDown_=rhs.numberDown_;
2225  numberUp_=rhs.numberUp_;
2226  downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
2227  upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
2228}
2229
2230// Assignment operator
2231CbcFixingBranchingObject & 
2232CbcFixingBranchingObject::operator=( const CbcFixingBranchingObject& rhs)
2233{
2234  if (this != &rhs) {
2235    CbcBranchingObject::operator=(rhs);
2236    delete [] downList_;
2237    delete [] upList_;
2238    numberDown_=rhs.numberDown_;
2239    numberUp_=rhs.numberUp_;
2240    downList_ = CoinCopyOfArray(rhs.downList_,numberDown_);
2241    upList_ = CoinCopyOfArray(rhs.upList_,numberUp_);
2242  }
2243  return *this;
2244}
2245CbcBranchingObject * 
2246CbcFixingBranchingObject::clone() const
2247{ 
2248  return (new CbcFixingBranchingObject(*this));
2249}
2250
2251
2252// Destructor
2253CbcFixingBranchingObject::~CbcFixingBranchingObject ()
2254{
2255  delete [] downList_;
2256  delete [] upList_;
2257}
2258double
2259CbcFixingBranchingObject::branch(bool normalBranch)
2260{
2261  if (model_->messageHandler()->logLevel()>2&&normalBranch)
2262    print(normalBranch);
2263  numberBranchesLeft_--;
2264  OsiSolverInterface * solver = model_->solver();
2265  const double * columnLower = solver->getColLower();
2266  int i;
2267  // *** for way - up means fix all those in up section
2268  if (way_<0) {
2269#ifdef FULL_PRINT
2270    printf("Down Fix ");
2271#endif
2272    for (i=0;i<numberDown_;i++) {
2273      int iColumn = downList_[i];
2274      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
2275#ifdef FULL_PRINT
2276      printf("Setting bound on %d to lower bound\n",iColumn);
2277#endif
2278    }
2279    way_=1;       // Swap direction
2280  } else {
2281#ifdef FULL_PRINT
2282    printf("Up Fix ");
2283#endif
2284    for (i=0;i<numberUp_;i++) {
2285      int iColumn = upList_[i];
2286      model_->solver()->setColUpper(iColumn,columnLower[iColumn]);
2287#ifdef FULL_PRINT
2288      printf("Setting bound on %d to lower bound\n",iColumn);
2289#endif
2290    }
2291    way_=-1;      // Swap direction
2292  }
2293#ifdef FULL_PRINT
2294  printf("\n");
2295#endif
2296  return 0.0;
2297}
2298void
2299CbcFixingBranchingObject::print(bool normalBranch)
2300{
2301  int i;
2302  // *** for way - up means fix all those in up section
2303  if (way_<0) {
2304    printf("Down Fix ");
2305    for (i=0;i<numberDown_;i++) {
2306      int iColumn = downList_[i];
2307      printf("%d ",iColumn);
2308    }
2309  } else {
2310    printf("Up Fix ");
2311    for (i=0;i<numberUp_;i++) {
2312      int iColumn = upList_[i];
2313      printf("%d ",iColumn);
2314    }
2315  }
2316  printf("\n");
2317}
Note: See TracBrowser for help on using the repository browser.