diff --git a/src/EasyGA.py b/src/EasyGA.py index 11642bc..18eb636 100644 --- a/src/EasyGA.py +++ b/src/EasyGA.py @@ -49,9 +49,10 @@ class GA(Attributes): if self.current_generation == 0: # Create the database here to allow the user to change - # the database name and structure in the running function. - self.database.create_data_table(self) - + # the database name and structure before running the function. + self.database.create_all_tables(self) + # Add the current configuration to the config table + self.database.insert_config(self) # Create the initial population self.initialize_population() diff --git a/src/attributes.py b/src/attributes.py index f2da06a..20b1a71 100644 --- a/src/attributes.py +++ b/src/attributes.py @@ -81,17 +81,42 @@ class Attributes: Database = sql_database.SQL_Database, database_name = 'database.db', sql_create_data_structure = """CREATE TABLE IF NOT EXISTS data ( - id integer PRIMARY KEY, - generation integer NOT NULL, - fitness DOUBLE, - chromosome text + id INTEGER PRIMARY KEY, + config_id INTEGER DEFAULT NULL, + generation INTEGER NOT NULL, + fitness REAL, + chromosome TEXT ); """, sql_create_config_structure = """CREATE TABLE IF NOT EXISTS config ( - id integer PRIMARY KEY, - generation integer NOT NULL, - fitness DOUBLE, - chromosome text - ); """, + id INTEGER PRIMARY KEY, + chromosome_length INTEGER NOT NULL, + population_size INTEGER NOT NULL, + chromosome_impl TEXT, + gene_impl TEXT, + target_fitness_type TEXT, + update_fitness INTEGER, + parent_ratio REAL, + selection_probability REAL, + tournament_size_ratio REAL, + current_generation INTEGER, + current_fitness REAL, + generation_goal INTEGER, + fitness_goal INTEGER, + tolerance_goal INTEGER, + percent_converged REAL, + chromosome_mutation_rate REAL, + gene_mutation_rate REAL, + initialization_impl TEXT, + fitness_function_impl TEXT, + parent_selection_impl TEXT, + crossover_individual_impl TEXT, + crossover_population_impl TEXT, + survivor_selection_impl TEXT, + mutation_individual_impl TEXT, + mutation_population_impl TEXT, + termination_impl TEXT, + database_name TEXT + ); """, Graph = matplotlib_graph.Matplotlib_Graph ): diff --git a/src/database/sql_database.py b/src/database/sql_database.py index 4ae5547..6001a6e 100644 --- a/src/database/sql_database.py +++ b/src/database/sql_database.py @@ -71,7 +71,7 @@ class SQL_Database: return cur.lastrowid - def create_data_table(self, ga): + def create_all_tables(self, ga): """Create the data table that store generation data.""" try: @@ -92,6 +92,103 @@ class SQL_Database: else: print("Error! cannot create the database connection.") + def insert_config(self,ga): + """Insert the configuration attributes into the config """ + + # If either function is None we handle the error + try: + chromosome_impl = ga.chromosome_impl.__name__ + except: + chromosome_impl = 'None' + + try: + gene_impl = ga.chromosome_impl.__name__ + except: + gene_impl = 'None' + + # Structure the insert data + db_config_list = [ + ga.chromosome_length, + ga.population_size, + chromosome_impl, + gene_impl, + ga.target_fitness_type, + ga.update_fitness, + ga.parent_ratio, + ga.selection_probability, + ga.tournament_size_ratio, + ga.current_generation, + float(ga.current_fitness), + ga.generation_goal, + ga.fitness_goal, + ga.tolerance_goal, + ga.percent_converged, + ga.chromosome_mutation_rate, + ga.gene_mutation_rate, + ga.initialization_impl.__name__, + ga.fitness_function_impl.__name__, + ga.parent_selection_impl.__name__, + ga.crossover_individual_impl.__name__, + ga.crossover_population_impl.__name__, + ga.survivor_selection_impl.__name__, + ga.mutation_individual_impl.__name__, + ga.mutation_population_impl.__name__, + ga.termination_impl.__name__, + ga.database_name + ] + + # Clean up so the sqlite database accepts the data structure + for i in range(len(db_config_list)): + if db_config_list[i] == None: + db_config_list[i] = "None" + if db_config_list[i] == True: + db_config_list[i] = "True" + if db_config_list [i] == False: + db_config_list[i] = "False" + + # For some reason it has to be in var = array(tuple()) form + db_config_list = tuple(db_config_list) + db_config_list = [db_config_list] + + # Create sql query structure + sql_start = '''INSERT INTO config (chromosome_length, + population_size, + chromosome_impl, + gene_impl, + target_fitness_type, + update_fitness, + parent_ratio, + selection_probability, + tournament_size_ratio, + current_generation, + current_fitness, + generation_goal, + fitness_goal, + tolerance_goal, + percent_converged, + chromosome_mutation_rate, + gene_mutation_rate, + initialization_impl, + fitness_function_impl, + parent_selection_impl, + crossover_individual_impl, + crossover_population_impl, + survivor_selection_impl, + mutation_individual_impl, + mutation_population_impl, + termination_impl, + database_name) VALUES(''' + + # Automate the value inputs + sql_middle = '?,' * (27 - 1) + sql_end = '?) ' + sql = sql_start + sql_middle + sql_end + + # Execute sql query + cur = self.conn.cursor() + cur.executemany(sql, db_config_list) + self.conn.commit() + return cur.lastrowid def query_all(self, query): """Query for muliple rows of data"""