Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

SbbCutGenerator.cpp

00001 // Copyright (C) 2003, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #if defined(_MSC_VER)
00004 // Turn off compiler warning about long names
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 // Default Constructor 
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 // Normal constructor
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 // Copy constructor 
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 // Assignment operator 
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 // Destructor 
00080 SbbCutGenerator::~SbbCutGenerator ()
00081 {
00082   free(generatorName_);
00083 }
00084 
00085 /* This is used to refresh any inforamtion.
00086    It also refreshes the solver in the cut generator
00087    in case generator wants to do some work 
00088 */
00089 void 
00090 SbbCutGenerator::refreshModel(SbbModel * model)
00091 {
00092   model_=model;
00093   generator_->refreshSolver(model_->solver());
00094 }
00095 /* Generate cuts for the model data contained in si.
00096    The generated cuts are inserted into and returned in the
00097    collection of cuts cs.
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       // Probing - return tight column bounds
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           // fix
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     // leave Probing every 10
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 }

Generated on Wed Dec 3 14:36:19 2003 for Sbb by doxygen 1.3.5