diff --git a/lab1/expirements.py b/lab1/expirements.py new file mode 100644 index 0000000..8499d73 --- /dev/null +++ b/lab1/expirements.py @@ -0,0 +1,109 @@ +import os +import shutil + +from gen import GARunConfig, genetic_algorithm +from prettytable import PrettyTable + +# Базовая папка для экспериментов +BASE_DIR = "experiments" + +# Параметры для экспериментов +POPULATION_SIZES = [10, 50, 100] +PC_VALUES = [0.5, 0.6, 0.7, 0.8, 0.9] # вероятности кроссинговера +PM_VALUES = [0.001, 0.01, 0.05, 0.1, 0.2] # вероятности мутации + +# Базовые параметры (как в main.py) +BASE_CONFIG = { + "x_min": 3.1, + "x_max": 20.0, + "precision_digits": 3, + "max_generations": 200, + "seed": 17, + "min_fitness_avg": 0.015, # критерий остановки + # при включенном сохранении графиков на время смотреть бессмысленно + # "save_generations": [0, 50, 199], +} + + +def run_single_experiment(pop_size: int, pc: float, pm: float) -> tuple[float, int]: + """ + Запускает один эксперимент с заданными параметрами. + Возвращает (время_в_мс, номер_поколения). + """ + config = GARunConfig( + **BASE_CONFIG, + pop_size=pop_size, + pc=pc, + pm=pm, + results_dir=f"{BASE_DIR}/{pop_size}/{pc:.3f}/{pm:.3f}", + ) + + result = genetic_algorithm(config) + return result.time_ms, result.generations + + +def run_experiments_for_population(pop_size: int) -> PrettyTable: + """ + Запускает эксперименты для одного размера популяции. + Возвращает таблицу результатов. + """ + print(f"\nЗапуск экспериментов для популяции размером {pop_size}...") + + # Создаем таблицу + table = PrettyTable() + table.field_names = ["Pc \\ Pm"] + [f"{pm:.3f}" for pm in PM_VALUES] + + # Запускаем эксперименты для всех комбинаций Pc и Pm + for pc in PC_VALUES: + 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})" + row.append(cell_value) + table.add_row(row) + + return table + + +def main(): + """Основная функция для запуска всех экспериментов.""" + print("=" * 60) + print("ЗАПУСК ЭКСПЕРИМЕНТОВ ПО ПАРАМЕТРАМ ГЕНЕТИЧЕСКОГО АЛГОРИТМА") + print("=" * 60) + print(f"Размеры популяции: {POPULATION_SIZES}") + print(f"Значения Pc: {PC_VALUES}") + print(f"Значения Pm: {PM_VALUES}") + print(f"Критерий остановки: среднее значение > {BASE_CONFIG['min_fitness_avg']}") + print("=" * 60) + + # Создаем базовую папку + if os.path.exists(BASE_DIR): + shutil.rmtree(BASE_DIR) + os.makedirs(BASE_DIR) + + # Запускаем эксперименты для каждого размера популяции + for pop_size in POPULATION_SIZES: + table = run_experiments_for_population(pop_size) + + print(f"\n{'='*60}") + print(f"РЕЗУЛЬТАТЫ ДЛЯ ПОПУЛЯЦИИ РАЗМЕРОМ {pop_size}") + print(f"{'='*60}") + print("Формат: время_в_мс (номер_поколения)") + print(table) + + pop_exp_dir = os.path.join(BASE_DIR, str(pop_size)) + os.makedirs(pop_exp_dir, exist_ok=True) + with open(os.path.join(pop_exp_dir, "results.csv"), "w", encoding="utf-8") as f: + f.write(table.get_csv_string()) + print(f"Результаты сохранены в папке: {pop_exp_dir}/") + + print(f"\n{'='*60}") + print("ВСЕ ЭКСПЕРИМЕНТЫ ЗАВЕРШЕНЫ!") + print(f"Результаты сохранены в папке: {BASE_DIR}/") + print(f"{'='*60}") + + +if __name__ == "__main__": + main()