tycho-solver
Version:
Evolutionary computation and optimization library
98 lines (97 loc) • 4.54 kB
JavaScript
"use strict";
/**
* Genetic Algorithm implementation
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
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.GeneticAlgorithm = void 0;
const GALoopOperator_1 = require("./components/GALoopOperator");
const InitializationOperator_1 = require("./components/InitializationOperator");
const EvaluationOperator_1 = require("./components/EvaluationOperator");
class GeneticAlgorithm {
constructor(fitnessFunction, config) {
this.fitnessFunction = fitnessFunction;
this.config = config;
this.generation = 0;
// Step 1: Always use InitializationOperator to create the population
const initializationOperator = config.initializationOperator || new InitializationOperator_1.GAInitializationOperator();
this.population = initializationOperator.initialize({
populationSize: config.populationSize || 100,
individualFactory: config.individualFactory
});
if (!Array.isArray(this.population) || this.population.length === 0) {
throw new Error('InitializationOperator produced an empty population. This is not allowed.');
}
// Step 2: Evaluation
const evaluationOperator = config.evaluationOperator || new EvaluationOperator_1.GAEvaluationOperator(fitnessFunction);
this.bestSolution = this.population[0];
this.bestFitness = evaluationOperator.evaluate(this.bestSolution);
for (const individual of this.population) {
const fitness = evaluationOperator.evaluate(individual);
if (fitness > this.bestFitness) {
this.bestFitness = fitness;
this.bestSolution = individual;
}
}
}
evolve(generations) {
return __awaiter(this, void 0, void 0, function* () {
const gens = generations || this.config.maxGenerations;
const eliteCount = this.config.eliteCount || 0;
const fitnessLimit = this.config.fitnessLimit;
const result = yield (0, GALoopOperator_1.GALoopOperator)({
population: this.population,
fitnessFunction: this.fitnessFunction,
maxGenerations: gens,
eliteCount,
fitnessLimit,
initializationOperator: this.config.initializationOperator,
evaluationOperator: this.config.evaluationOperator,
mutationOperator: this.config.mutationOperator,
crossoverOperator: this.config.crossoverOperator
});
this.population = result.population;
this.bestSolution = result.bestSolution;
this.bestFitness = result.bestFitness;
this.generation = result.generation;
return this.bestSolution;
});
}
getBestSolution() {
return this.bestSolution;
}
getBestFitness() {
return this.bestFitness;
}
getPopulation() {
return this.population;
}
getGeneration() {
return this.generation;
}
}
exports.GeneticAlgorithm = GeneticAlgorithm;
// Export components for advanced usage
__exportStar(require("./components"), exports);