LoginSignup
10
10

More than 5 years have passed since last update.

Rubyで使用されている乱数の均等分布について(メルセンヌ・ツイスタ)

Posted at

メルセンヌ・ツイスタとは、通常よりランダムな(周期の長い)値を生成する方法らしい(詳細はWikipedia)略してMT

Rubyは標準でこれを採用しているみたい
値が均等に分布しているのか、とりあえずこんな感じで100万回の平均をとってみた

MAX_VAL = 101
REP_CNT = 10**6

sum = 0.0
prng = Random.new(Random.new_seed)
(0...REP_CNT).each{|idx|
    p sum = (sum*idx + prng.rand(MAX_VAL))/(idx+1)
}

結果は
50.036861963137966

収束していることはわかったけど、どうやって収束していっているかを分かりやすくするためグラフを出してみた

# -*- encoding: utf-8 -*-

require 'rubygems'
require 'gruff'

FONT = "/Library/Fonts/Osaka.ttf"
MAX_VAL = 101
GRAPH_NUM = 7
REP_CNT = 10**GRAPH_NUM

graph_point = Array.new(GRAPH_NUM)

avg, rec_cnt = 0.0, 0
prng = Random.new(Random.new_seed)
(0...REP_CNT).each{|idx|
    avg = (avg*idx + prng.rand(MAX_VAL))/(idx+1)
    if 10**rec_cnt-1 == idx
        graph_point[rec_cnt] = avg
        rec_cnt += 1
    end
}

p graph_point

g = Gruff::Line.new
g.font = FONT

(0..graph_point.length).each{|idx|
    g.labels[idx] = "10^#{idx}"
}

g.data("Mersenne twister", graph_point)
g.write('MT.png')

MT.png

実際の値は
10^0:67.0
10^1:55.5
10^2:52.39
10^3:51.352
10^4:50.076400000000085
10^5:49.93751999999963
10^6:49.99161700000036
10^7:49.99675620000007

50に近づいていってることがわかった
均等に分布している事が分かったので安心

10
10
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
10
10