Last active
August 29, 2015 14:02
-
-
Save macrintr/116f1bea7ebf0464a586 to your computer and use it in GitHub Desktop.
DEAP setup to create functions with memory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Author: Thomas Macrina | |
Date created: 06/23/2014 | |
Python Version: 2.7 | |
Use global class to allow GP functions to access previous values | |
""" | |
import random | |
from operator import * | |
from deap import gp | |
from deap import base | |
from deap import creator | |
from deap import tools | |
from functools import wraps | |
class Storage(): | |
def __init__(self): | |
self.idx = 0 | |
self.data = [] | |
def write(self, w): | |
self.data[self.idx].append(w) | |
self.idx += 1 | |
def read(self, n=1): | |
if self.idx < len(self.data): | |
r = self.data[self.idx][-n] | |
else: | |
self.data.append([]) | |
r = 0 | |
return r | |
def reset_idx(self): | |
self.idx = 0 | |
def reset_data(self): | |
self.data = [] | |
def _store(self, f): | |
"""Wrapper makes current function inputs new args & previous output | |
""" | |
@wraps(f) # maintains name of wrapped function | |
def wrapper(*args): | |
prev = self.read() # read previous output from data array | |
d = f(prev, *args) # compute new output using previous & new args | |
self.write(d) # write new output for use the next time | |
return d | |
return wrapper | |
class Output(): | |
def __init__(self, x, y): | |
self.d = {"x": x, "y": y} | |
def output(x, y): | |
return Output(x, y) | |
s = Storage() | |
pset = gp.PrimitiveSetTyped("main", [int], Output) | |
pset.renameArguments(ARG0='a') | |
pset.addPrimitive(output, [int, int], Output) | |
pset.addPrimitive(s._store(add), [int], int) | |
pset.addEphemeralConstant("i", lambda: random.randint(5, 20), int) | |
def evaluate(ind): | |
func = gp.compile(expr=ind, pset=pset) | |
o = [] | |
for i in xrange(10): | |
d = func(i) | |
o.append(d.d["x"] - d.d["y"]) | |
s.reset_idx() | |
for d in s.data: print d | |
s.reset_data() | |
return sum(o) | |
# initialize creator | |
creator.create("FitnessMax", base.Fitness, weights=(1.0,)) | |
creator.create("Ind", gp.PrimitiveTree, fitness=creator.FitnessMax) | |
# initialize toolbox | |
toolbox = base.Toolbox() | |
toolbox.register("rules", gp.genGrow, pset=pset, min_=2, max_=6, type_=Output) | |
toolbox.register("individual", tools.initIterate, creator.Ind, toolbox.rules) | |
toolbox.register("population", tools.initRepeat, list, toolbox.individual) | |
toolbox.register("evaluate", evaluate) | |
def evolve(NPOP=5): | |
pop = toolbox.population(NPOP) | |
n = 0 | |
for ind in pop: | |
print str(n) + " / " + str(len(pop)) | |
print ind | |
fit = toolbox.evaluate(ind) | |
print fit | |
ind.fitness.values = (fit,) | |
n += 1 | |
print "\n" | |
if __name__ == "__main__": | |
evolve() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment