| 255 | } |
| 256 | |
| 257 | void LocalSearch::applyEmptyRouteMoves(Route::Node *U, |
| 258 | CostEvaluator const &costEvaluator) |
| 259 | { |
| 260 | assert(U->route()); |
| 261 | |
| 262 | // We apply moves involving empty routes in the (randomised) order of |
| 263 | // orderVehTypes. This helps because empty vehicle moves incur fixed cost, |
| 264 | // and a purely greedy approach over-prioritises vehicles with low fixed |
| 265 | // costs but possibly high variable costs. |
| 266 | for (auto const &[vehType, offset] : searchSpace_.vehTypeOrder()) |
| 267 | { |
| 268 | auto const begin = solution_.routes.begin() + offset; |
| 269 | auto const end = begin + data.vehicleType(vehType).numAvailable; |
| 270 | auto const pred = [](auto const &route) { return route.empty(); }; |
| 271 | auto empty = std::find_if(begin, end, pred); |
| 272 | |
| 273 | if (empty != end && applyNodeOps(U, (*empty)[0], costEvaluator)) |
| 274 | break; |
| 275 | } |
| 276 | } |
| 277 | |
| 278 | void LocalSearch::applyOptionalClientMoves(Route::Node *U, |
| 279 | CostEvaluator const &costEvaluator) |
nothing calls this directly
no test coverage detected