Added function decorators

This commit is contained in:
SimpleArt
2020-11-19 21:28:16 -05:00
parent 0bd08b94a9
commit 652e4a4b5b

View File

@ -2,8 +2,35 @@ import random
class Parent_Selection: class Parent_Selection:
def __check_selection_probability(selection_method):
def helper(ga):
if 0 < ga.selection_probability < 1:
selection_method(ga)
else:
raise Exception("Selection probability must be greater than 0 to select parents.")
return helper
def __check_positive_fitness(selection_method):
def helper(ga):
if ga.get_chromosome_fitness(0) == 0 or ga.get_chromosome_fitness(-1) < 0:
raise Exception("Converted fitness values must be all positive. Consider using rank selection instead.")
else:
selection_method(ga)
return helper
def __ensure_sorted(selection_method):
def helper(ga):
ga.population.sort_by_best_fitness(ga)
selection_method(ga)
return helper
class Rank: class Rank:
@Parent_Selection._Parent_Selection__check_selection_probability
@Parent_Selection._Parent_Selection__ensure_sorted
def tournament(ga): def tournament(ga):
""" """
Will make tournaments of size tournament_size and choose the winner (best fitness) Will make tournaments of size tournament_size and choose the winner (best fitness)
@ -11,14 +38,6 @@ class Parent_Selection:
of parents selected is determined by parent_ratio, an attribute to the GA object. of parents selected is determined by parent_ratio, an attribute to the GA object.
""" """
# Error if can't select parents
if ga.selection_probability <= 0:
print("Selection probability must be greater than 0 to select parents.")
return
# Make sure the population is sorted by fitness
ga.population.sort_by_best_fitness(ga)
# Choose the tournament size. # Choose the tournament size.
# Use no less than 5 chromosomes per tournament. # Use no less than 5 chromosomes per tournament.
tournament_size = int(len(ga.population)*ga.tournament_size_ratio) tournament_size = int(len(ga.population)*ga.tournament_size_ratio)
@ -49,6 +68,9 @@ class Parent_Selection:
class Fitness: class Fitness:
@Parent_Selection._Parent_Selection__check_selection_probability
@Parent_Selection._Parent_Selection__check_positive_fitness
@Parent_Selection._Parent_Selection__ensure_sorted
def roulette(ga): def roulette(ga):
"""Roulette selection works based off of how strong the fitness is of the """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 chromosomes in the population. The stronger the fitness the higher the probability
@ -58,20 +80,6 @@ class Parent_Selection:
the ball falls is a randomly generated number between 0 and 1. the ball falls is a randomly generated number between 0 and 1.
""" """
# Make sure the population is sorted by fitness
ga.population.sort_by_best_fitness(ga)
# Error if can't select parents
if ga.selection_probability <= 0:
print("Selection probability must be greater than 0 to select parents.")
return
# Error if not all chromosomes has positive fitness
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("Consider using stockastic roulette selection or tournament selection.")
return
# The sum of all the fitnessess in a population # The sum of all the fitnessess in a population
fitness_sum = sum(ga.get_chromosome_fitness(index) for index in range(len(ga.population))) fitness_sum = sum(ga.get_chromosome_fitness(index) for index in range(len(ga.population)))
@ -97,6 +105,9 @@ class Parent_Selection:
break break
@Parent_Selection._Parent_Selection__check_selection_probability
@Parent_Selection._Parent_Selection__check_positive_fitness
@Parent_Selection._Parent_Selection__ensure_sorted
def stochastic(ga): def stochastic(ga):
"""Stochastic roulette selection works based off of how strong the fitness is of the """Stochastic 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 chromosomes in the population. The stronger the fitness the higher the probability
@ -104,22 +115,8 @@ class Parent_Selection:
and incrementally increasing the chance something is selected, the stochastic method and incrementally increasing the chance something is selected, the stochastic method
just divides by the highest fitness and selects randomly.""" just divides by the highest fitness and selects randomly."""
# Make sure the population is sorted by fitness
ga.population.sort_by_best_fitness(ga)
# Error if can't select parents
if ga.selection_probability <= 0 or ga.selection_probability >= 1:
print("Selection probability must be between 0 and 1 to select parents.")
return
max_fitness = ga.get_chromosome_fitness(0) max_fitness = ga.get_chromosome_fitness(0)
# Error if the highest fitness is not positive
if max_fitness <= 0:
print("Error using stochastic roulette selection, best fitness must be positive.")
print("Consider using tournament selection.")
return
# Loops until it reaches a desired mating pool size # Loops until it reaches a desired mating pool size
while (len(ga.population.get_mating_pool()) < len(ga.population)*ga.parent_ratio): while (len(ga.population.get_mating_pool()) < len(ga.population)*ga.parent_ratio):