Merge branch 'master' into ryley_beta
This commit is contained in:
1
CHANGELOG.rst
Normal file
1
CHANGELOG.rst
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
19
MANIFEST.in
19
MANIFEST.in
@ -1,19 +0,0 @@
|
|||||||
graft docs
|
|
||||||
graft src
|
|
||||||
graft ci
|
|
||||||
graft tests
|
|
||||||
|
|
||||||
include .bumpversion.cfg
|
|
||||||
include .coveragerc
|
|
||||||
include .cookiecutterrc
|
|
||||||
include .editorconfig
|
|
||||||
|
|
||||||
include AUTHORS.rst
|
|
||||||
include CHANGELOG.rst
|
|
||||||
include CONTRIBUTING.rst
|
|
||||||
include LICENSE
|
|
||||||
include README.rst
|
|
||||||
|
|
||||||
include tox.ini .travis.yml .appveyor.yml .readthedocs.yml .pre-commit-config.yaml
|
|
||||||
|
|
||||||
global-exclude *.py[cod] __pycache__/* *.so *.dylib
|
|
||||||
30
README.md
30
README.md
@ -25,37 +25,7 @@ ga.evolve()
|
|||||||
Put the out here
|
Put the out here
|
||||||
```
|
```
|
||||||
|
|
||||||
## Customized:
|
|
||||||
```python
|
|
||||||
import random
|
|
||||||
import EasyGA
|
|
||||||
|
|
||||||
# Create the Genetic algorithm
|
|
||||||
ga = EasyGA.GA()
|
|
||||||
|
|
||||||
# Makes a new gene
|
|
||||||
new_gene = ga.make_gene("HelloWorld")
|
|
||||||
# Makes a chromosome to store genes in
|
|
||||||
new_chromosome = ga.make_chromosome()
|
|
||||||
# Makes a Population to store chromosomes in
|
|
||||||
new_population = ga.make_population()
|
|
||||||
|
|
||||||
ga.initialize()
|
|
||||||
|
|
||||||
print(ga.population)
|
|
||||||
|
|
||||||
for chromosome in ga.population.chromosomes:
|
|
||||||
print(chromosome.genes[0].__dict__)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Output:
|
|
||||||
```python
|
|
||||||
<initialization.population_structure.population.population object at 0x7f993002fdf0>
|
|
||||||
{'fitness': None, 'value': 47}
|
|
||||||
{'fitness': None, 'value': 4}
|
|
||||||
{'fitness': None, 'value': 68}
|
|
||||||
{'fitness': None, 'value': 57}
|
|
||||||
```
|
|
||||||
|
|
||||||
# How Testing works
|
# How Testing works
|
||||||
|
|
||||||
|
|||||||
12
setup.py
12
setup.py
@ -1,17 +1,21 @@
|
|||||||
from setuptools import setup
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
with open("README.md", "r") as fh:
|
with open("README.md", "r") as fh:
|
||||||
long_description = fh.read()
|
long_description = fh.read()
|
||||||
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='EasyGA',
|
name='EasyGA',
|
||||||
version='0.0.8',
|
version='0.0.25',
|
||||||
description='A ubiquitous or general purpuse GA',
|
description='A ubiquitous or general purpuse GA',
|
||||||
py_modules=["EasyGA"],
|
py_modules=["EasyGA"],
|
||||||
package_dir={'':'src'},
|
packages=find_packages(where='EasyGA'),
|
||||||
|
package_dir={
|
||||||
|
'': 'EasyGA',
|
||||||
|
},
|
||||||
python_requires='>=3.6',
|
python_requires='>=3.6',
|
||||||
url="https://github.com/danielwilczak101/EasyGA",
|
url="https://github.com/danielwilczak101/EasyGA",
|
||||||
author="Daniel Wilczak",
|
author="Daniel Wilczak, Jack RyanNguyen, Ryley Griffith, Jared Curtis, Matthew Chase Oxamendi",
|
||||||
author_email="danielwilczak101@gmail.com",
|
author_email="danielwilczak101@gmail.com",
|
||||||
long_description = long_description,
|
long_description = long_description,
|
||||||
long_description_content_type = "text/markdown",
|
long_description_content_type = "text/markdown",
|
||||||
|
|||||||
@ -72,6 +72,7 @@ class GA:
|
|||||||
self.population.set_all_chromosomes(self.sort_by_best_fitness())
|
self.population.set_all_chromosomes(self.sort_by_best_fitness())
|
||||||
|
|
||||||
number_of_generations -= 1
|
number_of_generations -= 1
|
||||||
|
|
||||||
self.current_generation += 1
|
self.current_generation += 1
|
||||||
|
|
||||||
def evolve(self):
|
def evolve(self):
|
||||||
@ -124,10 +125,13 @@ class GA:
|
|||||||
return chromosome_set
|
return chromosome_set
|
||||||
|
|
||||||
def make_gene(self,value):
|
def make_gene(self,value):
|
||||||
|
"""Let's the user create a gene."""
|
||||||
return create_gene(value)
|
return create_gene(value)
|
||||||
|
|
||||||
def make_chromosome(self):
|
def make_chromosome(self):
|
||||||
|
"""Let's the user create a chromosome."""
|
||||||
return create_chromosome()
|
return create_chromosome()
|
||||||
|
|
||||||
def make_population(self):
|
def make_population(self):
|
||||||
|
"""Let's the user create a population."""
|
||||||
return create_population()
|
return create_population()
|
||||||
|
|||||||
3
src/__init__.py
Normal file
3
src/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import EasyGA
|
||||||
|
import run_testing
|
||||||
|
import test_EasyGA
|
||||||
@ -1 +1 @@
|
|||||||
# Crossover function
|
# Mutation functions
|
||||||
|
|||||||
3
src/crossover/methods.py
Normal file
3
src/crossover/methods.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class Crossover_methods:
|
||||||
|
"""Mutation examples will go here """
|
||||||
|
pass
|
||||||
16
src/fitness_function/methods.py
Normal file
16
src/fitness_function/methods.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
class Fitness_methods:
|
||||||
|
"""Fitness function examples used"""
|
||||||
|
|
||||||
|
def is_it_5(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.gene_list:
|
||||||
|
# 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
|
||||||
@ -1,12 +0,0 @@
|
|||||||
class test_fitness_funciton:
|
|
||||||
def get_fitness(self, chromosome):
|
|
||||||
# For every gene in chromosome
|
|
||||||
for i in range(len(chromosome.genes)):
|
|
||||||
# If the gene has a five then add one to the fitness
|
|
||||||
# Example -> Chromosome = [5],[2],[2],[5],[5] then fitness = 3
|
|
||||||
if (chromosome.genes[i].get_value == 5):
|
|
||||||
# Add to the genes fitness
|
|
||||||
chromosome.genes[i].fitness += 1
|
|
||||||
# Add to the chromosomes fitness
|
|
||||||
chromosome.fitness += 1
|
|
||||||
return chromosome.fitness
|
|
||||||
1
src/fitness_function/test_methods.py
Normal file
1
src/fitness_function/test_methods.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
@ -1,5 +1,3 @@
|
|||||||
# FROM (. means local) file_name IMPORT function_name
|
# FROM (. means local) file_name IMPORT function_name
|
||||||
from .initialization_methods import Initialization_Methods
|
from .initialization_methods import Initialization_Methods
|
||||||
from .population_structure.population import Population
|
|
||||||
from .chromosome_structure.chromosome import Chromosome
|
|
||||||
from .gene_structure.gene import Gene
|
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
class Chromosome:
|
class Chromosome:
|
||||||
|
def __init__(self, gene_list = None):
|
||||||
def __init__(self, genes = None):
|
if gene_list is None:
|
||||||
if genes is None:
|
|
||||||
self.gene_list = []
|
self.gene_list = []
|
||||||
else:
|
else:
|
||||||
self.gene_list = genes
|
self.gene_list = genes
|
||||||
|
|
||||||
self.fitness = None
|
self.fitness = None
|
||||||
|
# If the chromosome has been selected then the flag would switch to true
|
||||||
|
self.selected = False
|
||||||
|
|
||||||
def add_gene(self, gene, index = -1):
|
def add_gene(self, gene, index = -1):
|
||||||
|
"""Add a gene to the chromosome at the specified index, defaulted to end of the chromosome"""
|
||||||
if index == -1:
|
if index == -1:
|
||||||
index = len(self.gene_list)
|
index = len(self.gene_list)
|
||||||
self.gene_list.insert(index, gene)
|
self.gene_list.insert(index, gene)
|
||||||
@ -19,6 +22,7 @@ class Chromosome:
|
|||||||
return self.gene_list
|
return self.gene_list
|
||||||
|
|
||||||
def get_fitness(self):
|
def get_fitness(self):
|
||||||
|
"""Return the fitness of the chromosome"""
|
||||||
return self.fitness
|
return self.fitness
|
||||||
|
|
||||||
def set_gene(self, gene, index):
|
def set_gene(self, gene, index):
|
||||||
@ -28,9 +32,11 @@ class Chromosome:
|
|||||||
self.gene_list = genes
|
self.gene_list = genes
|
||||||
|
|
||||||
def set_fitness(self, fitness):
|
def set_fitness(self, fitness):
|
||||||
|
"""Set the fitness value of the chromosome"""
|
||||||
self.fitness = fitness
|
self.fitness = fitness
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
"""Format the repr() output for the chromosome"""
|
||||||
output_str = ''
|
output_str = ''
|
||||||
for gene in self.gene_list:
|
for gene in self.gene_list:
|
||||||
output_str += gene.__repr__()
|
output_str += gene.__repr__()
|
||||||
|
|||||||
@ -6,16 +6,20 @@ def check_gene(value):
|
|||||||
class Gene:
|
class Gene:
|
||||||
|
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
|
"""Initialize a gene with fitness of value None and the input value"""
|
||||||
self.fitness = None
|
self.fitness = None
|
||||||
self.value = check_gene(value)
|
self.value = check_gene(value)
|
||||||
|
|
||||||
def get_fitness(self):
|
def get_fitness(self):
|
||||||
|
"""Return fitness of the gene"""
|
||||||
return self.fitness
|
return self.fitness
|
||||||
|
|
||||||
def get_value(self):
|
def get_value(self):
|
||||||
|
"""Return value of the gene"""
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
def set_fitness(self, fitness):
|
def set_fitness(self, fitness):
|
||||||
|
"""Set fitness of the gene"""
|
||||||
self.fitness = fitness
|
self.fitness = fitness
|
||||||
|
|
||||||
def set_value(self, value):
|
def set_value(self, value):
|
||||||
@ -23,4 +27,5 @@ class Gene:
|
|||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
"""Format the repr() output value"""
|
||||||
return f'[{self.value}]'
|
return f'[{self.value}]'
|
||||||
|
|||||||
33
src/initialization/methods.py
Normal file
33
src/initialization/methods.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# 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_methods:
|
||||||
|
"""Initialization examples that are used as defaults and examples"""
|
||||||
|
|
||||||
|
def random_initialization(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:
|
||||||
|
# gene_impl = [range function,lowerbound,upperbound]
|
||||||
|
function = ga.gene_impl[0]
|
||||||
|
chromosome.add_gene(create_gene(function(*ga.gene_impl[1:])))
|
||||||
|
else:
|
||||||
|
#Exit because either were not specified
|
||||||
|
print("Your domain or range were not specified")
|
||||||
|
population.add_chromosome(chromosome)
|
||||||
|
return population
|
||||||
0
src/initialization/population_structure/__init__.py
Normal file
0
src/initialization/population_structure/__init__.py
Normal file
@ -1,24 +1,25 @@
|
|||||||
class Population:
|
class Population:
|
||||||
|
def __init__(self, chromosome_list = None):
|
||||||
# fitness = Empty; population = [chromosome, chromosome, etc.]
|
"""Intiialize the population with fitness of value None, and a set of chromosomes dependant on user-passed parameter"""
|
||||||
def __init__(self, chromosomes = None):
|
if chromosome_list is None:
|
||||||
if chromosomes is None:
|
|
||||||
self.chromosome_list = []
|
self.chromosome_list = []
|
||||||
else:
|
else:
|
||||||
self.chromosome_list = chromosomes
|
self.chromosome_list = chromosome_list
|
||||||
self.fitness = None
|
self.fitness = None
|
||||||
self.mating_pool = []
|
self.mating_pool = []
|
||||||
|
|
||||||
def get_closet_fitness(self,value):
|
def get_closet_fitness(self,value):
|
||||||
# Get the chomosome that has the closets fitness to the value defined
|
"""Get the chomosome that has the closets fitness to the value defined"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def add_chromosome(self, chromosome, index = -1):
|
def add_chromosome(self, chromosome, index = -1):
|
||||||
|
"""Adds a chromosome to the population at the input index, defaulted to the end of the chromosome set"""
|
||||||
if index == -1:
|
if index == -1:
|
||||||
index = len(self.chromosome_list)
|
index = len(self.chromosome_list)
|
||||||
self.chromosome_list.insert(index, chromosome)
|
self.chromosome_list.insert(index, chromosome)
|
||||||
|
|
||||||
def remove_chromosome(self, index):
|
def remove_chromosome(self, index):
|
||||||
|
"""removes a chromosome from the indicated index"""
|
||||||
del self.chromosome_list[index]
|
del self.chromosome_list[index]
|
||||||
|
|
||||||
def get_all_chromosomes(self):
|
def get_all_chromosomes(self):
|
||||||
@ -26,6 +27,7 @@ class Population:
|
|||||||
return self.chromosome_list
|
return self.chromosome_list
|
||||||
|
|
||||||
def get_fitness(self):
|
def get_fitness(self):
|
||||||
|
"""returns the population's fitness"""
|
||||||
return self.fitness
|
return self.fitness
|
||||||
|
|
||||||
def set_all_chromosomes(self, chromosomes):
|
def set_all_chromosomes(self, chromosomes):
|
||||||
@ -37,6 +39,7 @@ class Population:
|
|||||||
self.chromosome_list[index] = chromosome
|
self.chromosome_list[index] = chromosome
|
||||||
|
|
||||||
def set_fitness(self, fitness):
|
def set_fitness(self, fitness):
|
||||||
|
"""Sets the fitness value of the population"""
|
||||||
self.fitness = fitness
|
self.fitness = fitness
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -44,9 +47,10 @@ class Population:
|
|||||||
return f'{self.chromosome_list[index]}'
|
return f'{self.chromosome_list[index]}'
|
||||||
|
|
||||||
def print_all(self):
|
def print_all(self):
|
||||||
# Ex .Current population
|
"""Prints information about the population in the following format:"""
|
||||||
# Chromosome 1 - [gene][gene][gene][.etc] / Chromosome fitness - #
|
"""Ex .Current population"""
|
||||||
|
"""Chromosome 1 - [gene][gene][gene][.etc] / Chromosome fitness - """
|
||||||
print("Current population:")
|
print("Current population:")
|
||||||
for index in range(len(self.chromosome_list)):
|
for index in range(len(self.chromosome_list)):
|
||||||
print(f'Chromosome - {index} {self.chromosome_list[index]}', end = "")
|
print(f'Chromosome - {index} {self.chromosome_list[index]}', end = "")
|
||||||
print(f' / Fitness = {self.chromosome_list[index].fitness}')
|
print(f' / Fitness = {self.chromosome_list[index].fitness}')
|
||||||
|
|||||||
0
src/initialization/test_methods.py
Normal file
0
src/initialization/test_methods.py
Normal file
3
src/mutation/methods.py
Normal file
3
src/mutation/methods.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class Mutation_methods:
|
||||||
|
"""Mutation examples will go here """
|
||||||
|
pass
|
||||||
0
src/mutation/test_methods.py
Normal file
0
src/mutation/test_methods.py
Normal file
2
src/parent_selection/__init__.py
Normal file
2
src/parent_selection/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# FROM (. means local) file_name IMPORT function_name
|
||||||
|
from .methods import Parent_methods
|
||||||
37
src/parent_selection/methods.py
Normal file
37
src/parent_selection/methods.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
class Parent_methods:
|
||||||
|
"""Selection defintion here"""
|
||||||
|
|
||||||
|
def tournament_selection(ga,matchs):
|
||||||
|
"""Tournament selection involves running several "tournaments" among a
|
||||||
|
few individuals (or "chromosomes")chosen at random from the population.
|
||||||
|
The winner of each tournament (the one with the best fitness) is selected
|
||||||
|
for crossover.
|
||||||
|
Ex
|
||||||
|
Chromsome 1----1 wins ------
|
||||||
|
Chromsome 2---- - --1 wins----
|
||||||
|
- -
|
||||||
|
Chromsome 3----3 wins ------ -- 5 Wins --->Chromosome 5 becomes Parent
|
||||||
|
Chromsome 4---- -
|
||||||
|
-
|
||||||
|
Chromsome 5----5 wins ---------5 wins----
|
||||||
|
Chromsome 6----
|
||||||
|
^--Matchs--^
|
||||||
|
"""
|
||||||
|
|
||||||
|
def small_tournament(ga):
|
||||||
|
""" Small tournament is only one round of tournament. Beat the other
|
||||||
|
randomly selected chromosome and your are selected as a parent.
|
||||||
|
Chromosome 1----
|
||||||
|
-- 1 wins -> Becomes selected for crossover.
|
||||||
|
Chromosome 2----
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def roulette_selection(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
|
||||||
0
src/parent_selection/test_methods.py
Normal file
0
src/parent_selection/test_methods.py
Normal file
@ -13,4 +13,4 @@ ga.gene_impl = [random.randrange,1,100]
|
|||||||
ga.evolve()
|
ga.evolve()
|
||||||
|
|
||||||
# Print the current population
|
# Print the current population
|
||||||
ga.population.print_all()
|
ga.population.print_all()
|
||||||
|
|||||||
1
src/survivor_selection/README.md
Normal file
1
src/survivor_selection/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Selection functions
|
||||||
2
src/survivor_selection/__init__.py
Normal file
2
src/survivor_selection/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# FROM (. means local) file_name IMPORT function_name
|
||||||
|
from .methods import Survivor_methods
|
||||||
8
src/survivor_selection/methods.py
Normal file
8
src/survivor_selection/methods.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
class Survivor_methods:
|
||||||
|
"""Survivor methods defintion here"""
|
||||||
|
|
||||||
|
def elitism():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove_two_worst():
|
||||||
|
pass
|
||||||
0
src/survivor_selection/test_methods.py
Normal file
0
src/survivor_selection/test_methods.py
Normal file
16
src/termination_point/methods.py
Normal file
16
src/termination_point/methods.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
class Termination_methods:
|
||||||
|
"""Example functions that can be used to terminate the the algorithms loop"""
|
||||||
|
|
||||||
|
def fitness_based(ga):
|
||||||
|
"""Fitness based approach to terminate when the goal fitness has been reached"""
|
||||||
|
status = True
|
||||||
|
if(ga.current_fitness > ga.fitness_goal):
|
||||||
|
status = False
|
||||||
|
return status
|
||||||
|
|
||||||
|
def generation_based(ga):
|
||||||
|
"""Generation based approach to terminate when the goal generation has been reached"""
|
||||||
|
status = True
|
||||||
|
if(ga.current_generation > ga.generation_goal):
|
||||||
|
status = False
|
||||||
|
return status
|
||||||
0
src/termination_point/test_methods.py
Normal file
0
src/termination_point/test_methods.py
Normal file
Reference in New Issue
Block a user