Skip to content

Instantly share code, notes, and snippets.

@metanomial
Created July 24, 2020 00:15
Show Gist options
  • Save metanomial/f5427805f7f511915cbf5a79e3f30d8b to your computer and use it in GitHub Desktop.
Save metanomial/f5427805f7f511915cbf5a79e3f30d8b to your computer and use it in GitHub Desktop.
const fibonacci = lucas(0, 1);
const dataset = Array(79)
.fill()
.map(_ => fibonacci.next().value);
let generation = 0;
let population = Array(10000)
.fill()
.map(_ => Array(4).fill().map(_ => Math.random() * 10 - 5))
.map(evalFitness);
console.log(generation, population[0], makeSequence(population[0]));
// Generation iterator
(function iterate() {
population = population
.sort((a, b) => a.fitness - b.fitness)
.slice(0, 1000)
.flatMap(chromosome => Array(10).fill(chromosome))
.map(chromosome => chromosome.map(gene => {
if (Math.random() < 0.0001) return Math.random() * 10 - 5;
if (Math.random() < 0.001) return -gene;
return gene + mutation(chromosome.fitness);
}))
.map(evalFitness);
++generation;
console.log(generation, population[0], makeSequence(population[0]));
if(population[0].fitness > 100) setTimeout(iterate, 0);
})();
// Lucas numbers generator
function* lucas (a, b) {
while (true) {
yield a;
[ a, b ] = [ b, a + b ];
}
}
// Evaluate the fitness of a given chromosome
function evalFitness (chromosome) {
chromosome.fitness = dataset.reduce((deviation, actual, n) => {
const [ c1, b1, c2, b2 ] = chromosome;
const computed = c1 * b1 ** n + c2 * b2 ** n;
return deviation + Math.abs(actual - computed);
}, 0);
return chromosome;
}
// Generate number sequence from a chromosome
function makeSequence ([ c1, b1, c2, b2 ]) {
return Array(20)
.fill()
.map((_, n) => Math.round( c1 * b1 ** n + c2 * b2 ** n ));
}
// Generate mutation value
function mutation (fitness) {
return (Math.random() - 0.5) * fitness / 1e16;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment