Skip to content

Instantly share code, notes, and snippets.

@soravux
Last active August 29, 2015 13:57
Show Gist options
  • Save soravux/9657679 to your computer and use it in GitHub Desktop.
Save soravux/9657679 to your computer and use it in GitHub Desktop.
import operator
import math
import random
import ctypes
from functools import reduce
import numpy
from deap import algorithms
from deap import base
from deap import creator
from deap import tools
from deap import gp
# Define new functions
def div(left, right):
try:
return int(left / right)
except ZeroDivisionError:
return 0
def mod(left, right):
try:
return int(left % right)
except ZeroDivisionError:
return 0
def lshift(val):
return operator.lshift(val, 1)
def rshift(val):
return operator.rshift(val, 1)
def arity3(left, middle, right):
return left + middle + right
defaultSymbolMap = {
'add': '({0} + {1})',
'sub': '({0} - {1})',
'xor': '({0} ^ {1})',
'mod': '({0} % {1})',
'mul': '({0} * {1})',
'div': '({0} / {1})',
'neg': '~{0}',
'lshift': '({0} << 1)',
'rshift': '({0} >> 1)',
}
def getInfix(individual, symbolMap=defaultSymbolMap, index=0):
x = individual[index]
if x.arity >= 3:
data = []
last_index = index
for _ in range(x.arity):
out, last_index = getInfix(individual, index=last_index+1)
data.append(out)
retVal = x.seq.format(*data)
elif x.arity == 2:
out_left, next_idx = getInfix(individual, index=index+1)
out_right, last_index = getInfix(individual, index=next_idx+1)
retVal = symbolMap.get(x.name, x.name).format(out_left, out_right)
elif x.arity == 1:
val, last_index = getInfix(individual, index=index+1)
retVal = symbolMap.get(x.name, x.name).format(val)
else:
retVal, last_index = x.value, index
if index == 0:
return retVal
return retVal, last_index
pset = gp.PrimitiveSet("MAIN", 1)
pset.addPrimitive(arity3, 3)
pset.addPrimitive(operator.add, 2)
pset.addPrimitive(operator.sub, 2)
pset.addPrimitive(operator.mul, 2)
pset.addPrimitive(mod, 2)
pset.addPrimitive(operator.xor, 2)
pset.addPrimitive(div, 2)
pset.addPrimitive(operator.neg, 1)
pset.addPrimitive(lshift, 1)
pset.addPrimitive(rshift, 1)
pset.addEphemeralConstant("rand101", lambda: random.randint(-1, 1))
pset.renameArguments(ARG0='x')
creator.create("FitnessMulti", base.Fitness, weights=(-1.0,))
creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMulti)
toolbox = base.Toolbox()
toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=2)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("compile", gp.compile, pset=pset)
def evaluation(individual, points):
# Transform the tree expression in a callable function
func = toolbox.compile(expr=individual)
# Evaluate the mean squared error between the expression
# and the real function
sqerrors = ((func(x) - (x ^ 0b101001101))**2 for x in points)
return math.fsum(sqerrors) / len(points),
points = [int(x) for x in range(0, 42)]
toolbox.register("evaluate", evaluation, points=points)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("mate", gp.cxOnePoint)
toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset)
def main():
#random.seed(315)
pop = toolbox.population(n=300)
hof = tools.HallOfFame(10)
stats_fit = tools.Statistics(lambda ind: ind.fitness.values)
stats_size = tools.Statistics(len)
mstats = tools.MultiStatistics(fitness=stats_fit, size=stats_size)
mstats.register("avg", numpy.mean)
mstats.register("std", numpy.std)
mstats.register("min", numpy.min)
mstats.register("max", numpy.max)
try:
pop, log = algorithms.eaSimple(pop, toolbox, 0.5, 0.1, 40, stats=mstats,
halloffame=hof, verbose=True)
except KeyboardInterrupt:
pass
print()
for idx, y in enumerate(hof):
err, = evaluation(y, points)
print("#{idx:01d}: ({err:.2f}) {eq}".format(
eq=getInfix(y),
**locals()
))
return pop, log, hof
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment