Усреднил значения

This commit is contained in:
2025-09-11 22:02:59 +03:00
parent b6c9bf8e68
commit 931af08511
3 changed files with 84 additions and 57 deletions

View File

@@ -1,6 +1,7 @@
import math
import os
import shutil
import statistics
from gen import GARunConfig, genetic_algorithm
from prettytable import PrettyTable
@@ -19,6 +20,9 @@ POPULATION_SIZES = [10, 25, 50, 100]
PC_VALUES = [0.3, 0.4, 0.5, 0.6, 0.7, 0.8] # вероятности кроссинговера
PM_VALUES = [0.001, 0.01, 0.05, 0.1, 0.2] # вероятности мутации
# Количество запусков для усреднения результатов
NUM_RUNS = 30
# Базовые параметры (как в main.py)
BASE_CONFIG = {
"x_min": 3.1,
@@ -26,7 +30,7 @@ BASE_CONFIG = {
"fitness_func": target_function,
"precision_digits": 3,
"max_generations": 200,
"seed": 17,
"seed": None, # None для случайности, т. к. всё усредняем
"minimize": True,
"fitness_avg_threshold": -0.049, # критерий остановки
# при включенном сохранении графиков на время смотреть бессмысленно
@@ -34,23 +38,42 @@ BASE_CONFIG = {
}
def run_single_experiment(pop_size: int, pc: float, pm: float) -> tuple[float, int]:
def run_single_experiment(
pop_size: int, pc: float, pm: float
) -> tuple[float, float, float, float]:
"""
Запускает один эксперимент с заданными параметрами.
Возвращает (время_в_мс, номер_поколения).
Запускает несколько экспериментов с заданными параметрами и усредняет результаты.
Возвращает (среднее_время_в_мс, стд_отклонениеремени, среднее_поколений, стд_отклонение_поколений).
"""
config = GARunConfig(
**BASE_CONFIG,
pop_size=pop_size,
pc=pc,
pm=pm,
results_dir=os.path.join(
BASE_DIR, str(pop_size), f"pc_{pc:.3f}", f"pm_{pm:.3f}"
),
)
times = []
generations = []
result = genetic_algorithm(config)
return result.time_ms, result.generations
for run_num in range(NUM_RUNS):
config = GARunConfig(
**BASE_CONFIG,
pop_size=pop_size,
pc=pc,
pm=pm,
results_dir=os.path.join(
BASE_DIR,
str(pop_size),
f"pc_{pc:.3f}",
f"pm_{pm:.3f}",
f"run_{run_num}",
),
)
result = genetic_algorithm(config)
times.append(result.time_ms)
generations.append(result.generations)
# Вычисляем средние значения и стандартные отклонения
avg_time = statistics.mean(times)
std_time = statistics.stdev(times) if len(times) > 1 else 0.0
avg_generations = statistics.mean(generations)
std_generations = statistics.stdev(generations) if len(generations) > 1 else 0.0
return avg_time, std_time, avg_generations, std_generations
def run_experiments_for_population(pop_size: int) -> PrettyTable:
@@ -59,6 +82,7 @@ def run_experiments_for_population(pop_size: int) -> PrettyTable:
Возвращает таблицу результатов.
"""
print(f"\nЗапуск экспериментов для популяции размером {pop_size}...")
print(f"Количество запусков для усреднения: {NUM_RUNS}")
# Создаем таблицу
table = PrettyTable()
@@ -69,9 +93,13 @@ def run_experiments_for_population(pop_size: int) -> PrettyTable:
row = [f"{pc:.1f}"]
for pm in PM_VALUES:
print(f" Эксперимент: pop_size={pop_size}, Pc={pc:.1f}, Pm={pm:.3f}")
time_ms, generations = run_single_experiment(pop_size, pc, pm)
# Форматируем результат: время(поколение)
cell_value = f"{time_ms:.1f} ({generations})"
avg_time, std_time, avg_generations, std_generations = (
run_single_experiment(pop_size, pc, pm)
)
# Форматируем результат: среднееремя±стд_отклонение (среднее_поколения±стд_отклонение)
# cell_value = f"{avg_time:.1f}±{std_time:.1f} ({avg_generations:.1f}±{std_generations:.1f})"
cell_value = f"{avg_time:.1f} ({avg_generations:.0f})"
row.append(cell_value)
table.add_row(row)
@@ -86,6 +114,7 @@ def main():
print(f"Размеры популяции: {POPULATION_SIZES}")
print(f"Значения Pc: {PC_VALUES}")
print(f"Значения Pm: {PM_VALUES}")
print(f"Количество запусков для усреднения: {NUM_RUNS}")
print(
f"Критерий остановки: среднее значение > {BASE_CONFIG['fitness_avg_threshold']}"
)
@@ -103,7 +132,10 @@ def main():
print(f"\n{'='*60}")
print(f"РЕЗУЛЬТАТЫ ДЛЯ ПОПУЛЯЦИИ РАЗМЕРОМ {pop_size}")
print(f"{'='*60}")
print("Формат: время_в_мсомер_поколения)")
print(
f"Формат: среднееремя±стд_отклонениес (среднее_поколения±стд_отклонение)"
)
print(f"Усреднено по {NUM_RUNS} запускам")
print(table)
pop_exp_dir = os.path.join(BASE_DIR, str(pop_size))