コンピュータは用意された値を正確に計算します。
つまり、乱数のように無茶苦茶な値を用いたい場合は、様々な方法で計算を行い疑似的に 乱数っぽい値(疑似乱数) を作っているのです。
つまり、乱数のように無茶苦茶な値を用いたい場合は、様々な方法で計算を行い疑似的に 乱数っぽい値(疑似乱数) を作っているのです。
VC++を用いる場合、rand() を使えばとりあえず疑似乱数が使えます。
しかし、 プログラムを何回実行しても同じ結果 になると思います。
しかし、 プログラムを何回実行しても同じ結果 になると思います。
そこで、疑似乱数が毎回同じ結果をはじくのは困る場合、それを防ぐ方法を紹介します。
疑似乱数はある初期値を元に計算を行って生成されます。
初期値を設定する関数は srand です。この初期値に毎回違う値を設定してやれば、 毎回同じ結果をはじくことはなくなります 。
初期値を設定する関数は srand です。この初期値に毎回違う値を設定してやれば、 毎回同じ結果をはじくことはなくなります 。
普通は
現在の時間を元に初期化
します。
現在の時間自体は乱数として利用できませんが、初期値としては十分利用できます。
現在の時間自体は乱数として利用できませんが、初期値としては十分利用できます。
現在の時間を取得する関数は time です。(必要なヘッダファイルは time.h )
この値は「万国標準時(UCT)での1970年1月1日0時0分0秒からの秒単位での経過時間」になります。
とにかく、1秒ごとに値が違うということが重要なのです。
この値は「万国標準時(UCT)での1970年1月1日0時0分0秒からの秒単位での経過時間」になります。
とにかく、1秒ごとに値が違うということが重要なのです。
この値の型は time_t です。
これは srand の引数の型である unsigned int に安全にキャストを行うことができます。
これは srand の引数の型である unsigned int に安全にキャストを行うことができます。
実例:
srand( (unsigned int)time(NULL) ) ;
srand( (unsigned int)time(NULL) ) ;
乱数の種類
①rand()
デフォルトでは、シミュレーションに使えるものではありません。
しかし、アルゴリズムに工夫すれば、精度を向上させることは可能です。⇒他人のアルゴリズムを絶対に使いたくない人向き
デフォルトでは、シミュレーションに使えるものではありません。
しかし、アルゴリズムに工夫すれば、精度を向上させることは可能です。⇒他人のアルゴリズムを絶対に使いたくない人向き
②xorshift
実装が楽なので、管理人推奨はコチラ。
精度も申し分なしです。
sse2で速度アップ可能。
実装が楽なので、管理人推奨はコチラ。
精度も申し分なしです。
sse2で速度アップ可能。
③メルセンヌ・ツイスター
実装が若干面倒なのが難点です。
ただし、精度は②より上なのは間違いないです。(最強)
デフォの速度はそこそこ。問題にはならない程度です。
sse2で速度アップ可能。
実装が若干面倒なのが難点です。
ただし、精度は②より上なのは間違いないです。(最強)
デフォの速度はそこそこ。問題にはならない程度です。
sse2で速度アップ可能。
精度と処理速度
xor130(SSE2) 精度:優 速度:秀 SFMT(SSE2) 精度:秀 速度:秀 xor128 () 精度:優 速度:優 SFMT 精度:秀 速度:良 rand() 精度:不可 速度:可
リンク
乱数の値域
どの方法をとるにしろ、使用したい値域で疑似乱数を生成したいですよね。
その場合、乱数の最大値を利用すれば簡単に表わせます。
例えば、 0以上1未満の疑似乱数(実数) を用いたい場合は以下の通りです。
その場合、乱数の最大値を利用すれば簡単に表わせます。
例えば、 0以上1未満の疑似乱数(実数) を用いたい場合は以下の通りです。
実例:
double r=(double)rand()/(RAND_MAX+1); <0以上1未満の疑似乱数(実数): r>
double r=(double)rand()/(RAND_MAX+1); <0以上1未満の疑似乱数(実数): r>
このwikiの更新情報RSS