Implemented basic functionality for using different target fitness types

This commit is contained in:
SimpleArt
2020-10-21 14:11:43 -04:00
parent 9101072f26
commit 8e2698fc0d
5 changed files with 45 additions and 17 deletions

View File

@ -80,4 +80,26 @@ class GA(attributes):
return sorted(chromosome_set, # list to be sorted return sorted(chromosome_set, # list to be sorted
key = lambda chromosome: chromosome.get_fitness(), # by fitness key = lambda chromosome: chromosome.get_fitness(), # by fitness
reverse = True) # from highest to lowest fitness reverse = (self.target_fitness_type == 'max')) # from highest to lowest fitness
def get_chromosome_fitness(self, index):
"""Returns the fitness value of the chromosome
at the specified index after conversion based
on the target fitness type.
"""
return self.convert_fitness(
self.population.get_chromosome(index).get_fitness()
)
def convert_fitness(self, fitness_value):
"""Returns the fitness value if the type of problem
is a maximization problem. Otherwise the fitness is
inverted using max - value + min.
"""
if self.target_fitness_type == 'max': return fitness_value
max_fitness = self.population.get_chromosome(-1).get_fitness()
min_fitness = self.population.get_chromosome(0).get_fitness()
return max_fitness - fitness_value + min_fitness

View File

@ -28,7 +28,7 @@ class attributes:
self.chromosome_impl = None self.chromosome_impl = None
self.gene_impl = lambda: random.randint(1, 10) self.gene_impl = lambda: random.randint(1, 10)
self.population = None self.population = None
self.target_fitness_type = 'maximum' self.target_fitness_type = 'max'
self.update_fitness = True self.update_fitness = True
# Selection variables # Selection variables

View File

@ -66,20 +66,20 @@ class Parent_Selection:
return return
# Error if not all chromosomes has positive fitness # 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): if (ga.get_chromosome_fitness(0) == 0 or ga.get_chromosome_fitness(-1) < 0):
print("Error using roulette selection, all fitnesses must be positive.") print("Error using roulette selection, all fitnesses must be positive.")
print("Consider using stockastic roulette selection or tournament selection.") print("Consider using stockastic roulette selection or tournament selection.")
return return
# The sum of all the fitnessess in a population # The sum of all the fitnessess in a population
fitness_sum = sum(chromosome.get_fitness() for chromosome in ga.population.get_all_chromosomes()) fitness_sum = sum(ga.get_chromosome_fitness(index) for index in range(ga.population.size()))
# 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 = [ga.selection_probability] probability = [ga.selection_probability]
# The chance of being selected increases incrementally # The chance of being selected increases incrementally
for chromosome in ga.population.chromosome_list: for index in range(ga.population.size()):
probability.append(probability[-1]+chromosome.fitness/fitness_sum) probability.append(probability[-1]+ga.get_chromosome_fitness(index)/fitness_sum)
probability = probability[1:] probability = probability[1:]
@ -111,7 +111,7 @@ class Parent_Selection:
print("Selection probability must be between 0 and 1 to select parents.") print("Selection probability must be between 0 and 1 to select parents.")
return return
max_fitness = ga.population.get_chromosome(0).get_fitness() max_fitness = ga.get_chromosome_fitness(0)
# Error if the highest fitness is not positive # Error if the highest fitness is not positive
if max_fitness <= 0: if max_fitness <= 0:
@ -126,5 +126,5 @@ class Parent_Selection:
index = random.randint(0, ga.population.size()-1) index = random.randint(0, ga.population.size()-1)
# Probability of becoming a parent is fitness/max_fitness # Probability of becoming a parent is fitness/max_fitness
if random.uniform(ga.selection_probability, 1) < ga.population.get_chromosome(index).get_fitness()/max_fitness: if random.uniform(ga.selection_probability, 1) < ga.get_chromosome_fitness(index)/max_fitness:
ga.population.set_parent(index) ga.population.set_parent(index)

View File

@ -3,10 +3,22 @@ import EasyGA
# Create the Genetic algorithm # Create the Genetic algorithm
ga = EasyGA.GA() ga = EasyGA.GA()
ga.target_fitness_type = 'min'
ga.chromosome_length = 10
ga.population_size = 25
ga.generation_goal = 50
ga.gene_impl = lambda: random.randint(0, 10)
ga.chromosome_length = 100 def fitness_function(chromosome):
return sum(
gene.get_value()
for gene in chromosome.get_gene_list())
ga.fitness_function_impl = fitness_function
ga.evolve() ga.evolve()
ga.set_all_fitness()
ga.population.sort_by_best_fitness(ga)
print(f"Current Generation: {ga.current_generation}") print(f"Current Generation: {ga.current_generation}")
ga.population.print_all() ga.population.print_all()

View File

@ -27,16 +27,10 @@ class Survivor_Selection:
def fill_in_parents_then_random(ga): def fill_in_parents_then_random(ga):
"""Fills in the next population with all parents followed by random chromosomes from the last population""" """Fills in the next population with all parents followed by random chromosomes from the last population"""
ga.population.append_children([ # add in chromosomes
random.choice( # randomly
ga.population.get_chromosome_list() # from the population
) # until the next population is full
for n in range(ga.population.size()-ga.population.total_children())])
ga.population.append_children( # add in chromosomes ga.population.append_children( # add in chromosomes
ga.population.get_mating_pool() # from the mating pool ga.population.get_mating_pool() # from the mating pool
) # ) #
ga.population.append_children([ # add in chromosomes ga.population.append_children([ # add in chromosomes
random.choice( # randomly random.choice( # randomly
ga.population.get_chromosome_list() # from the population ga.population.get_chromosome_list() # from the population