Implemented basic functionality for using different target fitness types
This commit is contained in:
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user