Sample a parent for exploitation (from archive/elite programs)
(self)
| 1378 | return self.programs[parent_id] |
| 1379 | |
| 1380 | def _sample_exploitation_parent(self) -> Program: |
| 1381 | """ |
| 1382 | Sample a parent for exploitation (from archive/elite programs) |
| 1383 | """ |
| 1384 | if not self.archive: |
| 1385 | # Fallback to exploration if no archive |
| 1386 | return self._sample_exploration_parent() |
| 1387 | |
| 1388 | # Clean up stale references in archive |
| 1389 | valid_archive = [pid for pid in self.archive if pid in self.programs] |
| 1390 | |
| 1391 | # Remove stale program IDs from archive |
| 1392 | if len(valid_archive) < len(self.archive): |
| 1393 | stale_ids = self.archive - set(valid_archive) |
| 1394 | logger.debug(f"Removing {len(stale_ids)} stale program IDs from archive") |
| 1395 | for stale_id in stale_ids: |
| 1396 | self.archive.discard(stale_id) |
| 1397 | |
| 1398 | # If no valid archive programs, fallback to exploration |
| 1399 | if not valid_archive: |
| 1400 | logger.warning( |
| 1401 | "Archive has no valid programs after cleanup, falling back to exploration" |
| 1402 | ) |
| 1403 | return self._sample_exploration_parent() |
| 1404 | |
| 1405 | # Prefer programs from current island in archive |
| 1406 | archive_programs_in_island = [ |
| 1407 | pid |
| 1408 | for pid in valid_archive |
| 1409 | if self.programs[pid].metadata.get("island") == self.current_island |
| 1410 | ] |
| 1411 | |
| 1412 | if archive_programs_in_island: |
| 1413 | parent_id = random.choice(archive_programs_in_island) |
| 1414 | return self.programs[parent_id] |
| 1415 | else: |
| 1416 | # Fall back to any valid archive program if current island has none |
| 1417 | parent_id = random.choice(valid_archive) |
| 1418 | return self.programs[parent_id] |
| 1419 | |
| 1420 | def _sample_random_parent(self) -> Program: |
| 1421 | """ |
no test coverage detected