Added more structure methods and some quality of life changes
Overall cleaned up a lot of comments. EasyGA: - Code cleanup. Population: - Added sort_by_best_fitness - Added parent/mating pool methods. - Renamed some methods for consistency. Chromosome: - Added get_gene(index). Parent Selection: - Improved selection methods to use the ga.selection_probability so that the roulette selection actually works well. - Added stochastic selection. Survivor Selection: - Added fill_in_random and fill_in_parents_then_random. Crossover/Mutation: - Cleaned up code.
This commit is contained in:
@ -10,11 +10,11 @@ from fitness_function import Fitness_Examples
|
|||||||
from initialization import Initialization_Methods
|
from initialization import Initialization_Methods
|
||||||
from termination_point import Termination_Methods
|
from termination_point import Termination_Methods
|
||||||
|
|
||||||
# Population Methods
|
# Parent/Survivor Selection Methods
|
||||||
from survivor_selection import Survivor_Selection
|
|
||||||
from parent_selection import Parent_Selection
|
from parent_selection import Parent_Selection
|
||||||
|
from survivor_selection import Survivor_Selection
|
||||||
|
|
||||||
# Manipulation Methods
|
# Genetic Operator Methods
|
||||||
from mutation import Mutation_Methods
|
from mutation import Mutation_Methods
|
||||||
from crossover import Crossover_Methods
|
from crossover import Crossover_Methods
|
||||||
|
|
||||||
@ -23,25 +23,24 @@ class GA:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Initialize the GA."""
|
"""Initialize the GA."""
|
||||||
# Initilization variables
|
# Initilization variables
|
||||||
self.chromosome_length = 10
|
self.chromosome_length = 10
|
||||||
self.population_size = 10
|
self.population_size = 10
|
||||||
self.chromosome_impl = None
|
self.chromosome_impl = None
|
||||||
self.gene_impl = [random.randint,1,10]
|
self.gene_impl = [random.randint,1,10]
|
||||||
self.population = None
|
self.population = None
|
||||||
self.target_fitness_type = 'maximum'
|
self.target_fitness_type = 'maximum'
|
||||||
self.update_fitness = True
|
self.update_fitness = True
|
||||||
|
|
||||||
# Selection variables
|
# Selection variables
|
||||||
self.parent_ratio = 0.1
|
self.parent_ratio = 0.1
|
||||||
self.selection_probability = 0.95
|
self.selection_probability = 0.95
|
||||||
self.tournament_size_ratio = 0.1
|
self.tournament_size_ratio = 0.1
|
||||||
|
|
||||||
# Termination variables
|
# Termination variables
|
||||||
self.current_generation = 0
|
self.current_generation = 0
|
||||||
self.current_fitness = 0
|
self.current_fitness = 0
|
||||||
|
self.generation_goal = 15
|
||||||
self.generation_goal = 15
|
self.fitness_goal = 9
|
||||||
self.fitness_goal = 9
|
|
||||||
|
|
||||||
# Mutation variables
|
# Mutation variables
|
||||||
self.mutation_rate = 0.10
|
self.mutation_rate = 0.10
|
||||||
@ -53,13 +52,11 @@ class GA:
|
|||||||
self.make_chromosome = create_chromosome
|
self.make_chromosome = create_chromosome
|
||||||
self.make_gene = create_gene
|
self.make_gene = create_gene
|
||||||
|
|
||||||
# Selects which chromosomes should be automaticly moved to the next population
|
# Methods for accomplishing Parent-Selection -> Crossover -> Survivor_Selection -> Mutation
|
||||||
self.survivor_selection_impl = Survivor_Selection.fill_in_best
|
|
||||||
|
|
||||||
# Methods for accomplishing parent-selection -> Crossover -> Mutation
|
|
||||||
self.parent_selection_impl = Parent_Selection.Tournament.with_replacement
|
self.parent_selection_impl = Parent_Selection.Tournament.with_replacement
|
||||||
self.crossover_individual_impl = Crossover_Methods.Individual.single_point_crossover
|
self.crossover_individual_impl = Crossover_Methods.Individual.single_point_crossover
|
||||||
self.crossover_population_impl = Crossover_Methods.Population.random_selection
|
self.crossover_population_impl = Crossover_Methods.Population.random_selection
|
||||||
|
self.survivor_selection_impl = Survivor_Selection.fill_in_best
|
||||||
self.mutation_individual_impl = Mutation_Methods.Individual.single_gene
|
self.mutation_individual_impl = Mutation_Methods.Individual.single_gene
|
||||||
self.mutation_population_impl = Mutation_Methods.Population.random_selection
|
self.mutation_population_impl = Mutation_Methods.Population.random_selection
|
||||||
|
|
||||||
@ -69,57 +66,63 @@ class GA:
|
|||||||
|
|
||||||
def evolve_generation(self, number_of_generations = 1, consider_termination = True):
|
def evolve_generation(self, number_of_generations = 1, consider_termination = True):
|
||||||
"""Evolves the ga the specified number of generations."""
|
"""Evolves the ga the specified number of generations."""
|
||||||
while(number_of_generations > 0 and (consider_termination == False or self.termination_impl(self))):
|
|
||||||
|
# Evolve the specified number of generations
|
||||||
|
# and if consider_termination flag is set then
|
||||||
|
# also check if termination conditions reached
|
||||||
|
while(number_of_generations > 0 and (not consider_termination or self.termination_impl(self))):
|
||||||
|
|
||||||
# If its the first generation then initialize the population
|
# If its the first generation then initialize the population
|
||||||
if self.current_generation == 0:
|
if self.current_generation == 0:
|
||||||
self.initialize_population()
|
self.initialize_population()
|
||||||
self.set_all_fitness(self.population.chromosome_list)
|
self.set_all_fitness()
|
||||||
self.population.set_all_chromosomes(self.sort_by_best_fitness(self.population.get_all_chromosomes()))
|
self.population.sort_by_best_fitness(self)
|
||||||
|
|
||||||
|
# Otherwise evolve the population
|
||||||
else:
|
else:
|
||||||
self.set_all_fitness(self.population.chromosome_list)
|
self.population.reset_mating_pool()
|
||||||
|
self.set_all_fitness()
|
||||||
|
self.population.set_all_chromosomes(self.sort_by_best_fitness(self.population.get_all_chromosomes()))
|
||||||
self.parent_selection_impl(self)
|
self.parent_selection_impl(self)
|
||||||
next_population = self.crossover_population_impl(self)
|
next_population = self.crossover_population_impl(self)
|
||||||
next_population = self.survivor_selection_impl(self, next_population)
|
self.survivor_selection_impl(self, next_population)
|
||||||
self.population = next_population
|
|
||||||
self.mutation_population_impl(self)
|
self.mutation_population_impl(self)
|
||||||
self.set_all_fitness(self.population.chromosome_list)
|
|
||||||
self.population.set_all_chromosomes(self.sort_by_best_fitness(self.population.get_all_chromosomes()))
|
|
||||||
|
|
||||||
number_of_generations -= 1
|
number_of_generations -= 1
|
||||||
|
|
||||||
self.current_generation += 1
|
self.current_generation += 1
|
||||||
|
|
||||||
|
|
||||||
def evolve(self):
|
def evolve(self):
|
||||||
"""Runs the ga until the termination point has been satisfied."""
|
"""Runs the ga until the termination point has been satisfied."""
|
||||||
# While the termination point hasnt been reached keep running
|
|
||||||
while(self.active()):
|
while(self.active()):
|
||||||
self.evolve_generation()
|
self.evolve_generation()
|
||||||
|
|
||||||
|
|
||||||
def active(self):
|
def active(self):
|
||||||
"""Returns if the ga should terminate base on the termination implimented"""
|
"""Returns if the ga should terminate based on the termination implimented."""
|
||||||
# Send termination_impl the whole ga class
|
|
||||||
return self.termination_impl(self)
|
return self.termination_impl(self)
|
||||||
|
|
||||||
|
|
||||||
def initialize_population(self):
|
def initialize_population(self):
|
||||||
"""Initialize the population using the initialization
|
"""Initialize the population using
|
||||||
implimentation that is currently set
|
the initialization implimentation
|
||||||
|
that is currently set.
|
||||||
"""
|
"""
|
||||||
self.population = self.initialization_impl(self)
|
self.population = self.initialization_impl(self)
|
||||||
|
|
||||||
|
|
||||||
def set_all_fitness(self, chromosome_set):
|
def set_all_fitness(self):
|
||||||
"""Will get and set the fitness of each chromosome in the population.
|
"""Will get and set the fitness of each chromosome in the population.
|
||||||
If update_fitness is set then all fitness values are updated.
|
If update_fitness is set then all fitness values are updated.
|
||||||
Otherwise only fitness values set to None (i.e. uninitialized
|
Otherwise only fitness values set to None (i.e. uninitialized
|
||||||
fitness values) are updated."""
|
fitness values) are updated.
|
||||||
# Get each chromosome in the population
|
"""
|
||||||
|
|
||||||
for chromosome in chromosome_set:
|
# Check each chromosome
|
||||||
if(chromosome.fitness == None or self.update_fitness == True):
|
for chromosome in self.population.get_all_chromosomes():
|
||||||
# Set the chromosomes fitness using the fitness function
|
|
||||||
|
# Update fitness if needed or asked by the user
|
||||||
|
if(chromosome.get_fitness() is None or self.update_fitness):
|
||||||
chromosome.set_fitness(self.fitness_function_impl(chromosome))
|
chromosome.set_fitness(self.fitness_function_impl(chromosome))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,17 +6,22 @@ class Crossover_Methods:
|
|||||||
"""Methods for selecting chromosomes to crossover"""
|
"""Methods for selecting chromosomes to crossover"""
|
||||||
|
|
||||||
def sequential_selection(ga):
|
def sequential_selection(ga):
|
||||||
"""Select sequential pairs from the mating pool"""
|
"""Select sequential pairs from the mating pool.
|
||||||
|
Every parent is paired with the previous parent.
|
||||||
|
The first parent is paired with the last parent.
|
||||||
|
"""
|
||||||
|
|
||||||
mating_pool = ga.population.mating_pool
|
mating_pool = ga.population.get_mating_pool()
|
||||||
return ga.make_population([ga.crossover_individual_impl(ga, mating_pool[index], mating_pool[index+1]) for index in range(len(mating_pool)-1)])
|
return ga.make_population([ga.crossover_individual_impl(ga, mating_pool[index], mating_pool[index-1]) for index in range(len(mating_pool))])
|
||||||
|
|
||||||
|
|
||||||
def random_selection(ga):
|
def random_selection(ga):
|
||||||
"""Select random pairs from the mating pool"""
|
"""Select random pairs from the mating pool.
|
||||||
|
Every parent is paired with a random parent.
|
||||||
|
"""
|
||||||
|
|
||||||
mating_pool = ga.population.mating_pool
|
mating_pool = ga.population.get_mating_pool()
|
||||||
return ga.make_population([ga.crossover_individual_impl(ga, random.choice(mating_pool), random.choice(mating_pool)) for n in mating_pool])
|
return ga.make_population([ga.crossover_individual_impl(ga, parent, random.choice(mating_pool)) for parent in mating_pool])
|
||||||
|
|
||||||
|
|
||||||
class Individual:
|
class Individual:
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class Mutation_Methods:
|
|||||||
|
|
||||||
# Randomly apply mutations
|
# Randomly apply mutations
|
||||||
if random.uniform(0, 1) < ga.mutation_rate:
|
if random.uniform(0, 1) < ga.mutation_rate:
|
||||||
ga.population.set_chromosome(ga.mutation_individual_impl(ga, ga.population.get_all_chromosomes()[index]), index)
|
ga.population.set_chromosome(ga.mutation_individual_impl(ga, ga.population.get_chromosome(index)), index)
|
||||||
|
|
||||||
|
|
||||||
class Individual:
|
class Individual:
|
||||||
|
|||||||
@ -10,26 +10,40 @@ class Parent_Selection:
|
|||||||
The total number of parents selected is determined by parent_ratio, an attribute to the GA object.
|
The total number of parents selected is determined by parent_ratio, an attribute to the GA object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Error if can't select parents
|
||||||
|
if ga.selection_probability <= 0:
|
||||||
|
print("Selection probability must be greater than 0 to select parents.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Make sure the population is sorted by fitness
|
||||||
|
ga.population.sort_by_best_fitness(ga)
|
||||||
|
|
||||||
|
# Choose the tournament size.
|
||||||
|
# Use no less than 5 chromosomes per tournament.
|
||||||
tournament_size = int(ga.population.size()*ga.tournament_size_ratio)
|
tournament_size = int(ga.population.size()*ga.tournament_size_ratio)
|
||||||
if tournament_size < 5:
|
if tournament_size < 5:
|
||||||
tournament_size = 5
|
tournament_size = 5
|
||||||
# Probability used for determining if a chromosome should enter the mating pool.
|
|
||||||
selection_probability = ga.selection_probability
|
|
||||||
|
|
||||||
# Repeat tournaments until the mating pool is large enough.
|
# Repeat tournaments until the mating pool is large enough.
|
||||||
while (len(ga.population.mating_pool) < ga.population.size()*ga.parent_ratio):
|
while (len(ga.population.get_mating_pool()) < ga.population.size()*ga.parent_ratio):
|
||||||
|
|
||||||
# Generate a random tournament group and sort by fitness.
|
# Generate a random tournament group and sort by fitness.
|
||||||
tournament_group = ga.sort_by_best_fitness([random.choice(ga.population.get_all_chromosomes()) for n in range(tournament_size)])
|
tournament_group = sorted([random.randint(0, ga.population.size()-1) for n in range(tournament_size)])
|
||||||
|
|
||||||
# For each chromosome, add it to the mating pool based on its rank in the tournament.
|
# For each chromosome, add it to the mating pool based on its rank in the tournament.
|
||||||
for index in range(tournament_size):
|
for index in range(tournament_size):
|
||||||
# Probability required is selection_probability * (1-selection_probability) ^ (tournament_size-index+1)
|
|
||||||
|
# Probability required is selection_probability * (1-selection_probability) ^ index
|
||||||
# e.g. top ranked fitness has probability: selection_probability
|
# e.g. top ranked fitness has probability: selection_probability
|
||||||
# second ranked fitness has probability: selection_probability * (1-selection_probability)
|
# second ranked fitness has probability: selection_probability * (1-selection_probability)
|
||||||
# third ranked fitness has probability: selection_probability * (1-selection_probability)^2
|
# third ranked fitness has probability: selection_probability * (1-selection_probability)^2
|
||||||
# etc.
|
# etc.
|
||||||
if random.uniform(0, 1) < selection_probability * pow(1-selection_probability, index):
|
if random.uniform(0, 1) < ga.selection_probability * pow(1-ga.selection_probability, index):
|
||||||
ga.population.mating_pool.append(tournament_group[index])
|
ga.population.set_parent(tournament_group[index])
|
||||||
|
|
||||||
|
# Stop if parent ratio reached
|
||||||
|
if len(ga.population.get_mating_pool()) >= ga.population.size()*ga.parent_ratio:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
class Roulette:
|
class Roulette:
|
||||||
@ -40,27 +54,74 @@ class Parent_Selection:
|
|||||||
that it will be selected. Using the example of a casino roulette wheel.
|
that it will be selected. Using the example of a casino roulette wheel.
|
||||||
Where the chromosomes are the numbers to be selected and the board size for
|
Where the chromosomes are the numbers to be selected and the board size for
|
||||||
those numbers are directly proportional to the chromosome's current fitness. Where
|
those numbers are directly proportional to the chromosome's current fitness. Where
|
||||||
the ball falls is a randomly generated number between 0 and 1"""
|
the ball falls is a randomly generated number between 0 and 1."""
|
||||||
|
|
||||||
|
# Make sure the population is sorted by fitness
|
||||||
|
ga.population.sort_by_best_fitness(ga)
|
||||||
|
|
||||||
|
# Error if can't select parents
|
||||||
|
if ga.selection_probability <= 0:
|
||||||
|
print("Selection probability must be greater than 0 to select parents.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Error if not all chromosomes has positive fitness
|
||||||
|
if (ga.population.get_chromosome(0).get_fitness() == 0 or ga.population.get_chromosome(-1).get_fitness() < 0):
|
||||||
|
print("Error using roulette selection, all fitnesses must be positive.")
|
||||||
|
print("Consider using stockastic roulette selection or tournament selection.")
|
||||||
|
return
|
||||||
|
|
||||||
# The sum of all the fitnessess in a population
|
# The sum of all the fitnessess in a population
|
||||||
total_fitness = sum(ga.population.chromosome_list[i].get_fitness() for i in range(len(ga.population.chromosome_list)))
|
fitness_sum = sum(chromosome.get_fitness() for chromosome in ga.population.get_all_chromosomes())
|
||||||
rel_fitnesses = []
|
|
||||||
|
|
||||||
# A list of each chromosome's relative chance of getting chosen
|
|
||||||
for chromosome in ga.population.chromosome_list:
|
|
||||||
if (total_fitness != 0):
|
|
||||||
rel_fitnesses.append(float(chromosome.fitness)/total_fitness)
|
|
||||||
|
|
||||||
# A list of ranges that represent the probability of a chromosome getting chosen
|
# A list of ranges that represent the probability of a chromosome getting chosen
|
||||||
probability = [sum(rel_fitnesses[:i+1]) for i in range(len(rel_fitnesses))]
|
probability = [ga.selection_probability]
|
||||||
|
|
||||||
|
# The chance of being selected increases incrementally
|
||||||
|
for chromosome in ga.population.chromosome_list:
|
||||||
|
probability.append(probability[-1]+chromosome.fitness/fitness_sum)
|
||||||
|
|
||||||
|
probability = probability[1:]
|
||||||
|
|
||||||
# Loops until it reaches a desired mating pool size
|
# Loops until it reaches a desired mating pool size
|
||||||
while (len(ga.population.mating_pool) < len(ga.population.get_all_chromosomes())*ga.parent_ratio):
|
while (len(ga.population.get_mating_pool()) < ga.population.size()*ga.parent_ratio):
|
||||||
|
|
||||||
|
# Spin the roulette
|
||||||
rand_number = random.random()
|
rand_number = random.random()
|
||||||
|
|
||||||
# Loop through the list of probabilities
|
# Find where the roulette landed.
|
||||||
for i in range(len(probability)):
|
for index in range(len(probability)):
|
||||||
# If the probability is greater than the random_number, then select that chromosome
|
if (probability[index] >= rand_number):
|
||||||
if (probability[i] >= rand_number):
|
ga.population.set_parent(index)
|
||||||
ga.population.mating_pool.append(ga.population.chromosome_list[i])
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def stochastic_selection(ga):
|
||||||
|
"""Stochastic roulette selection works based off of how strong the fitness is of the
|
||||||
|
chromosomes in the population. The stronger the fitness the higher the probability
|
||||||
|
that it will be selected. Instead of dividing the fitness by the sum of all fitnesses
|
||||||
|
and incrementally increasing the chance something is selected, the stochastic method
|
||||||
|
just divides by the highest fitness and selects randomly."""
|
||||||
|
|
||||||
|
# Make sure the population is sorted by fitness
|
||||||
|
ga.population.sort_by_best_fitness(ga)
|
||||||
|
|
||||||
|
# Error if can't select parents
|
||||||
|
if ga.selection_probability <= 0 or ga.selection_probability >= 1:
|
||||||
|
print("Selection probability must be between 0 and 1 to select parents.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Error if the highest fitness is not positive
|
||||||
|
if ga.population.get_chromosome(0).get_fitness() <= 0:
|
||||||
|
print("Error using stochastic roulette selection, best fitness must be positive.")
|
||||||
|
print("Consider using tournament selection.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Loops until it reaches a desired mating pool size
|
||||||
|
while (len(ga.population.get_mating_pool()) < ga.population.size()*ga.parent_ratio):
|
||||||
|
|
||||||
|
# Selected chromosome
|
||||||
|
index = random.randint(0, ga.population.size()-1)
|
||||||
|
|
||||||
|
# Probability of becoming a parent is fitness/max_fitness
|
||||||
|
if random.uniform(ga.selection_probability, 1) < ga.population.get_chromosome(index).get_fitness() / ga.population.get_chromosome(0).get_fitness():
|
||||||
|
ga.population.set_parent(index)
|
||||||
|
|||||||
@ -3,8 +3,15 @@ import EasyGA
|
|||||||
|
|
||||||
# Create the Genetic algorithm
|
# Create the Genetic algorithm
|
||||||
ga = EasyGA.GA()
|
ga = EasyGA.GA()
|
||||||
|
ga.population_size = 100
|
||||||
|
ga.generation_goal = 200
|
||||||
|
ga.parent_selection_impl = EasyGA.Parent_Selection.Roulette.stochastic_selection
|
||||||
|
ga.crossover_population_impl = EasyGA.Crossover_Methods.Population.sequential_selection
|
||||||
|
ga.survivor_selection_impl = EasyGA.Survivor_Selection.fill_in_parents_then_random
|
||||||
|
|
||||||
ga.evolve()
|
ga.evolve()
|
||||||
|
ga.set_all_fitness()
|
||||||
|
ga.population.set_all_chromosomes(ga.sort_by_best_fitness(ga.population.get_all_chromosomes()))
|
||||||
|
|
||||||
print(f"Current Generation: {ga.current_generation}")
|
print(f"Current Generation: {ga.current_generation}")
|
||||||
ga.population.print_all()
|
ga.population.print_all()
|
||||||
|
|||||||
@ -24,9 +24,15 @@ class Chromosome:
|
|||||||
|
|
||||||
|
|
||||||
def remove_gene(self, index):
|
def remove_gene(self, index):
|
||||||
|
"""Removes the gene at the given index"""
|
||||||
del self.gene_list[index]
|
del self.gene_list[index]
|
||||||
|
|
||||||
|
|
||||||
|
def get_gene(self, index):
|
||||||
|
"""Returns the gene at the given index"""
|
||||||
|
return gene_list[index]
|
||||||
|
|
||||||
|
|
||||||
def get_gene_list(self):
|
def get_gene_list(self):
|
||||||
return self.gene_list
|
return self.gene_list
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,11 @@ class Population:
|
|||||||
self.mating_pool = []
|
self.mating_pool = []
|
||||||
|
|
||||||
|
|
||||||
|
def sort_by_best_fitness(self, ga):
|
||||||
|
"""Sorts the population by fitness"""
|
||||||
|
self.set_all_chromosomes(ga.sort_by_best_fitness(self.chromosome_list))
|
||||||
|
|
||||||
|
|
||||||
def size(self):
|
def size(self):
|
||||||
"""Returns the size of the population"""
|
"""Returns the size of the population"""
|
||||||
return len(self.chromosome_list)
|
return len(self.chromosome_list)
|
||||||
@ -29,28 +34,68 @@ class Population:
|
|||||||
self.chromosome_list.insert(index, chromosome)
|
self.chromosome_list.insert(index, chromosome)
|
||||||
|
|
||||||
|
|
||||||
|
def add_parent(self, chromosome):
|
||||||
|
"""Adds a chromosome to the mating pool"""
|
||||||
|
self.mating_pool.append(chromosome)
|
||||||
|
|
||||||
|
|
||||||
def remove_chromosome(self, index):
|
def remove_chromosome(self, index):
|
||||||
"""removes a chromosome from the indicated index"""
|
"""Removes a chromosome from the indicated index from the population"""
|
||||||
del self.chromosome_list[index]
|
del self.chromosome_list[index]
|
||||||
|
|
||||||
|
|
||||||
|
def remove_parent(self, index):
|
||||||
|
"""Removes a parent from the indicated index from the mating pool"""
|
||||||
|
del self.mating_pool[index]
|
||||||
|
|
||||||
|
|
||||||
|
def reset_mating_pool(self):
|
||||||
|
"""Clears the mating pool"""
|
||||||
|
self.mating_pool = []
|
||||||
|
|
||||||
|
|
||||||
|
def get_chromosome(self, index):
|
||||||
|
"""Returns the chromosome at the given index in the population"""
|
||||||
|
return self.chromosome_list[index]
|
||||||
|
|
||||||
|
|
||||||
|
def get_parent(self, index):
|
||||||
|
"""Returns the parent at the given index in the mating pool"""
|
||||||
|
return self.mating_pool[index]
|
||||||
|
|
||||||
|
|
||||||
def get_all_chromosomes(self):
|
def get_all_chromosomes(self):
|
||||||
"""returns all chromosomes in the population"""
|
"""Returns all chromosomes in the population"""
|
||||||
return self.chromosome_list
|
return self.chromosome_list
|
||||||
|
|
||||||
|
|
||||||
|
def get_mating_pool(self):
|
||||||
|
"""Returns chromosomes in the mating pool"""
|
||||||
|
return self.mating_pool
|
||||||
|
|
||||||
|
|
||||||
def get_fitness(self):
|
def get_fitness(self):
|
||||||
"""returns the population's fitness"""
|
"""Returns the population's fitness"""
|
||||||
return self.fitness
|
return self.fitness
|
||||||
|
|
||||||
|
|
||||||
def set_all_chromosomes(self, chromosomes):
|
def set_parent(self, index):
|
||||||
self.chromosome_list = chromosomes
|
"""Sets the index chromosome from the population as a parent"""
|
||||||
|
self.add_parent(self.get_chromosome(index))
|
||||||
|
|
||||||
|
|
||||||
def set_chromosome(self, chromosome, index = -1):
|
def set_all_chromosomes(self, chromosome_list):
|
||||||
if index == -1:
|
"""Sets the chromosome list"""
|
||||||
index = len(self.chromosomes)-1
|
self.chromosome_list = chromosome_list
|
||||||
|
|
||||||
|
|
||||||
|
def set_mating_pool(self, chromosome_list):
|
||||||
|
"""Sets entire mating pool"""
|
||||||
|
self.mating_pool = chromosome_list
|
||||||
|
|
||||||
|
|
||||||
|
def set_chromosome(self, chromosome, index):
|
||||||
|
"""Sets the chromosome at the given index"""
|
||||||
self.chromosome_list[index] = chromosome
|
self.chromosome_list[index] = chromosome
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -4,5 +4,24 @@ class Survivor_Selection:
|
|||||||
"""Survivor selection determines which individuals should be brought to the next generation"""
|
"""Survivor selection determines which individuals should be brought to the next generation"""
|
||||||
|
|
||||||
def fill_in_best(ga, next_population):
|
def fill_in_best(ga, next_population):
|
||||||
"""Fills in the next population with the best chromosomes from the last population until the population size is met."""
|
"""Fills in the next population with the best chromosomes from the last population"""
|
||||||
return ga.make_population(ga.population.get_all_chromosomes()[:ga.population.size()-next_population.size()] + next_population.get_all_chromosomes())
|
|
||||||
|
ga.population.set_all_chromosomes(ga.population.get_all_chromosomes()[:ga.population.size()-next_population.size()] + next_population.get_all_chromosomes())
|
||||||
|
|
||||||
|
|
||||||
|
def fill_in_random(ga, next_population):
|
||||||
|
"""Fills in the next population with random chromosomes from the last population"""
|
||||||
|
|
||||||
|
ga.population.set_all_chromosomes([
|
||||||
|
random.choice(ga.population.get_all_chromosomes())
|
||||||
|
for n in range(ga.population.size()-next_population.size())]
|
||||||
|
+ next_population.get_all_chromosomes())
|
||||||
|
|
||||||
|
|
||||||
|
def fill_in_parents_then_random(ga, next_population):
|
||||||
|
"""Fills in the next population with all parents followed by random chromosomes from the last population"""
|
||||||
|
|
||||||
|
ga.population.set_all_chromosomes([
|
||||||
|
random.choice(ga.population.get_all_chromosomes())
|
||||||
|
for n in range(ga.population.size()-len(ga.population.get_mating_pool())-next_population.size())]
|
||||||
|
+ ga.population.get_mating_pool() + next_population.get_all_chromosomes())
|
||||||
|
|||||||
Reference in New Issue
Block a user