[Rust] 遺伝的アルゴリズムでテキスト生成

April 26, 2022

引き続きRustの勉強。

ゴールとなる文字列を決めておいて、簡易的な遺伝的アルゴリズムでその文字列を生成することを目指すもの。

これは、Nature of Codeにシェイクスピアの文章を生成する例として載っている。

Nature of Code -Processingではじめる自然現象のシミュレーション-

Nature of Codeのコード(全部じゃない)は、Rust製のクリエイティブコーディングツールNannouのRepoに一部移植されているので、それも参考にした。

https://github.com/nannou-org/nannou/blob/master/nature_of_code/chp_09_genetic_algorithms/9_1_ga_shakespeare.rs

実装方法

  1. 30個のランダム文字列を生成
  2. 成績の良いものを優先して親を選ぶ
  3. 選んだ親から子を生成
  4. 子の文字列には一定確率で突然変異を含ませる
  5. 2〜4を繰り返す

という感じでやった。Rubyで書いたら一瞬なんだけど、とても時間がかかった……。

入門書読んでる時は「所有権?そんな難しくないやん。こちとらObjective-Cの地獄を見てきたから、面構えが違うんやぞ」とか思っていたが、いざ書いてみると全然駄目だった。怒られまくる。

結果

動いた。

短い文字列なら一瞬で。

1
2
3
4
5
6
7
8
9
10
11
12
13
0 | 0.30 | 2 | eelta
1 | 0.53 | 3 | eelto
2 | 1.07 | 3 | eelto
3 | 1.77 | 3 | nelto
4 | 1.80 | 3 | nelto
5 | 2.03 | 3 | eeljo
6 | 2.07 | 3 | xeelo
7 | 2.17 | 3 | helju
8 | 2.03 | 3 | tellt
9 | 2.17 | 3 | eellt
10 | 2.53 | 4 | hellt
11 | 2.57 | 4 | hellt
12 | 2.83 | 5 | hello

そこそこ長いとだいぶ世代数が多くなることも。

1
2
3
4
5
6
7
8
9
10
11
12
13
0 | 0.33 | 2 | hvrsbgrmlu
1 | 0.43 | 2 | vqhwostxlt
2 | 0.60 | 3 | hqhwostxlt
3 | 1.03 | 3 | hpllfklpoe
4 | 1.20 | 2 | hvrytdiklt
:
:
:
604 | 8.50 | 9 | hellowkrld
605 | 8.50 | 9 | hellowkrld
606 | 8.63 | 9 | hellowkrld
607 | 8.60 | 9 | hellowkrld
608 | 8.67 | 10 | helloworld

コード

https://github.com/tnantoka/my_rust_sandbox/tree/main/ga_text