LineCrossover extends Crossover<G, C> { @Override protected int crossover(final MSeq<G> v, final MSeq<G> w) { final Random random = RandomRegistry.random(); final double min = v.get(0).min().doubleValue(); final double max = v.get(0).max().doubleValue(); final double a = nextDouble(-_p, 1 + _p, random); final double b = nextDouble(-_p, 1 + _p, random); boolean changed = false; for (int i = 0, n = min(v.length(), w.length()); i < n; ++i) { final double vi = v.get(i).doubleValue(); final double wi = w.get(i).doubleValue(); final double t = a*vi + (1 - a)*wi; final double s = b*wi + (1 - b)*vi; if (t >= min && s >= min && t < max && s < max) { v.set(i, v.get(i).newInstance(t)); w.set(i, w.get(i).newInstance(s)); changed = true; } } return changed ? 2 : 0; } LineCrossover(final double probability, final double p);  LineCrossover(final double probability);  LineCrossover(); @Override String toString();  }
@Test public void recombine() { final Factory<DoubleGene> factory = DoubleGene.of(0, 100); final MSeq<DoubleGene> v = MSeq.of(factory::newInstance, 10); final MSeq<DoubleGene> w = MSeq.of(factory::newInstance, 10); final LineCrossover<DoubleGene, Double> recombinator = new LineCrossover<>(); recombinator.crossover(v, w); Assert.assertTrue(v.forAll(DoubleGene::isValid)); Assert.assertTrue(w.forAll(DoubleGene::isValid)); }