Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save bakirillov/88ec29005b4569cd02f5c0d9a83186df to your computer and use it in GitHub Desktop.
Save bakirillov/88ec29005b4569cd02f5c0d9a83186df to your computer and use it in GitHub Desktop.
Yes, I wrote a code to win an internet argument. Look how bored I was.
import numpy as np
from tqdm import tqdm
class GenAlgWithoutPopulationRestriction():
def __init__(
self, N_init=10, target_string="ESCHO SPORIT SO MNOY BUDESH LOLKA SASAII",
temperature=1, pm=0.5, pmating=0.6
):
self.alphabet = [a for a in "ABCDEFGHIJKLMNOPQRSTUVWXYZ "]
self.ts = [a for a in target_string]
self.population = [self.generate_random() for a in np.arange(N_init)]
self.p_mutation = pm
self.temperature = temperature
self.p_mating = pmating
def generate_random(self):
return(np.random.choice(self.alphabet, len(self.ts)))
def fitness(self, s):
return(np.sum([1 if a == b else 0 for a,b in zip(s, self.ts)]))
def crossover(self, s1, s2):
mid = int(len(s1)/2)
s3 = list(s1[0:mid])+list(s2[mid:])
s4 = list(s2[0:mid])+list(s1[mid:])
return([s3, s4])
def mutate(self, s1):
s2 = s1[:]
s2[np.random.choice(np.arange(len(s1)))] = np.random.choice(self.alphabet)
return(s2)
def softmax(self, d):
e = np.exp(np.array(d)/self.temperature)
return(e/np.sum(e))
def mate(self, ffs):
pdist = self.softmax(ffs)
inds = np.random.choice(np.arange(len(self.population)), 2, p=pdist)
return(self.population[inds[0]], self.population[inds[1]])
def mating_selection(self, n_epochs=100):
for a in tqdm(list(range(n_epochs))):
if np.random.choice([True, False], p=[self.p_mutation, 1-self.p_mutation]):
chosen = np.random.choice(np.arange(len(self.population)))
self.population[chosen] = self.mutate(self.population[chosen])
if np.random.choice([True, False], p=[self.p_mating, 1-self.p_mating]):
ffs = [self.fitness(a) for a in self.population]
m1,m2 = self.mate(ffs)
self.population.extend(self.crossover(m1, m2))
def plot_top(self, n):
ordered = list(reversed(list(sorted(self.population, key=self.fitness))))
return(["".join(a) for a in ordered[0:n]])
g = GenAlgWithoutPopulationRestriction()
g.mating_selection(10000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment