Merge branch 'master' into ryley_beta

This commit is contained in:
Ryley
2020-10-06 21:11:22 -04:00
committed by GitHub
34 changed files with 168 additions and 82 deletions

1
CHANGELOG.rst Normal file
View File

@ -0,0 +1 @@

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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
View File

@ -0,0 +1,3 @@
import EasyGA
import run_testing
import test_EasyGA

View File

@ -1 +1 @@
# Crossover function # Mutation functions

3
src/crossover/methods.py Normal file
View File

@ -0,0 +1,3 @@
class Crossover_methods:
"""Mutation examples will go here """
pass

View 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

View File

@ -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

View File

@ -0,0 +1 @@

View File

@ -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

View File

@ -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__()

View File

@ -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}]'

View 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

View 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}')

View File

3
src/mutation/methods.py Normal file
View File

@ -0,0 +1,3 @@
class Mutation_methods:
"""Mutation examples will go here """
pass

View File

View File

@ -0,0 +1,2 @@
# FROM (. means local) file_name IMPORT function_name
from .methods import Parent_methods

View 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

View File

View 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()

View File

@ -0,0 +1 @@
# Selection functions

View File

@ -0,0 +1,2 @@
# FROM (. means local) file_name IMPORT function_name
from .methods import Survivor_methods

View File

@ -0,0 +1,8 @@
class Survivor_methods:
"""Survivor methods defintion here"""
def elitism():
pass
def remove_two_worst():
pass

View File

View 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

View File