Skip to main content

crossover_bin

Function crossover_bin 

pub fn crossover_bin(
    target: &[f64],
    mutant: &[f64],
    cr: f64,
    rng: &mut ChaCha8Rng,
) -> Vec<f64>
Expand description

Binomial crossover: mix mutant into target at rate cr, always keeping at least one mutant coordinate.

For each dimension the offspring takes the mutant coordinate with probability cr, else the target’s. One dimension j_rand, chosen uniformly, is forced to come from the mutant so crossover can never reproduce the target verbatim (the standard rand/1/bin guarantee).

The RNG draw order is fixed and documented so a resumed study reproduces it: first j_rand (random_range(0..d)), then exactly one f64 in [0, 1) per dimension for the per-coordinate coin flips — d + 1 draws for a d-dimensional target, whatever cr is and wherever j_rand falls.

The coin is therefore drawn even for the forced j_rand coordinate, where its value cannot change the outcome. That costs one draw and buys the property the paragraph above claims: the stream is a function of d alone, so it does not depend on which coordinate j_rand picked. (Short-circuiting the coin — the natural k == j_rand || rng.random::<f64>() < cr — consumed d draws instead, contradicting this contract; the code was changed to match the documented order rather than the other way round, which moved the generated sequence.)

A mutant shorter than target keeps the target’s coordinate there rather than panicking: the two are the same length by construction (one fixed-dimension population), but this is a public function on a library path and a caller’s mismatch must not abort the process.