Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions Python_codes/Genetic Algorithm/ga.py
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

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
112 changes: 112 additions & 0 deletions Python_codes/Genetic Algorithm/sample.py
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

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