8000 Change in best_solution() & new attribute added · rashed-03/GeneticAlgorithmPython@04d10f9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 04d10f9

Browse files
authored
Change in best_solution() & new attribute added
1. The `best_solution()` method in the `pygad.GA` class returns a new output representing the index of the best solution within the population. Now, it returns a total of 3 outputs and their order is: best solution, best solution fitness, and best solution idx. Here is an example: ```python solution, solution_fitness, solution_idx = ga_instance.best_solution() print("Parameters of the best solution :", solution) print("Fitness value of the best solution :", solution_fitness, "\n") print("Index of the best solution :", solution_idx, "\n") 2. A new attribute named `best_solution_generation` is added to the instances of the pygad.GA class. it holds the generation number at which the best solution is reached. It is only assigned the generation number after the `run()` method completes. Otherwise, its value is -1. Example: ```python print("Best solution reached after {best_solution_generation} generations.".format(best_solution_generation=ga_instance.best_solution_generation))
1 parent b79273c commit 04d10f9

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

pygad.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,9 @@ def __init__(self,
229229
self.random_mutation_max_val = random_mutation_max_val
230230

231231
# Even such this parameter is declared in the class header, it is assigned to the object here to access it after saving the object.
232-
self.best_solution_fitness = [] # A list holding the fitness value of the best solution for each generation.
232+
self.best_solutions_fitness = [] # A list holding the fitness value of the best solution for each generation.
233+
234+
self.best_solution_generation = -1 # The generation number at which the best solution is reached. It is only assigned the generation number after the `run()` method completes. Otherwise, its value is -1.
233235

234236
def initialize_population(self, low, high):
235237
"""
@@ -238,7 +240,9 @@ def initialize_population(self, low, high):
238240
# Population size = (number of chromosomes, number of genes per chromosome)
239241
self.pop_size = (self.sol_per_pop,self.num_genes) # The population will have sol_per_pop chromosome where each chromosome has num_genes genes.
240242
# Creating the initial population randomly.
241-
self.population = numpy.random.uniform(low=low, high=high, size=self.pop_size) # A NumPy array holding the initial population.
243+
self.population = numpy.random.uniform(low=low,
244+
high=high,
245+
size=self.pop_size) # A NumPy array holding the initial population.
242246

243247
# Keeping the initial population in the initial_population attribute.
244248
self.initial_population = self.population
@@ -254,6 +258,9 @@ def run(self):
254258
# Measuring the fitness of each chromosome in the population.
255259
fitness = self.cal_pop_fitness()
256260

261+
# Appending the fitness value of the best solution in the current generation to the best_solutions_fitness attribute.
262+
self.best_solutions_fitness.append(numpy.max(fitness))
263+
257264
# Selecting the best parents in the population for mating.
258265
parents = self.select_parents(fitness, num_parents=self.num_parents_mating)
259266

@@ -281,6 +288,7 @@ def run(self):
281288
if not (self.callback_generation is None):
282289
self.callback_generation(self)
283290

291+
self.best_solution_generation = numpy.where(numpy.array(self.best_solutions_fitness) == numpy.max(numpy.array(self.best_solutions_fitness)))[0][0]
284292
# After the run() method completes, the run_completed flag is changed from False to True.
285293
self.run_completed = True # Set to True only after the run() method completes gracefully.
286294

@@ -301,9 +309,6 @@ def cal_pop_fitness(self):
301309

302310
pop_fitness = numpy.array(pop_fitness)
303311

304-
# The best result in the current iteration.
305-
self.best_solution_fitness.append(numpy.max(pop_fitness))
306-
307312
return pop_fitness
308313

309314
def steady_state_selection(self, fitness, num_parents):
@@ -608,6 +613,7 @@ def best_solution(self):
608613
If no generation is completed (at least 1), an exception is raised. Otherwise, the following is returned:
609614
-best_solution: Best solution in the current population.
610615
-best_solution_fitness: Fitness value of the best solution.
616+
-best_match_idx: Index of the best solution in the current population.
611617
"""
612618

613619
if self.generations_completed < 1:
@@ -620,12 +626,12 @@ def best_solution(self):
620626
# At first, the fitness is calculated for each solution in the final generation.
621627
fitness = self.cal_pop_fitness()
622628
# Then return the index of that solution corresponding to the best fitness.
623-
best_match_idx = numpy.where(fitness == numpy.max(fitness))
629+
best_match_idx = numpy.where(fitness == numpy.max(fitness))[0][0]
624630

625-
best_solution = self.population[best_match_idx, :][0][0]
626-
best_solution_fitness = fitness[best_match_idx][0]
631+
best_solution = self.population[best_match_idx, :]
632+
best_solution_fitness = fitness[best_match_idx]
627633

628-
return best_solution, best_solution_fitness
634+
return best_solution, best_solution_fitness, best_match_idx
629635

630636
def plot_result(self):
631637
"""
@@ -641,7 +647,7 @@ def plot_result(self):
641647
# print("Warning calling the plot_result() method: \nGA is not executed yet and there are no results to display. Please call the run() method before calling the plot_result() method.\n")
642648

643649
matplotlib.pyplot.figure()
644-
matplotlib.pyplot.plot(self.best_solution_fitness)
650+
matplotlib.pyplot.plot(self.best_solutions_fitness)
645651
matplotlib.pyplot.title("PyGAD - Iteration vs. Fitness")
646652
matplotlib.pyplot.xlabel("Iteration")
647653
matplotlib.pyplot.ylabel("Fitness")
@@ -664,6 +670,8 @@ def load(filename):
664670
try:
665671
with open(filename + ".pkl", 'rb') as file:
666672
ga_in = pickle.load(file)
667-
except (FileNotFoundError):
668-
print("Error loading the file. Please check if the file exists.")
673+
except FileNotFoundError:
674+
raise FileNotFoundError("Error reading the file {filename}. Please check your inputs.".format(filename=filename))
675+
except:
676+
raise BaseException("Error loading the file. Please check if the file exists.")
669677
return ga_in

0 commit comments

Comments
 (0)
0