Created
April 4, 2012 06:35
-
-
Save desertmonad/2299154 to your computer and use it in GitHub Desktop.
helloworld genetic algorithm in python
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 collections import namedtuple | |
from operator import itemgetter | |
import string | |
import random | |
GA_POPSIZE = 1024 #ga population size | |
GA_MAXITER = 200 #maximum iterations | |
GA_ELITRATE = 0.2 #elitism rate (varname [sic]) | |
GA_MUTATIONRATE = 0.25 | |
GA_MUTATION = 32768 * GA_MUTATIONRATE | |
GA_TARGET = "Hello World" | |
ga_struct = namedtuple("ga_struct", [ "string", "fitness"]) | |
def init_population(ga_population, ga_buffer): | |
tsize = len(GA_TARGET) | |
for i in range(0,GA_POPSIZE): | |
random_string = "".join((random.choice(string.letters+" ") for x in range(0,tsize))) | |
citizen = ga_struct(random_string,0) | |
ga_population.append(citizen) | |
ga_buffer.append(ga_struct(" ",0)) | |
def calc_fitness(ga_population): | |
pop_index = 0 | |
for item in ga_population: | |
index = 0 | |
fitness = 0 | |
for letter in item.string: | |
fitness += abs(ord(letter) - ord(GA_TARGET[index])) | |
index += 1 | |
ga_population[pop_index] = item._replace(fitness=fitness) | |
pop_index += 1 | |
def sort_by_fitness(ga_population): | |
ga_population.sort(key=itemgetter(1)) | |
def mutate(ga_population, index): | |
rand_handler = random.Random() | |
tsize = len(GA_TARGET) | |
ipos = rand_handler.randint(0,tsize-1) - 1 | |
new_letter = random.choice(string.letters) | |
citizen = ga_population[index] | |
temp_list = list(citizen.string) | |
temp_list[ipos]=new_letter | |
citizen = citizen._replace(string="".join(temp_list)) | |
ga_population[index] = citizen | |
def elitism(ga_population, ga_buffer, esize): | |
for i in range(0,esize): | |
ga_buffer[i] = ga_population[i] | |
def mate(ga_population, ga_buffer): | |
esize = int(GA_POPSIZE * GA_ELITRATE) | |
tsize = len(GA_TARGET) | |
rand_handler = random.Random() | |
elitism(ga_population, ga_buffer, esize) | |
#mate the rest | |
for i in range(esize,GA_POPSIZE): | |
i1 = rand_handler.randint(0,int(GA_POPSIZE/2)) | |
i2 = rand_handler.randint(0,int(GA_POPSIZE/2)) | |
spos = rand_handler.randint(0,tsize) | |
ga_buffer[i] = ga_struct(ga_population[i1].string[0:spos] + ga_population[i2].string[spos:tsize],ga_buffer[i].fitness) | |
if rand_handler.random() < GA_MUTATION: | |
mutate(ga_buffer,i) | |
def main(): | |
my_population = [] | |
my_buffer = [] | |
init_population(my_population,my_buffer) | |
last = 0 | |
for i in range(0,GA_MAXITER): | |
calc_fitness(my_population) | |
sort_by_fitness(my_population) | |
if my_population[0].fitness != last: | |
print " iter: %d,\t%s, \t score:%d " % (i, my_population[0].string, my_population[0].fitness) | |
last = my_population[0].fitness | |
if my_population[0].fitness == 0: | |
break | |
mate(my_population, my_buffer) | |
(my_buffer, my_population) = (my_population, my_buffer) #swap | |
print "done" | |
if __name__=="__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment