/home/coin/SVN-release/OS-2.2.0/Bonmin/src/Algorithms/BonSolverHelp.cpp

Go to the documentation of this file.
00001 // (C) Copyright International Business Machines (IBM) 2006
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // P. Bonami, International Business Machines
00007 //
00008 // Date :  12/07/2006
00009 
00010 
00011 // Code separated from BonOaDecBase to try to clarify OAs
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         //         printf("xx %d at %g (bounds %g, %g)",i,value,nlp_->getColLower()[i],
00082         //                nlp_->getColUpper()[i]);
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); // make sure not volume
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) {//Variable branching object
00187         if (fabs(otherSol[colnum] - colsol[colnum]) > integer_tolerance) {
00188           return true;
00189         }
00190       }
00191       else {//It is a sos branching object
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 

Generated on Thu Aug 5 03:02:53 2010 by  doxygen 1.4.7