void loadProblem(EnvPtr env, MINOTAUR_AMPL::AMPLInterface* iface, ProblemPtr &oinst, double *obj_sense) { Timer *timer = env->getNewTimer(); OptionDBPtr options = env->getOptions(); JacobianPtr jac; HessianOfLagPtr hess; const std::string me("qg: "); timer->start(); oinst = iface->readInstance(options->findString("problem_file")->getValue()); env->getLogger()->msgStream(LogInfo) << me << "time used in reading instance = " << std::fixed << std::setprecision(2) << timer->query() << std::endl; // display the problem oinst->calculateSize(); if (options->findBool("display_problem")->getValue()==true) { oinst->write(env->getLogger()->msgStream(LogNone), 12); } if (options->findBool("display_size")->getValue()==true) { oinst->writeSize(env->getLogger()->msgStream(LogNone)); } // create the jacobian if (false==options->findBool("use_native_cgraph")->getValue()) { jac = (MINOTAUR_AMPL::AMPLJacobianPtr) new MINOTAUR_AMPL::AMPLJacobian(iface); oinst->setJacobian(jac); // create the hessian hess = (MINOTAUR_AMPL::AMPLHessianPtr) new MINOTAUR_AMPL::AMPLHessian(iface); oinst->setHessian(hess); } // set initial point oinst->setInitialPoint(iface->getInitialPoint(), oinst->getNumVars()-iface->getNumDefs()); if (oinst->getObjective() && oinst->getObjective()->getObjectiveType()==Maximize) { *obj_sense = -1.0; env->getLogger()->msgStream(LogInfo) << me << "objective sense: maximize (will be converted to Minimize)" << std::endl; } else { *obj_sense = 1.0; env->getLogger()->msgStream(LogInfo) << me << "objective sense: minimize" << std::endl; } delete timer; }
PresolverPtr presolve(EnvPtr env, ProblemPtr p, size_t ndefs, HandlerVector &handlers) { PresolverPtr pres = PresolverPtr(); // NULL const std::string me("qg: "); p->calculateSize(); if (env->getOptions()->findBool("presolve")->getValue() == true) { LinearHandlerPtr lhandler = (LinearHandlerPtr) new LinearHandler(env, p); handlers.push_back(lhandler); if (p->isQP() || p->isQuadratic() || p->isLinear() || true==env->getOptions()->findBool("use_native_cgraph")->getValue()) { lhandler->setPreOptPurgeVars(true); lhandler->setPreOptPurgeCons(true); lhandler->setPreOptCoeffImp(true); } else { lhandler->setPreOptPurgeVars(false); lhandler->setPreOptPurgeCons(false); lhandler->setPreOptCoeffImp(false); } if (ndefs>0) { lhandler->setPreOptDualFix(false); } else { lhandler->setPreOptDualFix(true); } if (!p->isLinear() && true==env->getOptions()->findBool("use_native_cgraph")->getValue() && true==env->getOptions()->findBool("nl_presolve")->getValue() ) { NlPresHandlerPtr nlhand = (NlPresHandlerPtr) new NlPresHandler(env, p); handlers.push_back(nlhand); } // write the names. env->getLogger()->msgStream(LogExtraInfo) << me << "handlers used in presolve:" << std::endl; for (HandlerIterator h = handlers.begin(); h != handlers.end(); ++h) { env->getLogger()->msgStream(LogExtraInfo) << me << (*h)->getName() << std::endl; } } pres = (PresolverPtr) new Presolver(p, env, handlers); pres->standardize(); if (env->getOptions()->findBool("presolve")->getValue() == true) { pres->solve(); } return pres; }
void writeSol(EnvPtr env, VarVector *orig_v, PresolverPtr pres, SolutionPtr sol, SolveStatus status, MINOTAUR_AMPL::AMPLInterface* iface) { if (sol) { sol = pres->getPostSol(sol); } if (env->getOptions()->findFlag("AMPL")->getValue() || true == env->getOptions()->findBool("write_sol_file")->getValue()) { iface->writeSolution(sol, status); } else if (sol && env->getLogger()->getMaxLevel()>=LogExtraInfo && env->getOptions()->findBool("display_solution")->getValue()) { sol->writePrimal(env->getLogger()->msgStream(LogExtraInfo), orig_v); } }
ParQGHandler::ParQGHandler(EnvPtr env, ProblemPtr minlp, EnginePtr nlpe) : env_(env), minlp_(minlp), nlCons_(0), nlpe_(nlpe), nlpStatus_(EngineUnknownStatus), objVar_(VariablePtr()), oNl_(false), rel_(RelaxationPtr()), relobj_(0.0) { intTol_ = env_->getOptions()->findDouble("int_tol")->getValue(); solAbsTol_ = env_->getOptions()->findDouble("feasAbs_tol")->getValue(); solRelTol_ = env_->getOptions()->findDouble("feasRel_tol")->getValue(); npATol_ = env_->getOptions()->findDouble("solAbs_tol")->getValue(); npRTol_ = env_->getOptions()->findDouble("solRel_tol")->getValue(); logger_ = env->getLogger(); stats_ = new ParQGStats(); stats_->nlpS = 0; stats_->nlpF = 0; stats_->nlpI = 0; stats_->nlpIL = 0; stats_->cuts = 0; }
SOS1Handler::SOS1Handler(EnvPtr env, ProblemPtr problem) : env_(env) { logger_ = env->getLogger(); modProb_ = true; modRel_ = true; zTol_ = 1e-6; problem_ = problem; }
MultilinearTermsHandler::MultilinearTermsHandler(EnvPtr env, ProblemPtr problem) : env_(env), problem_(problem) { logger_ = env->getLogger(); eTol_ = env->getOptions()->findDouble("ml_feastol")->getValue(); maxGroupSize_ = (UInt) env_->getOptions()->findInt("ml_max_group_size")->getValue(); augmentCoverFactor_ = env_->getOptions()->findDouble("ml_cover_augmentation_factor")->getValue(); initialTermCoverSize_ = 0; }
int showInfo(EnvPtr env) { OptionDBPtr options = env->getOptions(); const std::string me("qg: "); if (options->findBool("display_options")->getValue() || options->findFlag("=")->getValue()) { options->write(std::cout); return 1; } if (options->findBool("display_help")->getValue() || options->findFlag("?")->getValue()) { showHelp(); return 1; } if (options->findBool("display_version")->getValue() || options->findFlag("v")->getValue()) { env->getLogger()->msgStream(LogNone) << me << "Minotaur version " << env->getVersion() << std::endl; env->getLogger()->msgStream(LogNone) << me << "Quesada-Grossmann (LP/NLP) algorithm for convex MINLP" << std::endl; return 1; } if (options->findString("problem_file")->getValue()=="") { showHelp(); return 1; } env->getLogger()->msgStream(LogInfo) << me << "Minotaur version " << env->getVersion() << std::endl << me << "Quesada-Grossmann (LP/NLP) algorithm for convex MINLP" << std::endl; return 0; }
void writeBnbStatus(EnvPtr env, BranchAndBound *bab, double obj_sense) { const std::string me("qg: "); int err = 0; if (bab) { env->getLogger()->msgStream(LogInfo) << me << std::fixed << std::setprecision(4) << "best solution value = " << obj_sense*bab->getUb() << std::endl << me << std::fixed << std::setprecision(4) << "best bound estimate from remaining nodes = " << obj_sense*bab->getLb() << std::endl << me << "gap = " << std::max(0.0,bab->getUb() - bab->getLb()) << std::endl << me << "gap percentage = " << bab->getPerGap() << std::endl << me << "time used (s) = " << std::fixed << std::setprecision(2) << env->getTime(err) << std::endl << me << "status of branch-and-bound: " << getSolveStatusString(bab->getStatus()) << std::endl; env->stopTimer(err); assert(0==err); } else { env->getLogger()->msgStream(LogInfo) << me << std::fixed << std::setprecision(4) << "best solution value = " << INFINITY << std::endl << me << std::fixed << std::setprecision(4) << "best bound estimate from remaining nodes = " << INFINITY << std::endl << me << "gap = " << INFINITY << std::endl << me << "gap percentage = " << INFINITY << std::endl << me << "time used (s) = " << std::fixed << std::setprecision(2) << env->getTime(err) << std::endl << me << "status of branch-and-bound: " << getSolveStatusString(NotStarted) << std::endl; env->stopTimer(err); assert(0==err); } }
RandomBrancher::RandomBrancher(EnvPtr env, HandlerVector handlers) { logger_ = env->getLogger(); timer_ = env->getNewTimer(); stats_ = new RandomBrStats(); stats_->calls = 0; stats_->time = 0.0; handlers_ = handlers; seed_ = env->getOptions()->findInt("rand_seed")->getValue(); if (seed_ == 0) { srand(time(NULL)); } else { srand(seed_); } }
int main(int argc, char* argv[]) { EnvPtr env = (EnvPtr) new Environment(); OptionDBPtr options; MINOTAUR_AMPL::AMPLInterfacePtr iface = MINOTAUR_AMPL::AMPLInterfacePtr(); ProblemPtr inst; SolutionPtr sol, sol2; double obj_sense =1.0; // jacobian is read from AMPL interface and passed on to branch-and-bound JacobianPtr jPtr; // hessian is read from AMPL interface and passed on to branch-and-bound MINOTAUR_AMPL::AMPLHessianPtr hPtr; // the branch-and-bound BranchAndBound *bab = 0; PresolverPtr pres; EngineFactory *efac; const std::string me("qg: "); BrancherPtr br = BrancherPtr(); // NULL PCBProcessorPtr nproc; NodeIncRelaxerPtr nr; //handlers HandlerVector handlers; IntVarHandlerPtr vHand; LinearHandlerPtr lHand; QGAdvHandlerPtr qgHand; RCHandlerPtr rcHand; //engines EnginePtr nlp_e; EnginePtr proj_nlp_e; EnginePtr l1proj_nlp_e; LPEnginePtr lin_e; // lp engine LoggerPtr logger_ = (LoggerPtr) new Logger(LogInfo); VarVector *orig_v=0; int err = 0; // start timing. env->startTimer(err); if (err) { goto CLEANUP; } setInitialOptions(env); iface = (MINOTAUR_AMPL::AMPLInterfacePtr) new MINOTAUR_AMPL::AMPLInterface(env, "qg"); // parse options env->readOptions(argc, argv); options = env->getOptions(); options->findString("interface_type")->setValue("AMPL"); if (0!=showInfo(env)) { goto CLEANUP; } loadProblem(env, iface, inst, &obj_sense); // Initialize engines nlp_e = getNLPEngine(env, inst); //Engine for Original problem efac = new EngineFactory(env); lin_e = efac->getLPEngine(); // lp engine delete efac; // get presolver. orig_v = new VarVector(inst->varsBegin(), inst->varsEnd()); pres = presolve(env, inst, iface->getNumDefs(), handlers); handlers.clear(); if (Finished != pres->getStatus() && NotStarted != pres->getStatus()) { env->getLogger()->msgStream(LogInfo) << me << "status of presolve: " << getSolveStatusString(pres->getStatus()) << std::endl; writeSol(env, orig_v, pres, SolutionPtr(), pres->getStatus(), iface); writeBnbStatus(env, bab, obj_sense); goto CLEANUP; } if (options->findBool("solve")->getValue()==true) { if (true==options->findBool("use_native_cgraph")->getValue()) { inst->setNativeDer(); } // Initialize the handlers for branch-and-cut lHand = (LinearHandlerPtr) new LinearHandler(env, inst); lHand->setModFlags(false, true); handlers.push_back(lHand); assert(lHand); vHand = (IntVarHandlerPtr) new IntVarHandler(env, inst); vHand->setModFlags(false, true); handlers.push_back(vHand); assert(vHand); // Use of perspective handler is user choice if (env->getOptions()->findBool("perspective")->getValue() == true) { PerspCutHandlerPtr pcHand = (PerspCutHandlerPtr) new PerspCutHandler(env, inst); pcHand->findPRCons(); if (pcHand->getStatus()) { qgHand = (QGAdvHandlerPtr) new QGAdvHandler(env, inst, nlp_e, pcHand); } else { qgHand = (QGAdvHandlerPtr) new QGAdvHandler(env, inst, nlp_e); } } else { qgHand = (QGAdvHandlerPtr) new QGAdvHandler(env, inst, nlp_e); } qgHand->setModFlags(false, true); handlers.push_back(qgHand); assert(qgHand); if (options->findBool("rc_fix")->getValue()) { rcHand = (RCHandlerPtr) new RCHandler(env); rcHand->setModFlags(false, true); handlers.push_back(rcHand); assert(rcHand); } // report name env->getLogger()->msgStream(LogExtraInfo) << me << "handlers used:" << std::endl; for (HandlerIterator h = handlers.begin(); h != handlers.end(); ++h) { env->getLogger()->msgStream(LogExtraInfo) << me << (*h)->getName() << std::endl; } // Only store bound-changes of relaxation (not problem) nr = (NodeIncRelaxerPtr) new NodeIncRelaxer(env, handlers); nr->setModFlag(false); nr->setEngine(lin_e); nproc = (PCBProcessorPtr) new PCBProcessor(env, lin_e, handlers); if (env->getOptions()->findString("brancher")->getValue() == "rel") { ReliabilityBrancherPtr rel_br = (ReliabilityBrancherPtr) new ReliabilityBrancher(env, handlers); rel_br->setEngine(lin_e); nproc->setBrancher(rel_br); br = rel_br; } else if (env->getOptions()->findString("brancher")->getValue() == "maxvio") { MaxVioBrancherPtr mbr = (MaxVioBrancherPtr) new MaxVioBrancher(env, handlers); nproc->setBrancher(mbr); br = mbr; } else if (env->getOptions()->findString("brancher")->getValue() == "lex") { LexicoBrancherPtr lbr = (LexicoBrancherPtr) new LexicoBrancher(env, handlers); br = lbr; } nproc->setBrancher(br); env->getLogger()->msgStream(LogExtraInfo) << me << "brancher used = " << br->getName() << std::endl; bab = new BranchAndBound(env, inst); bab->setNodeRelaxer(nr); bab->setNodeProcessor(nproc); bab->shouldCreateRoot(true); // start solving bab->solve(); bab->writeStats(env->getLogger()->msgStream(LogExtraInfo)); //bab->writeStats(std::cout); nlp_e->writeStats(env->getLogger()->msgStream(LogExtraInfo)); lin_e->writeStats(env->getLogger()->msgStream(LogExtraInfo)); for (HandlerVector::iterator it=handlers.begin(); it!=handlers.end(); ++it) { //(*it)->writeStats(std::cout); (*it)->writeStats(env->getLogger()->msgStream(LogExtraInfo)); } writeSol(env, orig_v, pres, bab->getSolution(), bab->getStatus(), iface); writeBnbStatus(env, bab, obj_sense); } CLEANUP: if (iface) { delete iface; } if (orig_v) { delete orig_v; } if (bab) { delete bab; } return 0; }