Skip to content

Instantly share code, notes, and snippets.

@atif-hassan
Last active November 11, 2020 19:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atif-hassan/353e7a482fdc13e5f2c569d0b8c243c2 to your computer and use it in GitHub Desktop.
Save atif-hassan/353e7a482fdc13e5f2c569d0b8c243c2 to your computer and use it in GitHub Desktop.
'''
Genetic Algorithm for with Grid System 9x9
'''
import numpy as np
from Farm_Evaluator_Edit_Vec import fitness_func
import matplotlib.pyplot as plt
import pandas as pd
from joblib import Parallel, delayed
import multiprocessing
def convert_box_to_coord(surface):
surface = np.rot90(surface,0)
X, Y = list(), list()
for i in range(len(surface)):
for j in range(len(surface)):
if surface[i,j] == 1:
X.append((i+1)*433)
Y.append((j+1)*433)
return X, Y
def convert_coord_to_box(X, Y, n=9):
windfarm_layout = np.zeros((n,n), dtype=np.int)
for i in range(50):
x = X[i]
y = Y[i]
a = np.linspace(50,3900, n+1)
index_x = np.argmin(np.abs(np.array(a)-x))
index_y = np.argmin(np.abs(np.array(a)-y))
if a[index_x]>x:
index_x_box = index_x-1
else:
index_x_box = index_x
if a[index_y]>y:
index_y_box = index_y-1
else:
index_y_box = index_y
windfarm_layout[index_x_box, index_y_box] = 1
return np.rot90(windfarm_layout)
def convert_sol_to_idx(sol):
return np.where(sol==1)[0]
def convert_idx_to_sol(idx_sample, n=81):
a = np.zeros((n))
a[idx_sample] = 1
return a
def print_windfarm_layout(windfarm_layout):
for i in range(len(windfarm_layout)):
for j in range(len(windfarm_layout[0])):
print(windfarm_layout[i,j], end=" " )
print("\n")
def get_fitness_score(idx_sample):
wf_layout = convert_idx_to_sol(idx_sample).reshape(9,9)
X1, Y1 = convert_box_to_coord(wf_layout)
sc = fitness_func(X1,Y1)
return sc
all_idx = [i for i in range(81)]
def mutate(idx, k=50):
mutate_idx = np.random.randint(0, k)
diff_idx = list(set(all_idx) - set(idx))
idx[mutate_idx] = np.random.choice(diff_idx, 1)[0]
return idx
def get_population(n=100, best_layout=None, k=50):
best_sol = best_layout.flatten()
population = np.zeros((n,k), dtype=np.int8)
population[0] = convert_sol_to_idx(best_sol)
for i in range(1,n):
population[i] = mutate(convert_sol_to_idx(best_sol))
return population
def get_fitness_score_pop(pop):
num_cores = multiprocessing.cpu_count()
fit_score_pop =Parallel(n_jobs=num_cores)(delayed(get_fitness_score)(each) for each in pop)
return np.array(fit_score_pop)
def cross_over(a, b):
c = list(set(a).union(set(b)))
child = np.random.choice(c, 50, replace=False)
return child
## either read from the CSV or read from seed layout
read csv = False
if read_csv == True:
df = pd.read_csv("best_initializer_new.csv")
X = df['x']
Y = df['y']
else:
windfarm_layout = np.array(
[[1, 1, 1, 1, 1, 0, 1, 1, 1 ],
[1, 0, 1, 0, 1, 0, 1, 1, 1 ],
[1, 1, 0, 1, 0, 1, 0, 0, 1 ],
[1, 0, 0, 0, 0, 0, 1, 1, 1 ],
[0, 1, 0, 0, 0, 0, 1, 0, 1 ],
[1, 0, 1, 0, 1, 0, 1, 0, 1 ],
[1, 0, 1, 0, 1, 0, 1, 0, 1 ],
[1, 1, 1, 0, 1, 0, 1, 0, 1 ],
[1, 1, 1, 1, 1, 0, 1, 1, 1 ]]
)
X, Y = convert_box_to_coord(windfarm_layout)
## Plot the turbines
score = fitness_func(X,Y)
print("score:" , score)
plt.scatter(X,Y , c ='r')
plt.show()
## get the initialized Population for GA
pop = get_population(n=100, best_layout=windfarm_layout)
N_GEN = 10 ## Number of Gneration
N_CHILD = 50
p_C = 0.8 ## Cross-over probablity
p_M = 0.8 ## Mutation probablity
best_fit_gen = []
for gen in range(N_GEN):
print("Gen ",gen)
pop = pop.astype(np.int)
new_pop = np.zeros((N_CHILD,50))
fit_score_pop = get_fitness_score_pop(pop)
arg_fit = np.argsort(fit_score_pop)[::-1]
print("Top fitness:", fit_score_pop[arg_fit[:5]])
sum_fit = np.sum(fit_score_pop)
best_fit_gen.append(np.max(fit_score_pop))
## Convert the finess into selection probablities
selection_probs = [f/sum_fit for f in fit_score_pop]
for i in range(N_CHILD):
if np.random.random()< p_C:
## select couples with proportainal to selection probablities
couple = np.random.choice(len(pop), 2, p=selection_probs, replace=False)
new_pop[i] = cross_over(pop[couple[0]], pop[couple[1]])
else
new_pop[i] = pop[np.random.choice(len(pop), 1, p=selection_probs)]
if np.random.random()< p_M:
## mutate the new child
new_pop[i] = mutate(new_pop[i])
## merge top 50 of old populationa and 50 new child
pop = np.vstack((pop[arg_fit[:50]], new_pop))
print("best fit gen:", best_fit_gen)s
np.save('best_pop.npy', pop)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment