Browse Source

Finished writing the genetic algorithm.

pull/18/head
jrtechs 5 years ago
parent
commit
98bd2dd1c4
1 changed files with 164 additions and 14 deletions
  1. +164
    -14
      geneticAlgorithm/geneticAlgo.html

+ 164
- 14
geneticAlgorithm/geneticAlgo.html View File

@ -1,8 +1,6 @@
<html> <html>
<head> <head>
<script> <script>
class Gene class Gene
{ {
constructor(min, max, value) constructor(min, max, value)
@ -31,6 +29,11 @@
{ {
return new Gene(this.min, this.max, this.value); return new Gene(this.min, this.max, this.value);
} }
makeRandomGene()
{
return new Gene(this.min, this.max, Math.random());
}
} }
@ -54,10 +57,20 @@
{ {
this.genes[Math.round(Math.random() * (this.genes.length-1))].setValue(Math.random()); this.genes[Math.round(Math.random() * (this.genes.length-1))].setValue(Math.random());
} }
createRandomChromosome()
{
let geneAr = [];
for(let i = 0; i < this.genes.length; i++)
{
geneAr.push(this.genes[i].makeRandomGene());
}
return new Chromosome(geneAr);
}
} }
const mate = function(father, mother)
const breed = function(father, mother)
{ {
let son = new Chromosome(father.getGenes()); let son = new Chromosome(father.getGenes());
let daughter = new Chromosome(mother.getGenes()); let daughter = new Chromosome(mother.getGenes());
@ -67,6 +80,48 @@
let blendCoef = Math.random(); let blendCoef = Math.random();
blendGene(son.getGenes()[i], daughter.getGenes()[i], blendCoef); blendGene(son.getGenes()[i], daughter.getGenes()[i], blendCoef);
} }
return [son, daughter];
};
function predicateBy(prop)
{
return function(a,b)
{
var result;
if(a[prop] > b[prop])
{
result = 1;
}
else if(a[prop] < b[prop])
{
result = -1;
}
return result;
}
}
const naturalSelection = function(population, keepNumber, fitnessFunction)
{
let fitnessArray = [];
for(let i = 0; i < population.length; i++)
{
const fitness = fitnessFunction(population[i]);
console.log(fitness);
fitnessArray.push({fit:fitness, chrom: population[i]});
}
fitnessArray.sort(predicateBy("fit"));
let survivors = [];
let bestFitness = fitnessArray[0].fit;
let bestChromosome = fitnessArray[0].chrom;
for(let i = 0; i < keepNumber; i++)
{
survivors.push(fitnessArray[i].chrom);
}
return {survivors: survivors, bestFit: bestFitness, bestChrom: bestChromosome};
}; };
const blendGene = function(gene1, gene2, blendCoef) const blendGene = function(gene1, gene2, blendCoef)
@ -80,20 +135,115 @@
gene2.setValue(value2); gene2.setValue(value2);
}; };
let gene1 = new Gene(1,10,.6);
let gene2 = new Gene(2,5,0.4);
const matePopulation = function(population, desiredPopulationSize)
{
let pairsNeeded = (desiredPopulationSize - population.length)/2;
const originalLength = population.length;
for(let i = 0; i < pairsNeeded; i++)
{
let index1 = Math.round(Math.random() * (originalLength-1));
let index2 = Math.round(Math.random() * (originalLength-1));
if(index1 !== index2)
{
const babies = breed(population[index1], population[index2]);
population.push(babies[0]);
population.push(babies[1]);
}
}
};
const mutatePopulation = function(population, mutatePercentage)
{
if(population.length >= 2)
{
let mutations = mutatePercentage *
population.length *
population[0].getGenes().length;
for(let i = 0; i < mutations; i++)
{
population[i].mutate();
}
}
else
{
console.log("Error, population too small to mutate");
}
};
const newBlood = function(population, immigrationSize)
{
for(let i = 0; i < immigrationSize; i++)
{
let geneticChromosome = population[0];
population.push(geneticChromosome.createRandomChromosome());
}
};
const basicCostFunction = function(chromosome)
{
console.log(chromosome);
console.log((chromosome.getGenes()[0].getRealValue()));
return Math.abs(chromosome.getGenes()[0].getRealValue() - 6) +
Math.abs(chromosome.getGenes()[1].getRealValue() - 2);
};
const createRandomPopulation = function(geneticChromosome, populationSize)
{
let population = [];
for(let i = 0; i < populationSize; i++)
{
population.push(geneticChromosome.createRandomChromosome());
}
return population;
};
const runGeneticOptimization = function(geneticChromosome, constFunction,
populationSize, maxGenerations,
desiredCost, mutationRate, keepNumber,
newBloodNumber)
{
let population = createRandomPopulation(geneticChromosome, populationSize);
let generation = 0;
let bestCost = Number.MAX_VALUE;
let bestChromosome = geneticChromosome;
do
{
matePopulation(population, populationSize);
newBlood(population, newBloodNumber);
mutatePopulation(population, mutationRate);
let generationResult = naturalSelection(population, keepNumber, constFunction);
if(bestCost > generationResult.bestFit)
{
bestChromosome = generationResult.bestChrom;
bestCost = generationResult.bestFit;
}
population = generationResult.survivors;
generation++;
console.log("Generation " + generation + " Best Cost: " + bestCost);
console.log(generationResult);
}while(generation < maxGenerations && bestCost > desiredCost);
return bestChromosome;
};
let gene1 = new Gene(1,10,10);
let gene2 = new Gene(1,10,0.4);
let geneList = [gene1, gene2]; let geneList = [gene1, gene2];
var c = new Chromosome(geneList);
var c2 = new Chromosome(c.getGenes());
console.log(c.getGenes());
console.log(c2.getGenes());
c.mutate();
c.mutate();
console.log(c.getGenes());
console.log(c2.getGenes());
</script>
let exampleOrganism = new Chromosome(geneList);
runGeneticOptimization(exampleOrganism, basicCostFunction, 100, 50, 0.01, 0.3, 20, 10);
</script>
</head> </head>

Loading…
Cancel
Save