| 229 | |
| 230 | template <size_t N, size_t M> |
| 231 | void Exchange<N, M>::apply(Route::Node *U, Route::Node *V) const |
| 232 | { |
| 233 | stats_.numApplications++; |
| 234 | |
| 235 | auto &uRoute = *U->route(); |
| 236 | auto &vRoute = *V->route(); |
| 237 | auto *uToInsert = N == 1 ? U : uRoute[U->idx() + N - 1]; |
| 238 | auto *insertUAfter = M == 0 ? V : vRoute[V->idx() + M - 1]; |
| 239 | |
| 240 | // Insert these 'extra' nodes of U after the end of V... |
| 241 | for (size_t count = 0; count != N - M; ++count) |
| 242 | { |
| 243 | auto *prev = p(uToInsert); |
| 244 | uRoute.remove(uToInsert->idx()); |
| 245 | vRoute.insert(insertUAfter->idx() + 1, uToInsert); |
| 246 | uToInsert = prev; |
| 247 | } |
| 248 | |
| 249 | // ...and swap the overlapping nodes! |
| 250 | for (size_t count = 0; count != M; ++count) |
| 251 | { |
| 252 | Route::swap(U, V); |
| 253 | U = n(U); |
| 254 | V = n(V); |
| 255 | } |
| 256 | } |
| 257 | } // namespace pyvrp::search |
| 258 | |
| 259 | #endif // PYVRP_SEARCH_EXCHANGE_H |