BonSolverHelp.cpp
Go to the documentation of this file.
1 // (C) Copyright International Business Machines (IBM) 2006
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors :
6 // P. Bonami, International Business Machines
7 //
8 // Date : 12/07/2006
9 
10 
11 // Code separated from BonOaDecBase to try to clarify OAs
12 
13 #include <sstream>
14 #include "BonSolverHelp.hpp"
15 #include "OsiSolverInterface.hpp"
16 #include "OsiBranchingObject.hpp"
17 #include "OsiCuts.hpp"
18 #include "CoinWarmStartBasis.hpp"
19 namespace Bonmin {
21 bool integerFeasible(OsiSolverInterface & si, const OsiBranchingInformation & info,
22  double integer_tolerance,
23  OsiObject ** objects, int nObjects)
24 {
25  if (objects) {
26  int dummy;
27  for (int i = 0 ; i < nObjects ; i++) {
28  double infeasibility = objects[i]->infeasibility(&info, dummy);
29  if (infeasibility > 1000*integer_tolerance) return false;
30  }
31  }
32  else {
33  const double * sol = info.solution_;
34  int numcols = si.getNumCols();
35  for (int i = 0 ; i < numcols ; i++) {
36  if (si.isInteger(i)) {
37  if (fabs(sol[i] - floor(sol[i] + 0.5)) >
38  integer_tolerance) {
39  return false;
40  }
41  }
42  }
43  }
44  return true;
45 }
46 
49 void fixIntegers(OsiSolverInterface & si,
50  const OsiBranchingInformation & info,
51  double integer_tolerance,
52  OsiObject ** objects, int nObjects)
53 {
54  if (objects) {
55  for (int i = 0 ; i < nObjects ; i++) {
56  objects[i]->feasibleRegion(&si, &info);
57  }
58  }
59  else {
60  const double * colsol = info.solution_;
61  for (int i = 0; i < info.numberColumns_; i++) {
62  if (si.isInteger(i)) {
63  double value = colsol[i];
64 #ifndef NDEBUG
65  if (fabs(value - floor(value+0.5)) > integer_tolerance) {
66  std::stringstream stream;
67  stream<<"Error not integer valued solution"<<std::endl;
68  stream<<"---------------- x["<<i<<"] = "<<value<<std::endl;
69  throw CoinError(stream.str(),"fixIntegers","OaDecompositionBase::solverManip");
70  }
71 #endif
72  value = floor(value+0.5);
73  if (fabs(value) > 1e10) {
74  std::stringstream stream;
75  stream<<"Can not fix variable in nlp because it has too big a value ("<<value
76  <<") at optimium of LP relaxation. You should try running the problem with B-BB"<<std::endl;
77  throw CoinError(stream.str(),
78  "fixIntegers","OaDecompositionBase::solverManip") ;
79  }
80 #ifdef OA_DEBUG
81  // printf("xx %d at %g (bounds %g, %g)",i,value,nlp_->getColLower()[i],
82  // nlp_->getColUpper()[i]);
83  std::cout<<(int)value;
84 #endif
85  si.setColLower(i,value);
86  si.setColUpper(i,value);
87  }
88  }
89 #ifdef OA_DEBUG
90  std::cout<<std::endl;
91 #endif
92  }
93 }
94 
97 void relaxIntegers(OsiSolverInterface & si,
98  const OsiBranchingInformation & info,
99  double integer_tolerance,
100  OsiObject ** objects, int nObjects)
101 {
102  if (objects) {
103  for (int i = 0 ; i < nObjects ; i++) {
104  OsiSimpleInteger * obj = dynamic_cast<OsiSimpleInteger *>(objects[i]);
105  int colNumber = obj->columnNumber();
106  si.setColLower(colNumber, si.getColLower()[colNumber] - integer_tolerance);
107  si.setColUpper(colNumber, si.getColUpper()[colNumber] + integer_tolerance);
108  }
109  }
110  else {
111  for (int i = 0; i < info.numberColumns_; i++) {
112  if (si.isInteger(i)) {
113  const int &colNumber = i;
114  si.setColLower(colNumber, si.getColLower()[colNumber] - integer_tolerance);
115  si.setColUpper(colNumber, si.getColUpper()[colNumber] + integer_tolerance);
116  }
117  }
118  }
119 }
120 
121 bool refixIntegers(OsiSolverInterface & si,
122  const OsiBranchingInformation & info,
123  double integer_tolerance,
124  OsiObject ** objects, int nObjects)
125 {
126  if(!si.isProvenOptimal()) return false;
127  if (objects) {
128  for (int i = 0 ; i < nObjects ; i++) {
129  OsiSimpleInteger * obj = dynamic_cast<OsiSimpleInteger *>(objects[i]);
130  int colNumber = obj->columnNumber();
131  si.setColLower(colNumber, si.getColLower()[colNumber] - integer_tolerance);
132  si.setColUpper(colNumber, si.getColUpper()[colNumber] + integer_tolerance);
133  }
134  }
135  else {
136  for (int i = 0; i < info.numberColumns_; i++) {
137  if (si.isInteger(i)) {
138  const int &colNumber = i;
139  si.setColLower(colNumber, si.getColLower()[colNumber] - integer_tolerance);
140  si.setColUpper(colNumber, si.getColUpper()[colNumber] + integer_tolerance);
141  }
142  }
143  }
144  return true;
145 }
146 
148 void installCuts(OsiSolverInterface &si,
149  const OsiCuts& cs, int numberCuts){
150  int numberCutsBefore = cs.sizeRowCuts() - numberCuts;
151 
152  CoinWarmStartBasis * basis
153  = dynamic_cast<CoinWarmStartBasis*>(si.getWarmStart()) ;
154  assert(basis != NULL); // make sure not volume
155  int numrows = si.getNumRows();
156  basis->resize(numrows + numberCuts,si.getNumCols());
157  for (int i = 0 ; i < numberCuts ; i++) {
158  basis->setArtifStatus(numrows + i,
159  CoinWarmStartBasis::basic) ;
160  }
161 
162  const OsiRowCut ** addCuts = new const OsiRowCut * [numberCuts] ;
163  for (int i = 0 ; i < numberCuts ; i++) {
164  addCuts[i] = &cs.rowCut(i + numberCutsBefore) ;
165  }
166  si.applyRowCuts(numberCuts,addCuts) ;
167  delete [] addCuts ;
168  if (si.setWarmStart(basis) == false) {
169  delete basis;
170  throw CoinError("Fail setWarmStart() after cut installation.",
171  "generateCuts","OACutGenerator2") ;
172  }
173  delete basis;
174 }
175 
176 
178 bool isDifferentOnIntegers(OsiSolverInterface &si,
179  OsiObject ** objects, int nObjects,
180  double integer_tolerance,
181  const double * colsol, const double *otherSol)
182 {
183  if (objects) {
184  for (int i = 0 ; i < nObjects ; i++) {
185  OsiObject * obj = objects[i];
186  int colnum = obj->columnNumber();
187  if (colnum >= 0) {//Variable branching object
188  if (fabs(otherSol[colnum] - colsol[colnum]) > integer_tolerance) {
189  return true;
190  }
191  }
192  else {//It is a sos branching object
193  OsiSOS * sos = dynamic_cast<OsiSOS *>(obj);
194  assert(sos);
195  const int * members = sos->members();
196  int end = sos->numberMembers();
197  for (int k = 0 ; k < end ; k++) {
198  if (fabs(otherSol[members[k]] - colsol[members[k]]) > integer_tolerance) {
199  return true;
200  }
201  }
202  }
203  }
204  }
205  else {
206  int numcols = si.getNumCols();
207  for (int i = 0; i < numcols ; i++) {
208  if (si.isInteger(i) && fabs(otherSol[i] - colsol[i])>integer_tolerance)
209  return true;
210  }
211  }
212  return false;
213 }
214 
215 }
216 
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint fint * info
void installCuts(OsiSolverInterface &si, const OsiCuts &cs, int numberCuts)
Install cuts in solver.
bool isDifferentOnIntegers(OsiSolverInterface &si, OsiObject **objects, int nObjects, double integer_tolerance, const double *colsol, const double *otherSol)
Check if two solutions are the same on integer variables.
fint end
void fint fint * k
bool refixIntegers(OsiSolverInterface &si, const OsiBranchingInformation &info, double integer_tolerance, OsiObject **objects, int nObjects)
static int
Definition: OSdtoa.cpp:2173
void fixIntegers(OsiSolverInterface &si, const OsiBranchingInformation &info, double integer_tolerance, OsiObject **objects, int nObjects)
Fix integer variables in si to their values in colsol.
void relaxIntegers(OsiSolverInterface &si, const OsiBranchingInformation &info, double integer_tolerance, OsiObject **objects, int nObjects)
Slightly relax integer variables in si.
bool integerFeasible(OsiSolverInterface &si, const OsiBranchingInformation &info, double integer_tolerance, OsiObject **objects, int nObjects)
Check for integer feasibility of a solution return 1 if it is.