-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathga.py
58 lines (49 loc) · 1.71 KB
/
ga.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import random
from tqdm import tqdm
import matplotlib.pyplot as plt
from animation import Animation
class GeneticAlgorithm:
def __init__(
self,
population,
num_generations=50,
num_parents=4,
mutation_probability=0.05,
animate=False,
):
self.population = population
self.num_generations = num_generations
self.num_parents = num_parents
self.mutation_probability = mutation_probability
self.animate = animate
if self.animate:
self.animation = Animation()
self.fitness = []
def generate_offspring(self):
new_population = []
for _ in range(len(self.population.individuals)):
parent_a, parent_b = random.sample(self.population.parents, 2)
child = parent_a.crossover(parent_b)
child.mutate(self.mutation_probability)
new_population.append(child)
self.population.individuals = new_population
def evolutionary_cycle(self):
self.population.evaluate()
self.fitness.append(max(self.population.fitness))
self.population.select_parents(self.num_parents)
self.generate_offspring()
if self.animate:
self.animation.save_frame(self.population)
def evolve(self):
for _ in tqdm(range(self.num_generations), desc="Evolution"):
self.evolutionary_cycle()
if self.animate:
self.animation.generate()
def plot_fitness(self):
_, ax = plt.subplots(figsize=(8, 4))
ax.plot(self.fitness)
ax.set_xlabel("Generation")
ax.set_ylabel("Fitness")
ax.set_title("Fitness Evolution")
ax.grid(True)
plt.tight_layout()