1.1.10 • Published 5 years ago

genome.js v1.1.10

Weekly downloads
4
License
MIT
Repository
github
Last release
5 years ago

genome.js

genome.js is a Javascript to help build insane genetics algorithms in a few minutes.

Concept

General terms

  • Population: a subset of the possible solutions to the problem (ie. subset of chromosomes)

  • Chromosome: a specific solution to the problem

  • Gene: a value defining a chromosome

Specific terms

  • Blueprint: a schema defining the structure of every gene (number and possible values) in a chromosome.

Installation (via NPM)

npm install --save genome.js

Documentation

Population

MethodsReturn typeDescription
constructor(size: number, blueprint: Blueprint)PopulationCreate a population with size chromosomes using the blueprint
setFitnessCalculation(fitnessCalculation: any)nullSet the fitness calculation function. It should return a number value corresponding to the fitness of a chromosome.
setStopAt(fitness: number)nullStop the process once a chromosome reaches AT LEAST fitness value on its fitness.
setMutationRate(mutationRate: number)nullSet the mutation rate value. It should be between 0 (no mutation at all) and 1 (every chromosome will be mutated)
setCutOff(cutOff: number)nullSet the cut off value. It should be between 0 (no chromosome will be removed) and 1 (every chromosome will be removed)
run(rounds: number = 1)nullRun the process rounds times.
getGenerationNumber()numberReturn the current round number.
getBestChromosome()ChromosomeReturn the best chromosome.

Chromosome

MethodsReturn typeDescription
getGenes()Gene[]Return the genes of the chromosome.
getFitness()Gene[]Return the fitness of the chromosome.

Gene

MethodsReturn typeDescription
get()numberReturn the allele (value) of the gene.

Blueprint

MethodsReturn typeDescription
constructor()BlueprintCreate a new Blueprint.
add(factor: number, times: number = 1)nullDefine a property into the blueprint. The factor is used when you get back the allele (value) of a gene (ex: a gene created with add(26) will return a number between 0 and 25). You can add times a property by setting the times parameter.

GenoveEvent

MethodsReturn typeDescription
static on(eventType: GenomeEventType, callback: any)nullSTATIC Run the callback function when the event eventType is trigger.

Events

NameDescription
GENOME_EVENT_POPULATION_CREATEDTrigger when all chromosomes are initialized
GENOME_EVENT_GENERATION_BEGINTrigger when a new generation is processed
GENOME_EVENT_GENERATION_ENDTrigger when a generation is done processing
GENOME_EVENT_GENERATION_FINISHTrigger when the all processing is done (rounds limit or fitness limit)

Example

/*
* This example is based on the "infinite monkey theorem" (https://en.wikipedia.org/wiki/Infinite_monkey_theorem)
*
* The algorithm tries to reproduce a specific text input, here "helloworldhowareyoutoday" in a minimum rounds.
*/

// Importing all the dependencies
import { Population, Blueprint, Gene, Chromosome, GenomeEvent, GenomeEventType } from 'genome.js';

// Defining the string to reproduce
const answer = 'helloworldhowareyoutoday';

// We create a blueprint to represent the data structure of a chromosome
const blueprint = new Blueprint();
// Our chromosomes will have 'answer.length' genes between 0 and 26 (not included), so that each gene can represent one letter of the alphabet
blueprint.add(26, answer.length);

// We generate a population of 500 chromosomes using our blueprint
const population = new Population(500, blueprint);

// Just some basic configurations
population.setMutationRate(0.01);
population.setCutOff(0.5);
population.setStopAt(100); // We stop the processing when a chromosome reach AT LEAST 100 on his fitness

// We define now the function that calculate the fitness of every chromosome on each generation
// Be sure to never return 0 (cause a bug, WIP)
population.setFitnessCalculation((genes: Gene[]) => {
	let sum = 1; // Avoid to have 0 on fitness

	for (let i = 0; i < genes.length; i += 1) {
		const charCode = answer.charCodeAt(i) - 97;
		const geneCharCode = Math.floor(genes[i].get());
		// If the gene value is corresponding with the answer letter at the same location, then increment 'sum'
		if (charCode === geneCharCode) {
		sum += 1;
	}
}

// Basically a percent of correct genes' values
return (sum / (genes.length + 1)) * 100;
});

// We wait for a generation to end, and we display the best chromosome fitness into the console
GenomeEvent.on(GenomeEventType.GENOME_EVENT_GENERATION_END, (chromosomes: Chromosome[]) => {
	const bestChromosome = chromosomes[0];
	console.log(`Generation ${population.getGenerationNumber()}: ${bestChromosome.getFitness()}`);
});

// Once the process in finished (when a chromosome reach the fitness limit or the process has reach the round limit), we display the string contained in its genes
GenomeEvent.on(GenomeEventType.GENOME_EVENT_GENERATION_FINISH, (chromosomes: Chromosome[]) => {
	let finalString = '';
	const bestChromosome = chromosomes[0];
	bestChromosome.getGenes().map((gene: Gene) => {
		finalString += String.fromCharCode(gene.get() + 97);
	});
	console.log(`Result (fitness: ${bestChromosome.getFitness()}): ${finalString}`);
});

// We process the algorithm throught 500 rounds (more options comming soon)
population.run(500);
1.1.10

5 years ago

1.1.9

5 years ago

1.1.8

5 years ago

1.1.7

5 years ago

1.1.6

5 years ago

1.1.5

5 years ago

1.1.4

5 years ago

1.1.3

5 years ago

1.1.2

5 years ago

1.1.1

5 years ago

1.1.0

5 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago