Skip to content

Commit 9422c1a

Browse files
authored
Fix bug when save_best_solution=True
The bug is fixed by creating a copy of the best solution. This is by replacing the next line: ```python best_solution = self.population[best_match_idx, :] ``` By this line: ```python best_solution = self.population[best_match_idx, :].copy() ```
1 parent c7dd751 commit 9422c1a

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

pygad.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -661,9 +661,9 @@ def initialize_population(self, low, high):
661661
self.gene_space[gene_idx] = numpy.asarray(numpy.random.uniform(low=low,
662662
high=high,
663663
size=1), dtype=self.gene_type)[0]
664-
self.population[sol_idx, gene_idx] = self.gene_space[gene_idx]
664+
self.population[sol_idx, gene_idx] = self.gene_space[gene_idx].copy()
665665
elif type(self.gene_space[gene_idx]) in [int, float, numpy.int, numpy.int8, numpy.int16, numpy.int32, numpy.int64, numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64, numpy.float, numpy.float16, numpy.float32, numpy.float64]:
666-
self.population[sol_idx, gene_idx] = self.gene_space[gene_idx]
666+
self.population[sol_idx, gene_idx] = self.gene_space[gene_idx].copy()
667667
else:
668668
# Replace all the None values with random values using the init_range_low, init_range_high, and gene_type attributes.
669669
for idx, curr_gene_space in enumerate(self.gene_space):
@@ -727,6 +727,7 @@ def run(self):
727727
# Appending the best solution to the best_solutions list.
728728
if self.save_best_solutions:
729729
self.best_solutions.append(best_solution)
730+
print("AAAAAAAAA ", self.best_solutions)
730731

731732
# Selecting the best parents in the population for mating.
732733
parents = self.select_parents(fitness, num_parents=self.num_parents_mating)
@@ -809,7 +810,7 @@ def steady_state_selection(self, fitness, num_parents):
809810
# Selecting the best individuals in the current generation as parents for producing the offspring of the next generation.
810811
parents = numpy.empty((num_parents, self.population.shape[1]))
811812
for parent_num in range(num_parents):
812-
parents[parent_num, :] = self.population[fitness_sorted[parent_num], :]
813+
parents[parent_num, :] = self.population[fitness_sorted[parent_num], :].copy()
813814
return parents
814815

815816
def rank_selection(self, fitness, num_parents):
@@ -827,7 +828,7 @@ def rank_selection(self, fitness, num_parents):
827828
# Selecting the best individuals in the current generation as parents for producing the offspring of the next generation.
828829
parents = numpy.empty((num_parents, self.population.shape[1]))
829830
for parent_num in range(num_parents):
830-
parents[parent_num, :] = self.population[fitness_sorted[parent_num], :]
831+
parents[parent_num, :] = self.population[fitness_sorted[parent_num], :].copy()
831832
return parents
832833

833834
def random_selection(self, fitness, num_parents):
@@ -845,7 +846,7 @@ def random_selection(self, fitness, num_parents):
845846
rand_indices = numpy.random.randint(low=0.0, high=fitness.shape[0], size=num_parents)
846847

847848
for parent_num in range(num_parents):
848-
parents[parent_num, :] = self.population[rand_indices[parent_num], :]
849+
parents[parent_num, :] = self.population[rand_indices[parent_num], :].copy()
849850
return parents
850851

851852
def tournament_selection(self, fitness, num_parents):
@@ -863,7 +864,7 @@ def tournament_selection(self, fitness, num_parents):
863864
rand_indices = numpy.random.randint(low=0.0, high=len(fitness), size=self.K_tournament)
864865
K_fitnesses = fitness[rand_indices]
865866
selected_parent_idx = numpy.where(K_fitnesses == numpy.max(K_fitnesses))[0][0]
866-
parents[parent_num, :] = self.population[rand_indices[selected_parent_idx], :]
867+
parents[parent_num, :] = self.population[rand_indices[selected_parent_idx], :].copy()
867868
return parents
868869

869870
def roulette_wheel_selection(self, fitness, num_parents):
@@ -897,7 +898,7 @@ def roulette_wheel_selection(self, fitness, num_parents):
897898
rand_prob = numpy.random.rand()
898899
for idx in range(probs.shape[0]):
899900
if (rand_prob >= probs_start[idx] and rand_prob < probs_end[idx]):
900-
parents[parent_num, :] = self.population[idx, :]
901+
parents[parent_num, :] = self.population[idx, :].copy()
901902
break
902903
return parents
903904

@@ -935,7 +936,7 @@ def stochastic_universal_selection(self, fitness, num_parents):
935936
rand_pointer = first_pointer + parent_num*pointers_distance
936937
for idx in range(probs.shape[0]):
937938
if (rand_pointer >= probs_start[idx] and rand_pointer < probs_end[idx]):
938-
parents[parent_num, :] = self.population[idx, :]
939+
parents[parent_num, :] = self.population[idx, :].copy()
939940
break
940941
return parents
941942

@@ -1161,7 +1162,7 @@ def mutation_by_space(self, offspring):
11611162

11621163
if self.gene_space_nested:
11631164
# Returning the current gene space from the 'gene_space' attribute.
1164-
curr_gene_space = self.gene_space[gene_idx]
1165+
curr_gene_space = self.gene_space[gene_idx].copy()
11651166

11661167
# If the gene space has only a single value, use it as the new gene value.
11671168
if type(curr_gene_space) in [int, float, numpy.int, numpy.int8, numpy.int16, numpy.int32, numpy.int64, numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64, numpy.float, numpy.float16, numpy.float32, numpy.float64]:
@@ -1203,7 +1204,7 @@ def mutation_probs_by_space(self, offspring):
12031204
if probs[gene_idx] <= self.mutation_probability:
12041205
if self.gene_space_nested:
12051206
# Returning the current gene space from the 'gene_space' attribute.
1206-
curr_gene_space = self.gene_space[gene_idx]
1207+
curr_gene_space = self.gene_space[gene_idx].copy()
12071208

12081209
# If the gene space has only a single value, use it as the new gene value.
12091210
if type(curr_gene_space) in [int, float, numpy.int, numpy.int8, numpy.int16, numpy.int32, numpy.int64, numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64, numpy.float, numpy.float16, numpy.float32, numpy.float64]:
@@ -1422,7 +1423,7 @@ def adaptive_mutation_by_space(self, offspring):
14221423

14231424
if self.gene_space_nested:
14241425
# Returning the current gene space from the 'gene_space' attribute.
1425-
curr_gene_space = self.gene_space[gene_idx]
1426+
curr_gene_space = self.gene_space[gene_idx].copy()
14261427

14271428
# If the gene space has only a single value, use it as the new gene value.
14281429
if type(curr_gene_space) in [int, float, numpy.int, numpy.int8, numpy.int16, numpy.int32, numpy.int64, numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64, numpy.float, numpy.float16, numpy.float32, numpy.float64]:
@@ -1510,7 +1511,7 @@ def adaptive_mutation_probs_by_space(self, offspring):
15101511
if probs[gene_idx] <= adaptive_mutation_probability:
15111512
if self.gene_space_nested:
15121513
# Returning the current gene space from the 'gene_space' attribute.
1513-
curr_gene_space = self.gene_space[gene_idx]
1514+
curr_gene_space = self.gene_space[gene_idx].copy()
15141515

15151516
# If the gene space has only a single value, use it as the new gene value.
15161517
if type(curr_gene_space) in [int, float, numpy.int, numpy.int8, numpy.int16, numpy.int32, numpy.int64, numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64, numpy.float, numpy.float16, numpy.float32, numpy.float64]:
@@ -1597,7 +1598,7 @@ def best_solution(self, pop_fitness=None):
15971598
# Then return the index of that solution corresponding to the best fitness.
15981599
best_match_idx = numpy.where(pop_fitness == numpy.max(pop_fitness))[0][0]
15991600

1600-
best_solution = self.population[best_match_idx, :]
1601+
best_solution = self.population[best_match_idx, :].copy()
16011602
best_solution_fitness = pop_fitness[best_match_idx]
16021603

16031604
return best_solution, best_solution_fitness, best_match_idx

0 commit comments

Comments
 (0)