Skip to content

Instantly share code, notes, and snippets.

@danilobellini
Last active October 18, 2017 16:37
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danilobellini/55431e0d878169196f5070cc2898d7e3 to your computer and use it in GitHub Desktop.
Save danilobellini/55431e0d878169196f5070cc2898d7e3 to your computer and use it in GitHub Desktop.
A "Hello World" genetic algorithm I've made based on the C# code shown by Italo Jose de Oliveira at his TDC São Paulo 2017 presentation
#!/usr/bin/python3
"""
Genetic algorithm example that finds the best string match using the
hamming distance to define an aptitude function.
"""
from random import choice, seed, randrange
from functools import partial
import string
def crossover(a, b):
idx = randrange(len(a))
return a[:idx] + b[idx:]
def aptitude(goal, result):
"""Aptitude = String length - Hamming distance"""
return sum(a == b for a, b in zip(goal, result))
def generate_single(chars, length):
return "".join(choice(chars) for unused in range(length))
def solve_genetic(goal, chars, psize, keep, select, cross, epochs):
apt_goal = partial(aptitude, goal)
gen_rand = partial(generate_single, chars, len(goal))
population = [gen_rand() for unused in range(psize)]
for epoch in range(1, epochs + 1):
selected = sorted(population, key=apt_goal, reverse=True)[:select]
first = selected[0]
print("Generation {}: Aptitude = {} ({})"
.format(epoch, apt_goal(first), first))
population = [crossover(choice(selected), choice(selected))
for unused in range(cross)]
population.extend(gen_rand() for unused in range(psize - cross - keep))
population.extend(selected[:keep])
if __name__ == "__main__":
seed(123)
solve_genetic(goal="Hello world",
chars=string.ascii_letters + " ",
psize=100, keep=1, select=50, cross=50, epochs=150)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment