00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <climits>
00011
00012 #include "BonminConfig.h"
00013 #include "BonStrongBranchingSolver.hpp"
00014
00015 #include "RobotSetup.hpp"
00016 #include "BonNWayObject.hpp"
00017 #include "BonNWayChoose.hpp"
00018
00019
00020
00021 namespace Bonmin
00022 {
00023 RobotSetup::RobotSetup(const CoinMessageHandler * handler):BonminSetup(handler)
00024 {}
00025
00026 RobotSetup::RobotSetup(const RobotSetup &other):BonminSetup(other)
00027 {}
00028
00029 RobotSetup::RobotSetup(const RobotSetup &other,
00030 OsiTMINLPInterface &nlp):
00031 BonminSetup(other, nlp)
00032 {
00033 }
00034
00035 RobotSetup::RobotSetup(const RobotSetup &other,
00036 OsiTMINLPInterface &nlp,
00037 const std::string &prefix):
00038 BonminSetup(other, nlp, prefix)
00039 {
00040 initializeRobot();
00041 }
00042
00043 void RobotSetup::registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00044 {
00045 BonminSetup::registerAllOptions(roptions);
00046 BonNWayChoose::registerOptions(roptions);
00047
00048
00049 roptions->AddLowerBoundedIntegerOption("branch_on_frac_only",
00050 "Starting at given depth branch on the subset of fractional variables (and set the last branch that one of them is 1)",
00051 0,INT_MAX,"");
00052
00053 roptions->AddStringOption2("do_a_quick_one",
00054 "Do we try our luck?",
00055 "no",
00056 "no", "Don't (of course).",
00057 "yes", "Be crazy",
00058 "");
00059
00060 }
00061
00063 void
00064 RobotSetup::registerOptions()
00065 {
00066 registerAllOptions(roptions_);
00067 }
00068
00070 void
00071 RobotSetup::initialize(Ipopt::SmartPtr<TMINLP> tminlp, bool createContinuousSolver )
00072 {
00073 BonminSetup::initialize(tminlp,createContinuousSolver);
00074 initializeRobot();
00075 }
00076
00078 void
00079 RobotSetup::initialize(const OsiTMINLPInterface &nlpSi, bool createContinuousSolver )
00080 {
00081 BonminSetup::initialize(nlpSi,createContinuousSolver);
00082 initializeRobot();
00083 }
00084
00085 void RobotSetup::initializeRobot()
00086 {
00087 assert(continuousSolver_ == nonlinearSolver_);
00088
00089 delete branchingMethod_;
00090
00091 continuousSolver_->deleteObjects();
00092 continuousSolver_->findIntegersAndSOS(false);
00093 setPriorities();
00094 addNWays();
00095 Ipopt::SmartPtr<StrongBranchingSolver> strong_solver = NULL;
00096 nonlinearSolver_->SetStrongBrachingSolver(strong_solver);
00097 BonNWayChoose* chooseVariable = new BonNWayChoose(*this,
00098 nonlinearSolver_);
00099 branchingMethod_ = chooseVariable;
00100 branchingMethod_->setNumberStrong(intParam_[NumberStrong]);
00101
00102 }
00103
00104 void
00105 RobotSetup::addNWays()
00106 {
00107
00108 int do_quick;
00109 options()->GetEnumValue("do_a_quick_one", do_quick, prefix());
00110 int depth_frac;
00111 options()->GetIntegerValue("branch_on_frac_only", depth_frac, prefix());
00112
00113
00114 const TMINLP::SosInfo * sos = nonlinearSolver()->model()->sosConstraints();
00115 if (!getIntParameter(BabSetupBase::DisableSos) && sos && sos->num > 0)
00116 {
00117 const int & numSos = sos->num;
00118 OsiObject ** objects = new OsiObject*[numSos];
00119 const int * starts = sos->starts;
00120 const int * indices = sos->indices;
00121
00122 const double * weights = sos->weights;
00123 bool hasPriorities = false;
00124 const int * varPriorities = nonlinearSolver()->getPriorities();
00125 int numberObjects = nonlinearSolver()->numberObjects();
00126 if (varPriorities)
00127 {
00128 for (int i = 0 ; i < numberObjects ; i++) {
00129 if (varPriorities[i]) {
00130 hasPriorities = true;
00131 break;
00132 }
00133 }
00134 }
00135 const int * sosPriorities = sos->priorities;
00136 if (sosPriorities)
00137 {
00138 for (int i = 0 ; i < numSos ; i++) {
00139 if (sosPriorities[i]) {
00140 hasPriorities = true;
00141 break;
00142 }
00143 }
00144 }
00145
00146 std::vector<std::list<int> > groups(numSos + 1);
00147
00148 for (int i = 0 ; i < numSos ; i++)
00149 {
00150 int start = starts[i];
00151 int length = starts[i + 1] - start;
00152 for(int j = 0 ; j < length ; j++){
00153 groups[(size_t) weights[j]].push_back(indices[start+j]);
00154 }
00155 }
00156
00157 for (int i = 0 ; i < numSos ; i++)
00158 {
00159 int start = starts[i];
00160 int length = starts[i + 1] - start;
00161 BonNWayObject * nway = new BonNWayObject(length, &indices[start],i);
00162 nway->setPriority(1);
00163 for(int j = 0 ; j < length ; j++){
00164 n_way_consequences cons;
00165 std::vector<int>& ids = cons.indices;
00166 int idx = (int) weights[j];
00167 const std::list<int> &to_add = groups[idx];
00168 for(std::list<int>::const_iterator k = to_add.begin() ;
00169 k != to_add.end() ; k++){
00170 if(*k != indices[start+j]) ids.push_back(*k);
00171 }
00172 nway->setConsequence(j, cons);
00173 }
00174 objects[i] = nway;
00175
00176 if(do_quick)
00177 nway->make_quick();
00178 nway->set_only_frac_branches(depth_frac);
00179 if (hasPriorities && sosPriorities && sosPriorities[i]) {
00180 objects[i]->setPriority(sosPriorities[i]);
00181 }
00182 }
00183 nonlinearSolver()->addObjects(numSos, objects);
00184 for (int i = 0 ; i < numSos ; i++)
00185 delete objects[i];
00186 delete [] objects;
00187 }
00188 }
00189 }
00190