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