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
        mask = np.random.uniform(0,1,p) < Pmutate
        for i in np.arange(p)[mask]:
            offspring[i] += np.random.normal(0,xstd[i])
        if debug:
            print ("Mutated",sum(mask),"positions",offspring)

        # 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 [ ]: