Location : Home > Languages > Perl > Package Title : AI::Gene::Sequence |
![]() |
AI::Gene::Sequence
遺伝子配列を格納・変異させる基本クラスである。
package Somegene; use AI::Gene::Sequence; our @ISA = qw(AI::Gene::Sequence); my %things = ( a => [qw(a1 a2 a3 a4 a5)], b => [qw(b1 b2 b3 b4 b5)],); sub generate_token { my $self = shift; my ($type, $prev) = @_; if ($type) { $prev = ${ $things{$type} }[rand @{ $things{$type} }]; } else { $type = ('a','b')[rand 2]; $prev = ${$things{$type}}[rand @{$things{$type}}]; } return ($type, $prev); } sub valid_gene { my $self = shift; return 0 if $_[0] =~ /(.)\1/; return 1; } sub seed { my $self = shift; $self->[0] = 'ababab'; @{$self->[1]} = qw(A1 B1 A2 B2 A3 B3); } sub render { my $self = shift; return join(' ', @{$self->[1]}); } # どこかで package main; my $gene = Somegene->new; $gene->seed; print $gene->render, "\n"; $gene->mutate(5); print $gene->render, "\n"; $gene->mutate(5); print $gene->render, "\n";
これは遺伝子配列の生成・変異のための汎用メソッドを提供するクラスである。様々な変異が変異により有用なままで遺伝子を生成する方法として提供されている。(例えば遺伝子がコード化されたらそれが正しい文法かをテストする。)
あまりソートに時間を費やしたくなければ AI::Gene::Simple クラスを使わずに他のもっと高速なものを使うとよいだろう。変異へのインタフェースは同じで、とは言っても将来的に変更するかも知れないが、さほど問題にはならないだろう。
本モジュールを DNA 配列を解析するために用いられる bioperl モジュールと混同してはならない。
本コードにおけるメソッドは他のモジュールにより相続されることを想定している。
遺伝子(gene)はトークン(token)の列(sequence)であり、それぞれは類似のトークンのグループのメンバーである(もちろん単一のグループであってもよい)。本モジュールは遺伝子をトークンの型を示す文字列やトークン自身を含む配列にエンコードし、任意のデータを遺伝子内のトークンに格納する。
例えば正規表現では以下のようにエンコードされる。
$self = ['ccartm',['a', 'b', '|', '[A-Z]', '\W', '*?'] ]
遺伝子の対応する部分におけるソートを示す文字列は正規表現を用いて提案された遺伝子の正当性を確認するために用いられる。
遺伝子配列を利用するためには以下のメソッドの実装を行わねばならない。
以下のメソッドをオーバライドすることもできる。
変異メソッドは全て mutate_* という名称である。一般には、引数として、最初は必要な変異の回数を、続いて変化を受ける遺伝子上の位置、さらに変異を受ける配列の長さをとる。
位置が定義されなければランダムに設定される。長さが定義されなければ 1 に設定される(すなわち単一トークンのみに作用する)。長さが 0 であれば長さはランダムに指定される。
また変異が示唆されても配列が妥当でなければ変異は実行されない。
変異が遺伝子を破壊する場合(遺伝子の長さを超えて複写するなど)は無視される。変異メソッドは変異の数だけ実行される(影響を受けるトークンの数ではない)。
これらのメソッドは全て正の整数が渡されることを想定しており、undef や 0 その他の値の場合は何が起こるかわからない。
mutate([num, ref to hash of probs & methods])
これは変異メソッドの1つをランダムに呼び出す。
num 回繰り返し実行される。第2引数としてハッシュへの参照が渡され、実施する変異を決定するために使用される。
このハッシュは の $1 と適合するキーと、メソッドで与えられる値でなければならない。モジュールは正規化されるのでユーザは行なわくてよい。モジュールで好まないものはオーバーライドして自身の変異メソッドを定義することもできる。
mutate_insert([num, pos])
位置 pos に単一のトークンを挿入する。
トークンはオブジェクトの generate_token メソッドを呼び出すことでランダムに生成することができる。
mutate_overwrite([num, pos1, pos2, len])
選択した(位置 pos1 で始まり長さ len の)遺伝子を複写し、遺伝しないに戻して位置 pos2 から上書きする。
mutate_reverse([num, pos, len])
遺伝子から配列を取り出し、これを反転させる。位置 pos から始まる長さ len の配列を取り出す。
mutate_shuffle([num, pos1, pos2, len])
遺伝子から(位置 pos1 で始まり長さ len の)配列を取り、他の(pos2 から始まる)位置に移動させる。指定された位置が移動元の配列の範囲内にあれば奇妙なことになり、モジュールは変異しようと尽力することになる。
mutate_duplicate([num, pos1, pos2, length])
これは pos1 で始まり長さ length の遺伝子を複写し、pos2 の前に接合する。
mutate_remove([num, pos, length]))
pos から始まる遺伝子から length 個のトークンを削除する。これを num 回繰り返す。
mutate_minor([num, pos])
これは遺伝子中の位置 pos における単一のトークンを変異させ同じ型の1つへ移す。(オブジェクトの generate_token メソッドで決定される。)
mutate_major([num, pos])
単一のトークンをトークンタイプのトークンへ変更する。
位置 pos のトークンである。トークンはオブジェクト generate_token メソッドで生成される。.
mutate_switch([num, pos1, pos2, len1, len2])
1つの遺伝子における2つの配列を取り、それぞれの位置に入れ替える。1つめは位置 pos1 から始まる長さ len1 の配列、2つめは位置 pos2 から始まる長さ len2 の配列。2つの配列が重なっていれば実行しない。
以下のメソッドも利用可能であるが、おそらくユーザの遺伝子配列のほうを優先したいのでは。
generate_token([token type, current token])
これはトークンを変更したり、新しいトークンを生成したりする場合に用いる。生成されたトークンの型を示す単一の文字を含むリストを返す。トークンを修正することで意味がある場合にはトークンの型を指定する。
どんな型のトークンでもよければ引数を指定する必要はない。
このメソッドのバージョンでは 'a'..'z' の文字をランダムに返す。
valid_gene(string [, posn])
指定された変異が許容されているかを確認する。このメソッドは遺伝子全体のトークン型の文字列が渡され、それが意味を成す遺伝子上の位置(すなわち一つのトークンのみが変更される)が渡される。変更が妥当であれば true を返し、そうでなければ false を返す。
本メソッドのバージョンでは常に true を返す。
clone()
遺伝子の複写を新しいオブジェクトとして返す。ネスト化された遺伝子を使うかユーザ定義のトークンとして参照を使った場合には、自分自身でその複写を生成する必要がある。
new
空の遺伝子を返す。遺伝子の初期化をしたい場合には他のものを使うべきだろう。
render_gene
デバッグには有用。遺伝子のシリアル化された要約を返す。
このモジュールは Alex Gough (alex@rcon.org) によって書かれた。
本モジュールの使用方法については圧縮されているファイルにある Regexgene.pm, Musicgene.pm, spamscan.pl, music.pl を見よ。
Copyright (c) 2000 Alex Gough alex@rcon.org. All rights reserved.
本プログラムはフリーソフトウェアであり、Perl 本体と同等の条件で修正/再配布してもよい。
これは変異が妥当な遺伝子を生成するかを確認する必要がないのであれば非常に遅い。しかし速くしようとするとそれを外すことになる。これが面倒であれば代わりに AI::Gene::Simple クラスを使えばよい。
変な値を渡したら奇妙なことになるメソッドがあるが、これは試すべきではない。正の整数または undef をメソッドに渡している限り、優雅に復帰するだろう。
Perl で遺伝アルゴリズムや進化アルゴリズムを書くことは簡単で面白い。しかしたいていの場合、非常に低速で実装するには他の適切な言語で書くべきだろう。Perl におけるアプローチでは変異が大規模で大量にある場合に問題が生じる。人の思いつきによる選択で作曲をするようなものである。
![]() |
Updated : 2008/05/09 |