import asyncio import logging from dotenv import load_dotenv from mathema.core.population_monitor import init_population from mathema.genotype.neo4j.genotype import neo4j from mathema.utils.logging_config import setup_logging setup_logging() log = logging.getLogger(__name__) N_RUNS = 20 async def run_single_car_experiment(run_idx: int): pop_id = f"car_pop_run{run_idx:02d}" log.info(f"=== START RUN {run_idx + 1}/{N_RUNS} ({pop_id}) ===") monitor = await init_population(( pop_id, [{"morphology": "car_racing_features", "neural_afs": ["tanh"]}], "gt", "competition", )) try: # ⏱️ max. 35 Minuten warten (30 min Training + Puffer) await asyncio.wait_for( monitor._stopped_evt.wait(), timeout=35 * 60 ) except asyncio.TimeoutError: log.error( f"[RUN {run_idx:02d}] TIMEOUT after 35min – forcing shutdown" ) try: await monitor.stop("shutdown") except Exception as e: log.exception( f"[RUN {run_idx:02d}] failed to stop monitor cleanly: {e}" ) # --- Post-run logging --- s = monitor.state try: best = await monitor._best_fitness_in_population(s.population_id) except Exception: best = float("nan") log.info( f"=== END RUN {run_idx + 1}/{N_RUNS} " f"gens={s.pop_gen} best_fitness={best:.6f} evals={s.eval_acc} ===" ) async def main(): load_dotenv() try: for i in range(N_RUNS): await run_single_car_experiment(i) log.info("=== ALL RUNS FINISHED ===") finally: try: await neo4j.close() except Exception: pass if __name__ == "__main__": asyncio.run(main())