LoginSignup
6
5

More than 1 year has passed since last update.

Rustで遺伝的アルゴリズム [optimiGAtion]

Posted at

概要

 初めまして、最近Rustにはまっている学生です。ここでは、Rustの標準機能cargoを用いて、遺伝的アルゴリズムのライブラリを公開したので紹介させていただきます。

Rustとは

Rustは、c++の正当後継言語と言われる汎用システム言語です。詳しいことは省略しますが、なんといってもメモリ管理が圧倒的に楽ということがメリットです。ほかにも、c++と同様の速度を保持、cargoによるパッケージ管理機能(pythonでいうpip)、エラーメッセージの充実さなどが評価されている、流行間違いなし(想像)の言語です。

しかし、満足のいく研究や設計の際に用いられる最適化アルゴリズム、遺伝的アルゴリズムの汎用ライブラリがなかったので、作ってみました。

optimiGAtion

Rustで遺伝的アルゴリズム等の進化計算を支援するクレートです。任意の型、マルチ関数の時間的制御(評価関数を途中で変更できるということ)など対応しており、汎用性が非常に高いです。(2022/4/9現在は非対応、今後updateされる予定)

Repository

githubに公開してます。この記事もREADME.mdの日本語版のようなものです。

遺伝的アルゴリズムとは

別で簡単に紹介してますので、こちらを参照してくだされば助かります。

(pythonによるとか書いてますがこの記事ではpythonは出てきません(?)理論のみ説明されています。)

How to use.

まず、RustのフォルダにあるCargo.tomlの[dependencies]を編集しましょう。

Carfo.toml
[dependencies]
optimigation = "0.1.0"

リリースされたばかりなのでバージョンも低いです、、、

次に、main.rsを以下のようにしましょう。ここでは浮動小数点バージョンのONEBOX問題を解いてます。

main.rs

extern crate optimigation;
use optimigation::GenomeList;

use crate::optimigation::ga_algorithm::Generation;
use crate::optimigation::ga_algorithm::System;


fn sum(genome: &Vec<f32>) -> f32{

    let mut a: f32 = 0.0;
    for i in 0..genome.len(){
        a += genome[i];
    }
    a
}

fn main() {

    //評価関数のクロージャ作成(リスト形式)

    let c1: fn(&Vec<f32>) -> f32 = |x| {(sum(x)/x.len() as f32 - 10.0).abs()};
    let mut functions = Vec::new();
    functions.push(c1);




    let mut world = GenomeList::new(1000, 10, 0.0, 10.0, &functions);      //初期集団生成
    GenomeList::ga_loop(&mut world, 200, 1, 0.05, 0.0, 10.0);              //最適化開始

}

結果はすべて1の配列が理論解ですが、以下のように出力されます。

Note        : Creating first generation...
Note        : GA loop start.
Result      : Genome { dna: [9.999947, 9.999874, 9.999947, 9.999874, 9.999947, 9.999874, 9.999947, 9.999874, 9.999947, 9.999874], eval: 8.9645386e-5 }
Generations : 38761.0

浮動小数なので近似解が出てますね!

GenomeList::new(usize, usize, f32, f32, &Vec< fn(&Vec) -> f32 >)

初期集団を生成する関数です。第一引数に遺伝子の数、第二引数に遺伝子の長さ、第三引数に解の最小値、第四引数に解の最大値、第五引数に評価関数クロージャの参照がとられて、初期集団のリストを返します。

GenomeList::loop(& mut Self, usize, i8, f32, f32, f32)

最適化を行う関数です。第一引数に初期集団、第二引数に親遺伝子の数、第三引数に交叉方法を示す値、第四引数に解の最小値、第四引数に解の最小値をとります。

交叉方法は以下のようになります。

key way of crossover
-1 inherited average of parents component
0 inherited components in units of random
n > 0 inherited components in units of n

デメリット

 浮動小数しか対応していないこと!! 整数などの最適化は今は無理です。今後実装します。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5