Main controller for OpenEvolve Orchestrates the evolution process, coordinating between the prompt sampler, LLM ensemble, evaluator, and program database. Features: - Tracks the absolute best program across evolution steps - Ensures the best solution is not lost during the
| 54 | |
| 55 | |
| 56 | class OpenEvolve: |
| 57 | """ |
| 58 | Main controller for OpenEvolve |
| 59 | |
| 60 | Orchestrates the evolution process, coordinating between the prompt sampler, |
| 61 | LLM ensemble, evaluator, and program database. |
| 62 | |
| 63 | Features: |
| 64 | - Tracks the absolute best program across evolution steps |
| 65 | - Ensures the best solution is not lost during the MAP-Elites process |
| 66 | - Always includes the best program in the selection process for inspiration |
| 67 | - Maintains detailed logs and metadata about improvements |
| 68 | """ |
| 69 | |
| 70 | def __init__( |
| 71 | self, |
| 72 | initial_program_path: str, |
| 73 | evaluation_file: str, |
| 74 | config: Config, |
| 75 | output_dir: Optional[str] = None, |
| 76 | ): |
| 77 | # Load configuration (loaded in main_async) |
| 78 | self.config = config |
| 79 | |
| 80 | # Set up output directory |
| 81 | self.output_dir = output_dir or os.path.join( |
| 82 | os.path.dirname(initial_program_path), "openevolve_output" |
| 83 | ) |
| 84 | os.makedirs(self.output_dir, exist_ok=True) |
| 85 | |
| 86 | # Set up logging |
| 87 | self._setup_logging() |
| 88 | |
| 89 | # Manual mode queue lives in <openevolve_output>/manual_tasks_queue |
| 90 | self._setup_manual_mode_queue() |
| 91 | |
| 92 | # Set random seed for reproducibility if specified |
| 93 | if self.config.random_seed is not None: |
| 94 | import hashlib |
| 95 | import random |
| 96 | |
| 97 | import numpy as np |
| 98 | |
| 99 | # Set global random seeds |
| 100 | random.seed(self.config.random_seed) |
| 101 | np.random.seed(self.config.random_seed) |
| 102 | |
| 103 | # Create hash-based seeds for different components |
| 104 | base_seed = str(self.config.random_seed).encode("utf-8") |
| 105 | llm_seed = int(hashlib.md5(base_seed + b"llm").hexdigest()[:8], 16) % (2**31) |
| 106 | |
| 107 | # Propagate seed to LLM configurations |
| 108 | self.config.llm.random_seed = llm_seed |
| 109 | for model_cfg in self.config.llm.models: |
| 110 | if not hasattr(model_cfg, "random_seed") or model_cfg.random_seed is None: |
| 111 | model_cfg.random_seed = llm_seed |
| 112 | for model_cfg in self.config.llm.evaluator_models: |
| 113 | if not hasattr(model_cfg, "random_seed") or model_cfg.random_seed is None: |
no outgoing calls