Quickstart template
The alns library provides the ALNS algorithm and various
acceptance criteria in alns.accept, operator selection schemes in
alns.select, and stopping criteria in alns.stop.
You should minimally provide the following:
A solution state for your problem that implements an
objective()function.An initial solution.
One or more destroy and repair operators tailored to your problem. Each destroy operator should copy the passed-in state; see
add_destroy_operator()for details.
Typically, a good first destroy operator is random removal, which randomly destroys some part of the current solution. A good first repair operator is greedy repair, which repairs the partially destroyed solution in a greedy manner.
Note
The alns package assumes your problem is a minimisation problem. If you
instead want to maximise some objective, you can use that
that is, the solution \(x\) that maximises \(f(x)\) is the same \(x\) that minimises \(-f(x)\). In your ALNS implementation, you should thus implement your objective as \(-f(x)\).
The following is a quickstart template that can help you get started:
from alns import ALNS
from alns.accept import HillClimbing
from alns.select import RandomSelect
from alns.stop import MaxRuntime
import numpy.random as rnd
class ProblemState:
# TODO add attributes that encode a solution to the problem instance
def objective(self) -> float:
# TODO implement the objective function
pass
def get_context(self):
# TODO implement a method returning a context vector. This is only
# needed for some context-aware bandit selectors from MABWiser;
# if you do not use those, this default is already sufficient!
return None
def initial_state() -> ProblemState:
# TODO implement a function that returns an initial solution
pass
def destroy(current: ProblemState, rng: rnd.Generator) -> ProblemState:
# TODO implement how to destroy the current state, and return the destroyed
# state. Make sure to (deep)copy the current state before modifying!
pass
def repair(destroyed: ProblemState, rng: rnd.Generator) -> ProblemState:
# TODO implement how to repair a destroyed state, and return it
pass
# Create the initial solution
init_sol = initial_state()
print(f"Initial solution objective is {init_sol.objective()}.")
# Create ALNS and add one or more destroy and repair operators
alns = ALNS(rnd.default_rng(seed=42))
alns.add_destroy_operator(destroy)
alns.add_repair_operator(repair)
# Configure ALNS
select = RandomSelect(num_destroy=1, num_repair=1) # see alns.select for others
accept = HillClimbing() # see alns.accept for others
stop = MaxRuntime(60) # 60 seconds; see alns.stop for others
# Run the ALNS algorithm
result = alns.iterate(init_sol, select, accept, stop)
# Retrieve the final solution
best = result.best_state
print(f"Best heuristic solution objective is {best.objective()}.")
Hint
Have a look at the examples to get a feeling for how to implement the TODOs in the quickstart template!