PostgreSQLで疑似乱数

レンタル鯖で使える(≒環境を選ばない)疑似乱数の発生プログラムを考える上で、これまでは「特定の言語のネイティブ表現だけで疑似乱数アルゴリズムを実装する」方向で検討してきた訳だが、風呂に入ってだらだら考えたら別の遣り方が見えてきたので、試しに実験してみた。
いきなりMTはつらいので、まずは線形合同法で。

レンタル鯖に、この場合はPostgreSQLがインストールされ、使える状態にあるとする。

lcg_id, name, lcg_a, lcg_b, lcg_m, last_num, seedの六つのカラムを持つテーブルを作る。
それぞれ、シーケンス型のID,、サイコロにつける名前、線形合同法のAとBとM、最後に返した値(初期値は0)、種の六種。
これに、適当に線形合同法に則ったレコードを追加する。ひとつのレコードが一つのサイコロに該当する。

INSERT INTO lcg ( name, lcg_a, lcg_b, lcg_m, last_num, seed ) VALUES ( "sample", 51, 79, 65536, 0, 0 );

それから、関数を作る。

CREATE FUNCTION lcg_next ( varchar )
RETURNS integer
AS 'UPDATE lcg SET last_num = mod ( last_num * lcg_a + lcg_b , lcg_m ) WHERE name = $1; SELECT last_num FROM lcg WHERE name = $1;'
LANGUAGE 'SQL';

これで準備完了。
後は、

SELECT lcg_next('sample');

を実行する度に、線形合同法による疑似乱数が返される。

感想

RDBMを使ってメルセンヌ・ツイスターの実装って、頑張ればできそう。