java: la función de flujo paralelo tarda más tiempo

CorePress2024-01-25  9

Cerrado. Esta pregunta necesita ser más enfocada. Actualmente no acepta respuestas.

¿Quieres mejorar esta pregunta? Actualice la pregunta para que se centre en un solo problema editando esta publicación.

Cerrado

hace 2 años

.

mejorar esta pregunta

Tengo la siguiente función que calcula la aptitud de cada individuo en un algoritmo genético. La función de acondicionamiento físico requiere mucho tiempo, por lo que, para cada individuo de la población, requiere mucho tiempo.

Individual fittest = individuals.get(0);
        for (int i = 0; i < individuals.size(); i++) {
            if (fittest.getFitness() >= getIndividual(i).getFitness()) {
                fittest = getIndividual(i);
            }
        }
        return fittest;

Estoy probando la siguiente versión paralela pero es peor que la ejecución secuencial.

return
individuals.parallelStream().min(Comparator.comparing(GeneticAlgorithm::getFitness)).get();

Cualquier ayuda para calcular la aptitud de diferentes individuos en paralelo. Gracias

2

Esto ayudará. ¿Debería utilizar siempre una transmisión paralela cuando sea posible?

- tiro muerto

28 de marzo de 2021 a las 5:34

1

No ha proporcionado detalles ni cifras sobre sus afirmaciones de "tomar más tiempo". Y no has hecho una pregunta específica.

- Basil Bourque

28 de marzo de 2021 a las 5:36

¿Esto responde a tu pregunta? ¿Debo utilizar siempre una transmisión paralela cuando sea posible?

- Charlie Armstrong

28 de marzo de 2021 a las 5:40

1

Usar Comparator.comparar de esta manera es volver a calcular la aptitud de cada individuo cada vez que realiza una comparación individual, en lugar de "guardar" la aptitud de los mejores actuales.

- Louis Wasserman

28 de marzo de 2021 a las 6:03

1

@onkarruikar Muchas gracias señor. Estoy comprobando esto.

-Asad Rehman

28 de marzo de 2021 a las 8:11



------------------------------------

Sólo una sugerencia. Consulte el código a continuación. En clase Individual, almacena la condición física calculada. De esta manera no tendrás que calcularlo cada vez. Puede calcular la aptitud siempre que se llame al método de establecimiento de cualquier parámetro que afecte la fórmula de aptitud. Además, para cada solución puede calcular la aptitud de todos los individuos a la vez en una secuencia paralela como se muestra en tel código.

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;
    }

}

1

1

Muchas gracias. He realizado algunos cambios según mis requisitos. La idea es realmente útil

-Asad Rehman

30 de marzo de 2021 a las 5:15



------------------------------------

Si tardas mucho en getFitness(), debes minimizar su llamada.

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;

Esto reduce a la mitad el número de llamadas.

Compartir mejorar esta respuesta Seguir editado

28 de marzo de 2021 a las 6:06

Respondido

28 de marzo de 2021 a las 5:58

usuario4910279

usuario4910279

1

Gracias, me ayudó. Pero necesito alguna solución más eficiente que pueda acelerar la operación básica.

-Asad Rehman

28 de marzo de 2021 a las 6:55

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare