Cleaned up alighnment
This commit is contained in:
@ -31,12 +31,12 @@ from fitness_examples import Fitness_Examples
|
|||||||
from termination import Termination
|
from termination import Termination
|
||||||
|
|
||||||
# Parent/Survivor Selection Methods
|
# Parent/Survivor Selection Methods
|
||||||
from parent import Parent
|
from parent import Parent
|
||||||
from survivor import Survivor
|
from survivor import Survivor
|
||||||
|
|
||||||
# Genetic Operator Methods
|
# Genetic Operator Methods
|
||||||
from crossover import Crossover
|
from crossover import Crossover
|
||||||
from mutation import Mutation
|
from mutation import Mutation
|
||||||
|
|
||||||
# Default Attributes for the GA
|
# Default Attributes for the GA
|
||||||
from attributes import Attributes
|
from attributes import Attributes
|
||||||
@ -107,7 +107,7 @@ class GA(Attributes):
|
|||||||
if int(adapt_counter) < int(adapt_counter + self.adapt_rate):
|
if int(adapt_counter) < int(adapt_counter + self.adapt_rate):
|
||||||
self.adapt()
|
self.adapt()
|
||||||
|
|
||||||
number_of_generations -= 1
|
number_of_generations -= 1
|
||||||
self.current_generation += 1
|
self.current_generation += 1
|
||||||
|
|
||||||
|
|
||||||
@ -143,33 +143,39 @@ class GA(Attributes):
|
|||||||
population gradually approaches the solution.
|
population gradually approaches the solution.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Determines how much to adapt by
|
||||||
|
weight = self.adapt_probability_rate
|
||||||
|
|
||||||
# Don't adapt
|
# Don't adapt
|
||||||
if self.adapt_probability_rate is None or self.adapt_probability_rate <= 0:
|
if weight is None or weight <= 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Amount of the population desired to converge (default 50%)
|
# Amount of the population desired to converge (default 50%)
|
||||||
amount_converged = round(self.percent_converged*len(self.population))
|
amount_converged = round(self.percent_converged * len(self.population))
|
||||||
|
|
||||||
# Difference between best and i-th chromosomes
|
# Difference between best and i-th chromosomes
|
||||||
best_chromosome = self.population[0]
|
best_chromosome = self.population[0]
|
||||||
tol = lambda i: self.dist(best_chromosome, self.population[i])
|
tol = lambda i: self.dist(best_chromosome, self.population[i])
|
||||||
|
|
||||||
# Weighted averaging
|
|
||||||
average = lambda x, y: self.adapt_probability_rate * x + (1-self.adapt_probability_rate) * y
|
|
||||||
|
|
||||||
# Too few converged: cross more and mutate less
|
# Too few converged: cross more and mutate less
|
||||||
if tol(amount_converged//2) > tol(amount_converged//4)*2:
|
if tol(amount_converged//2) > tol(amount_converged//4)*2:
|
||||||
|
bounds = (self.max_selection_probability,
|
||||||
self.selection_probability = average(self.max_selection_probability , self.selection_probability)
|
self.min_chromosome_mutation_rate,
|
||||||
self.chromosome_mutation_rate = average(self.min_chromosome_mutation_rate, self.chromosome_mutation_rate)
|
self.min_gene_mutation_rate)
|
||||||
self.gene_mutation_rate = average(self.min_gene_mutation_rate , self.gene_mutation_rate)
|
|
||||||
|
|
||||||
# Too many converged: cross less and mutate more
|
# Too many converged: cross less and mutate more
|
||||||
else:
|
else:
|
||||||
|
bounds = (self.min_selection_probability,
|
||||||
|
self.max_chromosome_mutation_rate,
|
||||||
|
self.max_gene_mutation_rate)
|
||||||
|
|
||||||
self.selection_probability = average(self.min_selection_probability , self.selection_probability)
|
# Weighted average of x and y
|
||||||
self.chromosome_mutation_rate = average(self.max_chromosome_mutation_rate, self.chromosome_mutation_rate)
|
average = lambda x, y: weight * x + (1-weight) * y
|
||||||
self.gene_mutation_rate = average(self.max_gene_mutation_rate , self.gene_mutation_rate)
|
|
||||||
|
# Adjust rates towards the bounds
|
||||||
|
self.selection_probability = average(bounds[0], self.selection_probability)
|
||||||
|
self.chromosome_mutation_rate = average(bounds[1], self.chromosome_mutation_rate)
|
||||||
|
self.gene_mutation_rate = average(bounds[2], self.gene_mutation_rate)
|
||||||
|
|
||||||
|
|
||||||
def adapt_population(self):
|
def adapt_population(self):
|
||||||
@ -208,7 +214,6 @@ class GA(Attributes):
|
|||||||
# May reject negative weight or division by 0
|
# May reject negative weight or division by 0
|
||||||
try:
|
try:
|
||||||
self.population[n] = self.crossover_individual_impl(
|
self.population[n] = self.crossover_individual_impl(
|
||||||
self,
|
|
||||||
self.population[n],
|
self.population[n],
|
||||||
best_chromosome,
|
best_chromosome,
|
||||||
weight = min(0.25, 2 * tol_j / (tol(n) - tol_j))
|
weight = min(0.25, 2 * tol_j / (tol(n) - tol_j))
|
||||||
@ -218,7 +223,6 @@ class GA(Attributes):
|
|||||||
# Cross with j-th chromosome instead
|
# Cross with j-th chromosome instead
|
||||||
except:
|
except:
|
||||||
self.population[n] = self.crossover_individual_impl(
|
self.population[n] = self.crossover_individual_impl(
|
||||||
self,
|
|
||||||
self.population[n],
|
self.population[n],
|
||||||
self.population[j],
|
self.population[j],
|
||||||
weight = 0.75
|
weight = 0.75
|
||||||
@ -228,13 +232,11 @@ class GA(Attributes):
|
|||||||
self.population[n].fitness = self.fitness_function_impl(self.population[n])
|
self.population[n].fitness = self.fitness_function_impl(self.population[n])
|
||||||
|
|
||||||
# Update best chromosome
|
# Update best chromosome
|
||||||
if self.target_fitness_type == 'max':
|
if any((all((self.target_fitness_type == 'max',
|
||||||
cond = (self.population[n].fitness > best_chromosome.fitness)
|
self.population[n].fitness > best_chromosome.fitness)),
|
||||||
|
all((self.target_fitness_type == 'min',
|
||||||
if self.target_fitness_type == 'min':
|
self.population[n].fitness < best_chromosome.fitness))
|
||||||
cond = (self.population[n].fitness < best_chromosome.fitness)
|
)):
|
||||||
|
|
||||||
if cond:
|
|
||||||
tol_j = tol(j)
|
tol_j = tol(j)
|
||||||
best_chromosome = self.population[n]
|
best_chromosome = self.population[n]
|
||||||
|
|
||||||
@ -256,7 +258,7 @@ class GA(Attributes):
|
|||||||
self.population = self.make_population(
|
self.population = self.make_population(
|
||||||
(
|
(
|
||||||
self.gene_impl()
|
self.gene_impl()
|
||||||
for _
|
for __
|
||||||
in range(self.chromosome_length)
|
in range(self.chromosome_length)
|
||||||
)
|
)
|
||||||
for _
|
for _
|
||||||
@ -316,9 +318,7 @@ class GA(Attributes):
|
|||||||
on the target fitness type.
|
on the target fitness type.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return self.convert_fitness(
|
return self.convert_fitness(self.population[index].fitness)
|
||||||
self.population[index].fitness
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def convert_fitness(self, fitness_value):
|
def convert_fitness(self, fitness_value):
|
||||||
|
|||||||
@ -18,12 +18,12 @@ from fitness_examples import Fitness_Examples
|
|||||||
from termination import Termination
|
from termination import Termination
|
||||||
|
|
||||||
# Parent/Survivor Selection Methods
|
# Parent/Survivor Selection Methods
|
||||||
from parent import Parent
|
from parent import Parent
|
||||||
from survivor import Survivor
|
from survivor import Survivor
|
||||||
|
|
||||||
# Genetic Operator Methods
|
# Genetic Operator Methods
|
||||||
from crossover import Crossover
|
from crossover import Crossover
|
||||||
from mutation import Mutation
|
from mutation import Mutation
|
||||||
|
|
||||||
# Database class
|
# Database class
|
||||||
from database import sql_database
|
from database import sql_database
|
||||||
@ -46,111 +46,126 @@ class Attributes:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
run = 0,
|
# Attributes must be passed in using kwargs
|
||||||
chromosome_length = 10,
|
|
||||||
population_size = 10,
|
run = 0,
|
||||||
chromosome_impl = None,
|
|
||||||
gene_impl = None,
|
chromosome_length = 10,
|
||||||
population = None,
|
population_size = 10,
|
||||||
target_fitness_type = 'max',
|
chromosome_impl = None,
|
||||||
update_fitness = False,
|
gene_impl = None,
|
||||||
parent_ratio = 0.10,
|
population = None,
|
||||||
selection_probability = 0.50,
|
target_fitness_type = 'max',
|
||||||
tournament_size_ratio = 0.10,
|
update_fitness = False,
|
||||||
current_generation = 0,
|
|
||||||
current_fitness = 0,
|
parent_ratio = 0.10,
|
||||||
generation_goal = 100,
|
selection_probability = 0.50,
|
||||||
fitness_goal = None,
|
tournament_size_ratio = 0.10,
|
||||||
tolerance_goal = None,
|
|
||||||
percent_converged = 0.50,
|
current_generation = 0,
|
||||||
chromosome_mutation_rate = 0.15,
|
current_fitness = 0,
|
||||||
gene_mutation_rate = 0.05,
|
|
||||||
adapt_rate = 0.05,
|
generation_goal = 100,
|
||||||
adapt_probability_rate = 0.05,
|
fitness_goal = None,
|
||||||
adapt_population_flag = True,
|
tolerance_goal = None,
|
||||||
max_selection_probability = 0.75,
|
percent_converged = 0.50,
|
||||||
min_selection_probability = 0.25,
|
|
||||||
|
chromosome_mutation_rate = 0.15,
|
||||||
|
gene_mutation_rate = 0.05,
|
||||||
|
|
||||||
|
adapt_rate = 0.05,
|
||||||
|
adapt_probability_rate = 0.05,
|
||||||
|
adapt_population_flag = True,
|
||||||
|
|
||||||
|
max_selection_probability = 0.75,
|
||||||
|
min_selection_probability = 0.25,
|
||||||
max_chromosome_mutation_rate = None,
|
max_chromosome_mutation_rate = None,
|
||||||
min_chromosome_mutation_rate = None,
|
min_chromosome_mutation_rate = None,
|
||||||
max_gene_mutation_rate = 0.15,
|
max_gene_mutation_rate = 0.15,
|
||||||
min_gene_mutation_rate = 0.01,
|
min_gene_mutation_rate = 0.01,
|
||||||
dist = None,
|
|
||||||
fitness_function_impl = None,
|
dist = None,
|
||||||
make_population = make_population,
|
fitness_function_impl = None,
|
||||||
make_chromosome = make_chromosome,
|
|
||||||
make_gene = make_gene,
|
make_population = make_population,
|
||||||
parent_selection_impl = None,
|
make_chromosome = make_chromosome,
|
||||||
crossover_individual_impl = None,
|
make_gene = make_gene,
|
||||||
crossover_population_impl = None,
|
|
||||||
survivor_selection_impl = None,
|
parent_selection_impl = None,
|
||||||
mutation_individual_impl = None,
|
crossover_individual_impl = None,
|
||||||
mutation_population_impl = None,
|
crossover_population_impl = None,
|
||||||
termination_impl = None,
|
survivor_selection_impl = None,
|
||||||
Database = sql_database.SQL_Database,
|
mutation_individual_impl = None,
|
||||||
database_name = 'database.db',
|
mutation_population_impl = None,
|
||||||
sql_create_data_structure = """CREATE TABLE IF NOT EXISTS data (
|
|
||||||
id INTEGER PRIMARY KEY,
|
termination_impl = None,
|
||||||
config_id INTEGER DEFAULT NULL,
|
|
||||||
generation INTEGER NOT NULL,
|
Database = sql_database.SQL_Database,
|
||||||
fitness REAL,
|
database_name = 'database.db',
|
||||||
chromosome TEXT
|
sql_create_data_structure = """CREATE TABLE IF NOT EXISTS data (
|
||||||
); """,
|
id INTEGER PRIMARY KEY,
|
||||||
Graph = matplotlib_graph.Matplotlib_Graph
|
config_id INTEGER DEFAULT NULL,
|
||||||
|
generation INTEGER NOT NULL,
|
||||||
|
fitness REAL,
|
||||||
|
chromosome TEXT
|
||||||
|
); """,
|
||||||
|
|
||||||
|
Graph = matplotlib_graph.Matplotlib_Graph
|
||||||
):
|
):
|
||||||
|
|
||||||
# Keep track of the current run
|
# Keep track of the current run
|
||||||
self.run = run
|
self.run = run
|
||||||
|
|
||||||
# Initilization variables
|
# Initilization variables
|
||||||
self.chromosome_length = chromosome_length
|
self.chromosome_length = chromosome_length
|
||||||
self.population_size = population_size
|
self.population_size = population_size
|
||||||
self.chromosome_impl = chromosome_impl
|
self.chromosome_impl = chromosome_impl
|
||||||
self.gene_impl = gene_impl
|
self.gene_impl = gene_impl
|
||||||
self.population = population
|
self.population = population
|
||||||
self.target_fitness_type = target_fitness_type
|
self.target_fitness_type = target_fitness_type
|
||||||
self.update_fitness = update_fitness
|
self.update_fitness = update_fitness
|
||||||
|
|
||||||
# Selection variables
|
# Selection variables
|
||||||
self.parent_ratio = parent_ratio
|
self.parent_ratio = parent_ratio
|
||||||
self.selection_probability = selection_probability
|
self.selection_probability = selection_probability
|
||||||
self.tournament_size_ratio = tournament_size_ratio
|
self.tournament_size_ratio = tournament_size_ratio
|
||||||
|
|
||||||
# Termination variables
|
# Termination variables
|
||||||
self.current_generation = current_generation
|
self.current_generation = current_generation
|
||||||
self.current_fitness = current_fitness
|
self.current_fitness = current_fitness
|
||||||
self.generation_goal = generation_goal
|
self.generation_goal = generation_goal
|
||||||
self.fitness_goal = fitness_goal
|
self.fitness_goal = fitness_goal
|
||||||
self.tolerance_goal = tolerance_goal
|
self.tolerance_goal = tolerance_goal
|
||||||
self.percent_converged = percent_converged
|
self.percent_converged = percent_converged
|
||||||
|
|
||||||
# Mutation variables
|
# Mutation variables
|
||||||
self.chromosome_mutation_rate = chromosome_mutation_rate
|
self.chromosome_mutation_rate = chromosome_mutation_rate
|
||||||
self.gene_mutation_rate = gene_mutation_rate
|
self.gene_mutation_rate = gene_mutation_rate
|
||||||
|
|
||||||
# Adapt variables
|
# Adapt variables
|
||||||
self.adapt_rate = adapt_rate
|
self.adapt_rate = adapt_rate
|
||||||
self.adapt_probability_rate = adapt_probability_rate
|
self.adapt_probability_rate = adapt_probability_rate
|
||||||
self.adapt_population_flag = adapt_population_flag
|
self.adapt_population_flag = adapt_population_flag
|
||||||
|
|
||||||
# Bounds on probabilities when adapting
|
# Bounds on probabilities when adapting
|
||||||
self.max_selection_probability = max_selection_probability
|
self.max_selection_probability = max_selection_probability
|
||||||
self.min_selection_probability = min_selection_probability
|
self.min_selection_probability = min_selection_probability
|
||||||
self.max_chromosome_mutation_rate = max_chromosome_mutation_rate
|
self.max_chromosome_mutation_rate = max_chromosome_mutation_rate
|
||||||
self.min_chromosome_mutation_rate = min_chromosome_mutation_rate
|
self.min_chromosome_mutation_rate = min_chromosome_mutation_rate
|
||||||
self.max_gene_mutation_rate = max_gene_mutation_rate
|
self.max_gene_mutation_rate = max_gene_mutation_rate
|
||||||
self.min_gene_mutation_rate = min_gene_mutation_rate
|
self.min_gene_mutation_rate = min_gene_mutation_rate
|
||||||
|
|
||||||
# Distance between two chromosomes
|
# Distance between two chromosomes
|
||||||
self.dist = dist
|
self.dist = dist
|
||||||
|
|
||||||
# Default EasyGA implimentation structure
|
# Default EasyGA implimentation structure
|
||||||
self.fitness_function_impl = fitness_function_impl
|
self.fitness_function_impl = fitness_function_impl
|
||||||
self.make_population = make_population
|
self.make_population = make_population
|
||||||
self.make_chromosome = make_chromosome
|
self.make_chromosome = make_chromosome
|
||||||
self.make_gene = make_gene
|
self.make_gene = make_gene
|
||||||
|
|
||||||
# Methods for accomplishing Parent-Selection -> Crossover -> Survivor_Selection -> Mutation
|
# Methods for accomplishing Parent-Selection -> Crossover -> Survivor_Selection -> Mutation
|
||||||
self.parent_selection_impl = parent_selection_impl
|
self.parent_selection_impl = parent_selection_impl
|
||||||
self.crossover_individual_impl = crossover_individual_impl
|
self.crossover_individual_impl = crossover_individual_impl
|
||||||
self.crossover_population_impl = crossover_population_impl
|
self.crossover_population_impl = crossover_population_impl
|
||||||
self.survivor_selection_impl = survivor_selection_impl
|
self.survivor_selection_impl = survivor_selection_impl
|
||||||
@ -360,6 +375,22 @@ class Attributes:
|
|||||||
self._run = value
|
self._run = value
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_generation(self):
|
||||||
|
"""Getter function for the current generation."""
|
||||||
|
return self._current_generation
|
||||||
|
|
||||||
|
|
||||||
|
@current_generation.setter
|
||||||
|
def current_generation(self, generation):
|
||||||
|
"""Setter function for the current generation."""
|
||||||
|
|
||||||
|
if not isinstance(generation, int) or generation < 0:
|
||||||
|
raise ValueError("ga.current_generation must be an integer greater than or equal to 0")
|
||||||
|
|
||||||
|
self._current_generation = generation
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def chromosome_length(self):
|
def chromosome_length(self):
|
||||||
"""Getter function for chromosome length"""
|
"""Getter function for chromosome length"""
|
||||||
@ -367,14 +398,13 @@ class Attributes:
|
|||||||
|
|
||||||
|
|
||||||
@chromosome_length.setter
|
@chromosome_length.setter
|
||||||
def chromosome_length(self, value_input):
|
def chromosome_length(self, length):
|
||||||
"""Setter function with error checking for chromosome length"""
|
"""Setter function with error checking for chromosome length"""
|
||||||
|
|
||||||
# If the chromosome length is less then or equal 0 throw error
|
if(not isinstance(length, int) or length <= 0):
|
||||||
if(not isinstance(value_input, int) or value_input <= 0):
|
raise ValueError("Chromosome length must be integer greater than 0")
|
||||||
raise ValueError("Chromosome length must be integer greater then 0")
|
|
||||||
|
|
||||||
self._chromosome_length = value_input
|
self._chromosome_length = length
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -385,14 +415,13 @@ class Attributes:
|
|||||||
|
|
||||||
|
|
||||||
@population_size.setter
|
@population_size.setter
|
||||||
def population_size(self, value_input):
|
def population_size(self, size):
|
||||||
"""Setter function with error checking for population size"""
|
"""Setter function with error checking for population size"""
|
||||||
|
|
||||||
# If the population size is less then or equal 0 throw error
|
if(not isinstance(size, int) or size <= 0):
|
||||||
if(not isinstance(value_input, int) or value_input <= 0):
|
raise ValueError("Population size must be integer greater than 0")
|
||||||
raise ValueError("Population length must be integer greater then 0")
|
|
||||||
|
|
||||||
self._population_size = value_input
|
self._population_size = size
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -403,10 +432,10 @@ class Attributes:
|
|||||||
|
|
||||||
|
|
||||||
@target_fitness_type.setter
|
@target_fitness_type.setter
|
||||||
def target_fitness_type(self, value_input):
|
def target_fitness_type(self, target_fitness_type):
|
||||||
"""Setter function for target fitness type."""
|
"""Setter function for target fitness type."""
|
||||||
|
|
||||||
self._target_fitness_type = value_input
|
self._target_fitness_type = target_fitness_type
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -417,16 +446,16 @@ class Attributes:
|
|||||||
|
|
||||||
|
|
||||||
@max_chromosome_mutation_rate.setter
|
@max_chromosome_mutation_rate.setter
|
||||||
def max_chromosome_mutation_rate(self, value_input):
|
def max_chromosome_mutation_rate(self, rate):
|
||||||
"""Setter function with error checking and default value for max chromosome mutation rate"""
|
"""Setter function with error checking and default value for max chromosome mutation rate"""
|
||||||
|
|
||||||
# Default value
|
# Default value
|
||||||
if value_input is None:
|
if rate is None:
|
||||||
self._max_chromosome_mutation_rate = min(self.chromosome_mutation_rate*2, (1+self.chromosome_mutation_rate)/2)
|
self._max_chromosome_mutation_rate = min(self.chromosome_mutation_rate*2, (1+self.chromosome_mutation_rate)/2)
|
||||||
|
|
||||||
# Otherwise check value
|
# Otherwise check value
|
||||||
elif 0 <= value_input <= 1:
|
elif 0 <= rate <= 1:
|
||||||
self._max_chromosome_mutation_rate = value_input
|
self._max_chromosome_mutation_rate = rate
|
||||||
|
|
||||||
# Throw error
|
# Throw error
|
||||||
else:
|
else:
|
||||||
@ -441,16 +470,16 @@ class Attributes:
|
|||||||
|
|
||||||
|
|
||||||
@min_chromosome_mutation_rate.setter
|
@min_chromosome_mutation_rate.setter
|
||||||
def min_chromosome_mutation_rate(self, value_input):
|
def min_chromosome_mutation_rate(self, rate):
|
||||||
"""Setter function with error checking and default value for min chromosome mutation rate"""
|
"""Setter function with error checking and default value for min chromosome mutation rate"""
|
||||||
|
|
||||||
# Default value
|
# Default value
|
||||||
if value_input is None:
|
if rate is None:
|
||||||
self._min_chromosome_mutation_rate = self.chromosome_mutation_rate/2
|
self._min_chromosome_mutation_rate = self.chromosome_mutation_rate/2
|
||||||
|
|
||||||
# Otherwise check value
|
# Otherwise check value
|
||||||
elif 0 <= value_input <= 1:
|
elif 0 <= rate <= 1:
|
||||||
self._min_chromosome_mutation_rate = value_input
|
self._min_chromosome_mutation_rate = rate
|
||||||
|
|
||||||
# Throw error
|
# Throw error
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user