Add pluggable Threshold-Elites and Dominated Novelty Search (DNS) database variants alongside MAP-Elites#416
Open
fangyihao wants to merge 1 commit intoalgorithmicsuperintelligence:mainfrom
Conversation
…nts alongside MAP-elites
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This change makes the program database implementation configurable at runtime and introduces two new database strategies—DNSProgramDatabase and ThresholdElitesProgramDatabase—while tightening several multi-island correctness edge cases (copy embedding, infinite-score handling). It also adds dedicated unit tests for both new database variants.
What changed
openevolve/config.py
Extended DatabaseConfig with:
variant: str = "DNSProgramDatabase" to select the database implementation by class name.
distance_threshold: float = 1.5 (used by the threshold-based elite filtering).
openevolve/controller.py
Switched database construction from a fixed ProgramDatabase(...) to dynamic instantiation:
Reads config.database.variant (defaults to "ProgramDatabase" if missing).
Uses importlib to load openevolve.database. and instantiate it.
This enables selecting different database behaviors via config without changing code.
openevolve/database.py
General robustness fixes
Import copy and math.
_update_best_program: avoid comparing / logging combined_score when either side is ±inf (prevents misleading “best program changed” logs and edge-case issues).
When seeding/initializing empty islands via copying the best program, the copied program now deep-copies embedding to avoid shared references across programs/islands.
get_island_stats: filters out ±inf scores before computing best_score / avg_score for cleaner island stats.
New database variants
ThresholdElitesProgramDatabase
Computes feature embedding + fitness-derived combined_score.
Runs novelty gating via existing _is_novel.
Applies a distance-threshold competition inside an island:
DNSProgramDatabase
Implements Dominated Novelty Search-style selection:
For each program, considers the set of dominating programs (higher combined_score).
Computes dominated novelty score as mean distance to those dominating programs (or +inf if none dominate).
Uses the median dominated novelty score as a cutoff; programs below the median get combined_score = -inf.
Keeps island assignment consistent and respects novelty gating before DNS filtering.
Tests
Added two new test suites:
tests/test_dns_database.py
tests/test_threshold_elites_database.py
These validate:
Multi-island initialization (correct island counts, per-island best tracking).
Targeted island insertion + metadata["island"] correctness.
Migration behavior: no migrant suffix IDs and migrants don’t get re-migrated.
Empty-island sampling creates copies (not shared references) and passes validation.
No program is ever assigned to multiple islands.
Migration validation remains stable across multiple migration cycles (prevents exponential “migrant” growth).
How to use
Set in config:
database.variant = "DNSProgramDatabase" (default in this diff)
or database.variant = "ThresholdElitesProgramDatabase"
optionally tune database.distance_threshold for the Threshold-Elites behavior.
Testing
Added unit tests for both variants (DNS + Threshold-Elites).
Existing database test base class is reused to ensure behavior parity where intended.