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()