bool SOS1Handler::isFeasible(ConstSolutionPtr sol, RelaxationPtr rel, bool &, double &) { SOSPtr sos; bool isfeas = true; int nz; const double* x = sol->getPrimal(); for (SOSConstIterator siter=rel->sos1Begin(); siter!=rel->sos1End(); ++siter) { sos = *siter; nz = 0; for (VariableConstIterator viter = sos->varsBegin(); viter!=sos->varsEnd(); ++viter) { if (x[(*viter)->getIndex()]>zTol_) { ++nz; if (nz>1) { isfeas = false; break; } } } if (false == isfeas) { break; } } #if SPEW logger_->msgStream(LogDebug) << me_ << "isFeasible = " << isfeas << std::endl; #endif return isfeas; }
bool MultilinearTermsHandler::isFeasible(ConstSolutionPtr sol, RelaxationPtr , bool &, double &) { const double *x = sol->getPrimal(); bool is_feas = true; #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Checking feasibility: " << std::endl; #endif for (ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) { ConstVariablePtr zt = it->first; SetOfVars const &jt = it->second; if (allVarsBinary_(jt)) continue; double zval = x[zt->getIndex()]; double xval = 1.0; for(SetOfVars::const_iterator jt_it = jt.begin(); jt_it != jt.end(); ++jt_it) { xval *= x[(*jt_it)->getIndex()]; } #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Term for variable: " << std::endl; zt->write(std::cout); std::cout << " has error: " << fabs(zval - xval) << std::endl; #endif if (fabs(zval - xval) > eTol_) { is_feas = false; break; } } return(is_feas); }
void ParQGHandler::separate(ConstSolutionPtr sol, NodePtr , RelaxationPtr rel, CutManager *cutMan, SolutionPoolPtr s_pool, ModVector &, ModVector &, bool *sol_found, SeparationStatus *status) { double val; VariableType v_type; VariableConstIterator v_iter; const double *x = sol->getPrimal(); *status = SepaContinue; for (v_iter = rel->varsBegin(); v_iter != rel->varsEnd(); ++v_iter) { v_type = (*v_iter)->getType(); if (v_type == Binary || v_type == Integer) { val = x[(*v_iter)->getIndex()]; if (fabs(val - floor(val+0.5)) > intTol_) { #if SPEW logger_->msgStream(LogDebug) << me_ << "variable " << (*v_iter)->getName() << " has fractional value = " << val << std::endl; #endif return; } } } cutIntSol_(sol, cutMan, s_pool, sol_found, status); return; }
bool ParQGHandler::isFeasible(ConstSolutionPtr sol, RelaxationPtr, bool &, double &) { int error=0; double act, cUb; ConstraintPtr c; const double *x = sol->getPrimal(); for (CCIter it=nlCons_.begin(); it!=nlCons_.end(); ++it) { c = *it; act = c->getActivity(x, &error); if (error == 0) { cUb = c->getUb(); if ((act > cUb + solAbsTol_) && (cUb == 0 || act > cUb + fabs(cUb)*solRelTol_)) { #if SPEW logger_->msgStream(LogDebug) << me_ << "constraint " << c->getName() << " violated with violation = " << act - cUb << std::endl; #endif return false; } } else { logger_->msgStream(LogError) << me_ << c->getName() << "constraint not defined at this point."<< std::endl; #if SPEW logger_->msgStream(LogDebug) << me_ << "constraint " << c->getName() << " not defined at this point." << std::endl; #endif return false; } } if (oNl_) { error = 0; relobj_ = x[objVar_->getIndex()]; act = minlp_->getObjValue(x, &error); if (error == 0) { if ((act > relobj_ + solAbsTol_) && (relobj_ == 0 || (act > relobj_ + fabs(relobj_)*solRelTol_))) { #if SPEW logger_->msgStream(LogDebug) << me_ << "objective violated with " << "violation = " << act - relobj_ << std::endl; #endif return false; } } else { logger_->msgStream(LogError) << me_ <<"objective not defined at this point."<< std::endl; return false; } } return true; }
bool CxUnivarHandler::isFeasible(ConstSolutionPtr sol, RelaxationPtr , bool &, double &) { bool isfeas = true; CxUnivarConstraintIterator dit; for (dit = cons_data_.begin(); dit != cons_data_.end(); ++dit) { if (!(*dit)->isFeasible(sol->getPrimal())) { isfeas = false; break; } } return isfeas; }
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; }
Branches RandomBrancher::findBranches(RelaxationPtr rel, NodePtr , ConstSolutionPtr sol, SolutionPoolPtr s_pool, BrancherStatus & br_status, ModVector &mods) { Branches branches; DoubleVector x(rel->getNumVars()); BrVarCandSet cands; // candidates from which to choose one. BrVarCandSet cands2; // temporary set. BrCandVector gencands; BrCandVector gencands2; // temporary set. BrCandPtr best_can = BrCandPtr(); // NULL bool is_inf = false; timer_->start(); std::copy(sol->getPrimal(), sol->getPrimal()+rel->getNumVars(), x.begin()); ++(stats_->calls); br_status = NotModifiedByBrancher; for (HandlerIterator h = handlers_.begin(); h != handlers_.end(); ++h) { // ask each handler to give some candidates (*h)->getBranchingCandidates(rel, x, mods, cands2, gencands2, is_inf); for (BrVarCandIter it = cands2.begin(); it != cands2.end(); ++it) { (*it)->setHandler(*h); } for (BrCandVIter it = gencands2.begin(); it != gencands2.end(); ++it) { (*it)->setHandler(*h); } cands.insert(cands2.begin(), cands2.end()); gencands.insert(gencands.end(), gencands2.begin(), gencands2.end()); cands2.clear(); gencands2.clear(); if (is_inf || mods.size()>0) { cands.clear(); gencands.clear(); if (is_inf) { br_status = PrunedByBrancher; stats_->time += timer_->query(); timer_->stop(); return branches; } } } if (cands.size() > 0) { BrVarCandIter it = cands.begin(); std::advance(it,rand()%cands.size()); best_can = *(it); } else if (gencands.size() > 0) { BrCandVIter it = gencands.begin(); std::advance(it,rand()%gencands.size()); best_can = *(it); } if (best_can) { best_can->setDir(DownBranch); branches = best_can->getHandler()->getBranches(best_can, x, rel, s_pool); #if SPEW logger_->msgStream(LogDebug) << me_ << "best candidate = " << best_can->getName() << std::endl; #endif } else { assert(!"problem finding candidate in RandomBrancher"); } stats_->time += timer_->query(); timer_->stop(); return branches; }
void KnapCovHandler::separate(ConstSolutionPtr sol, NodePtr, RelaxationPtr rel, CutManager * cmanager, SolutionPoolPtr , bool * , SeparationStatus * status) { // Check integer feasibility of sol, must add cuts if it is not integral. numvars_ = minlp_->getNumVars(); VariableType type; const double * x = sol->getPrimal(); // Is the relaxation solution is integer feasible. bool isintfeas = true; // Iterators for variables. VariableConstIterator it; VariableConstIterator begin = rel->varsBegin(); VariableConstIterator end = rel->varsEnd(); // Temporary variable holder. ConstVariablePtr var; // Value of variable. double value; bool separated = false; UInt n_added = 0; // Check if integrality is satisfied for each integer variable. for (it=begin; it!=end; ++it) { var = *it; type = var->getType(); if (type==Binary || type==Integer) { value = x[var->getIndex()]; if (fabs(value - floor(value + 0.5)) > intTol_) { isintfeas = false; break; } } } if (isintfeas == false) { // We do another check in CoverCutGneerator for integrality, may be we // should eliminate it and use the one above. // Generate cover cuts from current relaxation. CoverCutGeneratorPtr cover = (CoverCutGeneratorPtr) new CoverCutGenerator(rel,sol, env_); // Add cuts to the relaxation by using cut manager. CutVector violatedcuts = cover->getViolatedCutList(); CutIterator itc; CutIterator beginc = violatedcuts.begin(); CutIterator endc = violatedcuts.end(); // Serdar I am not sure if we should add the constraints generated by // addCuts to the constraint vector of knapsack cover handler. // Currently CutMan2::addCuts does not add the cuts to the relaxation formulation. cmanager->addCuts(beginc, endc); cmanager->separate(rel, sol, &separated, &n_added); if (n_added>0) { *status = SepaResolve; } // Update statistics by using return from cover cut generator. ConstCovCutGenStatsPtr covstats = cover->getStats(); // Later put the code below to updateStats function. stats_->knaps += covstats->knaps; stats_->cuts += covstats->cuts; stats_->extended += covstats->extended; stats_->simple += covstats->simple; stats_->gns += covstats->gns; stats_->singlectwo += covstats->singlectwo; } }
void LinFeasPump::implementFP_(const double*, SolutionPoolPtr s_pool) { ConstSolutionPtr sol; const double* x_lp; double hash_val, f_nlp; UInt n_to_flip, k; SeparationStatus sep_status = SepaContinue; EngineStatus lp_status = EngineUnknownStatus; NodePtr node = NodePtr(); bool to_continue = true; bool is_feasible = false; bool sol_found = false; bool is_prob_infeasible = prepareLP_(); bool should_separate = true; UInt max_NLP = 10; UInt max_LP = 2000; UInt max_cycle = 1000; UInt min_flip = 2; UInt max_non_zero_obj = 500; double inf_meas = 0.0; int err; e_->setOptionsForSingleSolve(); lpE_->solve(); f_nlp = lpE_->getSolutionValue(); sol = lpE_->getSolution(); should_separate = (p_->getObjective()->getFunction()-> getNumVars() > max_non_zero_obj) ? false : true; while(!is_feasible && stats_->numNLPs < max_NLP && statsLFP_->numLPs < max_LP && stats_->numCycles < max_cycle) { while(to_continue && statsLFP_->numLPs < max_LP && stats_->numCycles < max_cycle) { sol_found = false; constructObj_(r_, sol); lp_status = lpE_->solve(); ++(statsLFP_->numLPs); if (!(lp_status == ProvenOptimal || lp_status == ProvenLocalOptimal)) { logger_->msgStream(LogDebug) << me_ << "LP relaxation is infeasible." << std::endl; return; } sol = lpE_->getSolution(); x_lp = sol->getPrimal(); to_continue = isFrac_(x_lp); k = std::max(min_flip, (UInt) ceil(sol->getObjValue())); n_to_flip = std::min(k, p_->getSize()->bins); if (!to_continue) { is_feasible = qh_->isFeasible(sol, r_, is_prob_infeasible, inf_meas); if (is_feasible) { #if SPEW logger_->msgStream(LogDebug) << me_ << "LP soln is feasible " << "to NLP" << std::endl; #endif err = 0; statsLFP_->bestObjValue = p_->getObjective()->eval(x_lp, &err); convertSol_(s_pool, sol); sol_found = true; } else { #if SPEW logger_->msgStream(LogDebug) << me_ << "LP soln is not feasible " << "to NLP." << std::endl; #endif } break; } hash_val = hash_(); if (cycle_(hash_val)) { perturb_(hash_val, n_to_flip); } } if (!to_continue) { if (false==sol_found) { ++(stats_->numNLPs); qh_->separate(sol, node, r_, 0, s_pool, &sol_found, &sep_status); to_continue = true; //reset to continue after separating #if SPEW logger_->msgStream(LogDebug) << me_ << "separation status = " << sep_status << std::endl; //r_->write(logger_->msgStream(LogDebug)); logger_->msgStream(LogDebug) << me_ << "sol_found = " << sol_found << std::endl; #endif if (SepaError==sep_status) { break; //exit pump } if (sol_found) { is_feasible = true; } } } if (is_feasible) { #if SPEW logger_->msgStream(LogInfo) << me_ << "best solution value = " << s_pool->getBestSolutionValue() << std::endl; #endif if (getSolGap_(f_nlp, s_pool->getBestSolutionValue()) > 10 && true==should_separate) { separatingCut_(f_nlp, s_pool); is_feasible = false; } else { break; } } } e_->setOptionsForRepeatedSolve(); }
void ParQGHandler::cutIntSol_(ConstSolutionPtr sol, CutManager *cutMan, SolutionPoolPtr s_pool, bool *sol_found, SeparationStatus *status) { double nlpval = INFINITY; const double *lpx = sol->getPrimal(), *nlpx; relobj_ = (sol) ? sol->getObjValue() : -INFINITY; fixInts_(lpx); // Fix integer variables solveNLP_(); unfixInts_(); // Unfix integer variables switch(nlpStatus_) { case (ProvenOptimal): case (ProvenLocalOptimal): ++(stats_->nlpF); updateUb_(s_pool, &nlpval, sol_found); if ((relobj_ >= nlpval-npATol_) || (nlpval != 0 && (relobj_ >= nlpval-fabs(nlpval)*npRTol_))) { *status = SepaPrune; break; } else { nlpx = nlpe_->getSolution()->getPrimal(); oaCutToCons_(nlpx, lpx, cutMan, status); oaCutToObj_(nlpx, lpx, cutMan, status); break; } case (ProvenInfeasible): case (ProvenLocalInfeasible): case (ProvenObjectiveCutOff): ++(stats_->nlpI); nlpx = nlpe_->getSolution()->getPrimal(); oaCutToCons_(nlpx, lpx, cutMan, status); break; case (EngineIterationLimit): ++(stats_->nlpIL); oaCutEngLim_(lpx, cutMan, status); break; case (FailedFeas): case (EngineError): case (FailedInfeas): case (ProvenUnbounded): case (ProvenFailedCQFeas): case (EngineUnknownStatus): case (ProvenFailedCQInfeas): default: logger_->msgStream(LogError) << me_ << "NLP engine status = " << nlpe_->getStatusString() << std::endl; logger_->msgStream(LogError)<< me_ << "No cut generated, may cycle!" << std::endl; *status = SepaError; } if (*status==SepaContinue) { // No linearizations are generated so prune the node *status = SepaPrune; } #if SPEW logger_->msgStream(LogDebug) << me_ << "NLP solve status = " << nlpe_->getStatusString() << " and separation status = " << *status << std::endl; #endif return; }