Skip to content

fix: use child_counts for novelty-weighted parent selection#37

Open
xbrxr03 wants to merge 1 commit into
facebookresearch:mainfrom
xbrxr03:fix/select-next-parent-use-child-counts
Open

fix: use child_counts for novelty-weighted parent selection#37
xbrxr03 wants to merge 1 commit into
facebookresearch:mainfrom
xbrxr03:fix/select-next-parent-use-child-counts

Conversation

@xbrxr03

@xbrxr03 xbrxr03 commented Jun 23, 2026

Copy link
Copy Markdown

Summary

select_next_parent builds a child_counts dictionary tracking the number of descendants each candidate parent has spawned, then immediately discards it and selects a parent uniformly at random via random.choice. The computation is dead code, and the selection is not novelty-weighted — contradicting what a reader would reasonably expect from a method named select_next_parent in an open-ended exploration framework.

Fixes #29.

What changed

select_next_parent.py

  • Replace random.choice(list(candidates.keys())) with np.random.choice using weights inversely proportional to (1 + child_counts[genid])
  • Candidates with fewer children get higher selection probability, preventing mode collapse
  • This is the standard mechanism used by FunSearch, MAP-Elites, and AlphaEvolve
  • child_counts is now actually used instead of being computed and thrown away

test_select_next_parent.py (new)

  • 5 tests covering: under-explored preference, single candidate, equal weights, empty archive error, and a static check that child_counts is used in the selection logic

Testing

5 passed in 0.14s

Design choice

I went with Option A from the issue — novelty-weighted selection — because:

  1. The code structure (computing child_counts) clearly intended to use it
  2. FunSearch, MAP-Elites, and AlphaEvolve all use inverse-child-count weighting for exactly this reason
  3. Uniform random is already trivially achievable without the child_counts computation

Happy to sign the CLA if needed.

select_next_parent computes child_counts but never uses it — the
function selects parents uniformly at random, ignoring the novelty
signal that under-explored branches should be preferentially picked.

Replace random.choice with numpy.random.choice using weights
inversely proportional to (1 + child_count). This is the standard
mechanism used by FunSearch, MAP-Elites, and AlphaEvolve to prevent
mode collapse during open-ended search.

Adds 5 tests:
- test_under_explored_parents_preferred: verifies fewer children → more selections
- test_single_candidate_always_selected: single candidate always wins
- test_equal_children_have_similar_counts: equal weights → roughly uniform
- test_no_valid_candidates_raises: ValueError on empty archive
- test_dead_code_eliminated: static check that child_counts is used

Fixes facebookresearch#29
@meta-cla

meta-cla Bot commented Jun 23, 2026

Copy link
Copy Markdown

Hi @xbrxr03!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

select_next_parent computes child_counts but never uses it; selection is uniform random

2 participants