StochasticUniversalSelector extends RouletteWheelSelector<G, N> { @Override public ISeq<Phenotype<G, N>> select( final Seq<Phenotype<G, N>> population, final int count, final Optimize opt ) { requireNonNull(population, "Population"); if (count < 0) { throw new IllegalArgumentException( "Selection count must be greater or equal then zero, but was " + count ); } if (count == 0 || population.isEmpty()) { return ISeq.empty(); } final MSeq<Phenotype<G, N>> selection = MSeq.ofLength(count); final Seq<Phenotype<G, N>> pop = _sorted ? population.asISeq().copy().sort(POPULATION_COMPARATOR) : population; final double[] probabilities = probabilities(pop, count, opt); assert pop.size() == probabilities.length; final double delta = 1.0/count; final double[] points = new double[count]; points[0] = RandomRegistry.random().nextDouble()*delta; for (int i = 1; i < count; ++i) { points[i] = delta*i; } int j = 0; double prop = 0; for (int i = 0; i < count; ++i) { while (points[i] > prop) { prop += probabilities[j]; ++j; } selection.set(i, pop.get(j%pop.size())); } return selection.toISeq(); } StochasticUniversalSelector(); @Override ISeq<Phenotype<G, N>> select(
		final Seq<Phenotype<G, N>> population,
		final int count,
		final Optimize opt
	); @Override String toString();  }
@Test public void selectMinimum() { final Function<Genotype<IntegerGene>, Integer> ff = gt -> gt.chromosome().stream() .mapToInt(IntegerGene::intValue) .sum(); Factory<Genotype<IntegerGene>> gtf = Genotype.of(IntegerChromosome.of(0, 100, 10)); final ISeq<Phenotype<IntegerGene, Integer>> population = IntStream.range(0, 50) .mapToObj(i -> { final Genotype<IntegerGene> gt = gtf.newInstance(); return Phenotype.of(gt, 50, gt.gene().intValue()); }) .collect(ISeq.toISeq()); final StochasticUniversalSelector<IntegerGene, Integer> selector = new StochasticUniversalSelector<>(); final ISeq<Phenotype<IntegerGene, Integer>> selection = selector.select(population, 50, Optimize.MINIMUM); }