Just a suggestion. Refer below code.
In Individual
class, store calculated fitness. This way you don't have to calculate it every time. You can calculate fitness whenever setter method of any parameter, affecting fitness formula, gets called.
Also, for each solution you can calculate fitness for all individuals at once in a parallel stream as shown in the code.
public class Test {
public static void main(String[] args) throws Exception {
List<Individual> allSpecimens = new ArrayList<>();
allSpecimens.add(new Individual("a", 50, 4));
allSpecimens.add(new Individual("b", 45, 3));
//after each solution or mutation run following code
allSpecimens.stream().parallel().forEach(s -> {
s.setFitness(GenericAlgorithm.getFitness(s));
});
//find fittest like this
//this should be fater now
Individual fittest = allSpecimens.stream()
.min(Comparator.comparing(Individual::getFitness)).get();
}
}
class GenericAlgorithm {
public static double getFitness(Individual specimen) {
return specimen.getWeight()/specimen.getHeight();
}
}
class Individual{
private String name;
private int height;
private int weight;
//cache calculated fitness
private double fitness;
public Individual(String name, int weight, int height) {
this.name = name;
this.weight = weight;
this.height = height;
//calculate every time you modify a parameter
//remove this if you calculate fitness on all at once
this.fitness = GenericAlgorithm.getFitness(this);
}
public void setHeightAndWeight(int newHeight, int newWeight) {
this.height = newHeight;
this.weight = newWeight;
//calculate every time you modify a parameter
this.fitness = GenericAlgorithm.getFitness(this);
}
public double getFitness(){
//there is no calculations here
//so it is faster now
return fitness;
}
public void setFitness(double fitness) {
this.fitness = fitness;
}
public int getHeight() {
return height;
}
public String getName() {
return name;
}
public int getWeight() {
return weight;
}
}