New Initialization Method

This is a test implementation of a potential new initialization method. A testing file - new_initialization_method_testing.py - is included to allow for quick testing.

In summary here is are the major points:
1) Two new attributes of GA were created - gene_input and gene_input_type. gene_input holds the user's custom range(s)/domain(s) after it gets passed to the initialize() function. gene_input_type holds an array with the same length as the chromosomes that holds the input type of the user's gene_input on a gene-by-gene basis. It does this in the same exact way that index-dependent gene ranges/domains are handled. By making the gene_input_type array the same size as the chromosome, the elements can be paired very easily. The acceptable values for this are either "range" or "domain". With a range, any value between the two can be generated; with domain, only the two elements included can be selected from randomly.
2) As mentioned in change 1, the user now has to pass their range(s)/domain(s) to the initialize() function.
3) The package is capable of implicitly determining if a certain input from the user is a range or domain. Strings can only ever be a domain – if given an element that only includes integers, the program assumes range.
4) If the user wishes to use numbers only as a domain, they can specify this by directly interacting with the ga.gene_input_type (or through a setter function).
5) the initialize() function in the GA object determines the implicit range/domain assignments if the user doesn’t do so themselves.
6) The random_initialization() function is effectively the same, except there is now an if/else to determine if the user is using the built-in gene creation function or not. If they are, then pass the gene_input, gene_input_type, and current gene index as arguments to the gene function. If they are using their own function, random_initialization() functions exactly the same way as it does in the current master branch.
7) Based on all the settings mentioned above, the random_gene() function will create a value before passing it back to random_initialization().
This commit is contained in:
RyleyGG
2020-09-25 01:15:53 -04:00
parent 99066e924b
commit 5821e709a3
5 changed files with 105 additions and 16 deletions

View File

@ -19,6 +19,8 @@ class GA:
self.mutation_rate = 0.03
# Defualt EastGA implimentation structure
self.gene_function_impl = random_gene
self.gene_input = []
self.gene_input_type = [] #What if user gives two numbers (i.e. [1,100]) but wants to pick between the two (domain)?
# Set the GA Configuration
self.initialization_impl = random_initialization
#self.mutation_impl = PerGeneMutation(Mutation_rate)
@ -28,12 +30,39 @@ class GA:
#self.evaluation_impl = TestEvaluation()
def initialize(self):
def initialize(self, gene_input):
self.gene_input = gene_input
#assuming domain if string (strings can never be range)
if self.gene_input_type == []:
for x in range(len(self.gene_input)):
if (isinstance(self.gene_input[x], list)):
for y in range(len(self.gene_input[x])):
if isinstance(gene_input[x][y], str):
self.gene_input_type.append("domain")
break
elif y == (len(self.gene_input[x]) -1):
self.gene_input_type.append("range")
else:
if isinstance(gene_input[x], str):
self.gene_input_type.append("domain")
else:
if isinstance(gene_input[x], int):
self.gene_input[x] = [self.gene_input[x], self.gene_input[x]]
self.gene_input_type.append("range")
#If length doesn't correspond to chromosome, update here
while len(self.gene_input_type) != self.chromosome_length:
self.gene_input_type.append(self.gene_input_type[len(self.gene_input_type)-1])
# Create the first population
self.population = self.initialization_impl(
self.population_size,
self.chromosome_length,
self.gene_function_impl)
self.gene_function_impl,
self.gene_input,
self.gene_input_type)
def evolve():
# If you just want to evolve through all generations

View File

@ -0,0 +1,13 @@
# Imported library
import random
def check_values(low,high):
#Check to make sure its not less then zero
assert low > 0 , "The random gene low can not be less then zero"
# Check to make sure the high value is not
# lower than or equal to low and not 0.
assert high > low , "High value can not be smaller then low value"
assert high != 0, "High value can not be zero"
def random_gene():
return random.randint(1,100)

View File

@ -6,8 +6,22 @@ def check_values(low,high):
assert low > 0 , "The random gene low can not be less then zero"
# Check to make sure the high value is not
# lower than or equal to low and not 0.
assert high > low , "High value can not be smaller then low value"
assert high > low, "High value can not be smaller then low value"
assert high != 0, "High value can not be zero"
def random_gene():
return random.randint(1,100)
def random_gene(gene_input, gene_input_type, gene_index):
created_gene = None
#Determining if single range/domain or index-dependent
if isinstance(gene_input[0], list):
if gene_input_type[gene_index] == "range":
created_gene = random.randint(gene_input[gene_index][0], gene_input[gene_index][1])
elif gene_input_type[gene_index] == "domain":
created_gene = random.choice(gene_input[gene_index])
else:
if gene_input_type[gene_index] == "range":
created_gene = random.randint(gene_input[0], gene_input[1])
elif gene_input_type[gene_index] == "domain":
created_gene = random.choice(gene_input)
return created_gene

View File

@ -2,15 +2,30 @@
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
from .gene_function.gene_random import random_gene as random_gene
def random_initialization(chromosome_length,population_size,gene_function):
# Create the population object
population = create_population()
# Fill the population with chromosomes
for i in range(population_size):
chromosome = create_chromosome()
#Fill the Chromosome with genes
for j in range(chromosome_length):
chromosome.add_gene(create_gene(gene_function()))
population.add_chromosome(chromosome)
return population
def random_initialization(chromosome_length,population_size,gene_function,gene_input,gene_input_type):
if gene_function == random_gene:
# Create the population object
population = create_population()
# Fill the population with chromosomes
for i in range(population_size):
chromosome = create_chromosome()
#Fill the Chromosome with genes
for j in range(chromosome_length-1):
chromosome.add_gene(create_gene(gene_function(gene_input, gene_input_type, j)))
population.add_chromosome(chromosome)
return population
else: #For user input gene-function, don't do anything with gene_input parameter
# Create the population object
population = create_population()
# Fill the population with chromosomes
for i in range(population_size):
chromosome = create_chromosome()
#Fill the Chromosome with genes
for j in range(chromosome_length):
chromosome.add_gene(create_gene(gene_function()))
population.add_chromosome(chromosome)
return population

View File

@ -0,0 +1,18 @@
import EasyGA
import random
# Create the Genetic algorithm
ga = EasyGA.GA()
test_range_two = [["left", "right"],[22,88],5,[22,"up"]]
ga.initialize(test_range_two)
ga.population.print_all()
#test_range_one = [1,100]
#test_domain_one = ["left", "right", "up", "down"]
#test_range_two = [[1,100],[0,1],[33,35],[5,6]]
#test_domain_two = [["left", "right"], ["up", "down"], ["left", "down"], ["down", "right"]]
#for index-specific bounds, do list of lists i.e. test_range = [[1, 100], [1, 25], [5, 25]]