| 61 | } |
| 62 | |
| 63 | Cost SwapStar::deltaLoadCost(Route::Node *U, |
| 64 | Route::Node *V, |
| 65 | CostEvaluator const &costEvaluator) const |
| 66 | { |
| 67 | auto const *uRoute = U->route(); |
| 68 | auto const *vRoute = V->route(); |
| 69 | |
| 70 | ProblemData::Client const &uClient = data.location(U->client()); |
| 71 | ProblemData::Client const &vClient = data.location(V->client()); |
| 72 | |
| 73 | auto const &uLoad = uRoute->load(); |
| 74 | auto const &uCap = uRoute->capacity(); |
| 75 | |
| 76 | auto const &vLoad = vRoute->load(); |
| 77 | auto const &vCap = vRoute->capacity(); |
| 78 | |
| 79 | // Separating removal and insertion means that the effects on load are not |
| 80 | // counted correctly: during insert, U is still in the route, and now V is |
| 81 | // added as well. The following addresses this issue with an approximation, |
| 82 | // which is inexact when there are both pickups and deliveries in the data. |
| 83 | // So it's pretty rough but fast and seems to mostly work well enough. |
| 84 | Cost cost = 0; |
| 85 | for (size_t dim = 0; dim != data.numLoadDimensions(); ++dim) |
| 86 | { |
| 87 | auto const delta |
| 88 | = std::max(uClient.delivery[dim], uClient.pickup[dim]) |
| 89 | - std::max(vClient.delivery[dim], vClient.pickup[dim]); |
| 90 | |
| 91 | cost += costEvaluator.loadPenalty(uLoad[dim] - delta, uCap[dim], dim); |
| 92 | cost -= costEvaluator.loadPenalty(uLoad[dim], uCap[dim], dim); |
| 93 | |
| 94 | cost += costEvaluator.loadPenalty(vLoad[dim] + delta, vCap[dim], dim); |
| 95 | cost -= costEvaluator.loadPenalty(vLoad[dim], vCap[dim], dim); |
| 96 | } |
| 97 | |
| 98 | return cost; |
| 99 | } |
| 100 | |
| 101 | SwapStar::InsertPoint SwapStar::bestInsertPoint( |
| 102 | Route::Node *U, Route::Node *V, CostEvaluator const &costEvaluator) |
nothing calls this directly
no test coverage detected