Skip to content

Instantly share code, notes, and snippets.

@thesephist
Created May 6, 2018 02:15
Show Gist options
  • Save thesephist/02457f4399ae5c9a2c0817ddf7c2d0f3 to your computer and use it in GitHub Desktop.
Save thesephist/02457f4399ae5c9a2c0817ddf7c2d0f3 to your computer and use it in GitHub Desktop.
Mutation rate vs. Population Simulation
// Constants
const M_RATES = [
0,
0.001,
0.01,
0.1,
];
const POP_SIZE = 100;
const GENERATIONS = 50;
const GENOME_LENGTH = 20;
const FITNESS_FACTOR = 0.8; // on a scale of 0 to 1 higher = more difficult
const LIFETIME = 4; // generations
const FERTILITY = .3;
class Individual {
constructor(m_rate, genome) {
this.m_rate = m_rate;
this.age = 0;
if (genome) {
this.genome = genome;
} else {
this.genome = [];
for (let i = 0; i < GENOME_LENGTH; i ++) {
this.genome.push(Math.random());
}
}
}
is_fit() {
// To be "fit", 90% of genes have to have value > FITNESS_FACTOR
let fit_genes_count = 0;
for (const gene of this.genome) {
if (gene > FITNESS_FACTOR) fit_genes_count ++;
}
return fit_genes_count > (0.2 * this.genome.length);
}
do_age() {
this.age ++;
}
clone() {
const n_ind = new Individual(this.m_rate, this.genome.slice());
for (let i = 0; i < GENOME_LENGTH; i ++) {
if (Math.random() < this.m_rate) {
n_ind.genome[i] = Math.random();
}
}
return n_ind;
}
}
class Population {
constructor(size, m_rate) {
this.size = size;
this.m_rate = m_rate;
this.population = [];
this.generation = 0;
for (let i = 0; i < size; i ++) {
this.population.push(new Individual(m_rate));
}
}
get_avg_fitness() {
let sum = 0;
for (const individual of this.population) {
if (individual.is_fit()) sum ++;
}
return sum / this.population.length;
}
/**
* Pass one generation, killing off unfit organisms
*/
age_generation() {
for (const individual of this.population) {
individual.do_age();
if (Math.random() < FERTILITY) {
this.population.push(individual.clone());
}
if (individual.age >= LIFETIME) {
this._remove_individual(individual);
}
}
this.generation ++;
}
_remove_individual(individual) {
this.population.splice(this.population.indexOf(individual), 1);
}
}
function main() {
// create populations
const populations = [];
for (const rate of M_RATES) {
populations.push(new Population(POP_SIZE, rate));
}
for (let i = 0; i < GENERATIONS; i ++) {
// loops
for (const pop of populations) {
pop.age_generation();
}
console.log(
populations.map(p => p.population.length).join('\t')
+ '\t'
+ populations.map(p => p.get_avg_fitness()).join('\t')
);
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment