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.
This commit is contained in:
@ -45,7 +45,7 @@ class GA:
|
||||
self.initialization_impl = Initialization_Methods.random_initialization
|
||||
self.fitness_function_impl = Fitness_Examples.index_dependent_values
|
||||
# Selects which chromosomes should be automaticly moved to the next population
|
||||
self.survivor_selection_impl = Survivor_Selection.remove_two_worst
|
||||
self.survivor_selection_impl = Survivor_Selection.remove_worst
|
||||
# Methods for accomplishing parent-selection -> Crossover -> Mutation
|
||||
self.parent_selection_impl = Parent_Selection.Tournament.with_replacement
|
||||
self.crossover_impl = Crossover_Methods.single_point_crossover
|
||||
|
||||
@ -3,19 +3,13 @@ from initialization.chromosome_structure.chromosome import Chromosome
|
||||
from initialization.population_structure.population import Population
|
||||
|
||||
class Crossover_Methods:
|
||||
""" Crossover explination goes here.
|
||||
|
||||
Points - Defined as sections between the chromosomes genetic makeup
|
||||
"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def single_point_crossover(ga):
|
||||
"""Single point crossover is when a "point" is selected and the genetic
|
||||
make up of the two parent chromosomes are "Crossed" or better known as swapped"""
|
||||
"""Single point crossover is when a "point" is selected and the genetic
|
||||
make up of the two parent chromosomes are swapped at that point"""
|
||||
|
||||
crossover_pool = ga.population.mating_pool
|
||||
|
||||
"""The structure of GA requires that the crossover method return a population strictly with offspring chromosomes"""
|
||||
new_population = Population()
|
||||
for i in range(len(crossover_pool)):
|
||||
if i + 1 < len(crossover_pool):
|
||||
|
||||
@ -16,11 +16,9 @@ class Fitness_Examples:
|
||||
return fitness
|
||||
|
||||
def index_dependent_values(chromosome):
|
||||
"""A very simple case test function - If the chromosomes gene value is a 5 add one
|
||||
to the chromosomes overall fitness value."""
|
||||
# Overall fitness value
|
||||
"""Test of the GA's ability to improve fitness when the value is index-dependent"""
|
||||
"""If a gene is equal to its index in the chromosome + 1, fitness is incremented"""
|
||||
fitness = 0
|
||||
# For each gene in the chromosome
|
||||
for i in range(len(chromosome.gene_list)):
|
||||
if (chromosome.gene_list[i].value == i+1):
|
||||
fitness += 1
|
||||
|
||||
@ -6,13 +6,16 @@ class Mutation_Methods:
|
||||
pass
|
||||
|
||||
def random_mutation(ga, chromosome_set = None):
|
||||
|
||||
"""Will take the input population and randomly reset entire chromosomes based on the GA's mutation rate"""
|
||||
|
||||
"""Defaulting to the GA's current population if no input is explicitly given"""
|
||||
if chromosome_set == None:
|
||||
chromosome_set = ga.population.get_all_chromosomes()
|
||||
|
||||
chromosome_mutate_num = int(len(chromosome_set)*ga.mutation_rate)
|
||||
temp_population = ga.initialization_impl(ga)
|
||||
|
||||
"""While more chromosomes need to be mutated, grab a random chromosome and re-initialize it entirely"""
|
||||
while chromosome_mutate_num > 0:
|
||||
chromosome_set[random.randint(0,ga.population_size-1)] = temp_population.get_all_chromosomes()[chromosome_mutate_num]
|
||||
chromosome_mutate_num -= 1
|
||||
@ -20,7 +23,8 @@ class Mutation_Methods:
|
||||
return chromosome_set
|
||||
|
||||
def per_gene_mutation(ga, chromosome_set = None, gene_mutate_count = 1):
|
||||
|
||||
"""Will iterate through all chromosomes, and if its selected, will randomly replace one of its genes based on initialization values"""
|
||||
|
||||
gene_mutate_count_static = int(gene_mutate_count)
|
||||
|
||||
if chromosome_set == None:
|
||||
@ -29,10 +33,12 @@ class Mutation_Methods:
|
||||
for i in range(len(chromosome_set)):
|
||||
random_num = random.uniform(0,1)
|
||||
|
||||
"""If a chromosome was selected to be mutated"""
|
||||
if (random_num <= ga.mutation_rate):
|
||||
while gene_mutate_count > 0:
|
||||
dummy_population = ga.initialization_impl(ga) #Really inefficient, but works for now
|
||||
random_index = random.randint(0, ga.chromosome_length-1)
|
||||
"""Replaces a random gene in the actual chromosome with a gene from a newly initialized chromosome"""
|
||||
chromosome_set[i].get_genes()[random_index] = dummy_population.get_all_chromosomes()[random.randint(0,ga.population_size-1)].get_genes()[random_index]
|
||||
gene_mutate_count -= 1
|
||||
gene_mutate_count = int(gene_mutate_count_static)
|
||||
|
||||
@ -7,7 +7,7 @@ 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.parent_ratio*ga.tournament_size_ratio)
|
||||
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.
|
||||
|
||||
@ -4,7 +4,7 @@ import random
|
||||
# Create the Genetic algorithm
|
||||
ga = EasyGA.GA()
|
||||
|
||||
ga.population_size = 15
|
||||
ga.population_size = 100
|
||||
ga.chromosome_length = 10
|
||||
ga.generation_goal = 100
|
||||
ga.gene_impl = [random.randint,1,10]
|
||||
|
||||
@ -5,32 +5,38 @@ from initialization.population_structure.population import Population
|
||||
from initialization.chromosome_structure.chromosome import Chromosome
|
||||
|
||||
class Survivor_Selection:
|
||||
def repeated_crossover(ga, next_population): #Might be cheating? I don't know honestly - RG
|
||||
while len(next_population.get_all_chromosomes()) < ga.population_size:
|
||||
crossover_pool = ga.population.mating_pool
|
||||
"""Survivor selection determines which individuals should be brought to the next generation"""
|
||||
|
||||
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 = create_chromosome(new_gene_set)
|
||||
chromosome_list.append(new_chromosome)
|
||||
|
||||
|
||||
for i in range(len(chromosome_list)):
|
||||
next_population.add_chromosome(chromosome_list[i])
|
||||
if len(next_population.get_all_chromosomes()) >= ga.population_size:
|
||||
break
|
||||
return next_population
|
||||
|
||||
def remove_two_worst(ga, next_population):
|
||||
iterator = 0
|
||||
while len(next_population.get_all_chromosomes()) < ga.population_size:
|
||||
next_population.add_chromosome(ga.population.get_all_chromosomes()[iterator])
|
||||
iterator += 1
|
||||
return next_population
|
||||
""" Pretty sure this isn't actually survivor selection - seems like its 'cheating'
|
||||
def repeated_crossover(ga, next_population):
|
||||
while len(next_population.get_all_chromosomes()) < ga.population_size:
|
||||
crossover_pool = ga.population.mating_pool
|
||||
|
||||
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 = create_chromosome(new_gene_set)
|
||||
chromosome_list.append(new_chromosome)
|
||||
|
||||
|
||||
for i in range(len(chromosome_list)):
|
||||
next_population.add_chromosome(chromosome_list[i])
|
||||
if len(next_population.get_all_chromosomes()) >= ga.population_size:
|
||||
break
|
||||
return next_population
|
||||
"""
|
||||
|
||||
"""Will bring all but the worst-performing chromosomes from the current generation"""
|
||||
"""The exact number of chromosomes removed depends on how many offspring were generated by parent selection"""
|
||||
def remove_worst(ga, next_population):
|
||||
iterator = 0
|
||||
while len(next_population.get_all_chromosomes()) < ga.population_size:
|
||||
next_population.add_chromosome(ga.population.get_all_chromosomes()[iterator])
|
||||
iterator += 1
|
||||
return next_population
|
||||
Reference in New Issue
Block a user