Skip to content

Instantly share code, notes, and snippets.

@vladinator1000
Created October 2, 2017 15:24
Show Gist options
  • Save vladinator1000/d85e713051c97eb1b36e065c3c37e5a6 to your computer and use it in GitHub Desktop.
Save vladinator1000/d85e713051c97eb1b36e065c3c37e5a6 to your computer and use it in GitHub Desktop.
so QUESTION
Hi, I'm trying to generate "Hello world!", but my results stop improving strings reach roughly about 70% similarity. Here's what I've done:
from difflib import SequenceMatcher
from numpy import std
from random import randint
import random
from pprint import pprint
GENES = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!."
TARGET = "Hello World!"
def randomCharFromString(string):
return string[randint(0, len(string) - 1)]
def randomStringFromString(string, length):
result = ''
for i in range(length - 1):
result += randomCharFromString(string)
return result
# Fitness
def asciiStringDistance(a, b):
distanceSum = 0
for charA, charB in zip(a, b):
distanceSum += abs(ord(charA) - ord(charB))
return distanceSum
# Two Tournaments, best of each become parents
def tournament(inputSet):
first = random.choice(tuple(inputSet))
second = random.choice(tuple(inputSet))
# Return tuple with bigger similarity ratio
if first[1] < second[1]:
return first
else:
return second
def mutateString(string, genes = GENES, probability = 0.05):
if random.random() < probability:
index = randint(0, len(string) - 1)
return string[:index] + randomCharFromString(genes) + string[index + 1:]
return string
# Crossover with probability, two strings returning tuple of tuples:
def crossover(parentOne, parentTwo, noCrossProbability = 0.05, fitnessFunction = asciiStringDistance):
if random.random() < noCrossProbability:
return (parentOne, parentTwo)
randomIndex = randint(0, len(parentOne[0]) - 1)
newStringOne = mutateString(
''.join((parentOne[0][:randomIndex], parentTwo[0][randomIndex:])),
)
newStringTwo = mutateString(
''.join((parentTwo[0][:randomIndex], parentOne[0][randomIndex:])),
GENES
)
return (
(newStringOne, fitnessFunction(newStringOne, TARGET)),
(newStringTwo, fitnessFunction(newStringTwo, TARGET)),
)
def generatePopulation(old = set([]), currentGeneration = 0, howManyGenerations = 50, fitnessStandardDeviations = []):
new = set([])
newDeviations = fitnessStandardDeviations
if currentGeneration < howManyGenerations:
while len(new) < len(old):
children = crossover(tournament(old), tournament(old))
for child in children:
new.add(child)
ratios = list(map(lambda child: child[1], list(new)))
newDeviations.append(std(ratios))
return generatePopulation(new, currentGeneration + 1, howManyGenerations, newDeviations)
return (old, newDeviations)
# Seed Population with tuples in this shape: (string, similarityRatio)
population = set([])
for i in range(500):
string = randomStringFromString(GENES, len(TARGET))
population.add(
(string, asciiStringDistance(string, TARGET))
)
result = generatePopulation(population, howManyGenerations = 50)
pprint(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment