From 6c3b8f53d0f04f05120b111b5d5039937fa6387a Mon Sep 17 00:00:00 2001 From: JInglue Date: Fri, 13 Dec 2024 17:14:10 +0900 Subject: [PATCH] DE fixed random number generator for parallel processing --- package/samplers/differential_evolution/de.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/package/samplers/differential_evolution/de.py b/package/samplers/differential_evolution/de.py index 7a748e25..ea27037e 100644 --- a/package/samplers/differential_evolution/de.py +++ b/package/samplers/differential_evolution/de.py @@ -6,6 +6,7 @@ import numpy as np import optuna from optuna.samplers import RandomSampler +from optuna.samplers._lazy_random_state import LazyRandomState import optunahub @@ -97,7 +98,7 @@ def __init__( # Store and set random seed self.seed = seed - self._rng = np.random.RandomState(seed) + self._rng = LazyRandomState(seed) # Initialize random sampler for categorical parameters self._random_sampler = RandomSampler(seed=seed) @@ -218,7 +219,7 @@ def _generate_trial_vectors(self, active_indices: list[int]) -> np.ndarray: for i in range(self.population_size): # Select three random distinct individuals for mutation indices = [idx for idx in range(self.population_size) if idx != i] - r1, r2, r3 = self._rng.choice(indices, 3, replace=False) + r1, r2, r3 = self._rng.rng.choice(indices, 3, replace=False) if self.population is None or self.lower_bound is None or self.upper_bound is None: raise ValueError( @@ -240,11 +241,11 @@ def _generate_trial_vectors(self, active_indices: list[int]) -> np.ndarray: # Crossover: combine target vector with mutant vector trial = np.copy(valid_population[i]) - crossover_mask = self._rng.rand(len(active_indices)) < self.CR + crossover_mask = self._rng.rng.rand(len(active_indices)) < self.CR # Ensure at least one parameter is taken from mutant vector if not np.any(crossover_mask): - crossover_mask[self._rng.randint(len(active_indices))] = True + crossover_mask[self._rng.rng.randint(len(active_indices))] = True trial[crossover_mask] = mutant[crossover_mask] trial_vectors[i] = trial @@ -309,6 +310,11 @@ def _get_generation_trials(self, study: optuna.study.Study, generation: int) -> ) ] + def reseed_rng(self) -> None: + """Reseed the random number generator for the sampler.""" + self._rng.rng.seed() + return self._random_sampler.reseed_rng() + def sample_relative( self, study: optuna.study.Study, @@ -393,7 +399,7 @@ def sample_relative( # Initialize population using seeded RNG self.population = ( - self._rng.rand(self.population_size, self.dim) + self._rng.rng.rand(self.population_size, self.dim) * (self.upper_bound - self.lower_bound) + self.lower_bound )