• ベストアンサー

擬似乱数の規則性をプロット図から読み取る

コンピュータの作る擬似乱数(RND関数など)に規則性があることを表現するために、3次元プロットした図をあげて、規則的な濃淡が現れていることが分かるようになっている書籍を見たことがあります。(書名失念) 自分で再現したくなっていろいろ試したのですが、うまくいきませんでした。同じような結果を出すにはどのようなアルゴリズムでプロットすればいいでしょうか。

  • baihu
  • お礼率77% (134/172)

質問者が選んだベストアンサー

  • ベストアンサー
  • UKY
  • ベストアンサー率50% (604/1207)
回答No.1

例えばこういうやつですかね? http://www.soi.wide.ad.jp/class/20010000/slides/03/6.html http://www.soi.wide.ad.jp/class/20010000/slides/03/7.html 基本的には、その擬似乱数がどのようなアルゴリズムで作られているかによって効果的なプロットの仕方も変わってくると思います。 例えば単純な線形合同法で乱数を生成する場合の欠点(の一つ)は、「a の次に b が出た場合、今度 a が出たときもまたその次に b が出る」というものなので、出てきた乱数の値を二つずつ組にして、それを座標としてプロットしてみるなどすればよいかと思います。 (上に挙げた URL では三つずつ組にして三次元でプロットしていますね)

baihu
質問者

お礼

ありがとうございます。 ご指摘のページの通りです! これはメルセンヌ・ツイスターという乱数発生法が優れていることを示しているわけですね。 試してみたのは MS Excel と 十進BASIC なのですが、それぞれの使用している乱数発生関数のアルゴリズムが分からないこともあるのでしょう、2次元/3次元のどちらを描いても、規則性が視認できませんでした。もしかすると結構優秀な乱数だということになるわけでしょうか。 周期が特定できれば、乱数をいくつごとにプロットさせるかを調整して、同じようなグラフが書けるんですね。

その他の回答 (2)

  • Jirorian
  • ベストアンサー率58% (7/12)
回答No.3

>long rand() { x=x*1103515245+12345; return x&2147483647; } C言語です BASIC的に書くならば x = x=x*1103515245+12345 x = x & 2147483647 です 二行目の&は32ビットにするためにマスクしているだけです (0x7FFF FFFF) drand48はコインテストをすれば乱数の悪さがわかります 参考URLをどうぞ

参考URL:
http://www001.upp.so-net.ne.jp/isaku/rand.html
  • Jirorian
  • ベストアンサー率58% (7/12)
回答No.2

古典的randなら2次元でも絶対に出ると思います long rand() { x=x*1103515245+12345; return x&2147483647; } で試してください 信じられないくらいの乱数の悪さを見ることが出来ます rand48なんかは周期が長いのでかなり大きいグラフにプロットする必要があるのではと思います

baihu
質問者

お礼

ご回答ありがとうございます。 > long rand() { x=x*1103515245+12345; return x&2147483647; } すみません、記載いただいた言語が読めなくて(^^; 後学のために、何て言語で、どういう式なのか、教えていただければ幸いです。 で、締め切らずにいた間、十進BASICのrnd関数で再現できました! 倍率を100倍にしたら、連続する2数の規則性が視認できました。

関連するQ&A

  • 超幾何分布に従う疑似乱数の生成について

    今、超幾何分布に従う疑似乱数を生成するコードをScilabで書こうとしています。しかし、Scilabには超幾何分布に従う疑似乱数の関数が実装されていません。有識者の方で、わかる方がいましたら教えてください。 ソースコードに関してはC言語、Basic、Scilabのどれかで教えていただけたら、助かります。また書籍をご存じなら、書籍名を教えてください。 よろしくお願いいたします。

  • ハッシュを使った擬似乱数

    予測不能な擬似乱数列を生成する際に、よく一方向ハッシュの性質を利用する 場合があります。一方向ハッシュの生成源として内部状態が与えられますが、 内部状態のbitサイズはどの程度にしたらよいでしょうか?   [種(カウンタの初期値)]        |        |        ↓ ┌→[内部状態(カウンタ)]―┬―→(一方向ハッシュ)――→擬似乱数列 |                 | |                 ↓ |               [1増加] |                 | └―――――――――――┘ ※ 暗号技術入門 秘密の国のアリス 結城 浩 著      ――第12章 乱数 Fig.12.5 より 極端な例として鍵(種)のサイズを32bit(C言語でunsigned long型)、値を0とします。 |0000 0000|0000 0000|0000 0000|0000 0000| 上記の値でハッシュ値を取ります。ハッシュアルゴリズムがSHA1の場合、 以下のような値が得られます(と思います)。 a = -1099956234 b = -343932961 c = -1287651379 d = -84150665 e = -1099170433 これらの値から鍵の値を得ることは困難なので、ハッシュ値によって生成された 擬似乱数は予測不能であるといえます。また、鍵の値を1だけ加算させて次の擬似乱数 を生成します。一般的にこのようにして乱数列は生成されます。 上記の例では32bitのとり得る値は0~4294967295です。鍵の値を一つずつ試し ていけば、それほど時間をかけることなく乱数の予測不能性は破られてしまいます。 ここで鍵の値を256bitとしました。 |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| しかしこれだと1加算しただけではビット全体に対して変化が少なすぎます。 |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0000| |0000 0000|0000 0000|0000 0000|0000 0001|← 2005年に中国の大学の研究チームによってSHA1の弱衝突耐性が破られてしまいました。 現段階ではSHA1に変わる新しいアルゴリズムは発見されていません。(SHA2が作られましたが、 これはSHA1のbit数を拡張しただけで基本設計は変わっていません)なのでハッシュ値を 生成させる値もなるべく変化に富んだ値を与えることが推奨されています。 まとめると、   ・鍵(種)を総当り攻撃されないようにbit数を大きくしなけらばならない。   ・bit数を大きくすると1加算したときに変化が小さすぎる。   ・最初の図の手法は同記の文献に書いてあったもので、なるべく変えたくない。    (実際に使われる手法はある程度保障されているから) の制約があります。なので”bit数をどの程度にしたら適当か???”というのが質問です。 また、これらの問題を打開する方法もあればよいのですが、、、

  • 偏りのある乱数のアルゴリズム

    偏りのある乱数のアルゴリズム(コード)を教えてください。 ただし、中心極限定理などに見られるような「中心にのみ偏る」乱数ではなく、「任意の位置を中心に偏る」乱数です。例えば、範囲を0.0<1.0、任意の位置を0.75とした場合の分布グラフを見ると、0.75がカーブの頂点となります。 また一方で、複数の偏りが見られる乱数のアルゴリズムも知りたいです。カーブが心電図のように複数見られる乱数です。ビットマップ上にプロットすると、部分的に点の集合が形成されるようなものが理想的です。 ※プログラミング言語・精度・速度は不問。本人数学に関しては素人です。

  • 三次元の分布図(散布図)の作成方法について教えてください。

    三次元の分布図(散布図)を作成しようと考えていますが、作成例などが掲載されているサイトや書籍がありましたら教えてください。 機能としては下記のようなものを想定しております。 ・三次元であること ・座標(例.x=1,y=1,Z=1)に画像をプロット ・マウスで回転やズームができる ※その際にプロットしてある画像は常に正面(ユーザー側)を向いている ・プロットしてある画像をクリックすると画像が別ウィンドウに表示される 作成ソフトについて調べたのですが、たくさんあって(openGLやFlash、 Shade等?)私には良くわかりませんでした。おすすめのものや各ソフトの特徴等も是非とも教えてください。 当方C言語に関しては一応理解しております。 宜しくお願いします。

  • rnd関数の使い方教えてください。

    初歩的かも知れませんが、よろしお願いします。 仕様環境:Access2007 Win7 ・・・・・ 只今、新規レコードに自動的にランダムな数字が割り振られるように テストしています。 調べたところ「rnd関数」というものを使うということが解りました。 試験用のデータベースを簡単に作り テーブルの項目(フィールド)も簡単にしました。 テストテーブル ------------------- ID(オートナンバー) 名前(テキスト型) 住所(テキスト型) 乱数(テキスト型)または(数値型)←あとで説明しますが。。 ------------------- 乱数のフィールドにある「規定値」にrnd関数を入力しテーブルを保存しようとすると、 「テーブルレベル入力規則の未定義の関数名です。。」と エラーが出てしまいます。テキスト型でも数値型でもです。 rnd関数は、、 int((200-100+1)*rnd+100) ↓入力してエンターを押すと Int((200-100+1)*Rnd()+100)となります。 つまり100から200までの間の数字をランダムに割り振ろうと挑戦しています。 ちなみにテーブルから「乱数」フィールドを消して、フォームにテキストボックスを作り、 コントロールソースに入力しても「未定義です」のようなエラーがでます。(関数の前に”=”もつけたのですが) また規定値に入力しビューで見ると「#Name?」となります。 クエリにrnd関数のフィールドを作ってフォームにつなげても出来ません。 (集計で「演算」にして作ってみたりしたのですが。。) まるっきりrnd関数の使い方がわかりません(汗)。 VBA(モジュール)は使わず、フィールドプロパティなど基本的な機能かマクロでやりたいです。 また重複しないようにしたいのです。 漠然とした相談ですが、どの場面(テーブルやクエリやフォーム)でどう使うか教えてください、 新規レコードにランダムな番号(複数桁で)割り振られるようにしたいです。 宜しくお願いします。

  • 数当てゲーム  malloc使用?

    こんにちは。 現在、「たのしいC」という書籍でC言語を勉強中なのですが、この本に載っている課題について質問です。 「数当てゲーム」をプログラムせよ。 ・擬似乱数を用いて2つ整数を取得。数当ての範囲とする。 ・その間の整数を擬似乱数を用いて取得し、この数を当てさせる。 ・最初に取得した数の範囲に応じてプレイヤーが入力できる回数を設定すること。 というのが大筋です。 今回質問させていただきたいのは、3つ目の、数の範囲に応じて入力回数を設定する部分についてです。 コンパイル時は数の範囲がまだわかっていないので、malloc関数を使うしか僕は思いつけなかったのです。 でもこの課題が出ているのは本の最初の部分で、malloc関数についてはまだ1度も書かれていないのです。 ひょっとして、malloc関数を使わなくても実現できるのでしょうか? 可能でしたら方法を教えてください。 本では自由課題になっていて、回答が書かれておらず、ホームページでも見当たらなかったのでここで質問させていただきました。

  • 一様乱数?疑似乱数?

    0.0以上~1.0未満の範囲のdouble型一様乱数rdmを1000個発生させて、ヒストグラムをつくりたいのですが、このような書き方で良いのか、ご教示願えませんでしょうか。 ヒストグラムと言っても、グラフではなく、区間0≤u<0.1、0.1≤u<0.2、…、0.9≤u<1.0の10区間とし、配列aaに格納しているだけです。 また、「Math.random」を用いるやり方は理解できるのですが、下記のような書き方はいまいち納得できません。 疑問点1つ目、前者は毎回発生する乱数が違うのに、後者は同じですよね?なぜでしょうか。後者は毎回決まった値が出るので、初期値(seed)から決まった計算をしているということでしょうか。 疑問点2つ目、//kokoの次の行に x = rdm.nextDouble(); のように発生させた乱数を一時的に入れておかなくてもよいのでしょうか。 import java.util.*; public class test { public static void main(String [] args) { int aa [] = new int [10]; long seed = 999L; Random rdm = new Random(); rdm.setSeed(seed); for(int i = 0; i < 1000; i++){ for(int j=1; j<=10; j++){//koko if(rdm.nextDouble() < ((j-1)*0.1) && rdm.nextDouble() >= (j*0.1)) aa[j-1] = aa[j-1] + 1; } } for(int i=0; i<10; i++){ System.out.println( aa[i] ); } } }

    • ベストアンサー
    • Java
  • 擬似乱数

    こんにちわ。 今日の擬似乱数の発展に寄与している偉大な数学者をあげるとしたら 誰が候補になるでしょうか? 古今東西関わらずありましたら名前をあげてくださればと思います。

  • 三次元形状曲面の導出法

    数学板でも質問したことなのですが、アドバイスもあってこちらに流れてきました。 質問番号3464667 に関連した質問なのですが 格子点上に並んでいない(x,y)と(dz/dx,dz/dy つまり各方向の傾き)がわかっている条件で三次元曲面形状を導出するアルゴリズムを作成しました。最小二乗法を基本としたアルゴリズムをフォートランで作成したのですが、なぜスプライン関数を使わないのかという指摘を受けました。 スプライン関数は曲線では非常に有力な補間法であることは理解しているのですが、格子点上に並んでいないデータでスプライン曲面を作るのは境界のつなぎ合わせや、パラメトリック曲線をどう作ればいいのかよくわからなくて敬遠したのですが、実際スプライン関数を用いて三次元形状を導出することは可能なのでしょうか? また近似曲面としてβスプライン関数やナーブス曲面は近似関数として適当なのでしょうか?(コンピュータグラフィックスの世界でしか使わない??) よろしくお願いします。

  • 規則に従った乱数

    一様乱数を発生させるプログラムはネット上でも入手できます。ある種の確率密度分布に従った乱数を発生させるにはどうしたらいいでしょうか。 例えば0から1の乱数ですが、平均が0.5で分散が0.2のガウス分布に従った乱数を発生させるとしたら0.5に近いところの値が多く出て、0.9のあたりはあまり出ないということになります。そういう乱数です。 そういうものを乱数というのかどうかわかりませんが。 しかし、物理現象は何らかの分布に従う乱数のようなものと考えることができるのではないでしょうか。 よろしくお願いします。