forked from: 遺伝的アルゴリズム??
bit演算でやってみますた
一応遺伝的アルゴリズム(GA)のつもり
* 赤字の答えにたどり着くために世代交代(交配)を繰り返します
* スクロールバーをつけてないので、テキストエリアをスクロールできないのですが
* マウスで選択してグアーっと下に選択していくとスクロール?して確認できます。
* 遺伝子のモデルは2進数なのでbit演算したほうが絶対良いのですが、やり方が分かりません・・・
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/6p0j
*/
// forked from fumix's 遺伝的アルゴリズム??
// bit演算でやってみますた
/*
* 一応遺伝的アルゴリズム(GA)のつもり
* 赤字の答えにたどり着くために世代交代(交配)を繰り返します
* スクロールバーをつけてないので、テキストエリアをスクロールできないのですが
* マウスで選択してグアーっと下に選択していくとスクロール?して確認できます。
* 遺伝子のモデルは2進数なのでbit演算したほうが絶対良いのですが、やり方が分かりません・・・
*/
package {
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
[SWF(width = 465, height = 465, backgroundColor = 0xFFFFFF, frameRate = 60)]
/**
* @author fumix
*/
public class GeneticAlogrithm extends Sprite {
private var tx : TextField;
private var answer : uint;
private var genicArray : Array;
private var generationCount : int;
private var upButton : Sprite;
private var downButton : Sprite;
private var N : int = 10;
private var M : int = 10;
/*
* コンストラクタ
*/
public function GeneticAlogrithm() {
tx = new TextField();
tx.multiline = true;
tx.width = 450;
tx.height = 450;
addChild(tx);
generationCount = 0;
//スクロールボタン
upButton = new Sprite();
upButton.graphics.beginFill(0x333333);
upButton.graphics.drawRect(0, 0, 15, 15);
upButton.graphics.endFill();
upButton.buttonMode = true;
upButton.x = 450;
upButton.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
addChild(upButton);
downButton = new Sprite();
downButton.graphics.beginFill(0x333333);
downButton.graphics.drawRect(0, 0, 15, 15);
downButton.graphics.endFill();
downButton.buttonMode = true;
downButton.x = 450;
downButton.y = 450;
downButton.addEventListener(MouseEvent.MOUSE_UP, onMouseDownHandler);
addChild(downButton);
//求める答え(N bit)
answer = generateGene(N);
addTextField(toBinaryString(answer), '#ff0000');
addTextField('----------');
//遺伝子を10個ためておく配列
genicArray = new Array(M);
for (var i : int = 0;i < M;i++) {
genicArray[i] = {gene : generateGene(N), score : 0};
}
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
}
private function onMouseDownHandler(event : MouseEvent) : void {
tx.scrollV++;
}
private function onMouseUpHandler(event : MouseEvent) : void {
tx.scrollV--;
}
private function onEnterFrameHandler(event : Event) : void {
//遺伝子の評価
var genicArray : Array = evaluateGene(answer, genicArray);
//交配
var newGene1 : uint = crossbreeding(genicArray[0].gene, genicArray[1].gene);
var newGene2 : uint = crossbreeding(genicArray[0].gene, genicArray[1].gene);
genicArray.pop();
genicArray.pop();
genicArray.push({gene : newGene1, score : 0});
genicArray.push({gene : newGene2, score : 0});
generationCount++;
addTextField(generationCount + '世代目');
for each(var v : Object in genicArray) {
//評価点が最大の場合、ループ終わり
if(v.score == N) {
addTextField(toBinaryString(v.gene) + ' ' + v.score, '#0000ff');
removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
} else {
addTextField(toBinaryString(v.gene) + ' ' + v.score);
}
}
addTextField('----------');
}
private function toBinaryString(a : uint) : String
{
var ret : String = "000000000000000000000000000000000000" + a.toString(2);
return ret.substring(ret.length - N);
}
/*
* 交配
*/
private function crossbreeding(gene1 : uint, gene2 : uint) : uint {
// もっとえろえろに交配する
var mask : uint = Math.random() * (1 << N);
var ret : uint = (gene1 & mask) | (gene2 & (~mask));
//突然変異
if(Math.random() < 0.9){
var mutatePoint : int = Math.random() * N;
ret ^= 1 << mutatePoint;
}
return ret;
}
private function evaluateGene(ans : uint, arr : Array) : Array {
for(var i : int = 0;i < arr.length;i++){
arr[i].score = N - bitcount(arr[i].gene ^ ans);
}
//評価点でソート
arr.sortOn("score", Array.DESCENDING | Array.NUMERIC);
return arr;
}
private function bitcount(a : uint) : int
{
a = (a & 0x55555555) + (a >> 1 & 0x55555555);
a = (a & 0x33333333) + (a >> 2 & 0x33333333);
a = (a & 0x0f0f0f0f) + (a >> 4 & 0x0f0f0f0f);
a = (a & 0x00ff00ff) + (a >> 8 & 0x00ff00ff);
a = (a & 0x0000ffff) + (a >> 16 & 0x0000ffff);
return a;
}
private function generateGene(bit : int = 1) : uint {
return Math.random() * (1 << bit);
}
/*
* テキストフィールドに文字列を表示させる
*/
private function addTextField(txt : String,color : String = '#000000') : void {
tx.htmlText += '<font color="' + color + '">' + txt + '</font>';
//trace(txt);
}
}
}