并行流功能需要更多时间
parallel stream function taking more time
我有以下函数,它在遗传算法中计算每个个体的适应度。适应度函数需要花费很多时间,因此对于种群中的每个个体来说,它都需要花费很多时间。
Individual fittest = individuals.get(0);
for (int i = 0; i < individuals.size(); i++) {
if (fittest.getFitness() >= getIndividual(i).getFitness()) {
fittest = getIndividual(i);
}
}
return fittest;
我正在尝试以下并行版本,但它比顺序执行更糟糕。
return
individuals.parallelStream().min(Comparator.comparing(GeneticAlgorithm::getFitness)).get();
有助于并行计算不同个体的适应度。谢谢
如果你花很长时间getFitness()
,你应该尽量减少它的调用。
Individual fittest = individuals.get(0);
int /* or long or double ? */ minFittness = fittest.getFitness();
for (int i = 0; i < individuals.size(); i++) {
Individual current = getIndividual(i);
int /* or long or double ? */ currentFitness = current.getFitness();
if (minFittness >= currentFitness) {
fittest = current;
minFittness = currentFitness;
}
}
return fittest;
这样调用次数减半。
只是一个建议。参考下面的代码。
在 Individual
class 中,存储计算的适应度。这样就不用每次都计算了。每当调用影响适应度公式的任何参数的 setter 方法时,您都可以计算适应度。
此外,对于每个解决方案,您可以在并行流中同时计算所有个体的适应度,如代码所示。
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;
}
}
我有以下函数,它在遗传算法中计算每个个体的适应度。适应度函数需要花费很多时间,因此对于种群中的每个个体来说,它都需要花费很多时间。
Individual fittest = individuals.get(0);
for (int i = 0; i < individuals.size(); i++) {
if (fittest.getFitness() >= getIndividual(i).getFitness()) {
fittest = getIndividual(i);
}
}
return fittest;
我正在尝试以下并行版本,但它比顺序执行更糟糕。
return
individuals.parallelStream().min(Comparator.comparing(GeneticAlgorithm::getFitness)).get();
有助于并行计算不同个体的适应度。谢谢
如果你花很长时间getFitness()
,你应该尽量减少它的调用。
Individual fittest = individuals.get(0);
int /* or long or double ? */ minFittness = fittest.getFitness();
for (int i = 0; i < individuals.size(); i++) {
Individual current = getIndividual(i);
int /* or long or double ? */ currentFitness = current.getFitness();
if (minFittness >= currentFitness) {
fittest = current;
minFittness = currentFitness;
}
}
return fittest;
这样调用次数减半。
只是一个建议。参考下面的代码。
在 Individual
class 中,存储计算的适应度。这样就不用每次都计算了。每当调用影响适应度公式的任何参数的 setter 方法时,您都可以计算适应度。
此外,对于每个解决方案,您可以在并行流中同时计算所有个体的适应度,如代码所示。
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;
}
}