jsdoで遺伝的アルゴリズム その２

#概要
遺伝的アルゴリズムを理解したかった。
jsdoで、やってみた。
genetic.jsを見つけた。

#写真
![image.png](https://qiita-image-store.s3.amazonaws.com/0/18104/8ec9ee70-b40d-8b56-8ca5-6d8121104786.png)

#one max
http://jsdo.it/ohisama1/OqxC

```
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

http://jsdo.it/ohisama1/waw3

```
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);



```

以上。