UNPKG

genetic-search

Version:

Multiprocessing genetic algorithm implementation library

143 lines 5.86 kB
import { zip } from "./itertools"; import { arraySum, calcRangeStatSummary, calcStatSummary, createEmptyGroupedStatSummary, createEmptyRangeStatSummary, createEmptyStatSummary, fullCopyObject, roundGroupedStatSummary, roundRangeStatSummary, roundStatSummary, } from "./utils"; /** * A manager for the statistics of a population of genomes. * * This class implements the [[GenomeStatsManagerInterface]] interface. * * @category Statistics */ export class GenomeStatsManager { init(population, origin) { for (const genome of population) { this.initItem(genome, origin); } } update(population, phenomeMatrix, fitnessColumn) { for (const [genome, phenome, fitness] of zip(population, phenomeMatrix, fitnessColumn)) { this.updateItem(genome, phenome, fitness); } } initItem(genome, origin, parents = []) { if (genome.stats !== undefined) { return genome.stats; } genome.stats = { fitness: 0, age: 0, phenome: [], origin, originCounters: { crossover: arraySum(parents.map((p) => { var _a, _b, _c; return (_c = (_b = (_a = p.stats) === null || _a === void 0 ? void 0 : _a.originCounters) === null || _b === void 0 ? void 0 : _b.crossover) !== null && _c !== void 0 ? _c : 0; })) + Number(origin === 'crossover'), mutation: arraySum(parents.map((p) => { var _a, _b, _c; return (_c = (_b = (_a = p.stats) === null || _a === void 0 ? void 0 : _a.originCounters) === null || _b === void 0 ? void 0 : _b.mutation) !== null && _c !== void 0 ? _c : 0; })) + Number(origin === 'mutation'), }, parentIds: parents.map((p) => p.id), }; return genome.stats; } /** * Updates the statistics of a genome. * * @param genome The genome to update. * @param phenome The phenome of the genome. * @param fitness The fitness of the genome. * * @returns The updated genome statistics. */ updateItem(genome, phenome, fitness) { const stats = this.initItem(genome, 'initial'); stats.age++; stats.fitness = fitness; stats.phenome = phenome; return stats; } } /** * A manager for the population summary. * * This class implements the [[PopulationSummaryManagerInterface]] interface. * It is used to manage the population summary, which is a summary of the * statistics of a population of genomes. * * @category Statistics */ export class PopulationSummaryManager { /** * Constructs a new population summary manager. */ constructor() { /** * The number of generations since the best genome has changed. */ this.stagnationCounter = 0; this.fitnessSummary = createEmptyStatSummary(); this.groupedFitnessSummary = createEmptyGroupedStatSummary(); this.ageSummary = createEmptyRangeStatSummary(); } get() { return { fitnessSummary: fullCopyObject(this.fitnessSummary), groupedFitnessSummary: fullCopyObject(this.groupedFitnessSummary), ageSummary: fullCopyObject(this.ageSummary), stagnationCounter: this.stagnationCounter, }; } getRounded(precision) { return { fitnessSummary: roundStatSummary(this.fitnessSummary, precision), groupedFitnessSummary: roundGroupedStatSummary(this.groupedFitnessSummary, precision), ageSummary: roundRangeStatSummary(this.ageSummary, precision), stagnationCounter: this.stagnationCounter, }; } update(sortedPopulation) { var _a; const bestGenomeId = (_a = sortedPopulation[0]) === null || _a === void 0 ? void 0 : _a.id; if (this.bestGenomeId !== bestGenomeId) { this.bestGenomeId = bestGenomeId; this.stagnationCounter = 0; } else { this.stagnationCounter++; } const statsCollection = sortedPopulation .filter((genome) => genome.stats !== undefined) .map((genome) => genome.stats); this.updateSummary(statsCollection); this.updateGroupedSummary(statsCollection); this.updateAgeSummary(statsCollection); } /** * Updates the summary of the population. * * @param sortedStatsCollection The sorted collection of genome statistics. */ updateSummary(sortedStatsCollection) { this.fitnessSummary = calcStatSummary(sortedStatsCollection.map((stats) => stats.fitness)); } /** * Updates the grouped summary of the population. * * @param sortedStatsCollection The sorted collection of genome statistics. */ updateGroupedSummary(sortedStatsCollection) { const initialCollection = sortedStatsCollection.filter((stats) => stats.origin === 'initial'); const crossoverCollection = sortedStatsCollection.filter((stats) => stats.origin === 'crossover'); const mutationCollection = sortedStatsCollection.filter((stats) => stats.origin === 'mutation'); this.groupedFitnessSummary = { initial: calcStatSummary(initialCollection.map((stats) => stats.fitness)), crossover: calcStatSummary(crossoverCollection.map((stats) => stats.fitness)), mutation: calcStatSummary(mutationCollection.map((stats) => stats.fitness)), }; } /** * Updates the summary of the age of the population. * * @param sortedStatsCollection The sorted collection of genome statistics. */ updateAgeSummary(sortedStatsCollection) { const ageCollection = sortedStatsCollection.map((stats) => stats.age); this.ageSummary = calcRangeStatSummary(ageCollection); } } //# sourceMappingURL=stats.js.map