Test Implementation for selection/crossover/mutation
The current test implementation includes random mutation, single point crossover, and tournament selection. The implementation, in short, is a nested approach. The selection method is the only thing actually called by the GA. Both crossover and mutation occur within the selection method. As long as these three systems all follow a standard input/output system, any implementation we build, as well as any user implementations, will work perfectly. The selection function must take GA as a parameter and output a new population. Crossover takes in GA and outputs a population. Mutation takes a chromosome set and outputs a new chromosome set. Many of the changes in this commit are regarding this test implementation. I have also changed many of the file names from "x_examples" to "x_types" and updated the class names to follow capitalziation standards. I did this because I feel personally like the built-in mutation, crossover, and selection implementations are less "examples" and more just already built implementations to make the code required from the user smaller.
This commit is contained in:
@ -1,3 +1,4 @@
|
|||||||
|
<<<<<<< Updated upstream
|
||||||
# Import all the data prebuilt modules
|
# Import all the data prebuilt modules
|
||||||
from initialization.population_structure.population import population as create_population
|
from initialization.population_structure.population import population as create_population
|
||||||
from initialization.chromosome_structure.chromosome import chromosome as create_chromosome
|
from initialization.chromosome_structure.chromosome import chromosome as create_chromosome
|
||||||
@ -107,6 +108,90 @@ class GA:
|
|||||||
# If you want to evolve through a number of generations
|
# If you want to evolve through a number of generations
|
||||||
# and be able to pause and output data based on that generation run.
|
# and be able to pause and output data based on that generation run.
|
||||||
pass
|
pass
|
||||||
|
=======
|
||||||
|
import random
|
||||||
|
# Import all the data structure prebuilt modules
|
||||||
|
from initialization import Population as create_population
|
||||||
|
from initialization import Chromosome as create_chromosome
|
||||||
|
from initialization import Gene as create_gene
|
||||||
|
# Import example classes
|
||||||
|
from fitness_function import Fitness_Examples
|
||||||
|
from initialization import Initialization_Types
|
||||||
|
from termination_point import Termination_Types
|
||||||
|
from selection import Selection_Types
|
||||||
|
from crossover import Crossover_Types
|
||||||
|
from mutation import Mutation_Types
|
||||||
|
|
||||||
|
class GA:
|
||||||
|
def __init__(self):
|
||||||
|
"""Initialize the GA."""
|
||||||
|
# Initilization variables
|
||||||
|
self.chromosome_length = 10
|
||||||
|
self.population_size = 100
|
||||||
|
self.chromosome_impl = None
|
||||||
|
self.gene_impl = None
|
||||||
|
self.population = None
|
||||||
|
# Termination varibles
|
||||||
|
self.current_generation = 0
|
||||||
|
self.current_fitness = 0
|
||||||
|
self.generation_goal = 35
|
||||||
|
self.fitness_goal = 3
|
||||||
|
# Mutation variables
|
||||||
|
self.mutation_rate = 0.075
|
||||||
|
|
||||||
|
# Rerun already computed fitness
|
||||||
|
self.update_fitness = True
|
||||||
|
|
||||||
|
# Defualt EastGA implimentation structure
|
||||||
|
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.crossover_impl = Crossover_Types().single_point_crossover
|
||||||
|
self.termination_impl = Termination_Types().generation_based
|
||||||
|
|
||||||
|
def initialize_population(self):
|
||||||
|
"""Initialize the population using the initialization
|
||||||
|
implimentation that is currently set"""
|
||||||
|
self.population = self.initialization_impl(self)
|
||||||
|
|
||||||
|
def set_all_fitness(self,chromosome_set):
|
||||||
|
"""Will get and set the fitness of each chromosome in the population.
|
||||||
|
If update_fitness is set then all fitness values are updated.
|
||||||
|
Otherwise only fitness values set to None (i.e. uninitialized
|
||||||
|
fitness values) are updated."""
|
||||||
|
# Get each chromosome in the population
|
||||||
|
|
||||||
|
for chromosome in chromosome_set:
|
||||||
|
if(chromosome.fitness == None or self.update_fitness == True):
|
||||||
|
# Set the chromosomes fitness using the fitness function
|
||||||
|
chromosome.set_fitness(self.fitness_function_impl(chromosome))
|
||||||
|
|
||||||
|
def evolve(self):
|
||||||
|
"""Runs the ga until the termination point has been satisfied."""
|
||||||
|
# While the termination point hasnt been reached keep running
|
||||||
|
while(self.active()):
|
||||||
|
self.evolve_generation()
|
||||||
|
|
||||||
|
def evolve_generation(self, number_of_generations = 1, consider_termination = True):
|
||||||
|
"""Evolves the ga the specified number of generations."""
|
||||||
|
while(number_of_generations > 0 and (consider_termination == False or self.termination_impl(self))):
|
||||||
|
# If its the first generation then initialize the population
|
||||||
|
if self.current_generation == 0:
|
||||||
|
self.initialize_population()
|
||||||
|
self.set_all_fitness(self.population.chromosomes)
|
||||||
|
|
||||||
|
next_population = self.selection_impl(self)
|
||||||
|
self.population = next_population
|
||||||
|
self.set_all_fitness(self.population.chromosomes)
|
||||||
|
|
||||||
|
number_of_generations -= 1
|
||||||
|
self.current_generation += 1
|
||||||
|
>>>>>>> Stashed changes
|
||||||
|
|
||||||
|
def active(self):
|
||||||
|
"""Returns if the ga should terminate base on the termination implimented"""
|
||||||
|
return self.termination_impl(self)
|
||||||
|
|
||||||
def make_gene(self,value):
|
def make_gene(self,value):
|
||||||
return create_gene(value)
|
return create_gene(value)
|
||||||
|
|||||||
2
src/crossover/__init__.py
Normal file
2
src/crossover/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# FROM (. means local) file_name IMPORT function_name
|
||||||
|
from .crossover_types import Crossover_Types
|
||||||
39
src/crossover/crossover_types.py
Normal file
39
src/crossover/crossover_types.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import random
|
||||||
|
from initialization.chromosome_structure.chromosome import Chromosome
|
||||||
|
from initialization.population_structure.population import Population
|
||||||
|
|
||||||
|
class Crossover_Types:
|
||||||
|
""" Crossover explination goes here.
|
||||||
|
|
||||||
|
Points - Defined as sections between the chromosomes genetic makeup
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def single_point_crossover(self, 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"""
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
|
new_population = Population()
|
||||||
|
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()
|
||||||
|
halfway_point = int(ga.chromosome_length/2)
|
||||||
|
new_gene_set.extend(parent_one[0:halfway_point])
|
||||||
|
new_gene_set.extend(parent_two[halfway_point:])
|
||||||
|
new_chromosome = Chromosome(new_gene_set)
|
||||||
|
new_population.add_chromosome(new_chromosome)
|
||||||
|
|
||||||
|
return new_population
|
||||||
|
|
||||||
|
def multi_point_crossover(self, ga,number_of_points = 2):
|
||||||
|
"""Multi point crossover is when a specific number (More then one) of
|
||||||
|
"points" are created to merge the genetic makup of the chromosomes."""
|
||||||
|
pass
|
||||||
2
src/fitness_function/__init__.py
Normal file
2
src/fitness_function/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# FROM (. means local) file_name IMPORT class name
|
||||||
|
from .examples import Fitness_Examples
|
||||||
17
src/fitness_function/examples.py
Normal file
17
src/fitness_function/examples.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class Fitness_Examples:
|
||||||
|
"""Fitness function examples used"""
|
||||||
|
|
||||||
|
def is_it_5(self, 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
|
||||||
|
fitness = 0
|
||||||
|
# For each gene in the chromosome
|
||||||
|
for gene in chromosome.genes:
|
||||||
|
# Check if its value = 5
|
||||||
|
if(gene.value == 5):
|
||||||
|
# If its value is 5 then add one to
|
||||||
|
# the overal fitness of the chromosome.
|
||||||
|
fitness += 1
|
||||||
|
|
||||||
|
return fitness
|
||||||
5
src/initialization/__init__.py
Normal file
5
src/initialization/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# FROM (. means local) file_name IMPORT function_name
|
||||||
|
from .initialization_types import Initialization_Types
|
||||||
|
from .population_structure.population import Population
|
||||||
|
from .chromosome_structure.chromosome import Chromosome
|
||||||
|
from .gene_structure.gene import Gene
|
||||||
@ -1,6 +1,11 @@
|
|||||||
|
<<<<<<< Updated upstream
|
||||||
class chromosome:
|
class chromosome:
|
||||||
|
|
||||||
# fitness = Empty; genes = [gene, gene, gene, etc.]
|
# fitness = Empty; genes = [gene, gene, gene, etc.]
|
||||||
|
=======
|
||||||
|
class Chromosome:
|
||||||
|
|
||||||
|
>>>>>>> Stashed changes
|
||||||
def __init__(self, genes = None):
|
def __init__(self, genes = None):
|
||||||
if genes is None:
|
if genes is None:
|
||||||
self.genes = []
|
self.genes = []
|
||||||
|
|||||||
@ -3,7 +3,12 @@ def check_gene(value):
|
|||||||
assert value != "" , "Gene can not be empty"
|
assert value != "" , "Gene can not be empty"
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
<<<<<<< Updated upstream
|
||||||
class gene:
|
class gene:
|
||||||
|
=======
|
||||||
|
class Gene:
|
||||||
|
|
||||||
|
>>>>>>> Stashed changes
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
self.fitness = None
|
self.fitness = None
|
||||||
self.value = check_gene(value)
|
self.value = check_gene(value)
|
||||||
@ -17,7 +22,12 @@ class gene:
|
|||||||
def set_fitness(self, fitness):
|
def set_fitness(self, fitness):
|
||||||
self.fitness = fitness
|
self.fitness = fitness
|
||||||
|
|
||||||
|
<<<<<<< Updated upstream
|
||||||
def set_value(self):
|
def set_value(self):
|
||||||
|
=======
|
||||||
|
def set_value(self, value):
|
||||||
|
"""Set value of the gene"""
|
||||||
|
>>>>>>> Stashed changes
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|||||||
32
src/initialization/initialization_types.py
Normal file
32
src/initialization/initialization_types.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Import the data structure
|
||||||
|
from .population_structure.population import Population as create_population
|
||||||
|
from .chromosome_structure.chromosome import Chromosome as create_chromosome
|
||||||
|
from .gene_structure.gene import Gene as create_gene
|
||||||
|
|
||||||
|
class Initialization_Types:
|
||||||
|
"""Initialization examples that are used as defaults and examples"""
|
||||||
|
|
||||||
|
def random_initialization(self, ga):
|
||||||
|
"""Takes the initialization inputs and choregraphs them to output the type of population
|
||||||
|
with the given parameters."""
|
||||||
|
# Create the population object
|
||||||
|
population = create_population()
|
||||||
|
|
||||||
|
# Fill the population with chromosomes
|
||||||
|
for i in range(ga.population_size):
|
||||||
|
chromosome = create_chromosome()
|
||||||
|
#Fill the Chromosome with genes
|
||||||
|
for j in range(ga.chromosome_length):
|
||||||
|
# Using the chromosome_impl to set every index inside of the chromosome
|
||||||
|
if ga.chromosome_impl != None:
|
||||||
|
# Each chromosome location is specified with its own function
|
||||||
|
chromosome.add_gene(create_gene(ga.chromosome_impl(j)))
|
||||||
|
# Will break if chromosome_length != len(lists) in domain
|
||||||
|
elif ga.gene_impl != None:
|
||||||
|
function = ga.gene_impl[0]
|
||||||
|
chromosome.add_gene(create_gene(function(*ga.gene_impl[1:])))
|
||||||
|
else:
|
||||||
|
#Exit because either were not specified
|
||||||
|
print("You did not specify any initialization constraints.")
|
||||||
|
population.add_chromosome(chromosome)
|
||||||
|
return population
|
||||||
@ -1,4 +1,4 @@
|
|||||||
class population:
|
class Population:
|
||||||
|
|
||||||
# fitness = Empty; population = [chromosome, chromosome, etc.]
|
# fitness = Empty; population = [chromosome, chromosome, etc.]
|
||||||
def __init__(self, chromosomes = None):
|
def __init__(self, chromosomes = None):
|
||||||
@ -21,7 +21,12 @@ class population:
|
|||||||
del self.chromosomes[index]
|
del self.chromosomes[index]
|
||||||
|
|
||||||
def get_all_chromosomes(self):
|
def get_all_chromosomes(self):
|
||||||
|
<<<<<<< Updated upstream
|
||||||
return chromosomes
|
return chromosomes
|
||||||
|
=======
|
||||||
|
"""returns all chromosomes in the population"""
|
||||||
|
return self.chromosomes
|
||||||
|
>>>>>>> Stashed changes
|
||||||
|
|
||||||
def get_fitness(self):
|
def get_fitness(self):
|
||||||
return self.fitness
|
return self.fitness
|
||||||
|
|||||||
2
src/mutation/__init__.py
Normal file
2
src/mutation/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# FROM (. means local) file_name IMPORT function_name
|
||||||
|
from .mutation_types import Mutation_Types
|
||||||
21
src/mutation/mutation_types.py
Normal file
21
src/mutation/mutation_types.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import random
|
||||||
|
|
||||||
|
class Mutation_Types:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def random_mutation(self, ga, chromosome_set = None):
|
||||||
|
|
||||||
|
if chromosome_set == None:
|
||||||
|
chromosome_set = ga.population
|
||||||
|
|
||||||
|
chromosome_mutate_num = int(len(chromosome_set)*ga.mutation_rate)
|
||||||
|
temp_population = ga.initialization_impl(ga)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
return chromosome_set
|
||||||
|
|
||||||
@ -1,8 +1,14 @@
|
|||||||
import EasyGA
|
import EasyGA
|
||||||
|
<<<<<<< Updated upstream
|
||||||
|
=======
|
||||||
|
import random
|
||||||
|
|
||||||
|
>>>>>>> Stashed changes
|
||||||
|
|
||||||
# Create the Genetic algorithm
|
# Create the Genetic algorithm
|
||||||
ga = EasyGA.GA()
|
ga = EasyGA.GA()
|
||||||
|
|
||||||
|
<<<<<<< Updated upstream
|
||||||
#Creating a gene with no fitness
|
#Creating a gene with no fitness
|
||||||
gene1 = ga.make_gene("Im a gene")
|
gene1 = ga.make_gene("Im a gene")
|
||||||
gene2 = ga.make_gene("Im also a gene")
|
gene2 = ga.make_gene("Im also a gene")
|
||||||
@ -18,3 +24,12 @@ print(gene1)
|
|||||||
print(chromosome)
|
print(chromosome)
|
||||||
print(populaiton)
|
print(populaiton)
|
||||||
populaiton.print_all()
|
populaiton.print_all()
|
||||||
|
=======
|
||||||
|
ga.gene_impl = [random.randrange,1,10]
|
||||||
|
|
||||||
|
# Run Everyhting
|
||||||
|
ga.evolve()
|
||||||
|
|
||||||
|
# Print the current population
|
||||||
|
ga.population.print_all()
|
||||||
|
>>>>>>> Stashed changes
|
||||||
|
|||||||
2
src/selection/__init__.py
Normal file
2
src/selection/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# FROM (. means local) file_name IMPORT function_name
|
||||||
|
from .selection_types import Selection_Types
|
||||||
103
src/selection/selection_types.py
Normal file
103
src/selection/selection_types.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
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 Selection_Types:
|
||||||
|
"""Selection is the process by which chromosomes are selected for crossover and eventually, influence the next generation of chromosomes."""
|
||||||
|
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.
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
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()))
|
||||||
|
|
||||||
|
#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
|
||||||
|
tournament_group_temp = tournament_group
|
||||||
|
not_sorted_check = 0
|
||||||
|
while (not_sorted_check != len(tournament_group_temp)):
|
||||||
|
not_sorted_check = 0
|
||||||
|
for i in range(len(tournament_group_temp)):
|
||||||
|
if ((i + 1 < len(tournament_group_temp)) and (tournament_group_temp[i + 1].fitness > tournament_group_temp[i].fitness)):
|
||||||
|
temp = tournament_group[i]
|
||||||
|
tournament_group_temp[i] = tournament_group[i + 1]
|
||||||
|
tournament_group_temp[i + 1] = temp
|
||||||
|
else:
|
||||||
|
not_sorted_check += 1
|
||||||
|
|
||||||
|
tournament_group = tournament_group_temp
|
||||||
|
|
||||||
|
#After sorting by fitness, randomly select a chromosome based on selection_probability
|
||||||
|
for i in range(tournament_size):
|
||||||
|
random_num = random.uniform(0,1)
|
||||||
|
|
||||||
|
#ugly implementation but its functional
|
||||||
|
if i == 0:
|
||||||
|
if random_num <= selection_probability:
|
||||||
|
tournament_group[i].selected = True
|
||||||
|
total_selected += 1
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if random_num <= selection_probability*((1-selection_probability)**(i-1)):
|
||||||
|
tournament_group[i].selected = True
|
||||||
|
total_selected += 1
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
|
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
|
||||||
|
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"""
|
||||||
|
pass
|
||||||
2
src/termination_point/__init__.py
Normal file
2
src/termination_point/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# FROM (. means local) file_name IMPORT class name
|
||||||
|
from .termination_types import Termination_Types
|
||||||
16
src/termination_point/termination_types.py
Normal file
16
src/termination_point/termination_types.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
class Termination_Types:
|
||||||
|
"""Example functions that can be used to terminate the the algorithms loop"""
|
||||||
|
|
||||||
|
def fitness_based(self, ga):
|
||||||
|
"""Fitness based approach to terminate when the goal fitness has been reached"""
|
||||||
|
continue_status = True
|
||||||
|
if(ga.current_fitness > ga.fitness_goal):
|
||||||
|
continue_status = False
|
||||||
|
return continue_status
|
||||||
|
|
||||||
|
def generation_based(self, ga):
|
||||||
|
"""Generation based approach to terminate when the goal generation has been reached"""
|
||||||
|
continue_status = True
|
||||||
|
if(ga.current_generation > ga.generation_goal-1):
|
||||||
|
continue_status = False
|
||||||
|
return continue_status
|
||||||
Reference in New Issue
Block a user