00001
00002
00003 #if defined(_MSC_VER)
00004
00005 # pragma warning(disable:4786)
00006 #endif
00007 #include <cassert>
00008 #include <cmath>
00009 #include <cfloat>
00010
00011 #include "OsiSolverInterface.hpp"
00012 #include "SbbModel.hpp"
00013 #include "SbbMessage.hpp"
00014 #include "SbbCutGenerator.hpp"
00015 #include "CglProbing.hpp"
00016
00017
00018 SbbCutGenerator::SbbCutGenerator ()
00019 : model_(NULL),
00020 generator_(NULL),
00021 whenCutGenerator_(-1),
00022 generatorName_(NULL),
00023 normal_(true),
00024 atSolution_(false),
00025 whenInfeasible_(false)
00026 {
00027 }
00028
00029 SbbCutGenerator::SbbCutGenerator(SbbModel * model,CglCutGenerator * generator,
00030 int howOften, const char * name,
00031 bool normal, bool atSolution,
00032 bool infeasible)
00033 {
00034 model_ = model;
00035 generator_=generator;
00036 generator_->refreshSolver(model_->solver());
00037 whenCutGenerator_=howOften;
00038 if (name)
00039 generatorName_=strdup(name);
00040 else
00041 generatorName_ = strdup("Unknown");
00042 normal_=normal;
00043 atSolution_=atSolution;
00044 whenInfeasible_=infeasible;
00045 }
00046
00047
00048 SbbCutGenerator::SbbCutGenerator ( const SbbCutGenerator & rhs)
00049 {
00050 model_ = rhs.model_;
00051 generator_=rhs.generator_;
00052 generator_->refreshSolver(model_->solver());
00053 whenCutGenerator_=rhs.whenCutGenerator_;
00054 generatorName_=strdup(rhs.generatorName_);
00055 normal_=rhs.normal_;
00056 atSolution_=rhs.atSolution_;
00057 whenInfeasible_=rhs.whenInfeasible_;
00058 }
00059
00060
00061 SbbCutGenerator &
00062 SbbCutGenerator::operator=( const SbbCutGenerator& rhs)
00063 {
00064 if (this!=&rhs) {
00065 delete generator_;
00066 free(generatorName_);
00067 model_ = rhs.model_;
00068 generator_=rhs.generator_;
00069 generator_->refreshSolver(model_->solver());
00070 whenCutGenerator_=rhs.whenCutGenerator_;
00071 generatorName_=strdup(rhs.generatorName_);
00072 normal_=rhs.normal_;
00073 atSolution_=rhs.atSolution_;
00074 whenInfeasible_=rhs.whenInfeasible_;
00075 }
00076 return *this;
00077 }
00078
00079
00080 SbbCutGenerator::~SbbCutGenerator ()
00081 {
00082 free(generatorName_);
00083 }
00084
00085
00086
00087
00088
00089 void
00090 SbbCutGenerator::refreshModel(SbbModel * model)
00091 {
00092 model_=model;
00093 generator_->refreshSolver(model_->solver());
00094 }
00095
00096
00097
00098
00099 bool
00100 SbbCutGenerator::generateCuts( OsiCuts & cs , bool fullScan)
00101 {
00102 int howOften = whenCutGenerator_;
00103 if (howOften==-100)
00104 return false;
00105 if (howOften>0)
00106 howOften = howOften % 1000000;
00107 else
00108 howOften=1;
00109 if (!howOften)
00110 howOften=1;
00111 bool returnCode=false;
00112 OsiSolverInterface * solver = model_->solver();
00113 if (fullScan||(model_->getNodeCount()%howOften)==0) {
00114 CglProbing* generator =
00115 dynamic_cast<CglProbing*>(generator_);
00116 if (!generator) {
00117 generator_->generateCuts(*solver,cs);
00118 } else {
00119
00120 generator->generateCutsAndModify(*solver,cs);
00121 const double * tightLower = generator->tightLower();
00122 const double * lower = solver->getColLower();
00123 const double * tightUpper = generator->tightUpper();
00124 const double * upper = solver->getColUpper();
00125 const double * solution = solver->getColSolution();
00126 int j;
00127 int numberColumns = solver->getNumCols();
00128 double primalTolerance = 1.0e-8;
00129 for (j=0;j<numberColumns;j++) {
00130 if (tightUpper[j]==tightLower[j]&&
00131 upper[j]>lower[j]) {
00132
00133 solver->setColLower(j,tightLower[j]);
00134 solver->setColUpper(j,tightUpper[j]);
00135 if (tightLower[j]>solution[j]+primalTolerance||
00136 tightUpper[j]<solution[j]-primalTolerance)
00137 returnCode=true;
00138 }
00139 }
00140 }
00141 }
00142 return returnCode;
00143 }
00144 void
00145 SbbCutGenerator::setHowOften(int howOften)
00146 {
00147
00148 if (howOften>=1000000) {
00149
00150 howOften = howOften % 1000000;
00151 CglProbing* generator =
00152 dynamic_cast<CglProbing*>(generator_);
00153
00154 if (generator&&howOften>10)
00155 howOften=10+1000000;
00156 }
00157 whenCutGenerator_ = howOften;
00158 }