Updated selection implementation, added with/without replacement variation

This commit is contained in:
RyleyGG
2020-10-04 15:54:38 -04:00
parent 89df506469
commit c18a531034
4 changed files with 101 additions and 50 deletions

View File

@ -23,10 +23,10 @@ class GA:
# Termination varibles
self.current_generation = 0
self.current_fitness = 0
self.generation_goal = 35
self.generation_goal = 50
self.fitness_goal = 3
# Mutation variables
self.mutation_rate = 0.075
self.mutation_rate = 0.05
# Rerun already computed fitness
self.update_fitness = True
@ -35,7 +35,7 @@ class GA:
self.initialization_impl = Initialization_Types().random_initialization
self.fitness_function_impl = Fitness_Examples().is_it_5
self.mutation_impl = Mutation_Types().random_mutation
self.selection_impl = Selection_Types().tournament_selection
self.selection_impl = Selection_Types().Tournament().with_replacement
self.crossover_impl = Crossover_Types().single_point_crossover
self.termination_impl = Termination_Types().generation_based

View File

@ -25,9 +25,10 @@ class Crossover_Types:
new_gene_set = []
parent_one = crossover_pool[i].get_genes()
parent_two = crossover_pool[i+1].get_genes()
halfway_point = int(ga.chromosome_length/2)
new_gene_set.extend(parent_one[0:halfway_point])
new_gene_set.extend(parent_two[halfway_point:])
#halfway_point = int(ga.chromosome_length/2)
split_point = random.randint(0,ga.chromosome_length)
new_gene_set.extend(parent_one[0:split_point])
new_gene_set.extend(parent_two[split_point:])
new_chromosome = Chromosome(new_gene_set)
new_population.add_chromosome(new_chromosome)

View File

@ -5,9 +5,9 @@ import random
# Create the Genetic algorithm
ga = EasyGA.GA()
ga.gene_impl = [random.randrange,1,10]
ga.gene_impl = [random.randrange,1,25]
# Run Everyhting
# Run Everything
ga.evolve()
# Print the current population

View File

@ -9,22 +9,69 @@ class Selection_Types:
def __init__(self):
pass
def tournament_selection(self, ga):
"""This example currently uses a 'with replacement' approach (chromosomes are placed back into the pool after participating)"""
class Tournament:
def with_replacement(self, ga):
tournament_size = int(len(ga.population.get_all_chromosomes())/10) #currently hard-coded for purposes of the example.
if tournament_size < 3:
tournament_size = int(len(ga.population.get_all_chromosomes())/3)
#selection_probability is the likelihood that a chromosome will be selected.
#best chromosome in a tournament is given a selection probablity of selection_probability
#2nd best is given probability of selection_probability*(1-selection_probability)
#3rd best is given probability of selection_probability*(1-selection_probability)**2
selection_probability = 0.95
total_selected = 0 #Total Chromosomes selected
while (total_selected <= ga.population_size*2):
#create & gather tournament group
tournament_group = []
for i in range(tournament_size):
tournament_group.append(random.choice(ga.population.get_all_chromosomes()))
total_selected = self.selection(tournament_group, tournament_size, total_selected, selection_probability)[0]
new_population = self.create_new_population(ga)
return new_population
def without_replacement(self, ga):
tournament_size = int(len(ga.population.get_all_chromosomes())/10) #currently hard-coded for purposes of the example.
if tournament_size < 3:
tournament_size = int(len(ga.population.get_all_chromosomes())/3)
#selection_probability is the likelihood that a chromosome will be selected.
#best chromosome in a tournament is given a selection probablity of selection_probability
#2nd best is given probability of selection_probability*(1-selection_probability)
#3rd best is given probability of selection_probability*(1-selection_probability)**2
selection_probability = 0.95
total_selected = 0 #Total Chromosomes selected
available_chromosome_indices = []
for i in range(len(ga.population.get_all_chromosomes())):
available_chromosome_indices.append(i)
continue_selecting = True
while (continue_selecting):
#create & gather tournament group
tournament_group = []
for i in range(tournament_size):
selected_chromosome_index = random.choice(available_chromosome_indices)
tournament_group.append(ga.population.get_all_chromosomes()[selected_chromosome_index])
winning_chromosome_index = self.selection(tournament_group, tournament_size, total_selected, selection_probability)[1]
for i in range(len(available_chromosome_indices)):
if tournament_group[winning_chromosome_index].selected:
del available_chromosome_indices[i]
break
#print(winning_chromosome_index)
#print(available_chromosome_indices)
if len(available_chromosome_indices) < 1:
continue_selecting = False
new_population = self.create_new_population(ga)
return new_population
def selection(self, tournament_group, tournament_size, total_selected, selection_probability):
#Sort the tournament contenders based on their fitness
#currently hard-coded to only consider higher fitness = better; can be changed once this impl is agreed on
#also currently uses bubble sort because its easy
@ -43,6 +90,7 @@ class Selection_Types:
tournament_group = tournament_group_temp
#After sorting by fitness, randomly select a chromosome based on selection_probability
selected_chromosome_tournament_index = 0
for i in range(tournament_size):
random_num = random.uniform(0,1)
@ -51,14 +99,18 @@ class Selection_Types:
if random_num <= selection_probability:
tournament_group[i].selected = True
total_selected += 1
selected_chromosome_tournament_index = i
break
else:
if random_num <= selection_probability*((1-selection_probability)**(i-1)):
tournament_group[i].selected = True
total_selected += 1
selected_chromosome_tournament_index = i
break
return total_selected,selected_chromosome_tournament_index
def create_new_population(self, ga):
new_population = ga.crossover_impl(ga)
#If the crossover doesn't create enough chromosomes (ugly right now pls no judgerino, can be changed)
@ -91,8 +143,6 @@ class Selection_Types:
return new_population
def roulette_selection(self, ga):
"""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