Skip to content

Commit

Permalink
feat: add new parameters for DECC
Browse files Browse the repository at this point in the history
- Add new boolean flag to ensure the number of evaluations used
  (default=False);
- Update version in pyproject.toml;
- Add number of evaluations in DECC output;
  • Loading branch information
moesio-f committed Sep 18, 2023
1 parent 22ca470 commit e9c7409
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 12 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "decc"
version = "0.2.2"
version = "0.2.3"
readme = "README.md"
description = "Cooperative Co-evolutionary Differential Evolution algorithms in Python."

Expand Down
23 changes: 18 additions & 5 deletions src/decc/optimizers/decc.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ def __init__(self,
grouping: Literal['halve',
'dims'] = 'halve',
F: float = 0.8,
CR: float = 0.3) -> None:
CR: float = 0.3,
ensure_evaluations: bool = False) -> None:
super().__init__(problem, seed)
self.subpop_size = subpopulation_size
self.F = F
self.CR = CR
self.max_fn = max_fn
self.variant = 'DECC-'
self.ensure_evaluations = ensure_evaluations

d = self.problem.dims
if grouping == 'halve':
Expand All @@ -55,7 +57,7 @@ def parameters(self) -> dict:
'max_evaluations': self.max_fn,
'n_subproblems': len(self.subproblem_indices)
}

def name(self) -> str:
return self.variant

Expand All @@ -68,7 +70,6 @@ def _optimize(self, *args, **kwargs) -> tuple[np.ndarray,
rng = np.random.default_rng(self.seed)
l, u = self.problem.bounds
d = self.problem.dims
p = self.pop_size
sp = self.subpop_size
fn = self.problem.fn
n_evaluations = 0
Expand Down Expand Up @@ -125,8 +126,13 @@ def update_best(population: np.ndarray,
subpopulations.append(population)
subpopulations_fitness.append(population_fitness)

# Early stop
if self.ensure_evaluations and \
n_evaluations >= self.max_fn:
break

# Evolution loop
while n_evaluations <= self.max_fn:
while n_evaluations < self.max_fn:
# Obtaining the new context vector
context_vector = np.zeros((d,),
dtype=np.float32)
Expand Down Expand Up @@ -185,7 +191,14 @@ def _fn(pop: np.ndarray) -> np.ndarray:
update_best(subpopulations[i],
subpopulations_fitness[i])

return best_fitness.squeeze(), best_solution, None
# Early stop
if self.ensure_evaluations and \
n_evaluations >= self.max_fn:
break

return (best_fitness.squeeze(),
best_solution,
dict(n_evaluations=n_evaluations))

def _population_w_context(self,
context: np.ndarray,
Expand Down
26 changes: 20 additions & 6 deletions src/decc/optimizers/decc_g.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ def __init__(self,
max_fn: int = int(1e6),
F: float = 0.8,
CR: float = 0.3,
weights_bound: tuple[float, float] = (-5, 5)) -> None:
weights_bound: tuple[float, float] = (-5, 5),
ensure_evaluations: bool = False) -> None:
super().__init__(problem, seed)
assert n_subproblems <= self.problem.dims

Expand All @@ -42,6 +43,7 @@ def __init__(self,
self.de_eval = de_evaluations
self.sansde_eval = sansde_evaluations
self.w_bounds = weights_bound
self.ensure_evaluations = ensure_evaluations

def parameters(self) -> dict:
return {
Expand All @@ -57,7 +59,7 @@ def parameters(self) -> dict:
'max_evaluations': self.max_fn,
'n_subproblems': self.n_sub
}

def name(self) -> str:
return "DECC-G"

Expand All @@ -73,8 +75,8 @@ def _optimize(self, *args, **kwargs) -> tuple[np.ndarray,
p = self.pop_size
fn = self.problem.fn
n_evaluations = 0
best_solution = None
best_fitness = None
best_solution: np.ndarray = None
best_fitness: np.ndarray = None
seed_interval = (0, 99999)

# Random initial population of
Expand Down Expand Up @@ -104,7 +106,7 @@ def update_best(population: np.ndarray,
# Update best
update_best(population, population_fitness)

while n_evaluations <= self.max_fn:
while n_evaluations < self.max_fn:
# Generating random groups
group_seed = rng.integers(*seed_interval)
groups = decomposition.random_group_decompose(
Expand Down Expand Up @@ -149,6 +151,11 @@ def _fn(pop: np.ndarray) -> np.ndarray:
# Update best
update_best(population, population_fitness)

# Early stop
if self.ensure_evaluations and \
n_evaluations >= self.max_fn:
break

# === Updating weight population ===
def _fn(w_pop: np.ndarray,
idx: int):
Expand Down Expand Up @@ -184,6 +191,11 @@ def _update_pop_w_weights(idx: int):
nonlocal n_evaluations
nonlocal population

# Early stop
if self.ensure_evaluations and \
n_evaluations >= self.max_fn:
return

# Obtain initial fitness of
# weighted individuals
w_f = _fn(weight_population, idx)
Expand Down Expand Up @@ -229,4 +241,6 @@ def _update_pop_w_weights(idx: int):
# Update best
update_best(population, population_fitness)

return best_fitness.squeeze(), best_solution, None
return (best_fitness.squeeze(),
best_solution,
dict(n_evaluations=n_evaluations))

0 comments on commit e9c7409

Please sign in to comment.