Files
EasyGA/src/parent_selection/parent_selection_methods.py
RyleyGG 94d7c52666 Added comments & fixed small bug
Mostly added comments, but also fixed a small bug in parent selection where the tournament size would be much smaller than it should be.
2020-10-12 09:23:41 -04:00

57 lines
3.5 KiB
Python

import random
from initialization.chromosome_structure.chromosome import Chromosome as create_chromosome
from initialization.gene_structure.gene import Gene as create_gene
from initialization.population_structure.population import Population
from initialization.chromosome_structure.chromosome import Chromosome
class Parent_Selection:
class Tournament:
def with_replacement(ga):
tournament_size = int(len(ga.population.get_all_chromosomes())*ga.tournament_size_ratio)
if 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.
while (len(ga.population.mating_pool) < len(ga.population.get_all_chromosomes())*ga.parent_ratio):
# 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)])
# For each chromosome, add it to the mating pool based on its rank in the tournament.
for index in range(tournament_size):
# Probability required is selection_probability * (1-selection_probability) ^ (tournament_size-index+1)
# e.g. top ranked fitness has probability: selection_probability
# second ranked fitness has probability: selection_probability * (1-selection_probability)
# third ranked fitness has probability: selection_probability * (1-selection_probability)^2
# etc.
if random.uniform(0, 1) < selection_probability * pow(1-selection_probability, index):
ga.population.mating_pool.append(tournament_group[index])
class Roulette:
def roulette_selection(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
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
those numbers are directly proportional to the chromosome's current fitness. Where
the ball falls is a randomly generated number between 0 and 1"""
total_fitness = sum(ga.population.chromosome_list[i].get_fitness() for i in range(len(ga.population.chromosome_list)))
rel_fitnesses = []
for chromosome in ga.population.chromosome_list:
if (total_fitness != 0):
rel_fitnesses.append(float(chromosome.fitness)/total_fitness)
probability = [sum(rel_fitnesses[:i+1]) for i in range(len(rel_fitnesses))]
while (len(ga.population.mating_pool) < len(ga.population.get_all_chromosomes())*ga.parent_ratio):
rand_number = random.random()
# Loop through the list of probabilities
for i in range(len(probability)):
# If the probability is greater than the random_number, then select that chromosome
if (probability[i] >= rand_number):
ga.population.mating_pool.append(ga.population.chromosome_list[i])
# print (f'Selected chromosome : {i}')
break