8000 Refac/step isolate by unkcpz · Pull Request #1 · unkcpz/GeneticAlgorithmPython · GitHub
[go: up one dir, main page]

Skip to content

Refac/step isolate #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added __pycache__/pygad.cpython-39.pyc
Binary file not shown.
346 changes: 346 additions & 0 deletions pygad.egg-info/PKG-INFO

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions pygad.egg-info/SOURCES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
README.md
setup.py
pygad.egg-info/PKG-INFO
pygad.egg-info/SOURCES.txt
pygad.egg-info/dependency_links.txt
pygad.egg-info/requires.txt
pygad.egg-info/top_level.txt
1 change: 1 addition & 0 deletions pygad.egg-info/dependency_links.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

2 changes: 2 additions & 0 deletions pygad.egg-info/requires.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
numpy
matplotlib
1 change: 1 addition & 0 deletions pygad.egg-info/top_level.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

89 changes: 71 additions & 18 deletions pygad.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,7 @@ def __init__(self,

self.last_generation_fitness = None # A list holding the fitness values of all solutions in the last generation.
self.last_generation_parents = None # A list holding the parents of the last generation.
self.last_generation_parents_indices = None # A list ....
self.last_generation_offspring_crossover = None # A list holding the offspring after applying crossover in the last generation.
self.last_generation_offspring_mutation = None # A list holding the offspring after applying mutation in the last generation.
self.previous_generation_fitness = None # Holds the fitness values of one generation before the fitness values saved in the last_generation_fitness attribute. Added in PyGAD 2.26.2
Expand Down Expand Up @@ -1131,32 +1132,44 @@ def initialize_population(self, low, high, allow_duplicate_genes, mutation_by_re

# Keeping the initial population in the initial_population attribute.
self.initial_population = self.population.copy()

def cal_pop_fitness(self):
if self.valid_parameters == False:
raise ValueError("ERROR calling the cal_pop_fitness() method: \nPlease check the parameters passed while creating an instance of the GA class.\n")

return self._cal_pop_fitness(self.population,
self.last_generation_parents,
self.last_generation_parents_indices,
self.previous_generation_fitness,
self.fitness_func)

@staticmethod
def _cal_pop_fitness(population,
last_generation_parents,
last_generation_parents_indices,
previous_generation_fitness,
fitness_func):

"""
Calculating the fitness values of all solutions in the current population.
It returns:
-fitness: An array of the calculated fitness values.
"""

if self.valid_parameters == False:
raise ValueError("ERROR calling the cal_pop_fitness() method: \nPlease check the parameters passed while creating an instance of the GA class.\n")

pop_fitness = []
# Calculating the fitness value of each solution in the current population.
for sol_idx, sol in enumerate(self.population):
for sol_idx, sol in enumerate(population):

# Check if this solution is a parent from the previous generation and its fitness value is already calculated. If so, use the fitness value instead of calling the fitness function.
if (self.last_generation_parents is not None) and len(numpy.where(numpy.all(self.last_generation_parents == sol, axis=1))[0] > 0):
if (last_generation_parents is not None) and len(numpy.where(numpy.all(last_generation_parents == sol, axis=1))[0] > 0):
# Index of the parent in the parents array (self.last_generation_parents). This is not its index within the population.
parent_idx = numpy.where(numpy.all(self.last_generation_parents == sol, axis=1))[0][0]
parent_idx = numpy.where(numpy.all(last_generation_parents == sol, axis=1))[0][0]
# Index of the parent in the population.
parent_idx = self.last_generation_parents_indices[parent_idx]
parent_idx = last_generation_parents_indices[parent_idx]
# Use the parent's index to return its pre-calculated fitness value.
fitness = self.previous_generation_fitness[parent_idx]
fitness = previous_generation_fitness[parent_idx]
else:
fitness = self.fitness_func(sol, sol_idx)
fitness = fitness_func(sol, sol_idx)
if type(fitness) in GA.supported_int_float_types:
pass
else:
Expand Down Expand Up @@ -3105,7 +3118,6 @@ def unique_gene_by_space(self, solution, gene_idx, gene_type, build_initial_pop=
return value_from_space

def best_solution(self, pop_fitness=None):

"""
Returns information about the best solution found by the genetic algorithm.
Accepts the following parameters:
Expand All @@ -3120,10 +3132,14 @@ def best_solution(self, pop_fitness=None):
# At first, the fitness is calculated for each solution in the final generation.
if pop_fitness is None:
pop_fitness = self.cal_pop_fitness()

return self._best_solution(pop_fitness, self.population)

def _best_solution(self, pop_fitness, population):
# Then return the index of that solution corresponding to the best fitness.
best_match_idx = numpy.where(pop_fitness == numpy.max(pop_fitness))[0][0]

best_solution = self.population[best_match_idx, :].copy()
best_solution = population[best_match_idx, :].copy()
best_solution_fitness = pop_fitness[best_match_idx]

return best_solution, best_solution_fitness, best_match_idx
Expand All @@ -3149,7 +3165,6 @@ def plot_result(self,
plot_type=plot_type,
color=color,
save_dir=save_dir)

def plot_fitness(self,
title="PyGAD - Generation vs. Fitness",
xlabel="Generation",
Expand All @@ -3175,20 +3190,58 @@ def plot_fitness(self,

Returns the figure.
"""
return self._plot_fitness(self.generations_completed,
self.best_solutions_fitness,
title="PyGAD - Generation vs. Fitness",
xlabel="Generation",
ylabel="Fitness",
linewidth=3,
font_size=14,
plot_type="plot",
color="#3870FF",
save_dir=None)

@staticmethod
def _plot_fitness(generations_completed,
best_solutions_fitness,
title="PyGAD - Generation vs. Fitness",
xlabel="Generation",
ylabel="Fitness",
linewidth=3,
font_size=14,
plot_type="plot",
color="#3870FF",
save_dir=None):

if self.generations_completed < 1:
raise RuntimeError("The plot_fitness() (i.e. plot_result()) method can only be called after completing at least 1 generation but ({generations_completed}) is completed.".format(generations_completed=self.generations_completed))
"""
Creates, shows, and returns a figure that summarizes how the fitness value evolved by generation. Can only be called after completing at least 1 generation. If no generation is completed, an exception is raised.

Accepts the following:
title: Figure title.
xlabel: Label on the X-axis.
ylabel: Label on the Y-axis.
linewidth: Line width of the plot. Defaults to 3.
font_size: Font size for the labels and title. Defaults to 14.
plot_type: Type of the plot which can be either "plot" (default), "scatter", or "bar".
color: Color of the plot which defaults to "#3870FF".
save_dir: Directory to save the figure.

Returns the figure.
"""

if generations_completed < 1:
raise RuntimeError("The plot_fitness() (i.e. plot_result()) method can only be called after completing at least 1 generation but ({generations_completed}) is completed.".format(generations_completed=generations_completed))

# if self.run_completed == False:
# if not self.suppress_warnings: warnings.warn("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")

fig = matplotlib.pyplot.figure()
if plot_type == "plot":
matplotlib.pyplot.plot(self.best_solutions_fitness, linewidth=linewidth, color=color)
matplotlib.pyplot.plot(best_solutions_fitness, linewidth=linewidth, color=color)
elif plot_type == "scatter":
matplotlib.pyplot.scatter(range(self.generations_completed + 1), self.best_solutions_fitness, linewidth=linewidth, color=color)
matplotlib.pyplot.scatter(range(generations_completed + 1), best_solutions_fitness, linewidth=linewidth, color=color)
elif plot_type == "bar":
matplotlib.pyplot.bar(range(self.generations_completed + 1), self.best_solutions_fitness, linewidth=linewidth, color=color)
matplotlib.pyplot.bar(range(generations_completed + 1), best_solutions_fitness, linewidth=linewidth, color=color)
matplotlib.pyplot.title(title, fontsize=font_size)
matplotlib.pyplot.xlabel(xlabel, fontsize=font_size)
matplotlib.pyplot.ylabel(ylabel, fontsize=font_size)
Expand Down
0