| 139 | |
| 140 | template <size_t N, size_t M> |
| 141 | Cost Exchange<N, M>::evalSwapMove(Route::Node *U, |
| 142 | Route::Node *V, |
| 143 | CostEvaluator const &costEvaluator) const |
| 144 | { |
| 145 | assert(U->idx() > 0 && V->idx() > 0); |
| 146 | assert(U->route() && V->route()); |
| 147 | |
| 148 | Cost deltaCost = 0; |
| 149 | |
| 150 | if (U->route() != V->route()) |
| 151 | { |
| 152 | auto const *uRoute = U->route(); |
| 153 | auto const *vRoute = V->route(); |
| 154 | |
| 155 | auto const uProposal |
| 156 | = Route::Proposal(uRoute->before(U->idx() - 1), |
| 157 | vRoute->between(V->idx(), V->idx() + M - 1), |
| 158 | uRoute->after(U->idx() + N)); |
| 159 | |
| 160 | auto const vProposal |
| 161 | = Route::Proposal(vRoute->before(V->idx() - 1), |
| 162 | uRoute->between(U->idx(), U->idx() + N - 1), |
| 163 | vRoute->after(V->idx() + M)); |
| 164 | |
| 165 | costEvaluator.deltaCost(deltaCost, uProposal, vProposal); |
| 166 | } |
| 167 | else // within same route |
| 168 | { |
| 169 | auto const *route = U->route(); |
| 170 | |
| 171 | if (U->idx() < V->idx()) |
| 172 | costEvaluator.deltaCost( |
| 173 | deltaCost, |
| 174 | Route::Proposal(route->before(U->idx() - 1), |
| 175 | route->between(V->idx(), V->idx() + M - 1), |
| 176 | route->between(U->idx() + N, V->idx() - 1), |
| 177 | route->between(U->idx(), U->idx() + N - 1), |
| 178 | route->after(V->idx() + M))); |
| 179 | else |
| 180 | costEvaluator.deltaCost( |
| 181 | deltaCost, |
| 182 | Route::Proposal(route->before(V->idx() - 1), |
| 183 | route->between(U->idx(), U->idx() + N - 1), |
| 184 | route->between(V->idx() + M, U->idx() - 1), |
| 185 | route->between(V->idx(), V->idx() + M - 1), |
| 186 | route->after(U->idx() + N))); |
| 187 | } |
| 188 | |
| 189 | return deltaCost; |
| 190 | } |
| 191 | |
| 192 | template <size_t N, size_t M> |
| 193 | Cost Exchange<N, M>::evaluate(Route::Node *U, |