void IpoptEngine::load(ProblemPtr problem) { if (problem_) { problem_->unsetEngine(); } problem_ = problem; sol_ = (IpoptSolPtr) new IpoptSolution(0, INFINITY, problem); mynlp_ = new Ipopt::IpoptFunInterface(problem, sol_); //Ipopt::ApplicationReturnStatus status; //status = myapp_->Initialize(); myapp_->Initialize(); // check if warm start needs to be saved if (prepareWs_) { ws_ = (IpoptWarmStartPtr) new IpoptWarmStart(); } // set the status of the engine to unknown. status_ = EngineUnknownStatus; bndChanged_ = true; consChanged_ = true; problem->calculateSize(); setOptionsForProb_(); problem->setEngine(this); }
void AMPLOsiUT::testOsiLP() { char file_name[] = "instances/lp0"; ProblemPtr inst = iface_->readInstance(file_name); FunctionPtr f = FunctionPtr(); // NULL // LPFormulationPtr lpForm = (LPFormulationPtr) // new LPFormulation(inst); engine_ptr_->load(inst); EngineStatus status = engine_ptr_->solve(); CPPUNIT_ASSERT(status == ProvenOptimal); CPPUNIT_ASSERT(engine_ptr_->getStatus() == ProvenOptimal); CPPUNIT_ASSERT(fabs(engine_ptr_->getSolutionValue()+8.42857) < 1e-5); inst->changeObj(f, 2.0); status = engine_ptr_->solve(); CPPUNIT_ASSERT(status == ProvenOptimal); CPPUNIT_ASSERT(engine_ptr_->getStatus() == ProvenOptimal); CPPUNIT_ASSERT(fabs(engine_ptr_->getSolutionValue()-2.0) < 1e-5); inst->negateObj(); status = engine_ptr_->solve(); CPPUNIT_ASSERT(status == ProvenOptimal); CPPUNIT_ASSERT(engine_ptr_->getStatus() == ProvenOptimal); CPPUNIT_ASSERT(fabs(engine_ptr_->getSolutionValue()+2.0) < 1e-5); }
bool Transformer::allConsAssigned_(ProblemPtr p, HandlerVector &handlers) { BoolVector asgn(p->getNumCons(), false); for (HandlerVector::const_iterator it=handlers.begin(); it!=handlers.end(); ++it) { for (ConstraintVector::const_iterator it2=(*it)->consBegin(); it2!=(*it)->consEnd(); ++it2) { if (asgn[(*it2)->getIndex()] == true) { std::cout << "constraint " << (*it2)->getName() << " with index " << (*it2)->getIndex() << " is assigned to more than one handlers!" << std::endl; (*it2)->write(std::cout); return false; } asgn[(*it2)->getIndex()] = true; } } for (UInt it=0; it<p->getNumCons(); ++it) { if (asgn[it] != true) { std::cout << "constraint " << p->getConstraint(it)->getName() << " with index " << it << " is not assigned to any handler!" << std::endl; p->getConstraint(it)->write(std::cout); return false; } } return true; }
VariablePtr Transformer::newVar_(CGraphPtr cg, ProblemPtr newp) { VariablePtr iv; VariablePtr ov = VariablePtr(); // NULL FunctionPtr f; LinearFunctionPtr lf; ConstraintPtr cnew; assert(cg); if (OpSumList!=cg->getOut()->getOp()) { ov = yUniExprs_->findY(cg); } if (!ov) { ov = newp->newVariable(VarTran); lf = (LinearFunctionPtr) new LinearFunction(); lf->addTerm(ov, -1.0); f = (FunctionPtr) new Function(lf, cg); cnew = newp->newConstraint(f, 0.0, 0.0); #if SPEW logger_->msgStream(LogDebug) << me_ << "added new constraint " << std::endl; cnew->write(logger_->msgStream(LogDebug)); #endif assignHandler_(cg, cnew); yUniExprs_->insert(ov, cg); } return ov; }
VariablePtr Transformer::newVar_(LinearFunctionPtr lf, double d, ProblemPtr newp) { VariablePtr ov; FunctionPtr f; ConstraintPtr cnew; ov = yLfs_->findY(lf, d); if (!ov) { LinearFunctionPtr lf2 = lf->clone(); ov = newp->newVariable(VarTran); yLfs_->insert(ov, lf2, d); lf->addTerm(ov, -1.0); f = (FunctionPtr) new Function(lf); cnew = newp->newConstraint(f, -d, -d); #if SPEW logger_->msgStream(LogDebug) << me_ << "added new constraint " << std::endl; cnew->write(logger_->msgStream(LogDebug)); #endif lHandler_->addConstraint(cnew); } return ov; }
VariablePtr Transformer::newVar_(VariablePtr iv, double d, ProblemPtr newp) { if (fabs(d)<zTol_) { return iv; } else { LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction(); VariablePtr ov; FunctionPtr f; ConstraintPtr cnew; ov = yVars_->findY(iv, d); if (!ov) { ov = newp->newVariable(VarTran); yVars_->insert(ov, iv, d); lf->addTerm(iv, 1.0); lf->addTerm(ov, -1.0); f = (FunctionPtr) new Function(lf); cnew = newp->newConstraint(f, -d, -d); #if SPEW logger_->msgStream(LogDebug) << me_ << "added new constraint " << std::endl; cnew->write(logger_->msgStream(LogDebug)); #endif lHandler_->addConstraint(cnew); } return ov; } }
EnginePtr getNLPEngine(EnvPtr env, ProblemPtr p) { EngineFactory *efac = new EngineFactory(env); EnginePtr e = EnginePtr(); // NULL bool cont=false; p->calculateSize(); if (p->isLinear()) { e = efac->getLPEngine(); if (e) { delete efac; return e; } else { cont = true; } } if (true==cont || p->isQP()) { e = efac->getQPEngine(); if (e) { delete efac; return e; } else { cont = true; } } e = efac->getNLPEngine(); assert (e || (!"No engine available for this problem.")); delete efac; return e; }
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 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; }
void Transformer::copyLinear_(ConstProblemPtr p, ProblemPtr newp) { FunctionPtr f; LinearFunctionPtr newlf; ConstConstraintPtr c; ConstraintPtr newc; ObjectivePtr obj; // copy linear constraints. for (ConstraintConstIterator it=p->consBegin(); it!=p->consEnd(); ++it) { c = *it; if (Linear==c->getFunction()->getType()) { // create a clone of this linear function. newlf = c->getLinearFunction()->cloneWithVars(newp->varsBegin()); f = (FunctionPtr) new Function(newlf); newc = newp->newConstraint(f, c->getLb(), c->getUb()); lHandler_->addConstraint(newc); } } // copy linear objective. obj = p->getObjective(); if (!obj) { f.reset(); newp_->newObjective(f, 0.0, Minimize); } else { switch (obj->getFunctionType()) { case (Constant): f = FunctionPtr(); // NULL newp->newObjective(f, obj->getConstant(), obj->getObjectiveType(), obj->getName()); break; case (Linear): newlf = obj->getFunction()->getLinearFunction()-> cloneWithVars(newp->varsBegin()); f = (FunctionPtr) new Function(newlf); newp->newObjective(f, obj->getConstant(), obj->getObjectiveType(), obj->getName()); break; default: break; } } }
CxUnivarHandler::CxUnivarHandler(EnvPtr , ProblemPtr problem) : eTol_(1e-6), vTol_(1e-5) { problem_ = problem; logger_ = (LoggerPtr) new Logger((LogLevel) 0 ); tmpX_.resize(problem->getNumVars(), 0.0); grad_.resize(problem->getNumVars(), 0.0); }
void AMPLOsiUT::testOsiBnB() { EnvPtr env = (EnvPtr) new Environment(); char file_name[] = "instances/milp"; HandlerVector handlers; ReliabilityBrancherPtr br; EnginePtr e; int err = 0; env->startTimer(err); ProblemPtr p = iface_->readInstance(file_name); BranchAndBound *bab = new BranchAndBound(env, p); IntVarHandlerPtr v_hand = (IntVarHandlerPtr) new IntVarHandler(env, p); LinearHandlerPtr l_hand = (LinearHandlerPtr) new LinearHandler(env, p); handlers.push_back(v_hand); handlers.push_back(l_hand); v_hand->setModFlags(false, true); l_hand->setModFlags(false, true); EngineFactory efac(env); e = efac.getLPEngine(); PCBProcessorPtr nproc = (PCBProcessorPtr) new PCBProcessor(env, e, handlers); br= (ReliabilityBrancherPtr) new ReliabilityBrancher(env, handlers); br->setEngine(e); nproc->setBrancher(br); bab->setNodeProcessor(nproc); NodeIncRelaxerPtr nr = (NodeIncRelaxerPtr) new NodeIncRelaxer(env, handlers); bab->setNodeRelaxer(nr); nr->setEngine(e); nr->setModFlag(false); p->setNativeDer(); bab->shouldCreateRoot(true); bab->setLogLevel(LogNone); bab->solve(); CPPUNIT_ASSERT(bab->getUb() == 1.0); delete bab; }
void computeReferenceSolution(const ProblemPtr& prob, SolutionTrace& sol_trace) { sol_trace.clear(); sol_trace.push_back(std::pair<double, ReaK::vect_n<double> >(prob->getInitialTime(), prob->getInitialValue())); double rec_step = (prob->getFinalTime() - prob->getInitialTime()) * 1e-3; ReaK::dormand_prince45_integrator<double> integ( "reference_integrator_ode45", sol_trace.back().second, sol_trace.back().first, rec_step * 1e-3, prob, rec_step, rec_step * 1e-6, 1e-6); std::cout << "Generating reference solution for problem: " << prob->getObjectType()->TypeName() << " with t in [" << prob->getInitialTime() << "," << prob->getFinalTime() << "]" << std::endl; for(double next_time = prob->getInitialTime() + rec_step; next_time < prob->getFinalTime() + 0.5 * rec_step; next_time += rec_step) { integ.integrate(next_time); sol_trace.push_back(std::pair<double, ReaK::vect_n<double> >( integ.getTime(), ReaK::vect_n<double>(integ.getStateBegin(), integ.getStateEnd()) )); std::cout << "\r" << std::setw(10) << next_time; for(std::size_t k = 0; k < sol_trace.back().second.size(); ++k) std::cout << std::setw(10) << sol_trace.back().second[k]; std::cout << std::flush; }; std::cout << std::endl << "Done!" << std::endl; };
CxUnivarHandler::CxUnivarHandler(EnvPtr , ProblemPtr problem) : eTol_(1e-6), vTol_(1e-5) { problem_ = problem; //logger_ = (LoggerPtr) new Logger((LogLevel) // env->getOptions()->findInt("handler_log_level")->getValue()); logger_ = (LoggerPtr) new Logger((LogLevel) 0 ); tmpX_.resize(problem->getNumVars(), 0.0); grad_.resize(problem->getNumVars(), 0.0); }
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; }
int main() { // Generate output. ofstream output; output.open("numknapcov.txt"); // Generate input. ifstream input; input.open("list.txt"); // Check if input is opened succesfully. if (input.is_open() == false) { cerr << "Input file read error." << endl; output << "Input file read error." << endl; exit(0); } /********************************************************************************/ // Headers for output data. output << "Statistics of knapsack cover cuts applied to root relaxation." << endl; output << "problem " << "vars " << "cons " << "lincons " << "knapcons " << "knapcov " << "knaps " << "totalcuts " << "cuts " << "violknapcuts " << "initobj " << "endobj " << "gapclosed " << "timeinit " << "timecut " << "timemod" << endl; /********************************************************************************/ // loop to test all problems in list.txt while (input.good()) { // problem name string pname; getline(input, pname); // At the end of file just exit from loop. if (pname.empty()) { break; } cout << "Problem considered is: " << pname << endl; // Real stuff begins. // Ampl interface, jacobian and hessian. MINOTAUR_AMPL::AMPLInterfacePtr iface = MINOTAUR_AMPL::AMPLInterfacePtr(); JacobianPtr jPtr; //! Jacobian read from AMPL HessianOfLagPtr hPtr; //! Hessian read from AMPL // environment, timers and options: EnvPtr env = (EnvPtr) new Environment(); OptionDBPtr options; // problem to be solved. ProblemPtr minlp; // solver pointers, including status. FilterSQPEngine e(env); EngineStatus status; // Presolver. PresolverPtr pres; // give parameters. UInt argc2 = 2; std::string arg1 = "bnb"; std::string arg2 = pname; char** argv2 = new char* [2]; argv2[0] = &arg1[0]; argv2[1] = &arg2[0]; // Default options env->getOptions()->findBool("presolve")->setValue(false); env->getOptions()->findBool("use_native_cgraph")->setValue(true); env->getOptions()->findBool("nl_presolve")->setValue(false); // parse options env->readOptions(argc2, argv2); options = env->getOptions(); options->findString("interface_type")->setValue("AMPL"); // read minlp from AMPL. iface = (MINOTAUR_AMPL::AMPLInterfacePtr) new MINOTAUR_AMPL::AMPLInterface(env); minlp = iface->readInstance(pname); // Timer is obtained. Timer * timer = env->getNewTimer(); // Nonlinearize objective function. Bool MIPCONSIDERED = false; if (MIPCONSIDERED == true) { ObjectivePtr initobjfun = minlp->getObjective(); if (initobjfun->getObjectiveType() == Maximize) { cerr << "Objective type is Maximize, change it to Minimize." << endl; exit(0); } LinearFunctionPtr lfinitobj = initobjfun->getLinearFunction(); // NonlinearFunctionPtr nlfobj = (NonlinearFunctionPtr) new NonlinearFunction(); CGraphPtr nlfobj = (CGraphPtr) new CGraph(); logobj(lfinitobj, nlfobj); FunctionPtr logobjfun = (FunctionPtr) new Function(nlfobj); ObjectiveType otyp = Minimize; minlp->changeObj(logobjfun, 0); } minlp->calculateSize(); minlp->prepareForSolve(); // Change format of problem to be suitable for Minotaur. HandlerVector handlers; // Use presolver to standardize problem. //pres = (PresolverPtr) new Presolver(minlp, env, handlers); //pres->standardize(); minlp->calculateSize(); minlp->prepareForSolve(); minlp->setJacobian(jPtr); minlp->setHessian(hPtr); minlp->setNativeDer(); minlp->calculateSize(); minlp->prepareForSolve(); minlp->setNativeDer(); //minlp->write(std::cout); /**************************************************************/ // Given problem statistics . // Number of variables. UInt numvars = minlp->getNumVars(); // number of constraints. UInt numcons = minlp->getNumCons(); // linear constraints. UInt numlin = minlp->getNumLinCons(); /*************************************************************/ // set option for engine to resolve to solve NLP repeatedly. // Probbaly does nothing. e.setOptionsForRepeatedSolve(); // load problem. e.load(minlp); // Solve problem. timer->start(); status = e.solve(); /********************************************************************/ // Solution time of relaxation. Double timeinit = timer->query(); timer->stop(); // Solution objective value Double initobj = e.getSolutionValue(); /********************************************************************/ std::cout << "Relaxation objective value = " << initobj << std::endl; // Get solution from engine. ConstSolutionPtr sol = e.getSolution(); // Construct relaxation. RelaxationPtr rel = (RelaxationPtr) new Relaxation(minlp); // Time for cut generation. timer->start(); // Generate kanpsack cover cuts. CoverCutGeneratorPtr knapgen = (CoverCutGeneratorPtr) new CoverCutGenerator(rel, sol, env); /*******************************************************************/ Double timecut = timer->query(); timer->stop(); /*******************************************************************/ // Get statistics of cut generator. ConstCovCutGenStatsPtr knapstats = knapgen->getStats(); /*******************************************************************/ // Knapsack cut generator statistics. // knapsack constraints. UInt numknap = (knapgen->getKnapsackList())->getNumKnaps(); // knapsacks that has cover sets. UInt numknapcov = knapgen->getNumCons(); // knapsack subproblems solved, i.e number of lifting subproblems solved. UInt knaps = knapstats->knaps; // cover cuts including duplicates. UInt totalcuts = knapstats->totalcuts; // cuts without duplicates. UInt numknapcuts = knapstats->cuts; // violated cuts. UInt violknapcuts = knapstats->violated; /*******************************************************************/ std::cout << "Number of knapsack cover cuts to be applied is: " << knapstats->violated << std::endl; // Get the violated cuts from generator. CutVector knapcuts = knapgen->getViolatedCutList(); // Iterators for cuts CutVectorConstIter it; CutVectorConstIter begin = knapcuts.begin(); CutVectorConstIter end = knapcuts.end(); // Apply the cuts to the problem. // Violation list. DoubleVector knapviols = knapgen->getViolList(); UInt curknap = 0; Double maxviol = 0.0; for (it=begin; it!=end; ++it) { std::cout << "Violation obtained from this constraint is: " << knapviols[curknap] << std::endl; ConstraintPtr newcons = rel->newConstraint((*it)->getFunction(), (*it)->getLb(), (*it)->getUb()); if (maxviol < knapviols[curknap]) { maxviol = knapviols[curknap]; } // add constraint to engine does not do anything. // Thus, we add constraint to the relaxation and reload it to engine. // e.addConstraint(newcons); } /*******************************************************************/ // Solution time of knapsack cover cuts added problem. Double timemod = 0.0; // Objective value after adding knapsack cover cuts. Double endobj = 0.0; // Gap closed by using knapsack cover cuts. Double gapknap = 0.0; /*******************************************************************/ if (violknapcuts >= 1) { // Reload problem to engine. // Check if we should reload the modified problem. e.clear(); const Double * xupdated; if (WARMSTART == 1) { // Set initial point as the solution of root solution. xupdated = sol->getPrimal(); rel->setInitialPoint(xupdated); } // Load the modified problem. e.load(rel); // warmstart continues. if (WARMSTART == 1) { // Before presolve, we set initial primal and // dual solutions as the root solution. SolutionPtr solupdated = (SolutionPtr) new Solution(initobj, xupdated, rel); // Create new dual solution. const Double * dualofvars = sol->getDualOfVars(); solupdated->setDualOfVars(dualofvars); const Double * initdualofcons = sol->getDualOfCons(); UInt numconsupdated = rel->getNumCons(); Double * dualofcons = new Double[numconsupdated]; memcpy(dualofcons, initdualofcons, numcons*sizeof(Double)); for (UInt indexx = numcons; indexx < numconsupdated; ++indexx) { dualofcons[indexx] = 0.0; } solupdated->setDualOfCons(dualofcons); FilterWSPtr warmstart = (FilterWSPtr) new FilterSQPWarmStart(); warmstart->setPoint(solupdated); e.loadFromWarmStart(warmstart); delete [] dualofcons; } // Solution time after adding knapsack cover cuts to relaxation. timer->start(); // Resolve the problem. e.solve(); /*******************************************************************/ // Solution time of knapsack cover cuts added problem. timemod = timer->query(); timer->stop(); // Objective value after adding knapsack cover cuts. endobj = e.getSolutionValue(); // Gap closed by using knapsack cover cuts. gapknap = (endobj-initobj)/fabs(initobj) * 100; /*******************************************************************/ } else { /*******************************************************************/ // Solution time of knapsack cover cuts added problem. timemod = timeinit; // Objective value after adding knapsack cover cuts. endobj = initobj; // Gap closed by using knapsack cover cuts. gapknap = 0.0; /*******************************************************************/ } std::cout << "Objective value of relaxation after adding cuts: " << endobj << std::endl; cout << pname << " " << numvars << " " << numcons << " " << numlin << " " << numknap << " " << numknapcov << " " << knaps << " " << totalcuts << " " << numknapcuts << " " << violknapcuts << std::fixed << std::setprecision(2) << " " << initobj << " " << endobj << " " << gapknap << " " << timeinit << " " << timecut << " " << timemod << endl; if (numknap >= 1) { // Save output data. output << pname << " " << numvars << " " << numcons << " " << numlin << " " << numknap << " " << numknapcov << " " << knaps << " " << totalcuts << " " << numknapcuts << " " << violknapcuts << std::fixed << std::setprecision(2) << " " << initobj << " " << endobj << " " << gapknap << " " << timeinit << " " << timecut << " " << timemod << endl; } delete iface; delete [] argv2; } output.close(); input.close(); return 0; }
//! main routine implementing outer approximation int main(int argc, char** argv) { //! Declaration of Variables ============================================ //! interface to AMPL (NULL): MINOTAUR_AMPL::AMPLInterfacePtr iface = MINOTAUR_AMPL::AMPLInterfacePtr(); MINOTAUR_AMPL::JacobianPtr jPtr; //! Jacobian read from AMPL MINOTAUR_AMPL::HessianOfLagPtr hPtr; //! Hessian read from AMPL //! environment, timers, options: EnvPtr env = (EnvPtr) new Environment(); TimerFactory *tFactory = new TimerFactory(); Timer *timer=tFactory->getTimer(); OptionDBPtr options; //! AMPL and MINOTAUR options //! problem pointers (MINLP, NLP, MILP): ProblemPtr minlp; //! MINLP instance to be solved ProblemPtr milp; //! MILP master problem //! solver pointers, including status FilterSQPEngine e(env); //! NLP engine: FilterSQP EngineStatus status; //! pointers to manipulate variables & constraints VariablePtr v, objVar; //! variable pointer (objective) ObjectivePtr objFun; //! remember objective function pt. //! local variables Double *x, *xsoln; Double *lobnd, *upbnd; Double objfLo = -INFINITY, objfUp = INFINITY, objfNLP, objfMIP; Double tol = 1E-2; Int feasibleNLP = 0, iterOA = 1, n; // ====================================================================== //! start the timer timer->start(); //! make sure solver is used correctly if (argc < 2) { usage(); return -1; } //! add AMPL options & flags to environment: flags (options without values) options = env->getOptions(); add_ampl_flags(options); env->readOptions(argc, argv); //! parse options if (!checkUserOK(options,env)) goto CLEANUP; //! check if user needs help //! read MINLP from AMPL & create Hessian/Jacobian for NLP solves iface = (MINOTAUR_AMPL::AMPLInterfacePtr) new MINOTAUR_AMPL::AMPLInterface(env); minlp = iface->readInstance(options->findString("problem_file")->getValue(),false); jPtr = (MINOTAUR_AMPL::JacobianPtr) new MINOTAUR_AMPL::Jacobian(iface); hPtr = (MINOTAUR_AMPL::HessianOfLagPtr) new MINOTAUR_AMPL::HessianOfLag(iface); minlp->setJacobian(jPtr); minlp->setHessian(hPtr); //! Display number of constraints and variables, and MINLP problem minlp->calculateSize(); n = minlp->getNumVars(); std::cout << "No. of vars, cons = " << minlp->getNumVars() << minlp->getNumCons() << std::endl; std::cout << std::endl << "The MINLP problem is: " << std::endl; minlp->write(std::cout); //! load the MINLP into the NLP solver (FilterSQP) e.load(minlp); //! get initial point & save original bounds x = new Double[n]; xsoln = new Double[n]; lobnd = new Double[n]; upbnd = new Double[n]; std::copy(iface->getInitialPoint(),iface->getInitialPoint()+n,x); for (VariableConstIterator i=minlp->varsBegin(); i!=minlp->varsEnd(); ++i) { v = *i; lobnd[v->getId()] = v->getLb(); upbnd[v->getId()] = v->getUb(); } //! initialize the MILP master problem by copying variables & linear c/s milp = (ProblemPtr) new Problem(); objFun = minlp->getObjective(); objVar = VariablePtr(); initMaster(minlp, milp, objVar, objFun, x); while ((objfLo <= objfUp)&&(iterOA<4)){ std::cout << "Iteration " << iterOA << std::endl << "===============" << std::endl << std::endl; //! set-up and solve NLP(y) with fixed integers solveNLP(minlp, e, x, objfNLP, feasibleNLP, n); std::cout << "Solved NLP " << iterOA << " objective = " << objfNLP << " NLPfeasible = " << feasibleNLP << std::endl; if (feasibleNLP && (objfNLP-tol < objfUp)) { objfUp = objfNLP - tol; std::copy(x,x+n,xsoln); } //! update MILP master problem by adding outer approximations updateMaster(minlp, milp, objVar, objFun, objfUp, x, n); //! solve MILP master problem solveMaster(env, milp, x, &objfMIP, n); objfLo = objfMIP; iterOA = iterOA + 1; } // end while (objfLo <= objfUp) //! output final result & timing std::cout << std::endl << "END outer-approximation: f(x) = " << objfUp << " time used = " << timer->query() << std::endl; CLEANUP: //! free storage delete timer; delete tFactory; if (minlp) { minlp->clear(); delete [] x; delete [] xsoln; delete [] lobnd; delete [] upbnd; } if (milp) { milp->clear(); } return 0; } // end outer approximation main
void Transformer::copyVars_(ConstProblemPtr p, ProblemPtr newp) { // first copy all variables from p to newp //XXX (Need to setup map here?) newp->newVariables(p->varsBegin(), p->varsEnd()); }