in nevergrad/optimization/differentialevolution.py [0:0]
def _internal_ask_candidate(self) -> p.Parameter:
if len(self.population) < self.llambda: # initialization phase
init = self._config.initialization
if self.sampler is None and init not in ["gaussian", "parametrization"]:
assert init in ["LHS", "QR"]
self.sampler = oneshot.SamplingSearch(
sampler=init if init == "LHS" else "Hammersley", scrambled=init == "QR", scale=self.scale
)(
self.parametrization,
budget=self.llambda,
)
if init == "parametrization":
candidate = self.parametrization.sample()
elif self.sampler is not None:
candidate = self.sampler.ask()
else:
new_guy = self.scale * self._rng.normal(0, 1, self.dimension)
candidate = self.parametrization.spawn_child().set_standardized_data(new_guy)
candidate.heritage["lineage"] = candidate.uid # new lineage
self.population[candidate.uid] = candidate
self._uid_queue.asked.add(candidate.uid)
return candidate
# init is done
lineage = self._uid_queue.ask()
parent = self.population[lineage]
candidate = parent.spawn_child()
candidate.heritage["lineage"] = lineage # tell-not-asked may have provided a different lineage
data = candidate.get_standardized_data(reference=self.parametrization)
# define all the different parents
uids = list(self.population)
a, b = (self.population[uids[self._rng.randint(self.llambda)]] for _ in range(2))
best = self.current_bests["pessimistic"].parameter
# redefine the different parents in case of multiobjective optimization
if self._config.multiobjective_adaptation and self.num_objectives > 1:
pareto = self.pareto_front()
# can't use choice directly on pareto, because parametrization can be iterable
if pareto:
best = parent if parent in pareto else pareto[self._rng.choice(len(pareto))]
if len(pareto) > 2: # otherwise, not enough diversity
a, b = (pareto[idx] for idx in self._rng.choice(len(pareto), size=2, replace=False))
# define donor
data_a, data_b, data_best = (
indiv.get_standardized_data(reference=self.parametrization) for indiv in (a, b, best)
)
donor = data + self._config.F1 * (data_a - data_b) + self._config.F2 * (data_best - data)
candidate.parents_uids.extend([i.uid for i in (a, b)])
# apply crossover
co = self._config.crossover
if co == "parametrization":
candidate.recombine(self.parametrization.spawn_child().set_standardized_data(donor))
else:
crossovers = Crossover(self._rng, 1.0 / self.dimension if co == "dimension" else co)
crossovers.apply(donor, data)
candidate.set_standardized_data(donor, reference=self.parametrization)
return candidate