-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optional callback after repair and on accept #71
Comments
I am not opposed to such callbacks, but: what's stopping you from writing your own AcceptanceCriterion that does both? Minimal example: from alns.accept import HillClimbing
class MyAcceptanceCriterion(HillClimbing):
def __call__(..., cand, ...):
<do after_repair around candidate>
if accept := super().__call__(..., cand, ...): # modified candidate was accepted
<do on_accept around candidate>
return accept In both cases you can, as far as I can tell, freely modify the passed-in candidate argument without having to worry about copying anything. |
Nothing is stopping me personally since I've already hacked through the entire ALNS class for my research :-). That's indeed a good suggestion which covers the proposed implementations. |
But that's OK. Clearly there's some demand for callbacks and such then - I believed in #30 that there was not. I will leave this issue open to revisit at some point in the near future! |
After some experimenting, I no longer think it's beneficial to have more callbacks in ALNS. As you said before, the acceptance criterion can be easily modified to apply local search after repair/on accept. This same principle can be also applied directly to destroy/repair operators, e.g., by decorating the operators. I think it's good to keep the ALNS class as simple as possible. Rather than adding more callbacks to the ALNS class, the current implementation provides enough flexibility for the user to define their own callbacks through the destroy/repair and acceptance criteria interfaces. These use cases can be demonstrated in the documentation/cookbook (#88). Feel free to close the issue if you agree/have no other remarks. |
I agree. The paper you referenced having a destroy-local search-repair cycle is completely equivalent to (destroy + local search)-repair, or destroy-(local search + repair). I think we are better off not adding all sorts of callbacks for these things into the library, but instead push those ideas off into user code.
Sounds like a good idea to me. We can definitely document some common 'callback use cases' there, and the recommended way to do that in the library. I am open to adding new callbacks when something is hard to do currently. But I cannot think of anything right now. So I will wait until there's a concrete use case :-). |
It would be nice to have a callback function to be called at moments other than when a new best solution is found. As fair as I know, the most frequent alternatives are:
after_repair
: After the repair step, before acceptance. Rationale: "explore with destroy/repair, exploit with local search"on_accept
: When accepted, before best. Rationale: "good enough" to be spend additional resources improving the solutionIdeally, the callback functions should all be different. For example, a callback function to be called after the repair step should only explore small neighborhoods since it will be called frequently, whereas we may want to spend more resources when we accepted the solution.
I also know of one paper that performs local search between the destroy and repair step, but it is quite niche and I haven't read an ALNS paper so far describing the same method.
The text was updated successfully, but these errors were encountered: