| 15 | using pyvrp::search::SearchSpace; |
| 16 | |
| 17 | pyvrp::Solution LocalSearch::operator()(pyvrp::Solution const &solution, |
| 18 | CostEvaluator const &costEvaluator, |
| 19 | bool exhaustive) |
| 20 | { |
| 21 | loadSolution(solution); |
| 22 | |
| 23 | if (!exhaustive) |
| 24 | perturbationManager_.perturb(solution_, searchSpace_, costEvaluator); |
| 25 | |
| 26 | while (true) |
| 27 | { |
| 28 | search(costEvaluator); |
| 29 | auto const numUpdates = numUpdates_; // after node search |
| 30 | |
| 31 | intensify(costEvaluator); |
| 32 | if (numUpdates_ == numUpdates) |
| 33 | // Then intensify (route search) did not do any additional |
| 34 | // updates, so the solution is locally optimal. |
| 35 | break; |
| 36 | } |
| 37 | |
| 38 | return solution_.unload(); |
| 39 | } |
| 40 | |
| 41 | pyvrp::Solution LocalSearch::search(pyvrp::Solution const &solution, |
| 42 | CostEvaluator const &costEvaluator) |