Releases: N-Wouda/ALNS
v5.0.1
v5.0.0
What's Changed
- Textual improvements by @leonlan in #89
- Rename weights to select by @leonlan in #96
- Add standalone documentation by @N-Wouda in #95
- Improve TSP example notebook by @N-Wouda in #101
- New selection scheme interface by @leonlan in #98
- New CVRP example notebook by @leonlan in #100
- alpha-UCB bandit operator selection scheme by @N-Wouda in #102
- Random operator selection scheme by @N-Wouda in #103
- Implement more callbacks by @N-Wouda in #104
Full Changelog: v4.1.0...v5.0.0
Version 4.1.0
What's Changed
- NoImprovement stopping criterion by @leonlan in #77
- RandomWalk acceptance criterion by @leonlan in #79
- WorseAccept acceptance criterion by @leonlan in #78
- ThresholdAcceptance acceptance criterion by @leonlan in #80
- GreatDeluge acceptance criterion by @leonlan in #81
- HillClimbing acceptance criterion by @leonlan in #82
Full Changelog: v4.0.0...v4.1.0
Version 4.0.0
Major version bump because of breaking changes introduced in the WeightScheme
's interface, and its dependents.
Changelog
Issue #57 (PR #70, thanks @leonlan) introduces the optional only_after
keyword argument to ALNS.add_repair_operator
. This keyword argument can be used to indicate that a repair operator only works with a specific set of destroy operators. One can use this argument as follows:
from alns import ALNS
def destroy_op1(current, rnd_state):
pass
def destroy_op2(current, rnd_state):
pass
def repair_op1(destroyed, rnd_state):
pass
def repair_op2(destroyed, rnd_state):
pass
alns = ALNS()
alns.add_destroy_operator(destroy_op1)
alns.add_destroy_operator(destroy_op2)
alns.add_repair_operator(repair_op1, only_after=[destroy_op1])
alns.add_repair_operator(repair_op2)
In this example, repair_op1
will only be selected if destroy_op1
was selected, whereas repair_op2
can be used with both destroy_op1
and destroy_op2
.
This has consequences for the WeightScheme.select_operators
interface: it now takes an additional op_coupling
argument, which is a binary 0/1 matrix indicating which operators can work together. In particular, element (i, j) is 1 if destroy operator i and repair operator j can work together, 0 otherwise. The WeightScheme
has been updated to use this information to select the appropriate operator pairs.
Existing code should not be impacted, unless your code uses a custom weight scheme.
Version 3.0.1
Adds logging to the ALNS library, using the default Python logging
module.
Version 3.0.0
Changelog:
Generalised stopping criteria (thanks @leonlan!) . Whereas previously only a maximum number of iterations was supported, you can now also use a maximum runtime.
Stopping criteria are available in alns.stop
, and should be passed as the stop
argument to ALNS.iterate
. The stop
argument replaces iterations
.
Take the following example, using 10_000 iterations:
alns.iterate(..., iterations=10_000)
You would now write this as
from alns.stop import MaxIterations
alns.iterate(..., stop=MaxIterations(10_000))
In addition, alns.stop.MaxRuntime
lets you set a maximum runtime (in seconds). You can also write your own stopping criterion, by inheriting from alns.stop.StoppingCriterion
.
With the addition of stopping criteria, the old usage of the criteria
module for acceptance criteria has become imprecise. This is why alns.criteria
is now accessible as alns.accept
. To simplify the module names further, alns.weight_schemes
has been renamed to alns.weights
.
ALNS now has a code style: black! The style is now consistent, and will be enforced through the CI pipeline.
Example notebooks and documentation have been updated to the new usage.
Version 2.1.2
Fixes a bug where key-word arguments passed to ALNS.iterate
were not available in the on_best
callback.
Version 2.1.1
Fix an off-by-one mistake in the number of runtimes to collect. We want to collect how long one iteration takes, but by accident collected the start time as well. This resulted in a mistaken value at index 0.
This release removes that mistake, such that the actual results are properly aligned.
Version 2.1.0
Collects iteration runtimes. These can be accessed as
res = alns.iterate(...)
runtimes = res.statistics.runtimes # per iteration, in seconds
Version 2.0.2
Allow passing kwargs to ALNS.iterate
. These kwargs are then passed to the operators. This is useful for larger heuristics, as this allows one to avoid explicit dependencies on global state (like a global data singleton).