Skip to content

Instantly share code, notes, and snippets.

@kana-sama
Created November 20, 2016 20:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kana-sama/9c1bffe0970241a0f1bdfaaa829a77a5 to your computer and use it in GitHub Desktop.
Save kana-sama/9c1bffe0970241a0f1bdfaaa829a77a5 to your computer and use it in GitHub Desktop.
const POPULATION_SIZE = 100
class GeneticAlgorithm {
generate(length) {
let chromosome = ''
for (let i = 0; i < length; i += 1) {
chromosome += String(Number(Math.random(1) > 0.5))
}
return chromosome
}
static mutationsMap = {
'0': '1',
'1': '0',
}
mutate(chromosome, p) {
let newChromosome = ''
for (let bit of chromosome) {
const willMutate = (Math.random() < p)
if (willMutate) {
bit = GeneticAlgorithm.mutationsMap[bit]
}
newChromosome += bit
}
return newChromosome
}
crossover(chromosome1, chromosome2, changeFrom) {
let newChromosome1 = ''
let newChromosome2 = ''
for (const index in chromosome1) {
let char1 = chromosome1[Number(index)]
let char2 = chromosome2[Number(index)]
if (index >= changeFrom) {
[char1, char2] = [char2, char1]
}
newChromosome1 += char1
newChromosome2 += char2
}
return [newChromosome1, newChromosome2]
}
select(population, fitnesses) {
let fullFitness = fitnesses.reduce((sum, current) => sum + current)
let selectedPoint = Math.random() * fullFitness
let selectedChromosome = 0
while (selectedPoint > 0) {
selectedPoint -= fitnesses[selectedChromosome]
selectedChromosome += 1
}
return population[selectedChromosome - 1]
}
run(fitness, length, p_c, p_m, iterations) {
let population = []
for (let i = 0; i < POPULATION_SIZE; i += 1) {
population.push(this.generate(length))
}
let fitnesses = population.map(fitness)
do {
let newPopulation = []
while (newPopulation.length < POPULATION_SIZE) {
let chromosome1 = this.select(population, fitnesses)
let chromosome2
do {
chromosome2 = this.select(population, fitnesses)
} while (chromosome1 === chromosome2)
const willCrossover = (Math.random() < p_c)
if (willCrossover) {
const crossoverPosition = Math.trunc(Math.random() * length)
let [newChromosome1, newChromosome2] = this.crossover(chromosome1, chromosome2, crossoverPosition)
newChromosome1 = this.mutate(newChromosome1, p_m)
newChromosome2 = this.mutate(newChromosome2, p_m)
newPopulation.push(newChromosome1, newChromosome2)
}
}
population = newPopulation
fitnesses = population.map(fitness)
} while (!fitnesses.some(f => f === 1))
for (let i = 0; i < POPULATION_SIZE; i += 1) {
if (fitnesses[i] === 1) {
return population[i]
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment