class FitnessProportionateSelectionOperator extends AbstractProportionateSelectionOperator {

    protected double[] makeAccumulatedProbabilities(Individual[] inputIndividuals){
        double[] accumulatedFitnessValues = new double[inputIndividuals.length];
        double[] accumulatedProbabilities = new double[inputIndividuals.length];
        double totalFitness = 0.0; // actual accumulated fitness value
        // make accumulated fitness values
        for (int i = 0; i < inputIndividuals.length; i++){
            if (inputIndividuals[i].getFitness() >= 0.0){
                accumulatedFitnessValues[i] = totalFitness + inputIndividuals[i].getFitness();
                totalFitness = accumulatedFitnessValues[i];
            } else {
                throw new OptimizationException(this.getClass().getSimpleName() + ": individual fitness value cannot be negative but found value of " + inputIndividuals[i].getFitness());
            }
        }
        // make accumulated probabilities
        for (int i = 0; i < inputIndividuals.length; i++){
            accumulatedProbabilities[i] = accumulatedFitnessValues[i] / totalFitness;
        }
        accumulatedProbabilities[inputIndividuals.length-1] = 1.0; // make sure that roulette selection always selects an Individual
        
        return accumulatedProbabilities;
    }

}