00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <sstream>
00014 #include "BonSolverHelp.hpp"
00015 #include "OsiSolverInterface.hpp"
00016 #include "OsiBranchingObject.hpp"
00017 #include "OsiCuts.hpp"
00018 #include "CoinWarmStartBasis.hpp"
00019 namespace Bonmin {
00021 bool integerFeasible(OsiSolverInterface & si, const OsiBranchingInformation & info,
00022 double integer_tolerance,
00023 OsiObject ** objects, int nObjects)
00024 {
00025 if (objects) {
00026 int dummy;
00027 for (int i = 0 ; i < nObjects ; i++) {
00028 double infeasibility = objects[i]->infeasibility(&info, dummy);
00029 if (infeasibility > 1000*integer_tolerance) return false;
00030 }
00031 }
00032 else {
00033 const double * sol = info.solution_;
00034 int numcols = si.getNumCols();
00035 for (int i = 0 ; i < numcols ; i++) {
00036 if (si.isInteger(i)) {
00037 if (fabs(sol[i] - floor(sol[i] + 0.5)) >
00038 integer_tolerance) {
00039 return false;
00040 }
00041 }
00042 }
00043 }
00044 return true;
00045 }
00046
00049 void fixIntegers(OsiSolverInterface & si,
00050 const OsiBranchingInformation & info,
00051 double integer_tolerance,
00052 OsiObject ** objects, int nObjects)
00053 {
00054 if (objects) {
00055 for (int i = 0 ; i < nObjects ; i++) {
00056 objects[i]->feasibleRegion(&si, &info);
00057 }
00058 }
00059 else {
00060 const double * colsol = info.solution_;
00061 for (int i = 0; i < info.numberColumns_; i++) {
00062 if (si.isInteger(i)) {
00063 double value = colsol[i];
00064 #ifndef NDEBUG
00065 if (fabs(value - floor(value+0.5)) > integer_tolerance) {
00066 std::stringstream stream;
00067 stream<<"Error not integer valued solution"<<std::endl;
00068 stream<<"---------------- x["<<i<<"] = "<<value<<std::endl;
00069 throw CoinError(stream.str(),"fixIntegers","OaDecompositionBase::solverManip");
00070 }
00071 #endif
00072 value = floor(value+0.5);
00073 if (fabs(value) > 1e10) {
00074 std::stringstream stream;
00075 stream<<"Can not fix variable in nlp because it has too big a value ("<<value
00076 <<") at optimium of LP relaxation. You should try running the problem with B-BB"<<std::endl;
00077 throw CoinError(stream.str(),
00078 "fixIntegers","OaDecompositionBase::solverManip") ;
00079 }
00080 #ifdef OA_DEBUG
00081
00082
00083 std::cout<<(int)value;
00084 #endif
00085 si.setColLower(i,value);
00086 si.setColUpper(i,value);
00087 }
00088 }
00089 #ifdef OA_DEBUG
00090 std::cout<<std::endl;
00091 #endif
00092 }
00093 }
00094
00097 void relaxIntegers(OsiSolverInterface & si,
00098 const OsiBranchingInformation & info,
00099 double integer_tolerance,
00100 OsiObject ** objects, int nObjects)
00101 {
00102 if (objects) {
00103 for (int i = 0 ; i < nObjects ; i++) {
00104 OsiSimpleInteger * obj = dynamic_cast<OsiSimpleInteger *>(objects[i]);
00105 int colNumber = obj->columnNumber();
00106 si.setColLower(colNumber, si.getColLower()[colNumber] - integer_tolerance);
00107 si.setColUpper(colNumber, si.getColUpper()[colNumber] + integer_tolerance);
00108 }
00109 }
00110 else {
00111 for (int i = 0; i < info.numberColumns_; i++) {
00112 if (si.isInteger(i)) {
00113 const int &colNumber = i;
00114 si.setColLower(colNumber, si.getColLower()[colNumber] - integer_tolerance);
00115 si.setColUpper(colNumber, si.getColUpper()[colNumber] + integer_tolerance);
00116 }
00117 }
00118 }
00119 }
00120
00121 bool refixIntegers(OsiSolverInterface & si,
00122 const OsiBranchingInformation & info,
00123 double integer_tolerance,
00124 OsiObject ** objects, int nObjects)
00125 {
00126 if(!si.isProvenOptimal()) return false;
00127 if (objects) {
00128 for (int i = 0 ; i < nObjects ; i++) {
00129 OsiSimpleInteger * obj = dynamic_cast<OsiSimpleInteger *>(objects[i]);
00130 int colNumber = obj->columnNumber();
00131 si.setColLower(colNumber, si.getColLower()[colNumber] - integer_tolerance);
00132 si.setColUpper(colNumber, si.getColUpper()[colNumber] + integer_tolerance);
00133 }
00134 }
00135 else {
00136 for (int i = 0; i < info.numberColumns_; i++) {
00137 if (si.isInteger(i)) {
00138 const int &colNumber = i;
00139 si.setColLower(colNumber, si.getColLower()[colNumber] - integer_tolerance);
00140 si.setColUpper(colNumber, si.getColUpper()[colNumber] + integer_tolerance);
00141 }
00142 }
00143 }
00144 return true;
00145 }
00146
00148 void installCuts(OsiSolverInterface &si,
00149 const OsiCuts& cs, int numberCuts){
00150 int numberCutsBefore = cs.sizeRowCuts() - numberCuts;
00151
00152 CoinWarmStartBasis * basis
00153 = dynamic_cast<CoinWarmStartBasis*>(si.getWarmStart()) ;
00154 assert(basis != NULL);
00155 int numrows = si.getNumRows();
00156 basis->resize(numrows + numberCuts,si.getNumCols());
00157 for (int i = 0 ; i < numberCuts ; i++) {
00158 basis->setArtifStatus(numrows + i,
00159 CoinWarmStartBasis::basic) ;
00160 }
00161
00162 const OsiRowCut ** addCuts = new const OsiRowCut * [numberCuts] ;
00163 for (int i = 0 ; i < numberCuts ; i++) {
00164 addCuts[i] = &cs.rowCut(i + numberCutsBefore) ;
00165 }
00166 si.applyRowCuts(numberCuts,addCuts) ;
00167 delete [] addCuts ;
00168 if (si.setWarmStart(basis) == false) {
00169 delete basis;
00170 throw CoinError("Fail setWarmStart() after cut installation.",
00171 "generateCuts","OACutGenerator2") ;
00172 }
00173 delete basis;
00174 }
00175
00176
00178 bool isDifferentOnIntegers(OsiSolverInterface &si,
00179 OsiObject ** objects, int nObjects,
00180 double integer_tolerance,
00181 const double * colsol, const double *otherSol)
00182 {
00183 if (objects) {
00184 for (int i = 0 ; i < nObjects ; i++) {
00185 OsiObject * obj = objects[i];
00186 int colnum = obj->columnNumber();
00187 if (colnum >= 0) {
00188 if (fabs(otherSol[colnum] - colsol[colnum]) > integer_tolerance) {
00189 return true;
00190 }
00191 }
00192 else {
00193 OsiSOS * sos = dynamic_cast<OsiSOS *>(obj);
00194 assert(sos);
00195 const int * members = sos->members();
00196 int end = sos->numberMembers();
00197 for (int k = 0 ; k < end ; k++) {
00198 if (fabs(otherSol[members[k]] - colsol[members[k]]) > integer_tolerance) {
00199 return true;
00200 }
00201 }
00202 }
00203 }
00204 }
00205 else {
00206 int numcols = si.getNumCols();
00207 for (int i = 0; i < numcols ; i++) {
00208 if (si.isInteger(i) && fabs(otherSol[i] - colsol[i])>integer_tolerance)
00209 return true;
00210 }
00211 }
00212 return false;
00213 }
00214
00215 }
00216