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; }
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; } }