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.