/**
* Copyright yuuganisakase ( http://wonderfl.net/user/yuuganisakase )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1PHX
*/
// Genetic Algorithm test1
package
{
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
[SWF(width=465, height=465, frameRate=15, backgroundColor=0x000000)]
public class GA extends Sprite
{
private var worlds:Array = new Array();
private var label:Label;
private var tf:TextField;
public function GA():void
{
super();
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
tf = new TextField();
var format:TextFormat = new TextFormat(null, 18, 0x888888);
format.align = TextFormatAlign.CENTER;
tf.defaultTextFormat = format;
tf.text =
tf.autoSize = TextFieldAutoSize.CENTER;
tf.x = 200;
tf.y = 160;
addChild(tf);
worlds.push(new Population(" to be or not to be "));
worlds.push(new Population(" that is the question "));
worlds.push(new Population(" whether tis nobler in the mind to suffer "));
worlds.push(new Population(" the slings and arrows of outrageous fortune "));
worlds.push(new Population(" or to take arms against a sea of troubles "));
worlds.push(new Population(" and by opposing end them "));
worlds.push(new Population(" to die to sleep "));
label = new Label(this, 50,50, "generation = 0");
label.setSize(70, 20);
addEventListener(Event.ENTER_FRAME, onEnter);
stage.addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent = null):void
{
for each(var w:Population in worlds)
{
w.finished = !w.finished;
}
}
private function onEnter(e:Event):void
{
var g:int = 0;
var s:String = "";
for (var i:int = 0; i < worlds.length; i++)
{
if (worlds[i].generation > g) g = worlds[i].generation;
s = s + worlds[i].getBest();
s = s + "\n" ;
}
tf.text = s;// worlds[0].getBest();
for each(var ww:Population in worlds)
{
if (ww.finished == false) {
ww.naturalSelection();
ww.generate();
ww.calcFitness();
ww.generation += 1;
}
}
label.text = "generation = " + g;
}
}
}
class Population
{
private const NUM:int = 110;
private var target:String;
public var population:Vector.<DNA> = new Vector.<DNA>(NUM);
private var fitness:Vector.<Number> = new Vector.<Number>(NUM);
public var darwin:Vector.<DNA> = new Vector.<DNA>();
public var generation:int = 0;
public var finished:Boolean = false;
public function Population(tar:String)
{
target = tar;
for (var i:int = 0; i < NUM; i++)
{
population[i] = (new DNA(tar.length) );
}
calcFitness();
}
public function calcFitness():void
{
for (var i:int = 0; i < NUM; i++)
{
fitness[i] = population[i].calcFitness(target);
}
}
public function naturalSelection():void
{
darwin.length = 0;
var i:int = 0;
for (i = 0; i < NUM; i++)
{
var n:DNA = population[i];
var ff:int = Math.floor(fitness[i] *fitness[i]*fitness[i] * 5500);
for (var j:int = 0; j < ff; j++)
{
darwin.push(n);
}
}
}
public function generate():void
{
for (var i:int = 0; i < NUM; i++)
{
var m:int = Math.floor(Math.random() * darwin.length);
var d:int = Math.floor(Math.random() * darwin.length);
var mom:DNA = darwin[m];
var dad:DNA = darwin[d];
var child:DNA = mom.mate(dad);
population[i] = child;
}
}
public function getBest():String
{
var best:Number = 0;
var index:int = 0;
var i:int;
for (i = 0; i < NUM; i++)
{
if (fitness[i] > best)
{
index = i;
best = fitness[i];
}
}
if (best == 1) finished = true;
var v:Vector.<String> = population[index].dna;
var s:String = "";
for (i = 0; i < v.length; i++)
{
s = s + v[i];
}
return s;
}
}
class DNA
{
public var dna:Vector.<String>;
public function DNA(len:int, d:Vector.<String> = null)
{
if (d == null) {
dna = new Vector.<String>(len);
for (var i:int = 0; i < len; i++)
{
dna[i] = getChar();
}
}else {
dna = d;
}
}
public function calcFitness(target:String):Number
{
var score:Number = 0;
for (var i:int = 0; i < dna.length; i++)
{
if (target.charAt(i) == dna[i]) score += 1;
}
return score / dna.length;
}
public function mate(partner:DNA):DNA
{
var child:Vector.<String> = dna.concat();
var len:int = dna.length;
var midPoint:int = Math.floor(Math.random() * len);
for (var i:int = 0; i < dna.length; i++)
{
if (i < midPoint) {}//child[i] = this.dna[i];
else child[i] = partner.dna[i];
}
var newDNA:DNA = new DNA(len, child);
newDNA.mutate(0.013);
return newDNA;
}
public function mutate(p:Number):void
{
/* var r:Number = Math.random();
if (r < p) {
var pos:int = Math.floor(Math.random() * dna.length);
dna[pos] = getChar();
}
*/ for (var i:int = 0; i < dna.length; i++)
{
if (Math.random() < p)
{
dna[i] = getChar();
}
}
}
private function getChar():String
{
var a:uint = "a".charCodeAt(0);
var z:uint = "z".charCodeAt(0);
var code:uint = Math.floor(Math.random() * (z - a)) + a;
return (Math.random() > 0.02)? String.fromCharCode(code): " ";
}
}