In [2]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from IPython.display import display, clear_output
import copy

In [26]:
def GAsearch(f, x0, xstd, popsize, ngenerations, Pmutate, Pcrossover,
figureBackgroundf=None, initialize=True):

debug = False
p = len(x0)

# initialize population
if initialize:
population = np.zeros((popsize,p))
for i in range(p):
population[:,i] = np.random.normal(x0[i], xstd[i], popsize)
evaluations = f(population)

fig = plt.figure(figsize=(20, 10))

#Loop for generations
for g in range(ngenerations):

#print np.hstack((evaluations.reshape((-1,1)),population))

# Pick worst individual
randorder = np.random.permutation(range(popsize))
worst = randorder[np.argmin(evaluations[randorder])]
if np.random.uniform() < Pcrossover:
# Do Crossover. Pick two best
best2 = np.argsort(-evaluations)[0:2]
# Pick crossover point
point = np.random.randint(1,p)
# This always takes first part from best. Should randomly choose which part from best.
offspring = np.hstack((population[best2[0], 0:point],
population[best2[1], point:p]))
if debug:
print( "Cross",best2[0],"and",best2[1],"at",point)
print( population[best2[0]], population[best2[1]], offspring)
else:
# No crossover. Just pick current best
offspring = copy.copy(population[np.argmax(evaluations),:])
if debug:
print( "Best",np.argmax(evaluations),np.max(evaluations),offspring)

# mutation. Make vector of random True False values for each component
offspring[i] += np.random.normal(0,xstd[i])
if debug:

# evaluate new offspring. If better than worst, replace worst.
offspringEvaluation = f(offspring.reshape((1,-1)))
if offspringEvaluation >  np.min(evaluations):
if debug:
print ("Replaced index",worst,"eval",evaluations[worst],'with',offspringEvaluation)
evaluations[worst] = offspringEvaluation
population[worst,:] = offspring

if (g+1) % 5 == 0:
plt.clf()
plt.subplot(1,2,1)
plt.hist(evaluations,bins=np.linspace(0,1.2,10))
plt.subplot(1,2,2)
if figureBackgroundf:
figureBackgroundf()
plt.plot(population[:,0],population[:,1],'wo',alpha=0.8)
plt.xlim(-5,5)
plt.ylim(-5,5)
plt.title("Generation %d" % (g+1))

clear_output(wait=True)
display(fig)

clear_output(wait=True)
return (population, evaluations)

In [27]:
def hills(z):
""" z has 2-d points in rows """
return np.exp(-0.1*((z[:,0]-2)**2 + (z[:,1]-2)**2)) + \
np.exp(-0.5*((z[:,0]-3)**2 + (z[:,1]+2)**2))

In [28]:
xs = np.linspace(-5, 5, 20)
ys = np.linspace(-5, 5, 20)
x, y = np.meshgrid(xs, ys)
points = np.vstack((x.flat, y.flat)).T
zs = hills(points).reshape(x.shape)

def drawContours():
plt.contourf(xs, ys, zs)
plt.colorbar()

drawContours()

In [29]:
GAsearch?

Signature:
GAsearch(
f,
x0,
xstd,
popsize,
ngenerations,
Pmutate,
Pcrossover,
figureBackgroundf=None,
initialize=True,
)
Docstring: <no docstring>
File:      ~/public_html/cs445/notebooks/<ipython-input-26-5dedc0aef5d1>
Type:      function

In [31]:
res = GAsearch(hills, [4, -2], [5, 5], 20, 500, 0.8, 0.5, drawContours)

In [ ]: