はじめに
最近AI/アルゴリズムの講演を聞きました。そこで、遺伝的アルゴリズムに興味を持ったので「作ってみたい!」と思い、作成したので、何かの参考になればと思いご紹介します。
実際の挙動
これらは毎フレームランダムに動かしているだけですが、とても人工知能ぽくみえます。
実践
ソースコードはこちら
※3D空間上でXZ平面を走っているのを上から撮影しています
float rotVelo = Random.Range(-rotateSpeed, rotateSpeed);
transform.eulerAngles = transform.eulerAngles + new Vector3(0, rotVelo, 0);
float posVelo = Random.Range(0, moveSpeed);
transform.position += transform.forward * posVelo;
このObjectを
20体用意して、
100mごとに障害物を置きます。
移動データの記録
それから動いた記録を保存するデータを作成します。
[Serializable]
public struct MoveData
{
public float pos;
public float rot;
public MoveData(float _pos, float _rot)
{
pos = _pos;
rot = _rot;
}
}
これのリストを作ってランダムに動いた結果を保存しておきます。
具体的な保存の値はそれぞれ、上記のrotVelo
とposVelo
です。
全員が壁にぶつかったら集計をします。
その際にどのObjectが一番進んだかを確かめて次の世代を生成します。
遺伝子の受け継ぎ
for (int i = 0; i < 一,二番優秀移動データリスト.Count; i++)
{
bool l = Random.Range(0,2) == 0;
次世代.移動データリスト.Add(l ? 一番優秀.移動データリスト[i] : 二番優秀.移動データリスト[i]);
}
こうすることで二人の親の遺伝子(移動データ)を持った子供が生まれます。
parent1+parent2->child1
parent1+parent3->child2
parent2+parent3->child3
parent2+parent4->child4
parent3+parent4->child5
parent3+parent5->child6
と子供を作っていきます
child7は一番優秀のデータをそのまま受け継ぎます。(最高記録が下がらないように)
chaild8,9,10はランダムに選んだ二人の遺伝子を組み合わせます。
ですがそこで突然変異を起こします。
突然変異
一定の確率で値をおかしくしてほしいので、
if(突然変異する)
{
for (int i = 0; i < 突然変異.移動データリスト.Count; i++)
{
突然変異.移動データリスト.Add(l ? 一番優秀.移動データリスト[i] : 二番優秀.移動データリスト[i]);
foreach(var 移動データ in 突然変異.移動データリスト)
{
if(Random.Range(0 , 突然変異でどれくらい変わるか) != 0)
移動データ.pos *= Random.Range(0,2);
移動データ.rot *= Random.Range(-2,2);
}
}
}
こんな感じで突然変異させます。
これらの出来上がったデータをObjectに記録させて、
第2世代が始まります。
第2世代
第2世代は遺伝で受け継いだデータのとおりに動きます。
データがなくなったらランダムに動き始めます。
これらを繰り返して行くとこんな感じになりました。
終わりに
講演とかYoutubeの動画を見ながらこんな感じで作るのかなーって作りきりました。
いいお勉強になって楽しかった。