遺伝アルゴリズムとか

フォント同士を交配させて新しいフォントを作る「genoTyp」が面白い
これ面白いなぁ。

『集合知プログラミング』を読んだのを思い出したので、そこの「遺伝アルゴリズム」を参考にして、それっぽいのを習作としてやってみた。

ルールは、
・まず最初にランダムな5個の数字 x 100組を生成する。
・5個の数字の積が1000になれば進化終了。1000に近いものを優先的に残す。
・100組のうち、結果がよい(積が1000に近いもの)50組を残す。
・突然変異(8割の確率)、交配(2割の確率)で新たに50組を生成する。
という感じ。

ってかなんだろね、このロジックを試してみるには、積が1000に近いとかって不適当かもしれんね。
数の並びとかあんま関係ないし。

[php]<?php

$list = array(); for ($i=0;$i<100;$i++) { $tmp = array(); for ($j=0;$j<5;$j++) { $tmp = mt_rand(1,10); } $list = $tmp; }

for ($i=1;$i<=10;$i++) { uasort($list, 'cmp'); display($list);

if (cost($list[0]) == 0) { echo "gene stop\n"; break; } $list = array_slice($list,0,count($list)*.5); $tmp = $list; while(count($tmp) < 100) { if (mt_rand(1,10) <= 8) { $tmp = mutate($list[mt_rand(0, count($list) - 1)]); } else { $tmp = crossover( $list[mt_rand(0, count($list) - 1)], $list[mt_rand(0, count($list) - 1)] ); } } $list = $tmp; }

function display($list) { static $gene = 1; echo $gene."gene\n"; echo "[".cost($list[0])."]"; echo "[".join(",",$list[0])."]"; echo "\n\n"; $gene++; return ; }

function mutate($data) { $res = $data; $n = mt_rand(0,count($res) - 1); $res[$n] = mt_rand(1,10); return $res; }

function crossover($data1, $data2) { $res = array(); $max = min(count($data1), count($data2)); for ($i=0;$i<$max;$i++) { $res[] = (mt_rand(0,1) == 0) ? $data1[$i] : $data2[$i]; } return $res; }

function cost($arr) { $n = abs(1000 - array_product($arr)); return $n; }

function cmp($a,$b) {

$a1 = cost($a); $b1 = cost($b);

if ($a1 == $b1) { return 0; } return ($a1 < $b1) ? -1 : 1; }[/php]