Created
September 3, 2011 17:24
-
-
Save Lambdanaut/1191488 to your computer and use it in GitHub Desktop.
A Simple Genetic Algorithm in Python for finding the best way to represent a number as a (limited) polynomial.
This file contains 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
from random import randint | |
#GE | |
#Constants | |
gens = 150 | |
popNum = 30 | |
mutRate = 20 # Rate of mutation = 1/mutRate | |
goal = 97 | |
chromosomeLength = 24 # Must be a multiple of 5 - 1. Example: 14, 19, 24, 29, 34 | |
#Init Variables | |
population = [[randint(0,1) for gene in range(0,chromosomeLength)] for x in range(0,popNum)] | |
#Math Funcs | |
def add (x,y): | |
return x + y | |
def sub(x,y): | |
return x - y | |
def mul(x,y): | |
return float(x) * float(y) | |
def div(x,y): | |
if y == 0: y = 1 #prevents from dividebyzero OH SHIT | |
return float(x) / float(y) | |
def getVal(val): | |
newVal = "" | |
for n in val: | |
newVal = newVal + str(n) | |
if newVal == "0000": | |
return 1 | |
elif newVal == "0001": | |
return 2 | |
elif newVal == "0010": | |
return 3 | |
elif newVal == "0011": | |
return 4 | |
elif newVal == "0100": | |
return 5 | |
elif newVal == "0101": | |
return 6 | |
elif newVal == "0110": | |
return 7 | |
elif newVal == "0111": | |
return 8 | |
elif newVal == "1000": | |
return 9 | |
elif newVal == "1001": | |
return 10 | |
elif newVal == "1010": | |
return 11 | |
elif newVal == "1011": | |
return 12 | |
elif newVal == "1100": | |
return 13 | |
elif newVal == "1101": | |
return 14 | |
elif newVal == "1110": | |
return 15 | |
elif newVal == "1111": | |
return 16 | |
else: | |
return 1 | |
#Fit Func | |
def evaluate (animal,willPrint): | |
stack = [] | |
toPrint = "" | |
while 1: | |
if len(stack) < 2: | |
stack.append(getVal(animal[0:4])) | |
toPrint = toPrint + str(getVal(animal[0:4])) | |
animal = animal[4:] | |
else: | |
if animal[0] == 0: | |
stack.append(mul(stack.pop(0),stack.pop(0))) | |
toPrint = toPrint + "*" | |
else: | |
stack.append(div(stack.pop(0),stack.pop(0))) | |
toPrint = toPrint + "/" | |
animal = animal [1:] | |
if len(animal) == 0: | |
break | |
toPrint = toPrint + " " | |
if willPrint == True: | |
print (toPrint) | |
return stack[0] | |
def fitness (num): | |
return abs(num - goal) | |
#Main | |
bestOfAllFit = population[0] | |
greatestFit = population[0] | |
for gen in range(0,gens): | |
print ("Number: " + str(evaluate(greatestFit,True)) ) | |
print ("Distance from Goal " + str(fitness(evaluate(greatestFit,False))) ) | |
greatestFit = population[0] | |
#Get new Greatest Fitness | |
for animal in population: | |
if fitness(evaluate(animal,False)) < fitness(evaluate(greatestFit,False)): | |
greatestFit = animal | |
if fitness(evaluate(greatestFit,False)) < fitness(evaluate(bestOfAllFit,False)): | |
bestOfAllFit = greatestFit | |
print ("\n---IMPORTANT TRANSITIONAL FORM---\n") | |
#Breed Populations | |
for animal in range(0,len(population)): | |
newAnimal = [] | |
for gene in range(0,len(population[animal])): | |
if randint(0,mutRate) == 0: | |
newAnimal.append(randint(0,1)) | |
else: | |
if randint(0,1) == 0: | |
newAnimal.append(greatestFit[gene]) | |
else: | |
newAnimal.append(population[animal][gene]) | |
population[animal] = newAnimal | |
print ("\n\n\n\nBest Solution: ") | |
print ("Number: " + str(evaluate(greatestFit,True)) ) | |
print ("Distance from Goal: " + str(fitness(evaluate(greatestFit,False))) ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment