読者です 読者をやめる 読者になる 読者になる

望月いちろうのREADME.md

書き溜めておいた技術記事や旅行記のバックアップです。

プログラマーなら必ず知らないといけない乱数についての知識について勉強しよう - C C++ Python

真の乱数

ハードウェア乱数生成器を備えた一部のCPUでのみ利用できる C++のstd::random_deviceなどで利用できる。

擬似乱数

一見乱数の様だが、実際には初期値をもとに任意の乱数列を決定的に発生させる。暗号論的には、各値が推測可能なもの、しかし実際には、メルセンヌツィスタなど非常に長い周期での一様に分布する乱数発生器が開発されており、科学技術計算などの用途に限れば、実用上は、それらを使えば差し支えない。

線形合同法

C言語の標準ライブラリに含まれる疑似乱数生成関数、randなどの中身はこれ。

周期が非常に短く、科学技術計算に用いるには適していない。

メルセンヌツイスタ

松本眞 ・西村拓士両先生によって開発された疑似乱数生成アルゴリズムで、2の19937乗のマイナス1という非常に長い周期を持っており、偏りも見られない。

Pythonのmathライブラリの乱数はこれ

ダウンロードは以下から

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/mt19937ar.html

SFMT

松本眞教授とその指導学生の 斎藤睦夫によって開発された。メルセンヌツイスタの改良版で、より高速で高性能。

ダウンロードは以下からで、整数から浮動点少数への変換コストを考慮したdSFMTも存在する。

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index-jp.html

たとえば、dSFMTを利用するには以下のソースコードのように、ソースファイルをインクルードした上で、内部状態と初期値を格納するdsfmt_t構造体を定義して、任意の乱数発生器にその参照を渡せばよい。

#include "dSFMT.c"

#include <time.h>

#include <limits.h>



int main(void){

  dsfmt_t dsfmt;

  dsfmt_init_gen_rand(&dsfmt,time(NULL)%INT_MAX);

  double s = (double)dsfmt_genrand_open_close(&dsfmt);

  for(int k = 0;k < 100000;k++){

     printf("%f\n",(double)dsfmt_genrand_open_close(&dsfmt));

  }

  return 0;

}