有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java并行流函数占用更多时间

我有下面的函数,在遗传算法中计算每个个体的适应度。适应度函数需要花费大量的时间,所以对于种群中的每个个体来说,它需要花费大量的时间

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();

在并行计算不同个体的适合度方面的任何帮助。谢谢


共 (2) 个答案

  1. # 1 楼答案

    如果花很长时间来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;
    

    这将使通话次数减半

  2. # 2 楼答案

    只是一个建议。请参阅下面的代码
    Individual类中,存储计算的适应度。这样你就不用每次都计算了。只要调用影响适应度公式的任何参数的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;
        }
    
    }