Skip to content

Commit

Permalink
Collect iteration runtimes (#60)
Browse files Browse the repository at this point in the history
* Collect iteration runtimes

* Bump version
  • Loading branch information
N-Wouda authored May 15, 2022
1 parent cb6260d commit 10dbba3
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
3 changes: 3 additions & 0 deletions alns/ALNS.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
from typing import Callable, Dict, List, Optional, Tuple

import numpy.random as rnd
Expand Down Expand Up @@ -164,6 +165,7 @@ class of vehicle routing problems with backhauls. *European Journal of

stats = Statistics()
stats.collect_objective(initial_solution.objective())
stats.collect_runtime(time.perf_counter())

for iteration in range(iterations):
d_idx, r_idx = weight_scheme.select_operators(self._rnd_state)
Expand All @@ -181,6 +183,7 @@ class of vehicle routing problems with backhauls. *European Journal of
stats.collect_objective(curr.objective())
stats.collect_destroy_operator(d_name, s_idx)
stats.collect_repair_operator(r_name, s_idx)
stats.collect_runtime(time.perf_counter())

return Result(best, stats)

Expand Down
19 changes: 19 additions & 0 deletions alns/Statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def __init__(self):
optionally populated by the ALNS algorithm.
"""
self._objectives = []
self._runtimes = []

self._destroy_operator_counts = defaultdict(lambda: [0, 0, 0, 0])
self._repair_operator_counts = defaultdict(lambda: [0, 0, 0, 0])
Expand All @@ -23,6 +24,13 @@ def objectives(self) -> np.ndarray:
"""
return np.array(self._objectives)

@property
def runtimes(self) -> np.ndarray:
"""
Returns an array of iteration run times (in seconds).
"""
return np.diff(self._runtimes, prepend=self._runtimes[0])

@property
def destroy_operator_counts(self) -> DefaultDict[str, List[float]]:
"""
Expand Down Expand Up @@ -62,6 +70,17 @@ def collect_objective(self, objective: float):
"""
self._objectives.append(objective)

def collect_runtime(self, time: float):
"""
Collects the time one iteration took.
Parameters
----------
time
Time in seconds.
"""
self._runtimes.append(time)

def collect_destroy_operator(self, operator_name: str, s_idx: int):
"""
Collects a score (index) for a used destroy operator. This maintains
Expand Down
16 changes: 15 additions & 1 deletion alns/tests/test_statistics.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from numpy.testing import assert_equal, assert_almost_equal
from numpy.testing import assert_equal, assert_almost_equal, assert_allclose

from alns.Statistics import Statistics

Expand Down Expand Up @@ -27,6 +27,20 @@ def test_collect_objectives():
assert_almost_equal(statistics.objectives[-1], objective)


def test_collect_runtimes():
"""
Tests if a Statistics object properly collects runtime values.
"""
statistics = Statistics()

for time in range(1, 100):
statistics.collect_runtime(time)

assert_equal(len(statistics.runtimes), time)
assert_almost_equal(statistics.runtimes[0], 0)
assert_allclose(statistics.runtimes[1:], 1)


def test_collect_destroy_counts_example():
"""
Tests if collecting for a destroy operator works as expected in a simple
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "alns"
version = "2.0.2"
version = "2.1.0"
description = "A flexible implementation of the adaptive large neighbourhood search (ALNS) algorithm."
authors = ["Niels Wouda <[email protected]>"]
license = "MIT"
Expand Down

0 comments on commit 10dbba3

Please sign in to comment.