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:
@ -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
|
||||
|
||||
13
src/initialization/gene_creation/gene_random.py
Normal file
13
src/initialization/gene_creation/gene_random.py
Normal 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)
|
||||
@ -9,5 +9,19 @@ def check_values(low,high):
|
||||
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
|
||||
|
||||
@ -2,8 +2,23 @@
|
||||
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):
|
||||
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
|
||||
|
||||
18
src/new_initialization_method_testing.py
Normal file
18
src/new_initialization_method_testing.py
Normal 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]]
|
||||
Reference in New Issue
Block a user