Compare commits

...

3 Commits

Author SHA1 Message Date
pre-commit-ci[bot]
9049228ff8 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-11-15 09:26:57 +00:00
UTSAV SINGHAL
84b29c0eed
Update genetic_algorithm_optimization.py 2024-11-15 14:56:23 +05:30
UTSAV SINGHAL
dbd29aed76
Update genetic_algorithm_optimization.py 2024-11-15 14:50:15 +05:30

View File

@ -1,6 +1,7 @@
import random
from collections.abc import Callable, Sequence
from concurrent.futures import ThreadPoolExecutor
import numpy as np
# Parameters
@ -59,10 +60,7 @@ class GeneticAlgorithm:
True
"""
return [
rng.uniform(
low=[self.bounds[j][0] for j in range(self.dim)],
high=[self.bounds[j][1] for j in range(self.dim)],
)
np.array([rng.uniform(b[0], b[1]) for b in self.bounds])
for _ in range(self.population_size)
]
@ -82,10 +80,10 @@ class GeneticAlgorithm:
... )
>>> individual = np.array([1.0, 2.0])
>>> ga.fitness(individual)
5.0 # The fitness should be 1^2 + 2^2 = 5
-5.0 # The fitness should be -1^2 + 2^2 = 5 for minimizing
>>> ga.maximize = True
>>> ga.fitness(individual)
-5.0 # The fitness should be -5 when maximizing
5.0 # The fitness should be 1^2 + 2^2 = 5 when maximizing
"""
value = float(self.function(*individual)) # Ensure fitness is a float
return value if self.maximize else -value # If minimizing, invert the fitness
@ -114,11 +112,17 @@ class GeneticAlgorithm:
>>> selected_parents = ga.select_parents(population_score)
>>> len(selected_parents)
2 # Should select the two parents with the best fitness scores.
>>> np.array_equal(selected_parents[0], np.array([1.0, 2.0])) # Parent 1 should be [1.0, 2.0]
>>> np.array_equal(selected_parents[0], np.array([1.0, 2.0]))
# Parent 1 should be [1.0, 2.0]
True
>>> np.array_equal(selected_parents[1], np.array([-1.0, -2.0])) # Parent 2 should be [-1.0, -2.0]
>>> np.array_equal(selected_parents[1], np.array([-1.0, -2.0]))
# Parent 2 should be [-1.0, -2.0]
True
"""
if not population_score:
raise ValueError("Population score is empty, cannot select parents.")
population_score.sort(key=lambda score_tuple: score_tuple[1], reverse=True)
selected_count = min(N_SELECTED, len(population_score))
return [ind for ind, _ in population_score[:selected_count]]
@ -237,10 +241,15 @@ class GeneticAlgorithm:
>>> isinstance(best_solution[1], float) # Second element should be a float
True
"""
best_individual = None
for generation in range(self.generations):
# Evaluate population fitness (multithreaded)
population_score = self.evaluate_population()
# Ensure population_score isn't empty
if not population_score:
raise ValueError("Population score is empty. No individuals evaluated.")
# Check the best individual
best_individual = max(
population_score, key=lambda score_tuple: score_tuple[1]
@ -253,7 +262,10 @@ class GeneticAlgorithm:
# Generate offspring using crossover and mutation
for i in range(0, len(parents), 2):
parent1, parent2 = parents[i], parents[(i + 1) % len(parents)]
parent1, parent2 = (
parents[i],
parents[(i + 1) % len(parents)],
) # Wrap around for odd cases
child1, child2 = self.crossover(parent1, parent2)
next_generation.append(self.mutate(child1))
next_generation.append(self.mutate(child2))