Skip to content

Instantly share code, notes, and snippets.

@JakubDotPy
Created November 24, 2021 13:55
Show Gist options
  • Save JakubDotPy/5333ef66561ec5b651ef9d9e399b2f76 to your computer and use it in GitHub Desktop.
Save JakubDotPy/5333ef66561ec5b651ef9d9e399b2f76 to your computer and use it in GitHub Desktop.
Simple genetical algorythm solving binomial equation.
"""
find foo(x, y, z) == 25
"""
import random
from itertools import chain
MAX_GENERATIONS = 10_000
GEN_POOL_SIZE = 1_000
BEST_N = 100
def foo(x, y, z):
return 6 * x ** 4 + 9 * y ** 2 + 90 * z - 25
def fitness(x, y, z):
"""rank the fitness of the solution"""
answer = foo(x, y, z)
return 99999 if answer == 0 else abs(1 / answer)
# generate random solutions
def rand_tuple():
return tuple(random.uniform(0, 10_000) for _ in range(3))
solutions = [rand_tuple() for _ in range(GEN_POOL_SIZE)]
for gen in range(MAX_GENERATIONS):
# evaluate and sort solutions
ranked_solutions = sorted(
((fitness(*sol), sol) for sol in solutions),
key=lambda x: x[0],
reverse=True
)
# take n best solutions
best_solutions = ranked_solutions[:BEST_N]
if best_solutions[0][0] > 999:
result = best_solutions[0]
print(f'{gen=}')
print(f'{result=}')
print(f'foo(result) = {foo(*result[1])}')
break
# combine solutions
parameter_pool = list(chain(
*(sol[1] for sol in best_solutions)
))
# mutate and create a new generation
new_gen = [
[random.choice(parameter_pool) * random.uniform(0.99, 1.01)
for _ in range(3)]
for _ in range(GEN_POOL_SIZE)
]
solutions = new_gen
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment