From c959b2c9644a9ca612b264003aadfef8f4028d24 Mon Sep 17 00:00:00 2001 From: ProofOfConcept Date: Sat, 14 Mar 2026 19:57:58 -0400 Subject: [PATCH] =?UTF-8?q?evaluate:=20fix=20RNG=20=E2=80=94=20xorshift32?= =?UTF-8?q?=20replaces=20degenerate=20LCG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LCG was producing only 2 distinct matchup pairs due to poor constants. Switch to xorshift32 for proper coverage of all type pairs. Co-Authored-By: Kent Overstreet --- poc-memory/src/cli/agent.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/poc-memory/src/cli/agent.rs b/poc-memory/src/cli/agent.rs index 24a7cc1..2118279 100644 --- a/poc-memory/src/cli/agent.rs +++ b/poc-memory/src/cli/agent.rs @@ -262,15 +262,20 @@ pub fn cmd_evaluate_agents(matchups: usize, model: &str, dry_run: bool) -> Resul // Load persisted ratings let mut ratings = load_elo_ratings(&agent_types); let config = EloConfig { k: 32.0 }; - let mut rng_state = std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH).unwrap().subsec_nanos(); + // Simple but adequate RNG: xorshift32 + let mut rng = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH).unwrap().subsec_nanos() | 1; + let mut next_rng = || -> usize { + rng ^= rng << 13; + rng ^= rng >> 17; + rng ^= rng << 5; + rng as usize + }; for i in 0..matchups { // Pick two different random agent types - rng_state = rng_state.wrapping_mul(1103515245).wrapping_add(12345); - let idx_a = (rng_state as usize) % active_types.len(); - rng_state = rng_state.wrapping_mul(1103515245).wrapping_add(12345); - let mut idx_b = (rng_state as usize) % active_types.len(); + let idx_a = next_rng() % active_types.len(); + let mut idx_b = next_rng() % active_types.len(); if idx_b == idx_a { idx_b = (idx_b + 1) % active_types.len(); } let type_a = active_types[idx_a]; @@ -279,10 +284,8 @@ pub fn cmd_evaluate_agents(matchups: usize, model: &str, dry_run: bool) -> Resul // Pick random recent action from each let acts_a = &actions[type_a]; let acts_b = &actions[type_b]; - rng_state = rng_state.wrapping_mul(1103515245).wrapping_add(12345); - let act_a = &acts_a[(rng_state as usize) % acts_a.len()]; - rng_state = rng_state.wrapping_mul(1103515245).wrapping_add(12345); - let act_b = &acts_b[(rng_state as usize) % acts_b.len()]; + let act_a = &acts_a[next_rng() % acts_a.len()]; + let act_b = &acts_b[next_rng() % acts_b.len()]; let sample_a = (type_a.to_string(), act_a.0.clone(), act_a.1.clone()); let sample_b = (type_b.to_string(), act_b.0.clone(), act_b.1.clone());