UNPKG

@syntest/core

Version:

The common core of the SynTest Framework

115 lines 5.15 kB
"use strict"; /* * Copyright 2020-2021 Delft University of Technology and SynTest contributors * * This file is part of SynTest Framework - SynTest Core. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EvolutionaryAlgorithm = void 0; const SearchAlgorithm_1 = require("../SearchAlgorithm"); const prng_1 = require("../../../util/prng"); const Configuration_1 = require("../../../Configuration"); const TournamentSelection_1 = require("../../operators/selection/TournamentSelection"); /** * Base class for Evolutionary Algorithms (EA). * Uses the T encoding. */ class EvolutionaryAlgorithm extends SearchAlgorithm_1.SearchAlgorithm { /** * Constructor. * * @param eventManager The event manager * @param objectiveManager The objective manager used by the specific algorithm * @param encodingSampler The encoding sampler used by the specific algorithm * @param crossover The crossover operator to apply * * @protected */ constructor(eventManager, objectiveManager, encodingSampler, crossover) { super(eventManager, objectiveManager); this._encodingSampler = encodingSampler; this._population = []; this._populationSize = Configuration_1.CONFIG.populationSize; this._crossover = crossover; } /** * @inheritDoc * @protected */ _initialize(budgetManager, terminationManager) { return __awaiter(this, void 0, void 0, function* () { for (let i = 0; i < Configuration_1.CONFIG.populationSize; i++) { this._population.push(this._encodingSampler.sample()); } // Evaluate initial population before starting the search loop yield this._objectiveManager.evaluateMany(this._population, budgetManager, terminationManager); // Compute ranking and crowding distance this._environmentalSelection(this._populationSize); }); } /** * @inheritDoc * @protected */ _iterate(budgetManager, terminationManager) { return __awaiter(this, void 0, void 0, function* () { const offspring = this._generateOffspring(); yield this._objectiveManager.evaluateMany(offspring, budgetManager, terminationManager); // If all objectives are covered, we don't need to rank the population anymore // The final test cases are in the archive, rather than the population if (!this._objectiveManager.hasObjectives()) { return; } this._population.push(...offspring); this._environmentalSelection(this._populationSize); }); } /** * Generates offspring based on the current population. * * @protected */ _generateOffspring() { const offspring = []; const rounds = Math.max(2, Math.round(this._populationSize / 5)); while (offspring.length < this._populationSize) { const parentA = (0, TournamentSelection_1.tournamentSelection)(this._population, rounds); const parentB = (0, TournamentSelection_1.tournamentSelection)(this._population, rounds); if (prng_1.prng.nextDouble(0, 1) <= Configuration_1.CONFIG.crossoverProbability) { const children = this._crossover.crossOver([parentA, parentB]); for (const child of children) { offspring.push(child.copy().mutate(this._encodingSampler)); } } else { offspring.push(parentA.copy().mutate(this._encodingSampler)); offspring.push(parentB.copy().mutate(this._encodingSampler)); } } offspring.push(this._encodingSampler.sample()); return offspring; } } exports.EvolutionaryAlgorithm = EvolutionaryAlgorithm; //# sourceMappingURL=EvolutionaryAlgorithm.js.map