npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

genome.js

v1.1.10

Published

Genetics algorithms done right

Downloads

19

Readme

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

|Methods|Return type|Description| |--|--|--| | constructor(size: number, blueprint: Blueprint) |Population|Create a population with size chromosomes using the blueprint| |setFitnessCalculation(fitnessCalculation: any)|null|Set the fitness calculation function. It should return a number value corresponding to the fitness of a chromosome.| | setStopAt(fitness: number) |null|Stop the process once a chromosome reaches AT LEAST fitness value on its fitness.| | setMutationRate(mutationRate: number) |null|Set the mutation rate value. It should be between 0 (no mutation at all) and 1 (every chromosome will be mutated)| | setCutOff(cutOff: number) |null|Set 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) |null|Run the process rounds times.| | getGenerationNumber() |number|Return the current round number.| | getBestChromosome() |Chromosome|Return the best chromosome.|

Chromosome

|Methods|Return type|Description| |--|--|--| | getGenes() |Gene[]|Return the genes of the chromosome.| | getFitness() |Gene[]|Return the fitness of the chromosome.|

Gene

|Methods|Return type|Description| |--|--|--| | get() |number|Return the allele (value) of the gene.|

Blueprint

|Methods|Return type|Description| |--|--|--| | constructor() |Blueprint|Create a new Blueprint.| | add(factor: number, times: number = 1) |null|Define 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

|Methods|Return type|Description| |--|--|--| | static on(eventType: GenomeEventType, callback: any) |null|STATIC Run the callback function when the event eventType is trigger.|

Events

|Name|Description| |--|--| |GENOME_EVENT_POPULATION_CREATED|Trigger when all chromosomes are initialized| |GENOME_EVENT_GENERATION_BEGIN|Trigger when a new generation is processed| |GENOME_EVENT_GENERATION_END|Trigger when a generation is done processing| |GENOME_EVENT_GENERATION_FINISH|Trigger 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);