Skip to content

Instantly share code, notes, and snippets.

@Curt-Park
Last active June 20, 2021 09:31
Show Gist options
  • Save Curt-Park/5ae319a87ac96de760ed13cb258c7c59 to your computer and use it in GitHub Desktop.
Save Curt-Park/5ae319a87ac96de760ed13cb258c7c59 to your computer and use it in GitHub Desktop.
Get the positive integer solution by Genetic Algorithm, given a / (b + c) + b / (a + c) + c / (a + b) = 4.
"""Genetic algorithm solver.
Given the following function:
y = f(w1:w3) = w1 / (w2 + w3) + w2 / (w1 + w3) + w3 / (w1 + w2)
where y=4
What are the best values for the 3 weights (w1 to w3)?
We are going to use the genetic algorithm to optimize this function.
"""
import pygad
import numpy
from fractions import Fraction
# number of generations
num_generations = 100000
# number of solutions to be selected as parents in the mating pool
num_parents_mating = 10
# number of solutions in the population
sol_per_pop = 1000
# function output
desired_output = 4
# mutation parameters
mutation_probability = 0.99
random_mutation_min_val = -10
random_mutation_max_val = 10
# gene parameters
gene_low = 0
gene_high = int(1e96)
gene_type = [int, int, int]
gene_space = [{"low": gene_low, "high": gene_high}] * len(gene_type)
# epsilon
eps = 1e-7
def fn(solution):
output = 0
output += solution[0] / (solution[1] + solution[2] + eps)
output += solution[1] / (solution[0] + solution[2] + eps)
output += solution[2] / (solution[0] + solution[1] + eps)
return output
def fitness_func(solution, solution_idx):
output = fn(solution)
fitness = 1.0 / (numpy.abs(output - desired_output) + eps)
return fitness
def on_generation(ga_instance):
best_solution = ga_instance.best_solution()[0]
fitness = ga_instance.best_solution()[1]
print(f"Generation: {ga_instance.generations_completed}")
print(f"\tBest Solution = {best_solution}")
print(f"\tFitness = {fitness}")
print(f"\tOutput = {fn(best_solution)}")
print()
ga_instance = pygad.GA(
num_generations=num_generations,
num_parents_mating=num_parents_mating,
sol_per_pop=sol_per_pop,
fitness_func=fitness_func,
mutation_probability=mutation_probability,
random_mutation_min_val=random_mutation_min_val,
random_mutation_max_val=random_mutation_max_val,
on_generation=on_generation,
num_genes=len(gene_type),
gene_space=gene_space,
gene_type=gene_type,
)
# Running the GA to optimize the parameters of the function.
ga_instance.run()
# Returning the details of the best solution.
solution, solution_fitness, solution_idx = ga_instance.best_solution(
ga_instance.last_generation_fitness
)
print(f"Parameters of the best solution : {solution}")
print(f"Fitness value of the best solution: {solution_fitness}")
print(f"The function output: {fn(solution)}")
ga_instance.plot_fitness()
# verification
x = Fraction(solution[0], solution[1] + solution[2])
y = Fraction(solution[1], solution[0] + solution[2])
z = Fraction(solution[2], solution[0] + solution[1])
out = x + y + z
print(out)
assert out == Fraction(4, 1)
@Curt-Park
Copy link
Author

Curt-Park commented Jun 20, 2021

Parameters of the best solution : [39019250076521295217317185053082552883919275822398149692658500881335160107394798713583993618432
 924324823125432460059785457267475183317228805791599002535468920824284456662552641964618006134784
 207455897457411893865061936344035918666029691739128390547583982434470344032139724600331189878784]
Fitness value of the best solution: 2756642.650468617
The function output: 4.000000262760113

Not optimal solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment