| 167 | } |
| 168 | |
| 169 | bool LocalSearch::applyNodeOps(Route::Node *U, |
| 170 | Route::Node *V, |
| 171 | CostEvaluator const &costEvaluator) |
| 172 | { |
| 173 | for (auto *nodeOp : nodeOps) |
| 174 | { |
| 175 | auto const deltaCost = nodeOp->evaluate(U, V, costEvaluator); |
| 176 | if (deltaCost < 0) |
| 177 | { |
| 178 | auto *rU = U->route(); // copy these because the operator can |
| 179 | auto *rV = V->route(); // modify the nodes' route membership |
| 180 | |
| 181 | [[maybe_unused]] auto const costBefore |
| 182 | = costEvaluator.penalisedCost(*rU) |
| 183 | + Cost(rU != rV) * costEvaluator.penalisedCost(*rV); |
| 184 | |
| 185 | searchSpace_.markPromising(U); |
| 186 | searchSpace_.markPromising(V); |
| 187 | |
| 188 | nodeOp->apply(U, V); |
| 189 | update(rU, rV); |
| 190 | |
| 191 | [[maybe_unused]] auto const costAfter |
| 192 | = costEvaluator.penalisedCost(*rU) |
| 193 | + Cost(rU != rV) * costEvaluator.penalisedCost(*rV); |
| 194 | |
| 195 | // When there is an improving move, the delta cost evaluation must |
| 196 | // be exact. The resulting cost is then the sum of the cost before |
| 197 | // the move, plus the delta cost. |
| 198 | assert(costAfter == costBefore + deltaCost); |
| 199 | |
| 200 | return true; |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | return false; |
| 205 | } |
| 206 | |
| 207 | bool LocalSearch::applyRouteOps(Route *U, |
| 208 | Route *V, |
nothing calls this directly
no test coverage detected