@File : iso.py
@Time : 2026/05/21 14:57:14
@Author : Alejandro Marrero (amarrerd@ull.edu.es)
@Version : 1.0
@Contact : amarrerd@ull.edu.es
@License : (C)Copyright 2026, Alejandro Marrero
@Desc : None
ISOLineMutation
Bases: Mutation
Source code in digneapy/operators/mutation/iso.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 | class ISOLineMutation(Mutation):
def __init__(
self,
sigma_iso: float,
sigma_line: float,
seed: Optional[int | np.random.SeedSequence] = None,
):
super().__init__(seed)
try:
self._sigma_iso = float(sigma_iso)
self._sigma_line = float(sigma_line)
except ValueError:
raise ValueError("sigma_iso and sigma_line must be float.")
def __call__(
self, population: np.ndarray, lb: np.ndarray, ub: np.ndarray
) -> np.ndarray:
"""Performs ISO+Line mutation from Vassiliades & Mouret 2018
Args:
population (np.ndarray): Batch of individuals to mutate
lb (np.ndarray): Lower bound for each dimension
ub (np.ndarray): Upper bound for each dimension
Raises:
ValueError: if dimension != bounds
Returns:
np.ndarray: Newly mutated individuals
"""
dimension = len(population[0])
if len(lb) != len(ub) or dimension != len(lb):
msg = f"The size of individuals ({dimension}) and bounds {len(lb)} is different in iso_line_mutation"
raise ValueError(msg)
indices = np.arange(len(population))
parents_a = np.asarray(
population[self._rng.choice(indices, size=len(population))], copy=True
)
parents_b = np.asarray(
population[self._rng.choice(indices, size=len(population))], copy=True
)
iso_noise = self._rng.normal(0, self._sigma_iso, size=parents_a.shape)
line_steps = self._rng.uniform(0, self._sigma_line, size=(len(parents_a), 1))
direction = parents_b - parents_a
offspring = parents_a + iso_noise + line_steps * direction
offspring = np.clip(offspring, lb, ub)
return offspring
|
__call__(population, lb, ub)
Performs ISO+Line mutation from Vassiliades & Mouret 2018
| Parameters: |
-
population
(ndarray)
–
Batch of individuals to mutate
-
lb
(ndarray)
–
Lower bound for each dimension
-
ub
(ndarray)
–
Upper bound for each dimension
|
| Returns: |
-
ndarray
–
np.ndarray: Newly mutated individuals
|
Source code in digneapy/operators/mutation/iso.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 | def __call__(
self, population: np.ndarray, lb: np.ndarray, ub: np.ndarray
) -> np.ndarray:
"""Performs ISO+Line mutation from Vassiliades & Mouret 2018
Args:
population (np.ndarray): Batch of individuals to mutate
lb (np.ndarray): Lower bound for each dimension
ub (np.ndarray): Upper bound for each dimension
Raises:
ValueError: if dimension != bounds
Returns:
np.ndarray: Newly mutated individuals
"""
dimension = len(population[0])
if len(lb) != len(ub) or dimension != len(lb):
msg = f"The size of individuals ({dimension}) and bounds {len(lb)} is different in iso_line_mutation"
raise ValueError(msg)
indices = np.arange(len(population))
parents_a = np.asarray(
population[self._rng.choice(indices, size=len(population))], copy=True
)
parents_b = np.asarray(
population[self._rng.choice(indices, size=len(population))], copy=True
)
iso_noise = self._rng.normal(0, self._sigma_iso, size=parents_a.shape)
line_steps = self._rng.uniform(0, self._sigma_line, size=(len(parents_a), 1))
direction = parents_b - parents_a
offspring = parents_a + iso_noise + line_steps * direction
offspring = np.clip(offspring, lb, ub)
return offspring
|