| 227 | } |
| 228 | |
| 229 | void HighsCutPool::separate(const std::vector<double>& sol, |
| 230 | const HighsDomain& domain, HighsCutSet& cutset, |
| 231 | double feastol, |
| 232 | const std::deque<HighsCutPool>& cutpools, |
| 233 | bool thread_safe) { |
| 234 | HighsInt nrows = matrix_.getNumRows(); |
| 235 | const HighsInt* ARindex = matrix_.getARindex(); |
| 236 | const double* ARvalue = matrix_.getARvalue(); |
| 237 | |
| 238 | std::vector<std::pair<double, HighsInt>> efficacious_cuts; |
| 239 | |
| 240 | HighsInt agelim = agelim_; |
| 241 | |
| 242 | HighsInt numCuts = getNumCuts() - numLpCuts; |
| 243 | while (agelim > 1 && numCuts > softlimit_) { |
| 244 | numCuts -= ageDistribution[agelim]; |
| 245 | --agelim; |
| 246 | } |
| 247 | |
| 248 | for (HighsInt i = 0; i < nrows; ++i) { |
| 249 | // cuts with an age of -1 are already in the LP and are therefore skipped |
| 250 | // Warning: Parallel case tries to add cuts already in current LP. |
| 251 | // Inefficient. Not sure what happens if added twice. |
| 252 | // The cut shouldn't have enough violation to be added though. |
| 253 | if (ages_[i] < 0) continue; |
| 254 | |
| 255 | HighsInt start = matrix_.getRowStart(i); |
| 256 | HighsInt end = matrix_.getRowEnd(i); |
| 257 | |
| 258 | double viol(-rhs_[i]); |
| 259 | |
| 260 | for (HighsInt j = start; j != end; ++j) { |
| 261 | HighsInt col = ARindex[j]; |
| 262 | double solval = sol[col]; |
| 263 | |
| 264 | viol += ARvalue[j] * solval; |
| 265 | } |
| 266 | |
| 267 | // if the cut is not violated more than feasibility tolerance |
| 268 | // we skip it and increase its age, otherwise we reset its age |
| 269 | bool isPropagated = matrix_.columnsLinked(i); |
| 270 | if (!thread_safe) { |
| 271 | ageDistribution[ages_[i]] -= 1; |
| 272 | if (isPropagated) { |
| 273 | propRows.erase(std::make_pair(ages_[i], i)); |
| 274 | } |
| 275 | } |
| 276 | if (double(viol) <= feastol) { |
| 277 | if (thread_safe) continue; |
| 278 | ++ages_[i]; |
| 279 | if (ages_[i] >= agelim) { |
| 280 | uint64_t h = compute_cut_hash(&ARindex[start], &ARvalue[start], |
| 281 | maxabscoef_[i], end - start); |
| 282 | |
| 283 | for (HighsDomain::CutpoolPropagation* propagationdomain : |
| 284 | propagationDomains) |
| 285 | propagationdomain->cutDeleted(i); |
| 286 |
no test coverage detected