Skip to content

Commit e108c44

Browse files
committed
Updated all the selector methods to use the decorator increase_counter.
1 parent 6e44ffd commit e108c44

File tree

7 files changed

+52
-52
lines changed

7 files changed

+52
-52
lines changed

pygenalgo/operators/selection/boltzmann_selector.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from math import fsum
22
from numpy import exp as np_exp
33
from pygenalgo.genome.chromosome import Chromosome
4+
from pygenalgo.operators.genetic_operator import increase_counter
45
from pygenalgo.operators.selection.select_operator import SelectionOperator
56

67

@@ -29,6 +30,7 @@ def __init__(self, select_probability: float = 1.0, k: float = 100.0):
2930
self._items = max(float(k), 50.0)
3031
# _end_def_
3132

33+
@increase_counter
3234
def select(self, population: list[Chromosome]):
3335
"""
3436
Select the individuals, from the input population, that will be passed on
@@ -44,8 +46,8 @@ def select(self, population: list[Chromosome]):
4446
# Compute the Temperature.
4547
T = max(0.1, np_exp(-self.iter/self._items))
4648

47-
# Get the length of the population list.
48-
N = len(population)
49+
# Get the population size.
50+
pop_size = len(population)
4951

5052
# Extract the fitness value of each chromosome.
5153
# This assumes that the fitness values are all positive.
@@ -58,11 +60,9 @@ def select(self, population: list[Chromosome]):
5860
# in the population (Boltzmann distribution).
5961
selection_probs = [f/sum_fitness for f in exp_fitness]
6062

61-
# Select 'N' new individuals (indexes).
62-
index = self.rng.choice(N, size=N, p=selection_probs, replace=True, shuffle=False)
63-
64-
# Increase the selection counter.
65-
self.inc_counter()
63+
# Select the new individuals indexes.
64+
index = self.rng.choice(pop_size, size=pop_size, p=selection_probs,
65+
replace=True, shuffle=False)
6666

6767
# Return the new parents (individuals).
6868
return [population[i] for i in index]

pygenalgo/operators/selection/linear_rank_selector.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from operator import attrgetter
2+
23
from pygenalgo.genome.chromosome import Chromosome
4+
from pygenalgo.operators.genetic_operator import increase_counter
35
from pygenalgo.operators.selection.select_operator import SelectionOperator
46

57

@@ -25,6 +27,7 @@ def __init__(self, select_probability: float = 1.0):
2527
super().__init__(select_probability)
2628
# _end_def_
2729

30+
@increase_counter
2831
def select(self, population: list[Chromosome]):
2932
"""
3033
Select the individuals, from the input population, that will be passed on
@@ -39,20 +42,18 @@ def select(self, population: list[Chromosome]):
3942
# Sort the population in ascending order using their fitness value.
4043
sorted_population = sorted(population, key=attrgetter("fitness"))
4144

42-
# Get the length of the population list.
43-
N = len(sorted_population)
45+
# Get the population size.
46+
pop_size = len(population)
4447

4548
# Calculate sum of all the ranked fitness values: "1 + 2 + 3 + ... + N".
46-
sum_ranked_values = float(0.5 * N * (N + 1))
49+
sum_ranked_values = float(0.5 * pop_size * (pop_size + 1))
4750

4851
# Calculate the "selection probabilities", of each member in the population.
49-
selection_probs = [n / sum_ranked_values for n in range(1, N + 1)]
50-
51-
# Increase the selection counter.
52-
self.inc_counter()
52+
selection_probs = [n / sum_ranked_values for n in range(1, pop_size + 1)]
5353

5454
# Select 'N' new individuals (indexes).
55-
index = self.rng.choice(N, size=N, p=selection_probs, replace=True, shuffle=False)
55+
index = self.rng.choice(pop_size, size=pop_size, p=selection_probs,
56+
replace=True, shuffle=False)
5657

5758
# Return the new parents (individuals).
5859
return [sorted_population[i] for i in index]

pygenalgo/operators/selection/random_selector.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from pygenalgo.genome.chromosome import Chromosome
2+
from pygenalgo.operators.genetic_operator import increase_counter
23
from pygenalgo.operators.selection.select_operator import SelectionOperator
34

45

@@ -24,6 +25,7 @@ def __init__(self, select_probability: float = 1.0):
2425
super().__init__(select_probability)
2526
# _end_def_
2627

28+
@increase_counter
2729
def select(self, population: list[Chromosome]):
2830
"""
2931
Select the individuals, from the input population, that will be passed on
@@ -34,14 +36,11 @@ def select(self, population: list[Chromosome]):
3436
3537
:return: the selected parents population (as list of chromosomes).
3638
"""
37-
# Get the length of the population list.
38-
N = len(population)
39+
# Get the population size.
40+
pop_size = len(population)
3941

40-
# Increase the selection counter.
41-
self.inc_counter()
42-
43-
# Select 'N' new individuals (indexes).
44-
index = self.rng.choice(N, size=N, replace=True, shuffle=False)
42+
# Select the new individuals indexes.
43+
index = self.rng.choice(pop_size, size=pop_size, replace=True, shuffle=False)
4544

4645
# Return the new parents (individuals).
4746
return [population[i] for i in index]

pygenalgo/operators/selection/roulette_wheel_selector.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from math import fsum
22
from pygenalgo.genome.chromosome import Chromosome
3+
from pygenalgo.operators.genetic_operator import increase_counter
34
from pygenalgo.operators.selection.select_operator import SelectionOperator
45

56

@@ -26,6 +27,7 @@ def __init__(self, select_probability: float = 1.0):
2627
super().__init__(select_probability)
2728
# _end_def_
2829

30+
@increase_counter
2931
def select(self, population: list[Chromosome]):
3032
"""
3133
Select the individuals, from the input population, that will be passed on
@@ -37,8 +39,8 @@ def select(self, population: list[Chromosome]):
3739
:return: the selected parents population (as list of chromosomes).
3840
"""
3941

40-
# Get the length of the population list.
41-
N = len(population)
42+
# Get the population size.
43+
pop_size = len(population)
4244

4345
# Extract the fitness value of each chromosome.
4446
# This assumes that the fitness values are all
@@ -52,11 +54,9 @@ def select(self, population: list[Chromosome]):
5254
# in the population.
5355
selection_probs = [f / sum_fitness for f in all_fitness]
5456

55-
# Select 'N' new individuals (indexes).
56-
index = self.rng.choice(N, size=N, p=selection_probs, replace=True, shuffle=False)
57-
58-
# Increase the selection counter.
59-
self.inc_counter()
57+
# Select the new individuals (indexes).
58+
index = self.rng.choice(pop_size, size=pop_size, p=selection_probs,
59+
replace=True, shuffle=False)
6060

6161
# Return the new parents (individuals).
6262
return [population[i] for i in index]

pygenalgo/operators/selection/stochastic_universal_selector.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from math import fsum
22
from itertools import accumulate
33
from pygenalgo.genome.chromosome import Chromosome
4+
from pygenalgo.operators.genetic_operator import increase_counter
45
from pygenalgo.operators.selection.select_operator import SelectionOperator
56

67

@@ -27,6 +28,7 @@ def __init__(self, select_probability: float = 1.0):
2728
super().__init__(select_probability)
2829
# _end_def_
2930

31+
@increase_counter
3032
def select(self, population: list[Chromosome]):
3133
"""
3234
Select the individuals, from the input population, that will be passed on to the next
@@ -42,21 +44,21 @@ def select(self, population: list[Chromosome]):
4244
# positive.
4345
all_fitness = [p.fitness for p in population]
4446

45-
# Get the size of the population.
46-
N = len(population)
47+
# Get the population size.
48+
pop_size = len(population)
4749

4850
# Compute the distance between pointers.
49-
dist_p = fsum(all_fitness) / N
51+
dist_p = fsum(all_fitness) / pop_size
5052

5153
# Get a random number between 0 and dist_p.
5254
start_0 = dist_p * self.rng.random()
5355

5456
# Calculate the pointers at equal distances 'dist_p'
5557
# starting from 'start_0'.
56-
pointers = (start_0 + i*dist_p for i in range(0, N))
58+
pointers = (start_0 + i*dist_p for i in range(pop_size))
5759

5860
# Create a list that will contain the new parents.
59-
new_parents = N * [None]
61+
new_parents = pop_size * [None]
6062

6163
# Compute the cumulative sum of the fitness values.
6264
cum_sum_fit = list(accumulate(all_fitness))
@@ -76,9 +78,6 @@ def select(self, population: list[Chromosome]):
7678
new_parents[n] = population[i]
7779
# _end_for_
7880

79-
# Increase the selection counter.
80-
self.inc_counter()
81-
8281
# Return the new parents (individuals).
8382
return new_parents
8483
# _end_def_

pygenalgo/operators/selection/tournament_selector.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from operator import attrgetter
22
from pygenalgo.genome.chromosome import Chromosome
3+
from pygenalgo.operators.genetic_operator import increase_counter
34
from pygenalgo.operators.selection.select_operator import SelectionOperator
45

56

@@ -29,6 +30,7 @@ def __init__(self, select_probability: float = 1.0, k: int = 2):
2930
self._items = max(2, int(k))
3031
# _end_def_
3132

33+
@increase_counter
3234
def select(self, population: list[Chromosome]):
3335
"""
3436
Select the individuals, from the input population that will be passed on
@@ -39,18 +41,19 @@ def select(self, population: list[Chromosome]):
3941
4042
:return: the selected parents population (as list of chromosomes).
4143
"""
42-
# Get the length of the population list.
43-
N = len(population)
44+
45+
# Get the population size.
46+
pop_size = len(population)
4447

4548
# Create a list that will contain the new parents.
46-
new_parents = N * [None]
49+
new_parents = pop_size * [None]
4750

4851
# Repeat the 'tournament' N times.
49-
for i in range(N):
52+
for i in range(pop_size):
5053

5154
# Select randomly 'k' individuals (indexes)
5255
# from the initial population.
53-
index = self.rng.choice(N, size=self._items,
56+
index = self.rng.choice(pop_size, size=self._items,
5457
replace=False, shuffle=False)
5558

5659
# Find the individual with the highest fitness value.
@@ -61,9 +64,6 @@ def select(self, population: list[Chromosome]):
6164
new_parents[i] = winner
6265
# _end_for_
6366

64-
# Increase the selection counter.
65-
self.inc_counter()
66-
6767
# Return the new parents (individuals).
6868
return new_parents
6969
# _end_def_

pygenalgo/operators/selection/truncation_selector.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from operator import attrgetter
22
from pygenalgo.genome.chromosome import Chromosome
3+
from pygenalgo.operators.genetic_operator import increase_counter
34
from pygenalgo.operators.selection.select_operator import SelectionOperator
45

56
class TruncationSelector(SelectionOperator):
@@ -28,6 +29,7 @@ def __init__(self, select_probability: float = 1.0, p: float = 0.3):
2829
self._items = max(min(float(p), 0.9), 0.1)
2930
# _end_def_
3031

32+
@increase_counter
3133
def select(self, population: list[Chromosome]):
3234
"""
3335
Select the individuals, from the input population, that will be passed on to the next
@@ -38,17 +40,16 @@ def select(self, population: list[Chromosome]):
3840
:return: the selected parents population (as list of chromosomes).
3941
"""
4042

41-
# Get the length of the population list.
42-
N = len(population)
43+
# Get the population size.
44+
pop_size = len(population)
4345

4446
# Sort the population in descending order using their fitness value.
4547
sorted_population = sorted(population, key=attrgetter("fitness"), reverse=True)
4648

47-
# Select 'N' using only the higher 'p%' of the (old) population (indexes).
48-
index = self.rng.choice(int(N*self._items), size=N, replace=True, shuffle=True)
49-
50-
# Increase the selection counter.
51-
self.inc_counter()
49+
# Select tne new parents using only the higher percentage '%' of
50+
# the old population (indexes).
51+
index = self.rng.choice(int(pop_size*self._items), size=pop_size,
52+
replace=True, shuffle=True)
5253

5354
# Return the new parents (individuals).
5455
return [sorted_population[i] for i in index]

0 commit comments

Comments
 (0)