-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroulette_wheel_selector.py
65 lines (47 loc) · 2.21 KB
/
roulette_wheel_selector.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
from math import fsum
from pygenalgo.genome.chromosome import Chromosome
from pygenalgo.operators.selection.select_operator import SelectionOperator
class RouletteWheelSelector(SelectionOperator):
"""
Description:
Roulette Wheel Selector implements 'fitness proportional selection'. Each member
of the population is assigned a probability value that is directly proportional
to its fitness value (compared to the rest of the population).
Individuals with higher fitness value are more likely to be selected for parents
when forming the new generation of individuals (offsprings).
"""
def __init__(self, select_probability: float = 1.0):
"""
Construct a 'RouletteWheelSelector' object with a given probability value.
:param select_probability: (float) in [0, 1].
"""
# Call the super constructor with the provided probability value.
super().__init__(select_probability)
# _end_def_
def select(self, population: list[Chromosome]):
"""
Select the individuals, from the input population, that will be passed on
to the next genetic operations of crossover and mutation to form the new
population of solutions.
:param population: a list of chromosomes to select the parents from.
:return: the selected parents population (as list of chromosomes).
"""
# Get the length of the population list.
N = len(population)
# Extract the fitness value of each chromosome.
# This assumes that the fitness values are all
# positive.
all_fitness = [p.fitness for p in population]
# Calculate sum of all fitness.
sum_fitness = fsum(all_fitness)
# Calculate the "selection probabilities", of each member
# in the population.
selection_probs = [f / sum_fitness for f in all_fitness]
# Select 'N' new individuals (indexes).
index = self.rng.choice(N, size=N, p=selection_probs, replace=True, shuffle=False)
# Increase the selection counter.
self.inc_counter()
# Return the new parents (individuals).
return [population[i] for i in index]
# _end_def_
# _end_class_