Added graphing capablities. It only graphs total fitness of generation.

This commit is contained in:
danielwilczak101
2020-11-06 02:11:06 -05:00
parent e012f6653c
commit 5c5b645c30
7 changed files with 75 additions and 26 deletions

View File

@ -26,6 +26,8 @@ setup(
"License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
"Operating System :: OS Independent", "Operating System :: OS Independent",
], ],
install_requires = ["matplotlib ~= 3.3.2",
],
extra_require = { extra_require = {
"dev": [ "dev": [
"pytest>=3.7", "pytest>=3.7",

View File

@ -23,6 +23,9 @@ from attributes import Attributes
from database import database from database import database
from sqlite3 import Error from sqlite3 import Error
# Graphing package
import matplotlib.pyplot as plt
class GA(Attributes): class GA(Attributes):
"""GA is the main class in EasyGA. Everything is run through the ga """GA is the main class in EasyGA. Everything is run through the ga
@ -154,3 +157,34 @@ class GA(Attributes):
"""Prints the best chromosome and its fitness""" """Prints the best chromosome and its fitness"""
print(f"Best Chromosome \t: {self.population.get_chromosome(0)}") print(f"Best Chromosome \t: {self.population.get_chromosome(0)}")
print(f"Best Fitness \t: {self.population.get_chromosome(0).get_fitness()}") print(f"Best Fitness \t: {self.population.get_chromosome(0).get_fitness()}")
def graph_scatter(self):
"""Show a scatter plot of the database information."""
# Query the X data
generations = self.database.query_one_item("SELECT COUNT(DISTINCT generation) FROM data;")
# Create the generations array
X = list(range(0, generations))
#Query the Y data
Y_data = self.database.query_all("SELECT SUM(fitness) FROM data GROUP BY generation;")
# Format the Y data so we can use it to plot
Y = [i[0] for i in Y_data]
# Set the plot size
plt.figure(figsize=[5, 5])
plt.scatter(X,Y)
# x and y labels
plt.xlabel('Generation')
plt.ylabel('Generation Total Fitness')
plt.title('Relationship Between Generations and Generation Total Fitness')
# Show the plot
plt.show()
def graph_line(self):
pass

View File

@ -24,6 +24,7 @@ from crossover import Crossover_Methods
from database import database from database import database
from sqlite3 import Error from sqlite3 import Error
class Attributes: class Attributes:
"""Default GA attributes can be found here. If any attributes have not """Default GA attributes can be found here. If any attributes have not
been set then they will fall back onto the default attribute. All been set then they will fall back onto the default attribute. All
@ -60,7 +61,7 @@ class Attributes:
termination_impl = Termination_Methods.fitness_and_generation_based, termination_impl = Termination_Methods.fitness_and_generation_based,
database = None, database = None,
database_name = 'database.db', database_name = 'database.db',
sql_create_data_structure = """CREATE TABLE IF NOT EXISTS data ( sql_create_data_structure = """CREATE TABLE IF NOT EXISTS data (
id integer PRIMARY KEY, id integer PRIMARY KEY,
generation integer NOT NULL, generation integer NOT NULL,
fitness DOUBLE, fitness DOUBLE,

BIN
src/database.db Normal file

Binary file not shown.

View File

@ -5,7 +5,7 @@ import os
class database: class database:
"""Main database class that controls all the functionality for input / """Main database class that controls all the functionality for input /
out of the database.""" out of the database."""
def __init__(self): def __init__(self):
@ -13,7 +13,7 @@ class database:
def create_connection(self, db_file): def create_connection(self, db_file):
""" create a database connection to the SQLite database """Create a database connection to the SQLite database
specified by db_file.""" specified by db_file."""
conn = None conn = None
@ -27,11 +27,8 @@ class database:
def create_table(self, create_table_sql): def create_table(self, create_table_sql):
""" create a table from the create_table_sql statement """Create a table from the create_table_sql statement."""
:param conn: Connection object
:param create_table_sql: a CREATE TABLE statement
:return:
"""
try: try:
c = self.conn.cursor() c = self.conn.cursor()
c.execute(create_table_sql) c.execute(create_table_sql)
@ -39,20 +36,15 @@ class database:
print(e) print(e)
def insert_chromosome(self, generation, chromosome): def insert_chromosome(self, generation, chromosome):
""" """ """
Insert a new chromosome
:param conn:
:param generation:
:param chromosome:
:return:
"""
# Structure the insert data # Structure the insert data
db_chromosome = (generation, chromosome.fitness, '[chromosome]') db_chromosome = (generation, chromosome.fitness, '[chromosome]')
# Create sql query structure
sql = ''' INSERT INTO data(generation,fitness,chromosome) sql = ''' INSERT INTO data(generation,fitness,chromosome)
VALUES(?,?,?) ''' VALUES(?,?,?) '''
cur = self.conn.cursor() cur = self.conn.cursor()
cur.execute(sql, db_chromosome) cur.execute(sql, db_chromosome)
self.conn.commit() self.conn.commit()
@ -61,16 +53,20 @@ class database:
def insert_current_population(self, ga): def insert_current_population(self, ga):
""" Insert current generations population """ """ Insert current generations population """
# For each chromosome in the population
for chromosome in ga.population.chromosome_list: for chromosome in ga.population.chromosome_list:
# Insert the chromosome into the database
self.insert_chromosome(ga.current_generation, chromosome) self.insert_chromosome(ga.current_generation, chromosome)
def create_data_table(self, ga): def create_data_table(self, ga):
"""Create the data table that store generation data."""
try: try:
# Remove old database if there # Remove old database file if it exists.
os.remove(ga.database_name) os.remove(ga.database_name)
except: except:
# If the database does not exist continue
pass pass
# create a database connection # create a database connection
@ -81,7 +77,23 @@ class database:
# create projects table # create projects table
self.create_table(ga.sql_create_data_structure) self.create_table(ga.sql_create_data_structure)
# create tasks table
# create_table(conn, sql_create_tasks_table)
else: else:
print("Error! cannot create the database connection.") print("Error! cannot create the database connection.")
def query_all(self, query):
"""Query for muliple rows of data"""
cur = self.conn.cursor()
cur.execute(query)
return cur.fetchall()
def query_one_item(self, query):
"""Query for single data point"""
cur = self.conn.cursor()
cur.execute(query)
query_data = cur.fetchone()
return query_data[0]

View File

View File

@ -1,14 +1,14 @@
import random
import EasyGA import EasyGA
import random
# Create the Genetic algorithm # Create the Genetic algorithm
ga = EasyGA.GA() ga = EasyGA.GA()
ga.population_size = 3 ga.generation_goal = 200
ga.generation_goal = 10 ga.population_size = 50
# Evolve the genetic algorithm
ga.evolve() ga.evolve()
# Print your default genetic algorithm
ga.print_generation()
ga.print_population() ga.print_population()
ga.graph_scatter()