|
|
|
|
@ -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)"""
|
|
|
|
|
tournament_size = int(len(ga.population.get_all_chromosomes())/10) #currently hard-coded for purposes of the example.
|
|
|
|
|
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)
|
|
|
|
|
selection_probability = 0.95
|
|
|
|
|
total_selected = 0 #Total Chromosomes selected
|
|
|
|
|
#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()))
|
|
|
|
|
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,47 +99,49 @@ 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
|
|
|
|
|
|
|
|
|
|
new_population = ga.crossover_impl(ga)
|
|
|
|
|
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)
|
|
|
|
|
#Just does single-point crossover at random indices
|
|
|
|
|
while len(new_population.chromosomes) < ga.population_size:
|
|
|
|
|
crossover_pool = []
|
|
|
|
|
for i in range(ga.population_size):
|
|
|
|
|
if ga.population.get_all_chromosomes()[i].selected:
|
|
|
|
|
crossover_pool.append(ga.population.get_all_chromosomes()[i])
|
|
|
|
|
#If the crossover doesn't create enough chromosomes (ugly right now pls no judgerino, can be changed)
|
|
|
|
|
#Just does single-point crossover at random indices
|
|
|
|
|
while len(new_population.chromosomes) < ga.population_size:
|
|
|
|
|
crossover_pool = []
|
|
|
|
|
for i in range(ga.population_size):
|
|
|
|
|
if ga.population.get_all_chromosomes()[i].selected:
|
|
|
|
|
crossover_pool.append(ga.population.get_all_chromosomes()[i])
|
|
|
|
|
|
|
|
|
|
split_point = random.randint(0,ga.chromosome_length)
|
|
|
|
|
chromosome_list = []
|
|
|
|
|
for i in range(len(crossover_pool)):
|
|
|
|
|
if i + 1 < len(crossover_pool):
|
|
|
|
|
new_gene_set = []
|
|
|
|
|
parent_one = crossover_pool[i].get_genes()
|
|
|
|
|
parent_two = crossover_pool[i+1].get_genes()
|
|
|
|
|
new_gene_set.extend(parent_one[0:split_point])
|
|
|
|
|
new_gene_set.extend(parent_two[split_point:])
|
|
|
|
|
new_chromosome = Chromosome(new_gene_set)
|
|
|
|
|
chromosome_list.append(new_chromosome)
|
|
|
|
|
|
|
|
|
|
for i in range(len(chromosome_list)):
|
|
|
|
|
new_population.add_chromosome(chromosome_list[i])
|
|
|
|
|
if len(new_population.chromosomes) >= ga.population_size:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
new_chromosome_set = ga.mutation_impl(ga, new_population.get_all_chromosomes())
|
|
|
|
|
new_population.set_all_chromosomes(new_chromosome_set)
|
|
|
|
|
|
|
|
|
|
return new_population
|
|
|
|
|
split_point = random.randint(0,ga.chromosome_length)
|
|
|
|
|
chromosome_list = []
|
|
|
|
|
for i in range(len(crossover_pool)):
|
|
|
|
|
if i + 1 < len(crossover_pool):
|
|
|
|
|
new_gene_set = []
|
|
|
|
|
parent_one = crossover_pool[i].get_genes()
|
|
|
|
|
parent_two = crossover_pool[i+1].get_genes()
|
|
|
|
|
new_gene_set.extend(parent_one[0:split_point])
|
|
|
|
|
new_gene_set.extend(parent_two[split_point:])
|
|
|
|
|
new_chromosome = Chromosome(new_gene_set)
|
|
|
|
|
chromosome_list.append(new_chromosome)
|
|
|
|
|
|
|
|
|
|
for i in range(len(chromosome_list)):
|
|
|
|
|
new_population.add_chromosome(chromosome_list[i])
|
|
|
|
|
if len(new_population.chromosomes) >= ga.population_size:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
new_chromosome_set = ga.mutation_impl(ga, new_population.get_all_chromosomes())
|
|
|
|
|
new_population.set_all_chromosomes(new_chromosome_set)
|
|
|
|
|
|
|
|
|
|
return new_population
|
|
|
|
|
|
|
|
|
|
def roulette_selection(self, ga):
|
|
|
|
|
"""Roulette selection works based off of how strong the fitness is of the
|
|
|
|
|
|