void LinFeasPump::separatingCut_(double f_nlp, SolutionPoolPtr s_pool) { double new_bnd; LinearFunctionPtr lf; FunctionPtr obj_f; double obj_weight = 0.6; // increase(<1) to get better improvement double f_feas = s_pool->getBestSolutionValue(); new_bnd = obj_weight*f_nlp + (1-obj_weight)*f_feas; if (objVar_) { r_->changeBound(objVar_, Upper, new_bnd); logger_->msgStream(LogDebug) << me_ << "upper bound on objective value is " << new_bnd << std::endl; } else { if (!objConstraint_) { lf = p_->getObjective()->getFunction()->getLinearFunction()->clone(); obj_f = (FunctionPtr) new Function(lf); objConstraint_ = r_->newConstraint(obj_f, -INFINITY, new_bnd, "obj_sep_cut"); } else { r_->changeBound(objConstraint_, Upper, new_bnd); } #if SPEW logger_->msgStream(LogDebug) << me_ << "upper bound on objective value is " << new_bnd << std::endl; #endif } }
void ParQGHandler::updateUb_(SolutionPoolPtr s_pool, double *nlpval, bool *sol_found) { double val = nlpe_->getSolutionValue(); double bestval = s_pool->getBestSolutionValue(); if (val <= bestval) { const double *x = nlpe_->getSolution()->getPrimal(); s_pool->addSolution(x, val); *sol_found = true; #if SPEW logger_->msgStream(LogDebug) << me_ << "new solution found, value = " << val << std::endl; #endif } *nlpval = val; return; }
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(); }