From 98cd2c100b78e7dc092eb8e832468597e045bded Mon Sep 17 00:00:00 2001 From: Tim Hutt Date: Fri, 7 Jun 2024 10:07:26 +0100 Subject: [PATCH 1/3] Add ability to pass custom Random to MinConflictsSolver This allows it to be used repeatably. --- CHANGELOG.md | 3 ++- constraint/solvers.py | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eac74da..f040eca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,12 +20,13 @@ in every released version. - Split the codebase into multiple files for convenience - Switched from `setup.py` to `pyproject.toml` - Achieved and requires test coverage of at least 65% - - Added `nox` for testing against all supported Python versions + - Added `nox` for testing against all supported Python versions - Added `ruff` for codestyle testing - Moved the documentation to GitHub Pages - Moved test & publishing automation to GitHub Actions - Switched dependency & build system to Poetry - Dropped Python 3.4, 3.5, 3.6, 3.7, 3.8 support + - Add ability to pass custom `Random` to `MinConflictsSolver`. ### Version 1.4.0 diff --git a/constraint/solvers.py b/constraint/solvers.py index e28b271..9923799 100644 --- a/constraint/solvers.py +++ b/constraint/solvers.py @@ -545,24 +545,30 @@ class MinConflictsSolver(Solver): NotImplementedError: MinConflictsSolver doesn't provide iteration """ - def __init__(self, steps=1000): + def __init__(self, steps=1000, rand=None): """Initialization method. Args: steps (int): Maximum number of steps to perform before giving up when looking for a solution (default is 1000) + rand (Random): Optional random.Random instance to use for + repeatability. """ self._steps = steps + self._rand = rand def getSolution(self, domains: dict, constraints: List[tuple], vconstraints: dict): # noqa: D102 + choice = self._rand.choice if self._rand is not None else random.choice + shuffle = self._rand.shuffle if self._rand is not None else random.shuffle + assignments = {} # Initial assignment for variable in domains: - assignments[variable] = random.choice(domains[variable]) + assignments[variable] = choice(domains[variable]) for _ in range(self._steps): conflicted = False lst = list(domains.keys()) - random.shuffle(lst) + shuffle(lst) for variable in lst: # Check if variable is not in conflict for constraint, variables in vconstraints[variable]: @@ -586,7 +592,7 @@ def getSolution(self, domains: dict, constraints: List[tuple], vconstraints: dic del minvalues[:] minvalues.append(value) # Pick a random one from these values. - assignments[variable] = random.choice(minvalues) + assignments[variable] = choice(minvalues) conflicted = True if not conflicted: return assignments From 97fdc5ad7262e8745a5112ecbc4e1805454443ea Mon Sep 17 00:00:00 2001 From: Floris-Jan Willemsen Date: Sat, 1 Feb 2025 14:15:53 +0100 Subject: [PATCH 2/3] Update CHANGELOG.md Removed suggested changes to CHANGELOG as they should not be made from a pull request --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d525fd..8a25760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,6 @@ All notable changes to this code base will be documented in this file, for every - Moved test & publishing automation to GitHub Actions - Switched dependency & build system to Poetry - Dropped Python 3.4, 3.5, 3.6, 3.7, 3.8 support - - Add ability to pass custom `Random` to `MinConflictsSolver`. ### Version 1.4.0 From c73fd0257cf0e52f8e5b7f1276bdc93f34e3e3fe Mon Sep 17 00:00:00 2001 From: Floris-Jan Willemsen Date: Sat, 1 Feb 2025 14:16:37 +0100 Subject: [PATCH 3/3] Update solvers.py Changed type hint from List to list --- constraint/solvers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constraint/solvers.py b/constraint/solvers.py index b82352a..0a78f09 100644 --- a/constraint/solvers.py +++ b/constraint/solvers.py @@ -556,7 +556,7 @@ def __init__(self, steps=1000, rand=None): self._steps = steps self._rand = rand - def getSolution(self, domains: dict, constraints: List[tuple], vconstraints: dict): # noqa: D102 + def getSolution(self, domains: dict, constraints: list[tuple], vconstraints: dict): # noqa: D102 choice = self._rand.choice if self._rand is not None else random.choice shuffle = self._rand.shuffle if self._rand is not None else random.shuffle assignments = {}