You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The fix from #150 (commit 6ad0aa8) correctly added elite/non-elite separation in _enforce_population_limit(), prioritizing removal of non-cell-owning programs before cell owners. However, the subsequent rewrite in PR #154 (commit 6264c74) that added per-island feature maps did not carry over this protection.
Current behavior
_enforce_population_limit() (line 1678 in database.py) sorts all programs globally by fitness and removes the worst ones, regardless of whether they own a MAP-Elites cell:
This means a cell owner with a low score (e.g., a diverse niche program) can be evicted before a homeless program with a higher score, defeating the diversity preservation purpose of MAP-Elites.
Expected behavior
Programs that own a MAP-Elites cell in any island should be prioritized for survival. Non-cell-owning (homeless) programs should be evicted first.
Suggested fix
Collect all cell-owning program IDs from island_feature_maps and prioritize removing non-owners first:
def_enforce_population_limit(self, exclude_program_id=None):
iflen(self.programs) <=self.config.population_size:
returnnum_to_remove=len(self.programs) -self.config.population_size# Collect all cell-owning program IDs across all islandselite_ids=set()
forisland_mapinself.island_feature_maps:
elite_ids.update(island_map.values())
protected_ids= {self.best_program_id, exclude_program_id} - {None}
all_programs=list(self.programs.values())
non_elite=sorted(
[pforpinall_programsifp.idnotinelite_idsandp.idnotinprotected_ids],
key=lambdap: get_fitness_score(p.metrics, self.config.feature_dimensions),
)
elite=sorted(
[pforpinall_programsifp.idinelite_idsandp.idnotinprotected_ids],
key=lambdap: get_fitness_score(p.metrics, self.config.feature_dimensions),
)
# Remove non-elite first, then elite if still neededprograms_to_remove=non_elite[:num_to_remove]
iflen(programs_to_remove) <num_to_remove:
remaining=num_to_remove-len(programs_to_remove)
programs_to_remove.extend(elite[:remaining])
# ... rest of removal logic
Additional context
The original fix in commit 6ad0aa8 (by @claude bot) correctly implemented this using feature_map_program_ids = set(self.feature_map.values())
PR Fix map elites #154 rewrote database.py with per-island feature maps (self.island_feature_maps) but did not adapt the elite protection
git merge-base --is-ancestor 6ad0aa8 HEAD confirms the fix commit is not in the current main
Additionally, when a cell owner is replaced within a cell (line 339), the old program is removed from self.islands but NOT from self.programs, creating zombie programs that consume population slots but can never be sampled for prompts.
Description
The fix from #150 (commit
6ad0aa8) correctly added elite/non-elite separation in_enforce_population_limit(), prioritizing removal of non-cell-owning programs before cell owners. However, the subsequent rewrite in PR #154 (commit6264c74) that added per-island feature maps did not carry over this protection.Current behavior
_enforce_population_limit()(line 1678 indatabase.py) sorts all programs globally by fitness and removes the worst ones, regardless of whether they own a MAP-Elites cell:This means a cell owner with a low score (e.g., a diverse niche program) can be evicted before a homeless program with a higher score, defeating the diversity preservation purpose of MAP-Elites.
Expected behavior
Programs that own a MAP-Elites cell in any island should be prioritized for survival. Non-cell-owning (homeless) programs should be evicted first.
Suggested fix
Collect all cell-owning program IDs from
island_feature_mapsand prioritize removing non-owners first:Additional context
6ad0aa8(by @claude bot) correctly implemented this usingfeature_map_program_ids = set(self.feature_map.values())database.pywith per-island feature maps (self.island_feature_maps) but did not adapt the elite protectiongit merge-base --is-ancestor 6ad0aa8 HEADconfirms the fix commit is not in the currentmainAdditionally, when a cell owner is replaced within a cell (line 339), the old program is removed from
self.islandsbut NOT fromself.programs, creating zombie programs that consume population slots but can never be sampled for prompts.Related: #150, #167