From db888807b4ff92e7e0977bde8b7064cb6306c289 Mon Sep 17 00:00:00 2001 From: Leon Lan <30997278+leonlan@users.noreply.github.com> Date: Sat, 19 Aug 2023 17:21:51 +0200 Subject: [PATCH 1/2] Logo (#165) --- README.md | 2 ++ docs/source/assets/images/icon.svg | 30 ++++++++++++++++++++++ docs/source/assets/images/logo.svg | 40 ++++++++++++++++++++++++++++++ docs/source/index.rst | 5 ++-- 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 docs/source/assets/images/icon.svg create mode 100644 docs/source/assets/images/logo.svg diff --git a/README.md b/README.md index ec13adec..7740f26b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![ALNS logo](docs/source/assets/images/logo.svg) + [![PyPI version](https://badge.fury.io/py/alns.svg)](https://badge.fury.io/py/alns) [![ALNS](https://github.com/N-Wouda/ALNS/actions/workflows/alns.yaml/badge.svg)](https://github.com/N-Wouda/ALNS/actions/workflows/alns.yaml) [![Documentation Status](https://readthedocs.org/projects/alns/badge/?version=latest)](https://alns.readthedocs.io/en/latest/?badge=latest) diff --git a/docs/source/assets/images/icon.svg b/docs/source/assets/images/icon.svg new file mode 100644 index 00000000..79f6fdaf --- /dev/null +++ b/docs/source/assets/images/icon.svg @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/docs/source/assets/images/logo.svg b/docs/source/assets/images/logo.svg new file mode 100644 index 00000000..038176c3 --- /dev/null +++ b/docs/source/assets/images/logo.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + diff --git a/docs/source/index.rst b/docs/source/index.rst index c25085dd..f43b57e4 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,5 +1,6 @@ -ALNS -==== +.. figure:: assets/images/logo.svg + :alt: ALNS logo + :figwidth: 100% ``alns`` is a general, well-documented and tested implementation of the adaptive large neighbourhood search (ALNS) metaheuristic in Python. ALNS is an algorithm that can be used to solve difficult combinatorial optimisation problems. From 04991b6b2d21437992da2da415a3f98958ec9e2c Mon Sep 17 00:00:00 2001 From: Leon Lan <30997278+leonlan@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:16:40 +0200 Subject: [PATCH 2/2] Rename acceptance criteria (#167) --- .../accept/{RandomWalk.py => AlwaysAccept.py} | 4 +- ...Threshold.py => MovingAverageThreshold.py} | 9 +- .../{WorseAccept.py => RandomAccept.py} | 8 +- alns/accept/__init__.py | 6 +- alns/accept/tests/test_adaptive_threshold.py | 124 ------------------ .../tests/test_moving_average_threshold.py | 124 ++++++++++++++++++ ..._worse_accept.py => test_random_accept.py} | 62 ++++----- alns/accept/tests/test_random_walk.py | 20 +-- docs/source/api/accept.rst | 16 +-- 9 files changed, 188 insertions(+), 185 deletions(-) rename alns/accept/{RandomWalk.py => AlwaysAccept.py} (51%) rename alns/accept/{AdaptiveThreshold.py => MovingAverageThreshold.py} (86%) rename alns/accept/{WorseAccept.py => RandomAccept.py} (89%) delete mode 100644 alns/accept/tests/test_adaptive_threshold.py create mode 100644 alns/accept/tests/test_moving_average_threshold.py rename alns/accept/tests/{test_worse_accept.py => test_random_accept.py} (62%) diff --git a/alns/accept/RandomWalk.py b/alns/accept/AlwaysAccept.py similarity index 51% rename from alns/accept/RandomWalk.py rename to alns/accept/AlwaysAccept.py index d513118a..126cfd4f 100644 --- a/alns/accept/RandomWalk.py +++ b/alns/accept/AlwaysAccept.py @@ -1,6 +1,6 @@ -class RandomWalk: +class AlwaysAccept: """ - The random walk criterion always accepts the candidate solution. + This criterion always accepts the candidate solution. """ def __call__(self, rnd, best, current, candidate): diff --git a/alns/accept/AdaptiveThreshold.py b/alns/accept/MovingAverageThreshold.py similarity index 86% rename from alns/accept/AdaptiveThreshold.py rename to alns/accept/MovingAverageThreshold.py index 5ed69076..741682c0 100644 --- a/alns/accept/AdaptiveThreshold.py +++ b/alns/accept/MovingAverageThreshold.py @@ -3,11 +3,12 @@ from typing import Deque, List -class AdaptiveThreshold: +class MovingAverageThreshold: """ - The Adaptive Threshold (AT) criterion of [1]. This criterion accepts a - candidate solution if it is better than an adaptive threshold value. The - adaptive threshold is computed as: + The Moving Average Threshold (MAT) criterion of [1]. This criterion accepts + a candidate solution if it is better than a threshold value that is based + on the moving average of the objective values of recently observed + candidate solutions. The threshold is computed as: .. math:: diff --git a/alns/accept/WorseAccept.py b/alns/accept/RandomAccept.py similarity index 89% rename from alns/accept/WorseAccept.py rename to alns/accept/RandomAccept.py index 6c06921b..02117cf9 100644 --- a/alns/accept/WorseAccept.py +++ b/alns/accept/RandomAccept.py @@ -1,11 +1,11 @@ from alns.accept.update import update -class WorseAccept: +class RandomAccept: """ - The Worse Accept criterion accepts a candidate solution if it improves over - the current one, or with a given probability :math:`P` regardless of the - cost. :math:`P` is updated in each iteration as: + The Random Accept criterion accepts a candidate solution if it improves + over the current one, or with a given probability :math:`P` regardless of + the cost. :math:`P` is updated in each iteration as: .. math:: diff --git a/alns/accept/__init__.py b/alns/accept/__init__.py index e3d3e5f6..e455c01f 100644 --- a/alns/accept/__init__.py +++ b/alns/accept/__init__.py @@ -1,10 +1,10 @@ from .AcceptanceCriterion import AcceptanceCriterion -from .AdaptiveThreshold import AdaptiveThreshold +from .AlwaysAccept import AlwaysAccept from .GreatDeluge import GreatDeluge from .HillClimbing import HillClimbing from .LateAcceptanceHillClimbing import LateAcceptanceHillClimbing +from .MovingAverageThreshold import MovingAverageThreshold from .NonLinearGreatDeluge import NonLinearGreatDeluge -from .RandomWalk import RandomWalk +from .RandomAccept import RandomAccept from .RecordToRecordTravel import RecordToRecordTravel from .SimulatedAnnealing import SimulatedAnnealing -from .WorseAccept import WorseAccept diff --git a/alns/accept/tests/test_adaptive_threshold.py b/alns/accept/tests/test_adaptive_threshold.py deleted file mode 100644 index a0c2822b..00000000 --- a/alns/accept/tests/test_adaptive_threshold.py +++ /dev/null @@ -1,124 +0,0 @@ -import numpy.random as rnd -from numpy.testing import assert_, assert_equal, assert_raises -from pytest import mark - -from alns.accept import AdaptiveThreshold -from alns.tests.states import One, Two, VarObj, Zero - - -@mark.parametrize( - "eta, gamma", - [ - (-1, 3), # eta cannot be < 0 - (2, 3), # eta cannot be > 1 - (0.5, -2), # gamma cannot be < 0 - (0.5, 0), # gamma cannot be 0 - ], -) -def test_raise_invalid_parameters(eta, gamma): - with assert_raises(ValueError): - AdaptiveThreshold(eta=eta, gamma=gamma) - - -@mark.parametrize("eta, gamma", [(1, 3), (0.4, 4)]) -def test_no_raise_valid_parameters(eta, gamma): - AdaptiveThreshold(eta=eta, gamma=gamma) - - -@mark.parametrize("eta", [0, 0.01, 0.5, 0.99, 1]) -def test_eta(eta): - adaptive_threshold = AdaptiveThreshold(eta, 3) - assert_equal(adaptive_threshold.eta, eta) - - -@mark.parametrize("gamma", range(1, 10)) -def test_gamma(gamma): - adaptive_threshold = AdaptiveThreshold(0.5, gamma) - assert_equal(adaptive_threshold.gamma, gamma) - - -def test_accepts_below_threshold(): - adaptive_threshold = AdaptiveThreshold(eta=0.5, gamma=4) - adaptive_threshold(rnd.RandomState(), One(), One(), One()) - adaptive_threshold(rnd.RandomState(), One(), One(), Zero()) - - # The threshold is set at 0 + 0.5 * (0.5 - 0) = 0.25 - assert_(adaptive_threshold(rnd.RandomState(), One(), One(), Zero())) - - -def test_rejects_above_threshold(): - adaptive_threshold = AdaptiveThreshold(eta=0.5, gamma=4) - adaptive_threshold(rnd.RandomState(), One(), One(), Two()) - adaptive_threshold(rnd.RandomState(), One(), One(), Zero()) - - # The threshold is set at 0 + 0.5 * (1 - 0) = 0.5 - assert_(not adaptive_threshold(rnd.RandomState(), One(), One(), One())) - - -def test_accepts_equal_threshold(): - accept = AdaptiveThreshold(eta=0.5, gamma=4) - accept(rnd.RandomState(), One(), One(), VarObj(7100)) - accept(rnd.RandomState(), One(), One(), VarObj(7200)) - - # The threshold is set at 7100 + 0.5 * (7140 - 7100) = 7120 - assert_(accept(rnd.RandomState(), One(), One(), VarObj(7120))) - - -def test_accepts_over_gamma_candidates(): - accept = AdaptiveThreshold(eta=0.2, gamma=3) - accept(rnd.RandomState(), One(), One(), VarObj(7100)) - accept(rnd.RandomState(), One(), One(), VarObj(7200)) - accept(rnd.RandomState(), One(), One(), VarObj(7200)) - - # The threshold is set at 7000 + 0.2 * (7133.33 - 7000) = 7013.33 - assert_(accept(rnd.RandomState(), One(), One(), VarObj(7000))) - - -def test_rejects_over_gamma_candidates(): - accept = AdaptiveThreshold(eta=0.2, gamma=3) - - for value in [7100, 7200, 7200, 7000]: - accept(rnd.RandomState(), One(), One(), VarObj(value)) - - # The threshold is set at 7000 + 0.2 * (7100 - 7000) = 7020 - result = accept(rnd.RandomState(), One(), One(), VarObj(7100)) - assert_(not result) - - -def test_evaluate_consecutive_solutions(): - """ - Test if AT correctly accepts and rejects consecutive solutions. - """ - accept = AdaptiveThreshold(eta=0.5, gamma=4) - - # The threshold is set at 7100, hence the solution is accepted. - assert_(accept(rnd.RandomState(), One(), One(), VarObj(7100))) - - # The threshold is set at 7125, hence the solution is accepted. - result = accept(rnd.RandomState(), One(), One(), VarObj(7200)) - assert_(not result) - - # The threshold is set at 7120, hence the solution is accepted. - assert_(accept(rnd.RandomState(), One(), One(), VarObj(7120))) - - -def test_history(): - """ - Test if AT correctly stores the history of the thresholds correctly. - """ - accept = AdaptiveThreshold(eta=0.5, gamma=4) - - accept(rnd.RandomState(), One(), One(), VarObj(7100)) - assert_equal(accept.history, [7100]) - - accept(rnd.RandomState(), One(), One(), VarObj(7200)) - assert_equal(accept.history, [7100, 7200]) - - accept(rnd.RandomState(), One(), One(), VarObj(7120)) - assert_equal(accept.history, [7100, 7200, 7120]) - - accept(rnd.RandomState(), One(), One(), VarObj(7100)) - assert_equal(accept.history, [7100, 7200, 7120, 7100]) - - accept(rnd.RandomState(), One(), One(), VarObj(7200)) - assert_equal(accept.history, [7200, 7120, 7100, 7200]) diff --git a/alns/accept/tests/test_moving_average_threshold.py b/alns/accept/tests/test_moving_average_threshold.py new file mode 100644 index 00000000..36713730 --- /dev/null +++ b/alns/accept/tests/test_moving_average_threshold.py @@ -0,0 +1,124 @@ +import numpy.random as rnd +from numpy.testing import assert_, assert_equal, assert_raises +from pytest import mark + +from alns.accept import MovingAverageThreshold +from alns.tests.states import One, Two, VarObj, Zero + + +@mark.parametrize( + "eta, gamma", + [ + (-1, 3), # eta cannot be < 0 + (2, 3), # eta cannot be > 1 + (0.5, -2), # gamma cannot be < 0 + (0.5, 0), # gamma cannot be 0 + ], +) +def test_raise_invalid_parameters(eta, gamma): + with assert_raises(ValueError): + MovingAverageThreshold(eta=eta, gamma=gamma) + + +@mark.parametrize("eta, gamma", [(1, 3), (0.4, 4)]) +def test_no_raise_valid_parameters(eta, gamma): + MovingAverageThreshold(eta=eta, gamma=gamma) + + +@mark.parametrize("eta", [0, 0.01, 0.5, 0.99, 1]) +def test_eta(eta): + moving_average = MovingAverageThreshold(eta, 3) + assert_equal(moving_average.eta, eta) + + +@mark.parametrize("gamma", range(1, 10)) +def test_gamma(gamma): + moving_average = MovingAverageThreshold(0.5, gamma) + assert_equal(moving_average.gamma, gamma) + + +def test_accepts_below_threshold(): + moving_average = MovingAverageThreshold(eta=0.5, gamma=4) + moving_average(rnd.RandomState(), One(), One(), One()) + moving_average(rnd.RandomState(), One(), One(), Zero()) + + # The threshold is set at 0 + 0.5 * (0.5 - 0) = 0.25 + assert_(moving_average(rnd.RandomState(), One(), One(), Zero())) + + +def test_rejects_above_threshold(): + moving_average = MovingAverageThreshold(eta=0.5, gamma=4) + moving_average(rnd.RandomState(), One(), One(), Two()) + moving_average(rnd.RandomState(), One(), One(), Zero()) + + # The threshold is set at 0 + 0.5 * (1 - 0) = 0.5 + assert_(not moving_average(rnd.RandomState(), One(), One(), One())) + + +def test_accepts_equal_threshold(): + moving_average = MovingAverageThreshold(eta=0.5, gamma=4) + moving_average(rnd.RandomState(), One(), One(), VarObj(7100)) + moving_average(rnd.RandomState(), One(), One(), VarObj(7200)) + + # The threshold is set at 7100 + 0.5 * (7140 - 7100) = 7120 + assert_(moving_average(rnd.RandomState(), One(), One(), VarObj(7120))) + + +def test_accepts_over_gamma_candidates(): + moving_average = MovingAverageThreshold(eta=0.2, gamma=3) + moving_average(rnd.RandomState(), One(), One(), VarObj(7100)) + moving_average(rnd.RandomState(), One(), One(), VarObj(7200)) + moving_average(rnd.RandomState(), One(), One(), VarObj(7200)) + + # The threshold is set at 7000 + 0.2 * (7133.33 - 7000) = 7013.33 + assert_(moving_average(rnd.RandomState(), One(), One(), VarObj(7000))) + + +def test_rejects_over_gamma_candidates(): + moving_average = MovingAverageThreshold(eta=0.2, gamma=3) + + for value in [7100, 7200, 7200, 7000]: + moving_average(rnd.RandomState(), One(), One(), VarObj(value)) + + # The threshold is set at 7000 + 0.2 * (7100 - 7000) = 7020 + result = moving_average(rnd.RandomState(), One(), One(), VarObj(7100)) + assert_(not result) + + +def test_evaluate_consecutive_solutions(): + """ + Test if MAT correctly accepts and rejects consecutive solutions. + """ + moving_average = MovingAverageThreshold(eta=0.5, gamma=4) + + # The threshold is set at 7100, hence the solution is accepted. + assert_(moving_average(rnd.RandomState(), One(), One(), VarObj(7100))) + + # The threshold is set at 7125, hence the solution is accepted. + result = moving_average(rnd.RandomState(), One(), One(), VarObj(7200)) + assert_(not result) + + # The threshold is set at 7120, hence the solution is accepted. + assert_(moving_average(rnd.RandomState(), One(), One(), VarObj(7120))) + + +def test_history(): + """ + Test if MAT correctly stores the history of the thresholds correctly. + """ + moving_average = MovingAverageThreshold(eta=0.5, gamma=4) + + moving_average(rnd.RandomState(), One(), One(), VarObj(7100)) + assert_equal(moving_average.history, [7100]) + + moving_average(rnd.RandomState(), One(), One(), VarObj(7200)) + assert_equal(moving_average.history, [7100, 7200]) + + moving_average(rnd.RandomState(), One(), One(), VarObj(7120)) + assert_equal(moving_average.history, [7100, 7200, 7120]) + + moving_average(rnd.RandomState(), One(), One(), VarObj(7100)) + assert_equal(moving_average.history, [7100, 7200, 7120, 7100]) + + moving_average(rnd.RandomState(), One(), One(), VarObj(7200)) + assert_equal(moving_average.history, [7200, 7120, 7100, 7200]) diff --git a/alns/accept/tests/test_worse_accept.py b/alns/accept/tests/test_random_accept.py similarity index 62% rename from alns/accept/tests/test_worse_accept.py rename to alns/accept/tests/test_random_accept.py index bc2062c4..0bb8bb56 100644 --- a/alns/accept/tests/test_worse_accept.py +++ b/alns/accept/tests/test_random_accept.py @@ -4,7 +4,7 @@ from numpy.testing import assert_, assert_equal, assert_raises from pytest import mark -from alns.accept import WorseAccept +from alns.accept import RandomAccept from alns.tests.states import One, Two, Zero @@ -22,7 +22,7 @@ ) def test_raises_invalid_parameters(start, end, step, method): with assert_raises(ValueError): - WorseAccept(start, end, step, method) + RandomAccept(start, end, step, method) @mark.parametrize( @@ -36,7 +36,7 @@ def test_raises_invalid_parameters(start, end, step, method): ], ) def test_no_raise_valid_parameters(start, end, step, method): - WorseAccept(start, end, step, method) + RandomAccept(start, end, step, method) @mark.parametrize( @@ -53,80 +53,82 @@ def test_properties(start, end, step, method): """ Tests if the properties are correctly set. """ - worse_accept = WorseAccept(start, end, step, method) + random_accept = RandomAccept(start, end, step, method) - assert_equal(worse_accept.start_prob, start) - assert_equal(worse_accept.end_prob, end) - assert_equal(worse_accept.step, step) - assert_equal(worse_accept.method, method) + assert_equal(random_accept.start_prob, start) + assert_equal(random_accept.end_prob, end) + assert_equal(random_accept.step, step) + assert_equal(random_accept.method, method) def test_zero_prob_accepts_better(): """ - Tests if WA with a zero start probability accepts better solutions. + Tests if random accept with a zero start probability accepts better + solutions. """ rnd_vals = [1] rng = Mock(spec_set=rnd.RandomState, random=lambda: rnd_vals.pop(0)) - worse_accept = WorseAccept(0, 0, 0.1) + random_accept = RandomAccept(0, 0, 0.1) - assert_(worse_accept(rng, Zero(), One(), Zero())) - assert_(worse_accept(rng, Zero(), Two(), Zero())) + assert_(random_accept(rng, Zero(), One(), Zero())) + assert_(random_accept(rng, Zero(), Two(), Zero())) def test_zero_prob_never_accept_worse(): """ - Tests if WA with a zero start probability does not accept worse solutions. + Tests if random accept with a zero start probability does not accept worse + solutions. """ - worse_accept = WorseAccept(0, 0, 0, "linear") + random_accept = RandomAccept(0, 0, 0, "linear") - assert_(not worse_accept(rnd.RandomState(), Zero(), One(), One())) - assert_(not worse_accept(rnd.RandomState(), Zero(), Zero(), One())) + assert_(not random_accept(rnd.RandomState(), Zero(), One(), One())) + assert_(not random_accept(rnd.RandomState(), Zero(), Zero(), One())) def test_one_prob_always_accept(): """ - Tests if WA with a fixed probability of 1 leads to always accepting - solutions. + Tests if random accept with a fixed probability of 1 leads to always + accepting solutions. """ - worse_accept = WorseAccept(1, 0, 0, "linear") + random_accept = RandomAccept(1, 0, 0, "linear") for _ in range(100): - assert_(worse_accept(rnd.RandomState(), Zero(), Zero(), One())) + assert_(random_accept(rnd.RandomState(), Zero(), Zero(), One())) def test_linear_consecutive_solutions(): """ - Test if WA with linear updating method correctly accepts and rejects - consecutive solutions. + Test if random accept with linear updating method correctly accepts and + rejects consecutive solutions. """ rnd_vals = [0.9, 0.8, 0.7, 0.6, 0.5, 1] rng = Mock(spec_set=rnd.RandomState, random=lambda: rnd_vals.pop(0)) - worse_accept = WorseAccept(1, 0, 0.1, "linear") + random_accept = RandomAccept(1, 0, 0.1, "linear") # For the first five, the probability is, resp., 1, 0.9, 0.8, 0.7, 0.6 # The random draw is, resp., 0.9, 0.8, 0.7, 0.6, 0.5 so the worsening # solution is still accepted. for _ in range(5): - assert_(worse_accept(rng, Zero(), Zero(), One())) + assert_(random_accept(rng, Zero(), Zero(), One())) # The probability is now 0.5 and the draw is 1, so reject. - assert_(not worse_accept(rng, Zero(), Zero(), One())) + assert_(not random_accept(rng, Zero(), Zero(), One())) def test_exponential_consecutive_solutions(): """ - Test if WA with exponential updating method correctly accepts and rejects - consecutive solutions. + Test if random accept with exponential updating method correctly accepts + and rejects consecutive solutions. """ rnd_vals = [0.5, 0.25, 0.125, 1] rng = Mock(spec_set=rnd.RandomState, random=lambda: rnd_vals.pop(0)) - worse_accept = WorseAccept(1, 0, 0.5, "exponential") + random_accept = RandomAccept(1, 0, 0.5, "exponential") # For the first three, the probability is, resp., 1, 0.5, 0.25 # The random draw is, resp., 0.5, 0.25, 0.125, so the worsening # solution is still accepted. for _ in range(3): - assert_(worse_accept(rng, Zero(), Zero(), One())) + assert_(random_accept(rng, Zero(), Zero(), One())) # The probability is now 0.5 and the draw is 1, so reject. - assert_(not worse_accept(rng, Zero(), Zero(), One())) + assert_(not random_accept(rng, Zero(), Zero(), One())) diff --git a/alns/accept/tests/test_random_walk.py b/alns/accept/tests/test_random_walk.py index eda1e609..c5bd47b3 100644 --- a/alns/accept/tests/test_random_walk.py +++ b/alns/accept/tests/test_random_walk.py @@ -1,30 +1,30 @@ import numpy.random as rnd from numpy.testing import assert_ -from alns.accept import RandomWalk +from alns.accept import AlwaysAccept from alns.tests.states import One, Zero def test_accepts_better(): """ - Tests if the random walk method accepts a better solution. + Tests if the always accept method accepts a better solution. """ - random_walk = RandomWalk() - assert_(random_walk(rnd.RandomState(), One(), One(), Zero())) + always_accept = AlwaysAccept() + assert_(always_accept(rnd.RandomState(), One(), One(), Zero())) def test_accepts_worse(): """ - Tests if the random walk method accepts a worse solution. + Tests if the always accept method accepts a worse solution. """ - random_walk = RandomWalk() - assert_(random_walk(rnd.RandomState(), Zero(), Zero(), One())) + always_accept = AlwaysAccept() + assert_(always_accept(rnd.RandomState(), Zero(), Zero(), One())) def test_accepts_equal(): """ - Tests if the random walk method accepts a solution that results in the + Tests if the always accept method accepts a solution that results in the same objective value. """ - random_walk = RandomWalk() - assert_(random_walk(rnd.RandomState(), Zero(), Zero(), Zero())) + always_accept = AlwaysAccept() + assert_(always_accept(rnd.RandomState(), Zero(), Zero(), Zero())) diff --git a/docs/source/api/accept.rst b/docs/source/api/accept.rst index 4005ec88..e0cb6c13 100644 --- a/docs/source/api/accept.rst +++ b/docs/source/api/accept.rst @@ -13,29 +13,29 @@ All acceptance criteria implement :class:`~alns.accept.AcceptanceCriterion.Accep .. automodule:: alns.accept.AcceptanceCriterion :members: -.. automodule:: alns.accept.AdaptiveThreshold +.. automodule:: alns.accept.AlwaysAccept :members: .. automodule:: alns.accept.GreatDeluge :members: -.. automodule:: alns.accept.NonLinearGreatDeluge - :members: - .. automodule:: alns.accept.HillClimbing :members: .. automodule:: alns.accept.LateAcceptanceHillClimbing :members: -.. automodule:: alns.accept.RandomWalk +.. automodule:: alns.accept.MovingAverageThreshold :members: -.. automodule:: alns.accept.RecordToRecordTravel +.. automodule:: alns.accept.NonLinearGreatDeluge :members: -.. automodule:: alns.accept.SimulatedAnnealing +.. automodule:: alns.accept.RandomAccept :members: -.. automodule:: alns.accept.WorseAccept +.. automodule:: alns.accept.RecordToRecordTravel + :members: + +.. automodule:: alns.accept.SimulatedAnnealing :members: