@@ -662,13 +662,38 @@ def _update_archive(self, program: Program) -> None:
662662 self .archive .add (program .id )
663663 return
664664
665- # Otherwise, find worst program in archive
666- archive_programs = [self . programs [ pid ] for pid in self . archive ]
667- worst_program = min ( archive_programs , key = lambda p : safe_numeric_average ( p . metrics ))
665+ # Clean up stale references and get valid archive programs
666+ valid_archive_programs = []
667+ stale_ids = []
668668
669- # Replace if new program is better
670- if self ._is_better (program , worst_program ):
671- self .archive .remove (worst_program .id )
669+ for pid in self .archive :
670+ if pid in self .programs :
671+ valid_archive_programs .append (self .programs [pid ])
672+ else :
673+ stale_ids .append (pid )
674+
675+ # Remove stale references from archive
676+ for stale_id in stale_ids :
677+ self .archive .discard (stale_id )
678+ logger .debug (f"Removing stale program { stale_id } from archive" )
679+
680+ # If archive is now not full after cleanup, just add the new program
681+ if len (self .archive ) < self .config .archive_size :
682+ self .archive .add (program .id )
683+ return
684+
685+ # Find worst program among valid programs
686+ if valid_archive_programs :
687+ worst_program = min (
688+ valid_archive_programs , key = lambda p : safe_numeric_average (p .metrics )
689+ )
690+
691+ # Replace if new program is better
692+ if self ._is_better (program , worst_program ):
693+ self .archive .remove (worst_program .id )
694+ self .archive .add (program .id )
695+ else :
696+ # No valid programs in archive, just add the new one
672697 self .archive .add (program .id )
673698
674699 def _update_best_program (self , program : Program ) -> None :
0 commit comments