概要
遺伝的アルゴリズムを理解したかった。
jsdoで、やってみた。
genetic.jsを見つけた。
写真
one max
var genetic;
genetic = Genetic.create();
genetic.optimize = Genetic.Optimize.Minimize;
genetic.select1 = Genetic.Select1.Tournament2;
genetic.select2 = Genetic.Select2.Tournament2;
genetic.seed = function() {
var a = [];
for (var i = 0; i < this.userData["term"]; i++)
{
a.push(Math.random() - 0.01);
}
return a;
};
genetic.mutate = function(entity) {
var drift = ((Math.random() - 0.5) * 2) * 0.05;
var i = Math.floor(Math.random() * entity.length);
entity[i] += drift;
return entity;
};
genetic.crossover = function(mother, father) {
function lerp(a, b, p) {
return a + (b - a) * p;
}
var len = mother.length;
var i = Math.floor(Math.random() * len);
var r = Math.random();
var son = [].concat(father);
var daughter = [].concat(mother);
son[i] = lerp(father[i], mother[i], r);
daughter[i] = lerp(mother[i], father[i], r);
return [son, daughter];
};
genetic.fitness = function(entity) {
var sumSqErr = 0;
var solutions = this.userData["solution"];
for (var i = 0; i < entity.length; i++)
{
var err = entity[i] - solutions[i];
sumSqErr += err * err;
}
return Math.sqrt(sumSqErr);
};
genetic.generation = function(pop, generation, stats) {
};
genetic.notification = function(pop, generation, stats, isFinished) {
if (isFinished)
{
document.getElementById('helloWorld').innerHTML += pop[0].entity + "<br>";
done();
}
};
var config = {
"iterations": 1000,
"size": 40,
"crossover": 0.3,
"mutation": 0.3
};
var userData = {
"term": 10,
"solution": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
};
genetic.evolve(config, userData);
sin fit
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function draw(data, n) {
var hcenter = 100;
ctx.strokeStyle = "#f00";
ctx.lineWidth = n;
for (var i = 1; i < 20; i++)
{
var x = data[i][0] * 20;
var y = data[i][1] * 20 + hcenter;
ctx.moveTo(x, y);
ctx.lineTo(x + 1, y + 1);
}
ctx.stroke();
}
function drawf(data) {
ctx.strokeStyle = "#00f";
ctx.lineWidth = 2;
for (var i = 0; i < 20; i++)
{
var x = i * 20;
var y = genetic.evaluatePoly(data, i) * 20 + 100;
if (i == 0)
{
ctx.moveTo(x, y);
}
else
{
ctx.lineTo(x, y);
}
}
ctx.stroke();
}
var genetic = Genetic.create();
genetic.optimize = Genetic.Optimize.Minimize;
genetic.select1 = Genetic.Select1.Tournament2;
genetic.select2 = Genetic.Select2.FittestRandom;
var solutions = [];
genetic.seed = function() {
var a = [];
var i;
for (i = 0; i < this.userData["terms"]; ++i)
{
a.push(Math.random() - 0.01);
}
return a;
};
genetic.mutate = function(entity) {
var drift = ((Math.random() - 0.5) * 2) * 0.05;
var i = Math.floor(Math.random() * entity.length);
entity[i] += drift;
return entity;
};
genetic.crossover = function(mother, father) {
function lerp(a, b, p) {
return a + (b - a) * p;
}
var len = mother.length;
var i = Math.floor(Math.random() * len);
var r = Math.random();
var son = [].concat(father);
var daughter = [].concat(mother);
son[i] = lerp(father[i], mother[i], r);
daughter[i] = lerp(mother[i], father[i], r);
return [son, daughter];
};
genetic.evaluatePoly = function(coefficients, x) {
var s = 0;
var p = 1;
var i;
for (i = 0; i < coefficients.length; ++i)
{
s += p * coefficients[i];
p *= x;
}
return s;
}
genetic.fitness = function(entity) {
var sumSqErr = 0;
var vertices = this.userData["vertices"];
var i;
for (i = 0; i < vertices.length; ++i)
{
var err = this.evaluatePoly(entity, vertices[i][0]) - vertices[i][1];
sumSqErr += err * err;
}
return Math.sqrt(sumSqErr);
};
genetic.generation = function(pop, generation, stats) {
};
genetic.notification = function(pop, generation, stats, isFinished) {
function poly(entity) {
var a = [];
var i;
for (i = entity.length - 1; i >= 0; --i)
{
var buf = entity[i].toPrecision(2);
if (i > 1) buf += "<em><b>x<sup>" + i + "<sup></b></em>";
else if (i == 1) buf += "<em><b>x</b></em>";
a.push(buf);
}
return a.join(" + ");
}
var last = last || "";
var str = pop[0].entity.join(",");
if (last != str || isFinished)
{
if (last != str)
{
last = str;
}
if (isFinished)
{
drawf(pop[0].entity);
document.getElementById('helloWorld').innerHTML = poly(pop[0].entity);
}
}
};
var config = {
"iterations": 1000,
"size": 250,
"crossover": 0.3,
"mutation": 0.3,
"skip": 10
};
var vertices = [];
var n = 20;
var off = Math.random() * 2 * 3.1415927;
var stride = 10 / n;
var i;
for (i = 0; i < n; ++i)
{
vertices.push([i * stride, Math.sin((off + i / n) * 2 * 3.1415627) * 3 + 5]);
}
draw(vertices, 3);
var userData = {
"terms": 4,
"vertices": vertices
};
genetic.evolve(config, userData);
以上。