Skip to content

Commit ccbf8a5

Browse files
committed
Update genetic_algorithm_optimization.py
1 parent 6dd4159 commit ccbf8a5

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

genetic_algorithm/genetic_algorithm_optimization.py

+42-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import numpy as np
22

3-
43
class GeneticAlgorithmOptimizer:
54
def __init__(
65
self,
@@ -25,6 +24,11 @@ def __init__(
2524
def initialize_population(self):
2625
"""
2726
Initialize a population of random solutions within the bounds.
27+
28+
>>> optimizer = GeneticAlgorithmOptimizer(func=lambda x: x**2, bounds=[(-10, 10)])
29+
>>> pop = optimizer.initialize_population()
30+
>>> pop.shape == (optimizer.population_size, optimizer.num_variables)
31+
True
2832
"""
2933
return self.rng.uniform(
3034
low=self.bounds[:, 0],
@@ -36,12 +40,25 @@ def fitness(self, individual):
3640
"""
3741
Evaluate the fitness of an individual.
3842
In minimization problems, we aim to minimize the function value.
43+
44+
>>> optimizer = GeneticAlgorithmOptimizer(func=lambda x: x**2, bounds=[(-10, 10)])
45+
>>> optimizer.fitness([2])
46+
4
47+
>>> optimizer.fitness([0])
48+
0
3949
"""
4050
return self.func(*individual)
4151

4252
def select_parents(self, population, fitness_scores):
4353
"""
4454
Select parents using tournament selection.
55+
56+
>>> optimizer = GeneticAlgorithmOptimizer(func=lambda x: x**2, bounds=[(-10, 10)])
57+
>>> population = optimizer.initialize_population()
58+
>>> fitness_scores = np.array([optimizer.fitness(ind) for ind in population])
59+
>>> parent = optimizer.select_parents(population, fitness_scores)
60+
>>> len(parent) == optimizer.num_variables
61+
True
4562
"""
4663
selected_indices = self.rng.choice(
4764
range(self.population_size), size=2, replace=False
@@ -50,8 +67,14 @@ def select_parents(self, population, fitness_scores):
5067

5168
def crossover(self, parent1, parent2):
5269
"""
53-
Perform one-point crossover to create offspring.
54-
Skip crossover for single-variable functions.
70+
Perform one-point crossover to create offspring. Skip crossover for single-variable functions.
71+
72+
>>> optimizer = GeneticAlgorithmOptimizer(func=lambda x: x**2, bounds=[(-10, 10)])
73+
>>> parent1 = [1]
74+
>>> parent2 = [2]
75+
>>> child1, child2 = optimizer.crossover(parent1, parent2)
76+
>>> child1 == parent1 and child2 == parent2
77+
True
5578
"""
5679
if self.num_variables == 1:
5780
return parent1, parent2 # No crossover needed for single-variable functions
@@ -66,6 +89,12 @@ def crossover(self, parent1, parent2):
6689
def mutate(self, individual):
6790
"""
6891
Apply mutation to an individual with a given mutation probability.
92+
93+
>>> optimizer = GeneticAlgorithmOptimizer(func=lambda x: x**2, bounds=[(-10, 10)])
94+
>>> individual = [1]
95+
>>> new_individual = optimizer.mutate(individual.copy())
96+
>>> len(new_individual) == len(individual)
97+
True
6998
"""
7099
if self.rng.random() < self.mutation_prob:
71100
index = self.rng.integers(0, self.num_variables)
@@ -108,10 +137,19 @@ def evolve(self):
108137

109138
return best_solution, best_fitness
110139

111-
112140
if __name__ == "__main__":
113141
# Define the function to optimize
114142
def func(x, y):
143+
"""
144+
Example function to minimize x^2 + y^2
145+
146+
>>> func(0, 0)
147+
0
148+
>>> func(3, 4)
149+
25
150+
>>> func(-3, -4)
151+
25
152+
"""
115153
return x**2 + y**2 # Example: Minimizing x^2 + y^2
116154

117155
# Define the bounds for each variable

0 commit comments

Comments
 (0)