@File : init.py
@Time : 2023/11/03 10:33:37
@Author : Alejandro Marrero
@Version : 1.0
@Contact : amarrerd@ull.edu.es
@License : (C)Copyright 2023, Alejandro Marrero
@Desc : None
binary_tournament_selection(population)
Binary Tournament Selection Operator
Parameters: |
-
population
(Sequence )
–
Population of individuals to select a parent from
|
Raises: |
-
RuntimeError
–
If the population is empty
|
Returns: |
-
IndType
–
Instance or Solution: New parent
|
Source code in digneapy/operators/_selection.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 | def binary_tournament_selection(population: Sequence[IndType]) -> IndType:
"""Binary Tournament Selection Operator
Args:
population (Sequence): Population of individuals to select a parent from
Raises:
RuntimeError: If the population is empty
Returns:
Instance or Solution: New parent
"""
if population is None or len(population) == 0:
msg = "Trying to selection individuals in an empty population."
raise ValueError(msg)
if len(population) == 1:
return population[0]
else:
idx1, idx2 = np.random.default_rng().integers(
low=0, high=len(population), size=2
)
return max(population[idx1], population[idx2], key=attrgetter("fitness"))
|
elitist_replacement(current_population, offspring, hof=1)
Returns a new population constructed using the Elitist approach.
HoF number of individuals from the current + offspring populations are
kept in the new population. The remaining individuals are selected from
the offspring population.
Parameters: |
-
current_population
( Sequence[IndType], )
–
Current population in the algorithm
-
offspring
( Sequence[IndType], )
–
-
hof
(int , default:
1
)
–
description. Defaults to 1.
|
Raises: |
-
ValueError
–
Raises if the sizes of the population are different
|
Source code in digneapy/operators/_replacement.py
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 | def elitist_replacement(
current_population: Sequence[IndType],
offspring: Sequence[IndType],
hof: int = 1,
) -> list[IndType]:
"""Returns a new population constructed using the Elitist approach.
HoF number of individuals from the current + offspring populations are
kept in the new population. The remaining individuals are selected from
the offspring population.
Args:
current_population Sequence[IndType],: Current population in the algorithm
offspring Sequence[IndType],: Offspring population
hof (int, optional): _description_. Defaults to 1.
Raises:
ValueError: Raises if the sizes of the population are different
Returns:
list[IndType]:
"""
if len(current_population) != len(offspring):
msg = f"The size of the current population ({len(current_population)}) != size of the offspring ({len(offspring)}) in elitist_replacement"
raise ValueError(msg)
combined_population = sorted(
itertools.chain(current_population, offspring),
key=attrgetter("fitness"),
reverse=True,
)
top = combined_population[:hof]
return list(top + offspring[1:])
|
first_improve_replacement(current_population, offspring)
Returns a new population produced by a greedy operator.
Each individual in the current population is compared with its analogous in the offspring population
and the best survives
Parameters: |
-
current_population
( Sequence[IndType], )
–
Current population in the algorithm
-
offspring
( Sequence[IndType], )
–
|
Raises: |
-
ValueError
–
Raises if the sizes of the population are different
|
Returns: |
-
list[IndType]
–
list[IndType]: New population
|
Source code in digneapy/operators/_replacement.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 | def first_improve_replacement(
current_population: Sequence[IndType],
offspring: Sequence[IndType],
) -> list[IndType]:
"""Returns a new population produced by a greedy operator.
Each individual in the current population is compared with its analogous in the offspring population
and the best survives
Args:
current_population ( Sequence[IndType],): Current population in the algorithm
offspring ( Sequence[IndType],): Offspring population
Raises:
ValueError: Raises if the sizes of the population are different
Returns:
list[IndType]: New population
"""
if len(current_population) != len(offspring):
msg = f"The size of the current population ({len(current_population)}) != size of the offspring ({len(offspring)}) in first_improve_replacement"
raise ValueError(msg)
return [a if a > b else b for a, b in zip(current_population, offspring)]
|
generational_replacement(current_population, offspring)
Returns the offspring population as the new current population
Parameters: |
-
current_population
( Sequence[IndType], )
–
Current population in the algorithm
-
offspring
( Sequence[IndType], )
–
|
Raises: |
-
ValueError
–
Raises if the sizes of the population are different
|
Returns: |
-
list[IndType]
–
Sequence[IndType]: New population
|
Source code in digneapy/operators/_replacement.py
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 | def generational_replacement(
current_population: Sequence[IndType],
offspring: Sequence[IndType],
) -> list[IndType]:
"""Returns the offspring population as the new current population
Args:
current_population ( Sequence[IndType],): Current population in the algorithm
offspring ( Sequence[IndType],): Offspring population
Raises:
ValueError: Raises if the sizes of the population are different
Returns:
Sequence[IndType]: New population
"""
if len(current_population) != len(offspring):
msg = f"The size of the current population ({len(current_population)}) != size of the offspring ({len(offspring)}) in generational replacement"
raise ValueError(msg)
return offspring[:]
|
one_point_crossover(ind, other)
One point crossover
Parameters: |
-
ind
(Instance or Solution )
–
First individual to apply crossover. Returned object
-
ind_2
(Instance or Solution )
–
Second individual to apply crossover
|
Raises: |
-
ValueError
–
When the len(ind_1) != len(ind_2)
|
Returns: |
-
IndType
–
Instance or Solution: New individual
|
Source code in digneapy/operators/_crossover.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 | def one_point_crossover(ind: IndType, other: IndType) -> IndType:
"""One point crossover
Args:
ind Instance or Solution: First individual to apply crossover. Returned object
ind_2 Instance or Solution: Second individual to apply crossover
Raises:
ValueError: When the len(ind_1) != len(ind_2)
Returns:
Instance or Solution: New individual
"""
if len(ind) != len(other):
msg = f"Individual of different length in uniform_crossover. len(ind) = {len(ind)} != len(other) = {len(other)}"
raise ValueError(msg)
offspring = ind.clone()
cross_point = np.random.default_rng().integers(low=0, high=len(ind))
offspring[cross_point:] = other[cross_point:]
return offspring
|
Uniform Crossover Operator for Instances and Solutions
Parameters: |
-
ind
(Instance or Solution )
–
First individual to apply crossover. Returned object.
-
ind_2
(Instance or Solution )
–
Second individual to apply crossover
-
cxpb
(float , default:
0.5
)
–
description. Defaults to 0.5.
|
Raises: |
-
ValueError
–
When the len(ind_1) != len(ind_2)
|
Returns: |
-
IndType
–
Instance or Solution: New individual
|
Source code in digneapy/operators/_crossover.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 | def uniform_crossover(ind: IndType, other: IndType, cxpb: float = 0.5) -> IndType:
"""Uniform Crossover Operator for Instances and Solutions
Args:
ind Instance or Solution: First individual to apply crossover. Returned object.
ind_2 Instance or Solution: Second individual to apply crossover
cxpb (float, optional): _description_. Defaults to 0.5.
Raises:
ValueError: When the len(ind_1) != len(ind_2)
Returns:
Instance or Solution: New individual
"""
if len(ind) != len(other):
msg = f"Individual of different length in uniform_crossover. len(ind) = {len(ind)} != len(other) = {len(other)}"
raise ValueError(msg)
probs = np.random.default_rng().random(size=len(ind))
chromosome = [i if pb <= cxpb else j for pb, i, j in zip(probs, ind, other)]
offspring = ind.clone()
offspring[:] = chromosome
return offspring
|