Added graphing capablities. It only graphs total fitness of generation.
This commit is contained in:
2
setup.py
2
setup.py
@ -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",
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
BIN
src/database.db
Normal file
Binary file not shown.
@ -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]
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user