- 締切済み
M系列の乱数の検定
多ビットのシフトレジスタをいくつか使って,M系列乱数を発生させるプログラム(verilog)を作りました。その結果、乱数の出力値が8~10桁です。そしてこの乱数の検定をするためにまずは度数検定をしたいのです。もしこの8~10桁の数字を1桁ずつばらばらにできれば、エクセルを使って、0~9の数字が等頻度で出ているか調べることができるのですが、そんなことはできないのでしょうか?? 乱数についてはこの2ヶ月で色々調べて、何も知らない状態から、やっと乱数発生までこぎつけました。これがまだ使い物になるとは思いませんが、とりあえずは検定をしたいので、ご指導よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- stomachman
- ベストアンサー率57% (1014/1775)
二進数ではだめで、十進10桁の疑似乱数を生成したいということなんですね。それは珍しい。 > 2進で1001010100000010111110001111111111までの範囲(10進で9999999999までの範囲)で乱数を作りました。 範囲を外れてしまったときには、その31桁の2進数を捨てているでしょうか。それとも、捨てずに1ビットシフトして、生成した1ビットを加えているでしょうか。後者だと偏りが出ます。 ご質問で十進8~10桁とおっしゃっているのは、先頭に0が来たときにそれを無視しているんではありませんかね。(No.2のやりかたは先頭の0を無視せずに抽出します)。Ecxelに限らず利用できる、もっと普通のやりかたを 書いておきます。 Nを桁ごとにバラしたい数とするとき、 s = N 以下j=1,2,…,10について繰り返す a ← s を 10で割った答(整数) r[j] ← s を 10で割った余り(つまりr[j] = s - 10a) s ← a 繰り返し終わり によって、下からj桁目が、r[j]に取り出せます。
- stomachman
- ベストアンサー率57% (1014/1775)
Excelで大量のデータを処理するのは無理です。データ数が数万のオーダーになるとえらく遅い。Excelはバージョンが上がるごとに計算がどんどん遅くなってる気がするんですが…という話はどうでもよくて、もっと重要なポイントがあります。 M系列から一体どうやって十進8~10桁の整数を生成なさったんでしょうか。 ひょっとして、「0と1の並んだ系列を32個ずつ区切って32桁の二進数だと思うと、十進数に直せば10桁になる」というような話だったりしないでしょうか。 もしそうだったら、その十進10桁の数の各桁の現れる数字の頻度は均一にはなりません。(ですから、おっしゃるところの「検定」には全く意味がありません。)なぜかというと: まず簡単な例で説明しましょう。0と1からなる列を4個ずつ区切って4桁の二進数だと見ると、十進数に直せば、0~15のどれかになります。もしこの0と1の列が本当に乱数列であったとすると、十進数にした数値(0~15、16通り)がどれも均等の確率で現れるでしょう。たとえば、数字"8"は16通りのうち1回しか現れませんが、数字"4"なら2回、数字"1"は7回現れます。ですから、数字の出現頻度を調べると「"1"は"8"に比べて7倍も多く現れる」という結果になる筈です。 同様に、32桁の二進数は十進数にすると0~4294967295 (33桁なら0~8589934591)のどれかです。もし0と1の列が本当に乱数列であったとすると、これらの数値がどれも均等の確率で現れるという性質を持っているでしょう。しかし、数値の範囲を見れば分かるように10桁目に9が現れることはない。このために"9"の出現頻度は例えば"1"に比べて低くなります。 要するに「数値(つまり0~4294967295)の出現頻度」と「数字(つまり0~9)の出現頻度」とは別の話なんです。しかも、前者が均一であるということと、後者が均一であるということは両立しません。(一方が成り立てば、他方は成り立ちません。) そして、検査すべきは前者です。
- stomachman
- ベストアンサー率57% (1014/1775)
うみゅー? No.1に付けて戴いたコメントでは、まださっぱり納得いかない。でもま、とりあえず、「8~10桁の十進数値をEXCELで1桁ごとにバラスにはどーしたらいいですか」というご質問であると解釈してみますと: Cell A1 に、問題の非負整数の数値(10桁以下)が入っているものとします。 Cell B1 数値に10000000000を足して11桁にし、それを文字列に変換する式 =FIXED(A1+1E10,0,1) Cell C1 下から1桁目の値を数値として取り出す式 =VALUE(MID(B1,11,1)) Cell D1 下から2桁目の値を数値として取り出す式 = VALUE(MID(B1,10,1)) Cell E1 下から3桁目の値を数値として取り出す式 = VALUE(MID(B1,9,1)) を入れる。以下同様、てな調子です。 解説:最初に11桁に揃えてしまえば、左からn文字目を取り出すMID(B1,n,1)が使える。その文字(一桁の数字)を数値にするのにVALUEを使います。
- stomachman
- ベストアンサー率57% (1014/1775)
どうも話が読めないのですけど。 M系列は0か1が並んだ列ですから、「出力値が8~10桁」っておかしくないですか? M系列の性質は多くの論文がありますので、わざわざご自分で検定なさるまでもないのでは?これもおかしくなくないでしょうか。 さらにプログラムを自作するほどの方が、「8~10桁の数字を1桁ずつばらばらに」するのに難渋なさるのも、また検定を「エクセルを使って」やろうとなさるのも、なんだかおかしくなくなくない? 「使い物になるとは思いませんが」ということは実用のために作っていらっしゃるのでしょうか。実用が本当の目的であるのなら、M系列より優れた性質を持つ疑似乱数「メルセンヌ・ツイスター」のソースプログラムが公開されていますから、そっちをご利用になってはどうか?
お礼
回答ありがとうございます。 すみません、まだ今は大学生で勉強途中でして、というか本当に始めたばっかりなのでなにもわかっていないので、わかりにくい質問をしてしまったようですみません。 M系列を利用して作った乱数を10進数に直すと、8~10桁の乱数ができました。それの乱数性を調べたいのです。作ったのはいいもののこれが本当に乱数かどうかはとても怪しいと思うので。 パソコンが本当に苦手で、今回までエクセルを使ったことはありませんでした。今、エクセルも勉強中です。そして、プログラムは大の苦手です。苦手なのに進学先をそういう方面にしてしまった私が悪いのですが…。 「8~10桁の数字を1桁ずつばらばらに」することはそんなに簡単なのですか??エクセルの本は、基礎の基礎の本と、数学的な解析の本しかなくて、統計用のものがないのでわからなくて困っています。 なるべくならプログラムは苦手なので、エクセルでできるのならエクセルを活用したいです。 メルセンヌツイスターほど高性能なものは必要ないんです。そこまでの精度はいらないので、程ほどの精度で、実装の際の大きさを小さくしたいので。ワーキングメモリを小さくしたいので、メルセンヌ以外で作りたいんです。 何かアドバイスがあればよろしくお願いします。
お礼
エクセルの件、教えていただいてありがとうございます。 どうやって10進数で10桁の乱数を作ったかを以下に説明します。 2進数31ビットシフトレジスタからは1ビットずつ乱数が出力されます(周期:2^31-1)そのシフトレジスタを31個用いれば、2進数31ビットの乱数ができます(周期:2^31-1)。それを10進数になおしてやります。その場合、stomachmanさんが おっしゃるようなことがあってはいけないので、2進で1001010100000010111110001111111111までの範囲(10進で9999999999までの範囲)で乱数を作りました。 検定のために、まず、10進数で「数字(つまり0~9)の出現頻度」を調べて、次に2進数で「数字(つまり0・1)の出現頻度」を調べようと思っています。それがおわれば、「数値(つまり0~9999999999)の出現頻度」を5桁ずつにわけてポーカー検定で確率的に調べようと思っています。 まったく検討違いだったりしたら教えてください。ご迷惑をおかけしますが、よろしくお願いします。