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 }
00145
00147 void installCuts(OsiSolverInterface &si,
00148 const OsiCuts& cs, int numberCuts){
00149 int numberCutsBefore = cs.sizeRowCuts() - numberCuts;
00150
00151 CoinWarmStartBasis * basis
00152 = dynamic_cast<CoinWarmStartBasis*>(si.getWarmStart()) ;
00153 assert(basis != NULL);
00154 int numrows = si.getNumRows();
00155 basis->resize(numrows + numberCuts,si.getNumCols());
00156 for (int i = 0 ; i < numberCuts ; i++) {
00157 basis->setArtifStatus(numrows + i,
00158 CoinWarmStartBasis::basic) ;
00159 }
00160
00161 const OsiRowCut ** addCuts = new const OsiRowCut * [numberCuts] ;
00162 for (int i = 0 ; i < numberCuts ; i++) {
00163 addCuts[i] = &cs.rowCut(i + numberCutsBefore) ;
00164 }
00165 si.applyRowCuts(numberCuts,addCuts) ;
00166 delete [] addCuts ;
00167 if (si.setWarmStart(basis) == false) {
00168 delete basis;
00169 throw CoinError("Fail setWarmStart() after cut installation.",
00170 "generateCuts","OACutGenerator2") ;
00171 }
00172 delete basis;
00173 }
00174
00175
00177 bool isDifferentOnIntegers(OsiSolverInterface &si,
00178 OsiObject ** objects, int nObjects,
00179 double integer_tolerance,
00180 const double * colsol, const double *otherSol)
00181 {
00182 if (objects) {
00183 for (int i = 0 ; i < nObjects ; i++) {
00184 OsiObject * obj = objects[i];
00185 int colnum = obj->columnNumber();
00186 if (colnum >= 0) {
00187 if (fabs(otherSol[colnum] - colsol[colnum]) > integer_tolerance) {
00188 return true;
00189 }
00190 }
00191 else {
00192 OsiSOS * sos = dynamic_cast<OsiSOS *>(obj);
00193 assert(sos);
00194 const int * members = sos->members();
00195 int end = sos->numberMembers();
00196 for (int k = 0 ; k < end ; k++) {
00197 if (fabs(otherSol[members[k]] - colsol[members[k]]) > integer_tolerance) {
00198 return true;
00199 }
00200 }
00201 }
00202 }
00203 }
00204 else {
00205 int numcols = si.getNumCols();
00206 for (int i = 0; i < numcols ; i++) {
00207 if (si.isInteger(i) && fabs(otherSol[i] - colsol[i])>integer_tolerance)
00208 return true;
00209 }
00210 }
00211 return false;
00212 }
00213
00214 }
00215