Skip to content

Commit 0f9bc97

Browse files
committed
Optimize the code
1 parent 034129d commit 0f9bc97

File tree

3 files changed

+34
-84
lines changed

3 files changed

+34
-84
lines changed

pygad/helper/misc.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,15 @@ def print_params_summary():
238238
summary_output = summary_output + m + "\n"
239239
return summary_output
240240

241+
def initialize_parents_array(self, shape):
242+
"""
243+
Standardize array initialization for parents and offspring.
244+
"""
245+
if self.gene_type_single:
246+
return numpy.empty(shape, dtype=self.gene_type[0])
247+
else:
248+
return numpy.empty(shape, dtype=object)
249+
241250
def change_population_dtype_and_round(self,
242251
population):
243252
"""

pygad/utils/mutation.py

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,7 @@ def mutation_by_space(self, offspring):
6666
sample_size=self.sample_size)
6767

6868
# Before assigning the selected value from the space to the gene, change its data type and round it.
69-
if self.gene_type_single == True:
70-
if not self.gene_type[1] is None:
71-
offspring[offspring_idx, gene_idx] = numpy.round(self.gene_type[0](value_from_space),
72-
self.gene_type[1])
73-
else:
74-
offspring[offspring_idx, gene_idx] = self.gene_type[0](value_from_space)
75-
else:
76-
if not self.gene_type[gene_idx][1] is None:
77-
offspring[offspring_idx, gene_idx] = numpy.round(self.gene_type[gene_idx][0](value_from_space),
78-
self.gene_type[gene_idx][1])
79-
else:
80-
offspring[offspring_idx, gene_idx] = self.gene_type[gene_idx][0](value_from_space)
69+
offspring[offspring_idx, gene_idx] = self.change_gene_dtype_and_round(gene_idx, value_from_space)
8170

8271
if self.allow_duplicate_genes == False:
8372
offspring[offspring_idx], _, _ = self.solve_duplicate_genes_by_space(solution=offspring[offspring_idx],
@@ -107,18 +96,7 @@ def mutation_probs_by_space(self, offspring):
10796
sample_size=self.sample_size)
10897

10998
# Assigning the selected value from the space to the gene.
110-
if self.gene_type_single == True:
111-
if not self.gene_type[1] is None:
112-
offspring[offspring_idx, gene_idx] = numpy.round(self.gene_type[0](value_from_space),
113-
self.gene_type[1])
114-
else:
115-
offspring[offspring_idx, gene_idx] = self.gene_type[0](value_from_space)
116-
else:
117-
if not self.gene_type[gene_idx][1] is None:
118-
offspring[offspring_idx, gene_idx] = numpy.round(self.gene_type[gene_idx][0](value_from_space),
119-
self.gene_type[gene_idx][1])
120-
else:
121-
offspring[offspring_idx, gene_idx] = self.gene_type[gene_idx][0](value_from_space)
99+
offspring[offspring_idx, gene_idx] = self.change_gene_dtype_and_round(gene_idx, value_from_space)
122100

123101
if self.allow_duplicate_genes == False:
124102
offspring[offspring_idx], _, _ = self.solve_duplicate_genes_by_space(solution=offspring[offspring_idx],
@@ -540,18 +518,7 @@ def adaptive_mutation_by_space(self, offspring):
540518
sample_size=self.sample_size)
541519

542520
# Assigning the selected value from the space to the gene.
543-
if self.gene_type_single == True:
544-
if not self.gene_type[1] is None:
545-
offspring[offspring_idx, gene_idx] = numpy.round(self.gene_type[0](value_from_space),
546-
self.gene_type[1])
547-
else:
548-
offspring[offspring_idx, gene_idx] = self.gene_type[0](value_from_space)
549-
else:
550-
if not self.gene_type[gene_idx][1] is None:
551-
offspring[offspring_idx, gene_idx] = numpy.round(self.gene_type[gene_idx][0](value_from_space),
552-
self.gene_type[gene_idx][1])
553-
else:
554-
offspring[offspring_idx, gene_idx] = self.gene_type[gene_idx][0](value_from_space)
521+
offspring[offspring_idx, gene_idx] = self.change_gene_dtype_and_round(gene_idx, value_from_space)
555522

556523
if self.allow_duplicate_genes == False:
557524
offspring[offspring_idx], _, _ = self.solve_duplicate_genes_by_space(solution=offspring[offspring_idx],
@@ -678,18 +645,7 @@ def adaptive_mutation_probs_by_space(self, offspring):
678645
sample_size=self.sample_size)
679646

680647
# Assigning the selected value from the space to the gene.
681-
if self.gene_type_single == True:
682-
if not self.gene_type[1] is None:
683-
offspring[offspring_idx, gene_idx] = numpy.round(self.gene_type[0](value_from_space),
684-
self.gene_type[1])
685-
else:
686-
offspring[offspring_idx, gene_idx] = self.gene_type[0](value_from_space)
687-
else:
688-
if not self.gene_type[gene_idx][1] is None:
689-
offspring[offspring_idx, gene_idx] = numpy.round(self.gene_type[gene_idx][0](value_from_space),
690-
self.gene_type[gene_idx][1])
691-
else:
692-
offspring[offspring_idx, gene_idx] = self.gene_type[gene_idx][0](value_from_space)
648+
offspring[offspring_idx, gene_idx] = self.change_gene_dtype_and_round(gene_idx, value_from_space)
693649

694650
if self.allow_duplicate_genes == False:
695651
offspring[offspring_idx], _, _ = self.solve_duplicate_genes_by_space(solution=offspring[offspring_idx],

pygad/utils/parent_selection.py

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,11 @@ def steady_state_selection(self, fitness, num_parents):
2929
fitness_sorted = self.sort_solutions_nsga2(fitness=fitness)
3030

3131
# Selecting the best individuals in the current generation as parents for producing the offspring of the next generation.
32-
if self.gene_type_single == True:
33-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=self.gene_type[0])
34-
else:
35-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=object)
32+
parents = self.initialize_parents_array((num_parents, self.population.shape[1]))
33+
parents_indices = numpy.array(fitness_sorted[:num_parents])
34+
parents[:, :] = self.population[parents_indices, :].copy()
3635

37-
for parent_num in range(num_parents):
38-
parents[parent_num, :] = self.population[fitness_sorted[parent_num], :].copy()
39-
40-
return parents, numpy.array(fitness_sorted[:num_parents])
36+
return parents, parents_indices
4137

4238
def rank_selection(self, fitness, num_parents):
4339

@@ -91,15 +87,9 @@ def random_selection(self, fitness, num_parents):
9187
-The indices of the selected solutions.
9288
"""
9389

94-
if self.gene_type_single == True:
95-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=self.gene_type[0])
96-
else:
97-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=object)
98-
90+
parents = self.initialize_parents_array((num_parents, self.population.shape[1]))
9991
rand_indices = numpy.random.randint(low=0.0, high=fitness.shape[0], size=num_parents)
100-
101-
for parent_num in range(num_parents):
102-
parents[parent_num, :] = self.population[rand_indices[parent_num], :].copy()
92+
parents[:, :] = self.population[rand_indices, :].copy()
10393

10494
return parents, rand_indices
10595

@@ -119,11 +109,7 @@ def tournament_selection(self, fitness, num_parents):
119109
# This function works with both single- and multi-objective optimization problems.
120110
fitness_sorted = self.sort_solutions_nsga2(fitness=fitness)
121111

122-
if self.gene_type_single == True:
123-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=self.gene_type[0])
124-
else:
125-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=object)
126-
112+
parents = self.initialize_parents_array((num_parents, self.population.shape[1]))
127113
parents_indices = []
128114

129115
for parent_num in range(num_parents):
@@ -137,10 +123,11 @@ def tournament_selection(self, fitness, num_parents):
137123

138124
# Append the index of the selected parent.
139125
parents_indices.append(rand_indices[selected_parent_idx])
140-
# Insert the selected parent.
141-
parents[parent_num, :] = self.population[rand_indices[selected_parent_idx], :].copy()
142126

143-
return parents, numpy.array(parents_indices)
127+
parents_indices = numpy.array(parents_indices)
128+
parents[:, :] = self.population[parents_indices, :].copy()
129+
130+
return parents, parents_indices
144131

145132
def roulette_wheel_selection(self, fitness, num_parents):
146133

@@ -186,11 +173,13 @@ def roulette_wheel_selection(self, fitness, num_parents):
186173
rand_prob = numpy.random.rand()
187174
for idx in range(probs.shape[0]):
188175
if (rand_prob >= probs_start[idx] and rand_prob < probs_end[idx]):
189-
parents[parent_num, :] = self.population[idx, :].copy()
190176
parents_indices.append(idx)
191177
break
192178

193-
return parents, numpy.array(parents_indices)
179+
parents_indices = numpy.array(parents_indices)
180+
parents[:, :] = self.population[parents_indices, :].copy()
181+
182+
return parents, parents_indices
194183

195184
def wheel_cumulative_probs(self, probs, num_parents):
196185
"""
@@ -220,10 +209,7 @@ def wheel_cumulative_probs(self, probs, num_parents):
220209
probs[min_probs_idx] = float('inf')
221210

222211
# Selecting the best individuals in the current generation as parents for producing the offspring of the next generation.
223-
if self.gene_type_single == True:
224-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=self.gene_type[0])
225-
else:
226-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=object)
212+
parents = self.initialize_parents_array((num_parents, self.population.shape[1]))
227213

228214
return probs_start, probs_end, parents
229215

@@ -281,22 +267,21 @@ def stochastic_universal_selection(self, fitness, num_parents):
281267
size=1)[0] # Location of the first pointer.
282268

283269
# Selecting the best individuals in the current generation as parents for producing the offspring of the next generation.
284-
if self.gene_type_single == True:
285-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=self.gene_type[0])
286-
else:
287-
parents = numpy.empty((num_parents, self.population.shape[1]), dtype=object)
270+
parents = self.initialize_parents_array((num_parents, self.population.shape[1]))
288271

289272
parents_indices = []
290273

291274
for parent_num in range(num_parents):
292275
rand_pointer = first_pointer + parent_num*pointers_distance
293276
for idx in range(probs.shape[0]):
294277
if (rand_pointer >= probs_start[idx] and rand_pointer < probs_end[idx]):
295-
parents[parent_num, :] = self.population[idx, :].copy()
296278
parents_indices.append(idx)
297279
break
298280

299-
return parents, numpy.array(parents_indices)
281+
parents_indices = numpy.array(parents_indices)
282+
parents[:, :] = self.population[parents_indices, :].copy()
283+
284+
return parents, parents_indices
300285

301286
def tournament_selection_nsga2(self,
302287
fitness,

0 commit comments

Comments
 (0)