Фитнес функция как параметр
This commit is contained in:
@@ -1,9 +1,16 @@
|
||||
import math
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from gen import GARunConfig, genetic_algorithm
|
||||
from prettytable import PrettyTable
|
||||
|
||||
|
||||
def target_function(x: float) -> float:
|
||||
"""f(x) = sin(x)/x^2"""
|
||||
return math.sin(x) / (x * x)
|
||||
|
||||
|
||||
# Базовая папка для экспериментов
|
||||
BASE_DIR = "experiments"
|
||||
|
||||
@@ -16,6 +23,7 @@ PM_VALUES = [0.001, 0.01, 0.05, 0.1, 0.2] # вероятности мутаци
|
||||
BASE_CONFIG = {
|
||||
"x_min": 3.1,
|
||||
"x_max": 20.0,
|
||||
"fitness_func": target_function,
|
||||
"precision_digits": 3,
|
||||
"max_generations": 200,
|
||||
"seed": 17,
|
||||
|
||||
36
lab1/gen.py
36
lab1/gen.py
@@ -10,11 +10,6 @@ import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
|
||||
def target_function(x: float) -> float:
|
||||
"""f(x) = sin(x)/x^2"""
|
||||
return math.sin(x) / (x * x)
|
||||
|
||||
|
||||
def bits_for_precision(x_min: float, x_max: float, digits_after_decimal: int) -> int:
|
||||
"""
|
||||
Подбор числа бит L так, чтобы шаг сетки был ≤ 10^{-digits_after_decimal}.
|
||||
@@ -133,13 +128,14 @@ def mutation(chrom: List[int], pm: float) -> None:
|
||||
|
||||
@dataclass
|
||||
class GARunConfig:
|
||||
x_min: float = 3.1
|
||||
x_max: float = 20.0
|
||||
precision_digits: int = 3 # точность сетки ~0.001
|
||||
pop_size: int = 100 # размер популяции
|
||||
pc: float = 0.7 # вероятность кроссинговера
|
||||
pm: float = 0.01 # вероятность мутации
|
||||
max_generations: int = 200 # максимальное количество поколений
|
||||
x_min: float
|
||||
x_max: float
|
||||
fitness_func: Callable[[float], float]
|
||||
precision_digits: int # точность сетки ~0.001
|
||||
pop_size: int # размер популяции
|
||||
pc: float # вероятность кроссинговера
|
||||
pm: float # вероятность мутации
|
||||
max_generations: int # максимальное количество поколений
|
||||
seed: int | None = None # seed для генератора случайных чисел
|
||||
save_generations: list[int] | None = (
|
||||
None # индексы поколений для сохранения графиков
|
||||
@@ -166,10 +162,7 @@ class GARunResult:
|
||||
L: int # число бит
|
||||
|
||||
|
||||
def genetic_algorithm(
|
||||
config: GARunConfig,
|
||||
fitness_func: Callable[[float], float] = target_function,
|
||||
) -> GARunResult:
|
||||
def genetic_algorithm(config: GARunConfig) -> GARunResult:
|
||||
if config.seed is not None:
|
||||
random.seed(config.seed)
|
||||
np.random.seed(config.seed)
|
||||
@@ -187,7 +180,9 @@ def genetic_algorithm(
|
||||
best_x, best_f = 0, -float("inf")
|
||||
|
||||
for generation in range(config.max_generations):
|
||||
xs, fits = eval_population(population, config.x_min, config.x_max, fitness_func)
|
||||
xs, fits = eval_population(
|
||||
population, config.x_min, config.x_max, config.fitness_func
|
||||
)
|
||||
|
||||
# лучший в поколении + глобально лучший
|
||||
gi = int(np.argmax(fits))
|
||||
@@ -233,6 +228,7 @@ def genetic_algorithm(
|
||||
config.x_min,
|
||||
config.x_max,
|
||||
config.results_dir,
|
||||
config.fitness_func,
|
||||
)
|
||||
break
|
||||
|
||||
@@ -247,6 +243,7 @@ def genetic_algorithm(
|
||||
config.x_min,
|
||||
config.x_max,
|
||||
config.results_dir,
|
||||
config.fitness_func,
|
||||
)
|
||||
|
||||
# селекция
|
||||
@@ -285,6 +282,7 @@ def plot_generation_snapshot(
|
||||
x_min: float,
|
||||
x_max: float,
|
||||
results_dir: str,
|
||||
fitness_func: Callable[[float], float],
|
||||
) -> str:
|
||||
"""
|
||||
График для конкретного поколения с отображением всей популяции.
|
||||
@@ -292,10 +290,10 @@ def plot_generation_snapshot(
|
||||
os.makedirs(results_dir, exist_ok=True)
|
||||
|
||||
xs = np.linspace(x_min, x_max, 1500)
|
||||
ys = np.sin(xs) / (xs * xs)
|
||||
ys = [fitness_func(x) for x in xs]
|
||||
|
||||
fig = plt.figure(figsize=(10, 6))
|
||||
plt.plot(xs, ys, label="f(x)=sin(x)/x^2", alpha=0.7, color="blue")
|
||||
plt.plot(xs, ys, label="Целевая функция", alpha=0.7, color="blue")
|
||||
|
||||
# Отображаем всю популяцию текущего поколения
|
||||
if generation < len(history_populations_x):
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import math
|
||||
import os
|
||||
|
||||
from gen import GARunConfig, genetic_algorithm
|
||||
|
||||
|
||||
def target_function(x: float) -> float:
|
||||
"""f(x) = sin(x)/x^2"""
|
||||
return math.sin(x) / (x * x)
|
||||
|
||||
|
||||
# Запуск эксперимента с генетическим алгоритмом
|
||||
config = GARunConfig(
|
||||
x_min=3.1,
|
||||
x_max=20.0,
|
||||
fitness_func=target_function,
|
||||
precision_digits=3,
|
||||
pop_size=15,
|
||||
pc=0.7,
|
||||
|
||||
Reference in New Issue
Block a user