public void calculateNextGeneration() {
        
        System.out.println(population.size());
        
        //// Prepare
        
        calculateCumulativeFitness();
        
        //// Reproduce species
        
        int speciesToReproduce = (int)(REPRODUCTION_RATE * POPULATION_SIZE);
        speciesToReproduce &= 0xFFFFFFFE; // Make even number
        
        int couplesCount = speciesToReproduce / 2;
        while (couplesCount > 0) {
            Speciment parent1 = chooseSpeciment();
            Speciment parent2 = chooseSpeciment();
            
            Speciment.Children children = parent1.crossGenomes(parent2);
            
            offspring.add(children.child1);
            offspring.add(children.child2);
            
            --couplesCount;
        }
        
        //// Transfer species to offspring unchanged
        
        int speciesToTransfer = POPULATION_SIZE - speciesToReproduce;
        while (speciesToTransfer > 0) {
            offspring.add(chooseSpeciment());
            --speciesToTransfer;
        }
        
        //// Mutate offspring
        
        int speciesToMutate = (int)(POPULATION_SIZE * MUTATION_RATE);
        while (speciesToMutate > 0) {
            int mutationIndex = generator.nextInt(POPULATION_SIZE);
            offspring.get(mutationIndex).mutateGenome();
            --speciesToMutate;
        }
        
        //// Move to next iteration
        
        population.clear();
        for (Speciment speciment : offspring) {
            if (speciment.getFitness() > bestSpeciment.getFitness()) {
                bestSpeciment = speciment;
            }
            
            population.add(speciment);
        }
        
        offspring.clear();
        
        ++generationCount;
    }