diff --git a/Python_codes/Genetic Algorithm/ga.py b/Python_codes/Genetic Algorithm/ga.py
new file mode 100644
index 0000000..8f1c2da
--- /dev/null
+++ b/Python_codes/Genetic Algorithm/ga.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2021 Jude Michael Teves
+#
+# This file is a modification of the genetic algorithm library made by the same author.
+# The link of the original implementation can be found here: https://github.com/Cyntwikip/libraries/blob/master/genetic_algo/ga.py
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see .
+
+import ast, random, itertools
+
+import numpy as np
+import pandas as pd
+
+from collections.abc import Iterable
+
+class GeneticAlgo():
+
+ def __init__(self, genes_dict, debug=False, random_seed=42):
+ self.debug = debug
+ self.random_seed = random_seed
+ self.genes_dict = genes_dict
+ self.generate_chromosomes()
+
+ def generate_chromosomes(self):
+ keys = self.genes_dict.keys()
+ values = self.genes_dict.values()
+ chromosomes = list(itertools.product(*values))
+ c_len = len(chromosomes)
+ codes = [str(i).zfill(5) for i in range(c_len)]
+ chromosomes = pd.DataFrame(chromosomes, index=codes, columns=keys)
+ self.chromosomes = chromosomes
+ if self.debug:
+ print('Number of Chromosomes: {}'.format(chromosomes.shape[0]))
+
+ def get_initial_population(self, n):
+ np.random.seed(self.random_seed)
+ codes = list(self.chromosomes.index)
+ return np.random.choice(codes, n, replace=False)
+
+ def get_best_parents(self, fitness):
+ '''
+ fitness - dict {code: score}
+ '''
+ result = sorted(fitness.items(), key=lambda x: x[1], reverse=True)[:2]
+ result = [i[0] for i in result] # get code
+ # duplicate single parent
+ if len(result) == 1:
+ result = result*2
+ return result
+
+ def make_children(self, parent1_code, parent2_code, num_children, mutation_prob=0.1):
+ # random seed
+ np.random.seed(self.random_seed)
+ random.seed(self.random_seed)
+
+ parent_prob = (1 - mutation_prob)/2
+ children_chromosomes = []
+ for i in range(num_children):
+ chromosome = []
+ for key in self.chromosomes:
+ choices = [self.chromosomes.loc[parent1_code, key],
+ self.chromosomes.loc[parent2_code, key],
+ random.choice(self.genes_dict[key])]
+ if type(choices[0]) != str and isinstance(choices[0], Iterable):
+ choices = [str(i) for i in choices]
+ gene = [np.random.choice(choices, p = [parent_prob, parent_prob, mutation_prob])][0]
+ gene = ast.literal_eval(gene)
+ else:
+ gene = [np.random.choice(choices, p = [parent_prob, parent_prob, mutation_prob])][0]
+
+ chromosome.append(gene)
+ children_chromosomes.append(chromosome)
+
+ codes = list(map(self.get_chromosome_code, children_chromosomes))
+ codes = list(set(codes))
+ return codes
+
+ def get_chromosome_code(self, chromosome):
+ c = self.chromosomes
+ for key, row in c.iterrows():
+ if (row.values.tolist()==chromosome):
+ break
+ return key
diff --git a/Python_codes/Genetic Algorithm/sample.py b/Python_codes/Genetic Algorithm/sample.py
new file mode 100644
index 0000000..c944d71
--- /dev/null
+++ b/Python_codes/Genetic Algorithm/sample.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2021 Jude Michael Teves
+#
+# This file is a modification of the genetic algorithm library made by the same author.
+# The link of the original implementation can be found here: https://github.com/Cyntwikip/libraries/blob/master/genetic_algo/sample.py
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see .
+
+import click
+from ga import GeneticAlgo as ga
+
+import numpy as np
+
+# Pool of genes
+pool_scaler = ["MinMax (-1,1)", "MinMax (0,1)", "Std"]
+pool_batch_size = [64, 72, 128, 256]
+pool_lstm_layers = [[128, 128, 128],
+ [64, 64, 64],
+ [32, 32, 32],
+ [128, 64, 64],
+ [64, 32, 32],
+ [128, 64, 32]]
+pool_dropout = [0., 0.1, 0.2]
+pool_activation = ['tanh', 'sigmoid']
+pool_loss = ['mean_squared_error', 'mae']
+pool_epochs = [5]
+
+genes_dict = dict( scaler = pool_scaler,
+ batch_size = pool_batch_size,
+ lstm_layers = pool_lstm_layers,
+ dropout = pool_dropout,
+ activation = pool_activation,
+ loss = pool_loss,
+ epochs = pool_epochs
+ )
+
+ga = ga(genes_dict, debug=True)
+
+@click.group()
+def cli():
+ pass
+
+@cli.command(name='make-children')
+@click.argument('code1', type=str)
+@click.argument('code2', type=str)
+@click.option('-n', default=10)
+def make_children(code1, code2, n):
+ codes = ga.make_children(code1, code2, n)
+ print(codes)
+ return
+
+@cli.command(name='chromosomes-head')
+@click.option('-n', default=5)
+def chromosomes_head(n):
+ print(ga.chromosomes.head(n))
+
+@cli.command(name='get-population')
+@click.option('-n', default=10)
+def get_population(n):
+ pop = ga.get_initial_population(n)
+ print(pop)
+
+@cli.command(name='get-chromosome')
+@click.argument('code', type=str)
+def get_chromosome(code):
+ print(ga.chromosomes.loc[code])
+
+@cli.command(name='survival')
+@click.option('-n', default=10)
+def survival(n):
+ # n=1
+ codes = ga.get_initial_population(n)
+ np.random.seed(42)
+ scores = np.random.randint(0,40,n)
+ fitness = dict(zip(codes, scores))
+ print(fitness)
+ best_parents = ga.get_best_parents(fitness)
+ print(best_parents)
+
+@cli.command(name='random')
+@click.option('-n', default=5)
+def randomizer(n):
+ np.random.seed(42)
+ a = [1,2,3,4,5,6,7,8,9,10]
+
+ for i in range(n):
+ print(np.random.choice(a))
+
+@cli.command(name='test1')
+def test1():
+ import pandas as pd
+ df = pd.DataFrame({'a':[[0,1,3],[2,3,4]], 'b':['a','b'], 'c':[64, 128]})
+ compare = [[0,1,3], 'a', 64]
+ for key, row in df.iterrows():
+ if (row.values==compare).all():
+ print(key)
+
+if __name__ == '__main__':
+ cli()