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