Non riesco a capire come parallelizzare il calcolo della quantità di prole prevista per le specie nell'algoritmo genetico

1

Ho sviluppato un algoritmo genetico in java 8 sfruttando le sue opportunità di parallelismo ragionevolmente libere con gli Stream. Come probabilmente saprai, l'esecuzione delle epoche richiede tempo anche per un problema di test che generi la frase "essere o non essere, cioè la domanda" con i geni char. Sono riuscito a parallelizzare tutte le operazioni tranne due, che sono diventati significativi colli di bottiglia: la speciazione (che determina la compatibilità di un cromosoma con gli altri in modo che possano essere inseriti nelle specie appropriate o crearne di nuovi) e il calcolo di quanti esemplari di una specie dovrebbe avere.

Dubito che sarò mai in grado di parallelizzare la speciazione, poiché coinvolge l'iterazione attraverso tutti i cromosomi mentre crea nuove specie se necessario a cui il prossimo cromosoma dovrebbe avere accesso; troppe modifiche simultanee di elenchi. Ho la sensazione che il calcolo della prole della specie possa essere parallelizzato, ma non riesco a capire come. Penso che sia un'operazione di riduzione, ma è necessario riportare la parte frazionaria delle divisioni in modo che possano essere aggiunte quando necessario. Questo accumulo dovrebbe essere disponibile per ogni specie e ciascun cromosoma. Sospetto che la soluzione potrebbe comportare la creazione di una classe complessa che implementa IntConsumer, ma non sono abbastanza brillante da capire. Il codice è sotto Qualche idea?

    private Map<ID, Integer> createMapWithTheExpectedOffspringNumberForEachSpecies() {

    final Map<ID, Integer> mapWithTheExpectedOffspringNumberForEachSpecies = new ConcurrentHashMap<ID, Integer>();

    final double averageOfFitnesses = this.calculateAverageOfFitnesses();

    double skim = 0.0;

    for (final ISpecies<T> species : this.collectionOfSpecies.get()) {

        int offspringThisSpeciesShouldHave = 0;

        for (final IChromosome<T> chromosome : species.getChromosomes().get()) {

            int offspringThisChromosomeShouldHave = 0;

            final double fitnessOfThisChromosome = this
                    .retrieveFitnessForChromosome(chromosome);

            final int floorOfChromosomesExpectedOffspring = (int) Math.floor(this.expectedAmountOfChildrenForChromosome(averageOfFitnesses,
                    fitnessOfThisChromosome));
            final double fractionalPartOfChromosomesExpectedOffspring = this.expectedAmountOfChildrenForChromosome(averageOfFitnesses,
                    fitnessOfThisChromosome) % 1.0;

            offspringThisChromosomeShouldHave += floorOfChromosomesExpectedOffspring;

            skim += fractionalPartOfChromosomesExpectedOffspring;

            if (skim > 1.0) {
                final double skimIntPart = Math.floor(skim);
                offspringThisChromosomeShouldHave += skimIntPart;
                skim -= skimIntPart;
            }

            offspringThisSpeciesShouldHave += offspringThisChromosomeShouldHave;
        }

        mapWithTheExpectedOffspringNumberForEachSpecies.put(
                species.getID(), offspringThisSpeciesShouldHave);
    }

    return mapWithTheExpectedOffspringNumberForEachSpecies;
}
    
posta Jon Iñaki Ureña 16.04.2015 - 08:32
fonte

0 risposte