@syntest/core
Version:
The common core of the SynTest Framework
115 lines • 5.15 kB
JavaScript
"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