-
Notifications
You must be signed in to change notification settings - Fork 0
/
evo.min.js
7 lines (7 loc) · 11.4 KB
/
evo.min.js
1
2
3
4
5
6
7
/**
* evo.js v0.2.4
* Evolutionary Algorithm Tool wrapped with ANN
* Copyright (c) 2016 Alex Rowe <[email protected]>
* Licensed MIT
**/
(function(){var a,b=function(a,b){return function(){return a.apply(b,arguments)}},c=function(a,b){function c(){this.constructor=a}for(var e in b)d.call(b,e)&&(a[e]=b[e]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},d={}.hasOwnProperty;a="undefined"!=typeof window&&null!==window?window:this,function(b){return"object"==typeof exports?module.exports=b.call(a):"function"==typeof define&&define.amd?define(function(){return b.call(a)}):a.evo=b.call(a)}(function(){var a,d,e,f,g,h;return h={},h.population=function(a){return a=h.util.extend(h.config.pool,a),new g(a)},h.network=function(a,b,c){return c=h.util.extend(h.config.network,c),"feedforward"===a?new e(b,c):"cppn"===a?new d(b,c):void 0},h.configure=function(a){return h.config=h.util.extend(h.config,a)},h.config={pool:{genes:200,cross_rate:.05,mutate_rate:.05,mutate_amount:1,precision:1,size:100,ratios:{top:.25,mutate:.25,cross:.25,random:.1,average:.05,fresh:.1},run_conditions:{generations:1e3,iterations:void 0,score:1/0,auto_stop:!1,min_generations:10,"while":void 0},gene_options:[],on_breed:void 0,on_member:void 0,on_run:void 0,on_finish:void 0},network:{output_fn:"tanh",output_nodes:2,hidden_layers:2,hidden_nodes:2,input_nodes:2}},h.util={random:function(a,b){return null==a&&(a=-1),null==b&&(b=1),Math.random()*(b-a)+a},sin:function(a,b,c){return null==b&&(b=1),null==c&&(c=0),Math.sin(a*b*6.2832+c)},gaussian:function(a,b,c){return null==b&&(b=0),null==c&&(c=1),Math.exp(-Math.pow(b-a,2)*c)},linear:function(a,b,c){return null==b&&(b=1),null==c&&(c=0),(a+c)*b},flatten:function(a){return a>1?1:-1>a?-1:a},tanh:function(a){var b,c;return-3>a||a>3?h.util.flatten(a):(b=Math.exp(a),c=Math.exp(-a),(b-c)/(b+c))},step:function(a){return 0>a?-1:1},sample:function(a){return a[Math.floor(Math.random()*a.length)]},shuffle:function(a){var b,c,d,e,f,g;for(d=a.length,g=Array(d),b=c=0,f=d-1;f>=0?f>=c:c>=f;b=f>=0?++c:--c)e=Math.floor(Math.random()*b),e!==b&&(g[b]=g[e]),g[e]=a[b];return g},clone:function(a){var b,c;if(null===a||"object"!=typeof a)return a;c=a.constructor();for(b in a)a.hasOwnProperty(b)&&(c[b]=a[b]);return c},extend:function(a,b){var c;if(a=h.util.clone(a),null==b)return a;for(c in b)b[c]&&b[c].constructor&&b[c].constructor===Object?(a[c]=a[c]||{},a[c]=arguments.callee(a[c],b[c])):a[c]=b[c];return a},normalize:function(a){var b,c,d,e;d=0;for(b in a)e=a[b],d+=e;c={};for(b in a)e=a[b],e||(e=0),c[b]=e/d;return c},mean:function(a){var b,c,d,e,f;if(null==a.length||0===a.length)throw"data must be a list of numbers";for(f=0,b=a.length,d=0,e=a.length;e>d;d++)c=a[d],f+=c;return f/b},stddev:function(a){var b,c,d,e,f,g;for(f=h.util.mean(a),b=a.length,g=0,d=0,e=a.length;e>d;d++)c=a[d],g+=(c-f)*(c-f);return Math.sqrt(g/b)}},a=function(){function a(){}return a.prototype.config={},a.prototype.on=function(a,b){return this.config["on_"+a]=b,this},a.prototype.trigger=function(a,b){return null==b&&(b=null),null!=this.config["on_"+a]?this.config["on_"+a].call(this,b):void 0},a}(),g=function(a){function d(a){var c,d,e;for(this.config=a,this._mutateGene=b(this._mutateGene,this),this._setGeneOptions=b(this._setGeneOptions,this),this.generation=0,this.iteration=0,this.genes=[],c=d=1,e=this.config.size;e>=1?e>=d:d>=e;c=e>=1?++d:--d)this.genes.push(this._freshGenes());this.average=0,this._prevGenes=this.genes.slice(0),this._scoredGenes=[],this._history=[],this._setGeneOptions(this.config.gene_options)}return c(d,a),d.prototype.currentSize=function(){return this.genes.length},d.prototype.constructMember=function(a){var b;return null==a&&(a=null),b=this.trigger("member",a),null==b?null:(b._evo={},b._evo.genes=a,b._evo.score=0,b._evo.report=function(a){return function(){return a.report(b)}}(this),b)},d.prototype.nextGenes=function(){var a;if(a=this.genes.pop(),0===this.genes.length){if(!(this._scoredGenes.length>0))throw"Gene pool is empty";this._generate()}return a},d.prototype.nextGeneDict=function(){var a,b,c,d,e,f,g;for(c=this.nextGenes(),b={_raw:c},d=e=0,f=c.length;f>e;d=++e)a=c[d],g=d,null!=this._geneOptions[d]&&(g=this._geneOptions[d].name),null!=this._geneOptions[d]&&null!=this._geneOptions[d].range?null!=b[g]?b[g].push(a):b[g]=[a]:b[g]=a;return b},d.prototype.nextMember=function(){return null!=this.config.on_member?this.constructMember(this.nextGenes()):void 0},d.prototype.report=function(a,b){return null==b&&(b=0),this.iteration++,null!=a._evo&&(b=a._evo.score,a=a._evo.genes),null!=a._raw&&(a=a._raw),this._scoredGenes.push({genes:a,score:b})},d.prototype._checkRun=function(a){var b;return b=!0,null!=a.generations&&(b=b&&this.generation<a.generations),null!=a.iterations&&(b=b&&this.iteration<a.iterations),null!=a.score&&(b=b&&this.average<a.score),null!=a["while"]&&(b=b&&a["while"].call(this)),0===this._scoredGenes.length&&a.auto_stop&&(b=b&&!this._autoStop(a)),b},d.prototype._autoStop=function(a){var b,c;return this._history.length<a.min_generations?!1:(c=h.util.stddev(this._history.slice(this._history.length-this.config.min_generations,+(this._history.length-2)+1||9e9)),b=h.util.mean(this._history.slice(this._history.length-this.config.min_generations,+(this._history.length-2)+1||9e9)),Math.abs(this._history[this._history.length-1]-b)>c*c)},d.prototype.run=function(a){for(null==a&&(a={}),"number"==typeof a?a={iterations:a}:"function"==typeof a&&(a={"while":a}),null!=a.generations&&(a.generations+=this.generation),null!=a.iterations&&(a.iterations+=this.iteration),a=h.util.extend(this.config.run_conditions,a);this._checkRun(a);)this._runOnce();return this.trigger("finish")},d.prototype.bestGenes=function(a){return null==a?this._prevGenes[0]:this._prevGenes.slice(0,+(a-1)+1||9e9)},d.prototype.loadGenes=function(a){return this.genes=a.slice(0),this._scoredGenes=[]},d.prototype._freshGenes=function(){var a,b,c,d;for(d=[],a=b=1,c=this.config.genes;c>=1?c>=b:b>=c;a=c>=1?++b:--b)d.push(h.util.random()*this.config.mutate_amount);return d},d.prototype._cloneGenes=function(a){return a.slice(0)},d.prototype._mutateGenes=function(a){var b,c,d,e,f;for(f=[],c=d=0,e=a.length;e>d;c=++d)b=a[c],f[c]=this._mutateGene(a[c],this._geneOptions[c]);return f},d.prototype._crossGenes=function(a,b){var c,d,e,f,g,h;for(h=[],c=!1,e=f=0,g=a.length;g>f;e=++f)d=a[e],Math.random()<this.config.cross_rate&&(c=!c),h.push(c?a[e]:b[e]);return h},d.prototype._averageGenes=function(a,b){var c,d,e,f,g;for(g=[],d=e=0,f=a.length;f>e;d=++e)c=a[d],g.push((a[d]+b[d])/2);return g},d.prototype._runOnce=function(){var a,b;if(a=this.nextMember()||this.nextGenes(),b=this.trigger("run",a),null!=a._evo)return this.report(a);if("undefined"!=typeof b)return this.report(a,b);throw"score was not returned in run function"},d.prototype._generate=function(){var a,b,c,d,e,f,g,i,j,k,l,m,n,o,p,q,r,s;for(l=h.util.normalize(this.config.ratios),this.genes=[],q=function(){var b,c,d,e;for(d=this._scoredGenes,e=[],b=0,c=d.length;c>b;b++)a=d[b],e.push(a.score);return e}.call(this),this.average=h.util.mean(q),this._scoredGenes=this._scoredGenes.sort(function(a,b){return a.score-b.score}),s=this._scoredGenes.reverse().slice(0,+(this.config.ratios.top*this.config.size)+1||9e9),this._history.push(s[0].score),r=this.config.size,1>r&&(r=0),e=0,f=s.length;f>e;e++)a=s[e],this.genes.push(this._cloneGenes(a.genes));if(l.mutate>0)for(d=g=1,m=l.mutate*r;m>=1?m>=g:g>=m;d=m>=1?++g:--g)this.genes.push(this._mutateGenes(h.util.sample(s).genes));if(l.cross>0)for(d=i=1,n=l.cross*r;n>=1?n>=i:i>=n;d=n>=1?++i:--i)b=h.util.sample(s).genes,c=h.util.sample(s).genes,this.genes.push(this._crossGenes(b,c));if(l.average>0)for(d=j=1,o=l.meld*r;o>=1?o>=j:j>=o;d=o>=1?++j:--j)b=h.util.sample(s).genes,c=h.util.sample(s).genes,this.genes.push(this._averageGenes(b,c));if(l.random>0)for(d=k=1,p=l.random*r;p>=1?p>=k:k>=p;d=p>=1?++k:--k)this.genes.push(this._cloneGenes(h.util.sample(this._scoredGenes).genes));for(;this.genes.length<=r;)this.genes.push(this._freshGenes());return this.generation++,this._prevGenes=this.genes.slice(0),this.genes=h.util.shuffle(this.genes),this.trigger("breed"),this._scoredGenes=[]},d.prototype._setGeneOptions=function(a){var b,c,d,e,f,g;for(this._geneOptions=[],g=[],b=d=0,e=a.length;e>d;b=++d)f=a[b],g.push(null!=f.range?function(){var a,b,d,e;for(e=[],c=a=b=f.range[0],d=f.range[1];d>=b?d>=a:a>=d;c=d>=b?++a:--a)e.push(this._geneOptions[c]=f);return e}.call(this):this._geneOptions[b]=f);return g},d.prototype._mutateGene=function(a,b){var c,d,e,f;for(null==b&&(b={}),f=a,b.mutate_amount||(b.mutate_amount=this.config.mutate_amount),b.mutate_rate||(b.mutate_rate=this.config.mutate_rate),b.precision||(b.precision=this.config.precision),c=d=0,e=b.precision;e>=0?e>=d:d>=e;c=e>=0?++d:--d)b.mutate_rate>h.util.random()&&(f+=h.util.random()*b.mutate_amount*Math.exp(-c));return null!=b.max&&a>b.max?f=b.max:null!=b.min&&a<b.min&&(f=b.min),f},d}(a),f=function(){function a(a,b){this.weights=a,this.config=b,this.output_fn="function"==typeof this.config.output_fn?this.config.output_fn:"linear"===this.config.output_fn?h.util.linear:"step"===this.config.output_fn?h.util.step:h.util.tanh}return a.prototype.calc=function(){},a}(),d=function(a){function b(a,c){var d,e,f,g,h,i,j;for(this.config=c,this.node_fn=[],d=a.slice(0),e=g=0,i=this.config.hidden_layers-1;i>=0?i>=g:g>=i;e=i>=0?++g:--g)for(this.node_fn[e]=[],f=h=0,j=this.config.hidden_nodes-1;j>=0?j>=h:h>=j;f=j>=0?++h:--h)this.node_fn[e].push(this.get_fn(d.pop()));this.weights=d.slice(0),b.__super__.constructor.call(this,this.weights,this.config)}return c(b,a),b.node_fn=[h.util.gaussian,h.util.sin,function(a,b,c){return h.util.tanh(h.util.linear(a,b,c))}],b.prototype.get_fn=function(a){var c;return c=Math.round(Math.abs(a)*b.node_fn.length)%b.node_fn.length,b.node_fn[c]},b.prototype.calc=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A;for(h=this.config.hidden_nodes,b=this.weights.slice(0),c=[],f=g=0,o=this.config.hidden_layers-1;o>=0?o>=g:g>=o;f=o>=0?++g:--g)for(c[f]=[],d=j=0,p=this.config.hidden_nodes-1;p>=0?p>=j:j>=p;d=p>=0?++j:--j)c[f][d]=0;for(l=0,i=a.length;i>l;l++)for(A=a[l],d=m=0,q=this.config.hidden_nodes-1;q>=0?q>=m:m>=q;d=q>=0?++m:--m)c[0][d]+=A*b.pop();for(f=n=0,r=this.config.hidden_layers-2;r>=0?r>=n:n>=r;f=r>=0?++n:--n)for(d=w=0,s=this.config.hidden_nodes-1;s>=0?s>=w:w>=s;d=s>=0?++w:--w)if(c[f][d]=this.node_fn[f][d](c[f][d],b.pop(),b.pop()),f+1<this.config.hidden_layers)for(e=x=0,t=this.config.hidden_nodes-1;t>=0?t>=x:x>=t;e=t>=0?++x:--x)c[f+1][e]+=c[f][d]*b.pop();for(k=[],e=y=0,u=this.config.output_nodes-1;u>=0?u>=y:y>=u;e=u>=0?++y:--y){for(k[e]=0,d=z=0,v=this.config.hidden_nodes-1;v>=0?v>=z:z>=v;d=v>=0?++z:--z)k[e]+=c[this.config.hidden_layers-1][d]*b.pop();k[e]=this.output_fn(k[e])}return k},b}(f),e=function(a){function b(a,c){this.weights=a,this.config=c,b.__super__.constructor.call(this,this.weights,this.config)}return c(b,a),b.prototype.calc=function(a){var b,c,d,e,f,g,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(a.length!==this.config.input_nodes)throw Error("Inputs dont match. Expected: "+this.config.input_nodes+", Received: "+a.length);for(b=this.weights.slice(0).reverse(),d=[],f=g=0,t=this.config.hidden_nodes-1;t>=0?t>=g:g>=t;f=t>=0?++g:--g)d[f]=0;for(p=[],f=n=0,u=this.config.output_nodes-1;u>=0?u>=n:n>=u;f=u>=0?++n:--n)p[f]=0;for(q=0,i=a.length;i>q;q++)for(e=a[q],f=r=0,j=d.length;j>r;f=++r)c=d[f],d[f]+=e*b.pop();for(e=s=0,k=d.length;k>s;e=++s)for(c=d[e],d[e]+=b.pop(),d[e]=h.util.tanh(d[e]),f=v=0,l=p.length;l>v;f=++v)o=p[f],p[f]+=d[e]*b.pop();for(e=w=0,m=p.length;m>w;e=++w)o=p[e],p[e]=this.output_fn(p[e]);return 1===p.length?p[0]:p},b}(f),h})}).call(this);