疑似乱数

出典: 謎の百科事典もどき『エンペディア(Enpedia)』
ナビゲーションに移動 検索に移動

疑似乱数は、アルゴリズムによって生成された乱数のことである。このサイト(Enpedia)でよくある言い方を借りれば、「謎の乱数もどき」である。[1]

概要[編集]

完全な乱数を得ようとするならば、量子力学に頼るしかなく、かなり面倒くさい。

とはいえ、実用上「乱数」が必要なこともあるわけで、疑似乱数を生成することが要求されるのだが、いまのところ「質の高い乱数を生成するアルゴリズム」というのは数少ない。

広く知られているものとしては線形合同法があるが、あまり質がよくない。現在知られている質の良い乱数生成法としては「最長周期律法(M系列法)」や「メルセンヌ・ツイスター」程度である。このあたりの悩みはWeb検索されたい。

疑似乱数の生成方法[編集]

ある数(これを乱数の種という)を前述のアルゴリズムに入力すると、アルゴリズムの中で複雑な計算が行われ、疑似乱数が生成される。その疑似乱数を種として生成を繰り返すことで、たくさんの乱数を生成できる。

この「乱数の種」が重要なポイントで、毎回同じ数が種だと同じ乱数が返ってくる。一般的には現在時刻を利用する。

コード[編集]

Java による、原始多項式を用いた最長周期法によるコードである。

/**
 * Luwis & payne
 * M 系列法(最長周期法)による
 * 疑似乱数の生成
 * x^pwp^ + x^pwq = 1
 */

public class RandLP {
    public static void main( String[] args ) {
      _main();
      return;
    }

    private static void _main() {

      System.out.println(Integer.MAX_VALUE);
      for (int ncnt = 0; ncnt < 100; ncnt+=1) {
       //LP(52);
       System.out.println(LP2(52));
      }
      /*
      for (int i = 0; i < 89; i+=1) {
      //  System.out.print(LP(32768)+ ", ");
       System.out.print((int)(LP(1) * Integer.MAX_VALUE) + ", ");

       if ((i % 5) == 0) System.out.println();
      }
      */
      return;
    }

  static final int IP  = 89;
  static final int PWQ = 38;
  static final int IQ  = IP - PWQ;
  static final int MAX  = Integer.MAX_VALUE;
  static int j = 0;

   static int m[] = {
       1592226944, 1984348928, 1592225792, 2015294208,  424637056,
       2077481472,  387402720, 2083704192,  624210816, 1722843392, //10
       1354712320, 1797627008,  444747744,  163130688, 1824820992,
        681686400,  907007552,  747478976, 1919608448, 2083701376, //20
       1824821504, 1592227968,  747476416, 1984354560, 1493592832,
       2083706368, 1919609856,  999998272, 1132738560,  681684288, //30
       1919607936, 1984353280,  132187704, 1147480320,  907002176,
       1654435200, 2083706752, 1592221696,  163132096, 2015290624, //40
       1919608832,  387402912,   63775904,  945283712, 1919610368,
        841217024,  945289024, 1824818816, 1465799808, 1632732160, //50
        227869760,  681688960, 1202196736,  907006336, 1906826624,
       2147478400, 1240478336, 1654438784,   63774792,  624207360, //60
       1400010240, 1309745920, 1919612288,  837735296, 1418951424,
        747473472, 1702736384, 1240478720,  444746848, 1078530432, //60
       1972103168,   70008336,  322661760, 2077480320, 1972105216,
       2015291904, 1760083584, 1702738816,  907004032,  653889920, //70
       1919610624, 1465797632, 1309751680, 1078532864, 1654435712,
           1523274624, 1760078464,  493044128, 1523277184, 1400006400, //80
          1972103168, 1202194688,  322661760, 2077480320, 1972105216,
           555259072, 1592223488, 1984352384, 1919613696
   };

    public static float LP(int range) {
       int ipx, iqx;
       j       = ( j + 1 )  % IP;
       int k   = ( j + IQ) % IP;
       m[ j ] ^= m[ k ];

//     return ((float)( m[j] * (double)range) / (float )MAX));
      return ((float) m[j]) / ((float)MAX);
    }

    public static long LP2(int range) {
       int ipx, iqx;
       j       = ( j + 1 )  % IP;
       int k   = ( j + IQ) % IP;
       m[ j ] ^= m[ k ];

//     return ((float)( m[j] * (double)range) / (float )MAX));
      return ((long) m[j]) * (long)range / ((long)MAX);
    }
}

このサイト上での乱数の生成方法[編集]

このサイトでも、テンプレート:おすすめピックアップおみくじで簡易な疑似乱数が使われている。どんな方法で生成されているのかについては各ページのコードを参照。

参考文献[編集]

  • 伏見正則「一様乱数の発生法について」(数学セミナー vol.7 No.10、(1979年10月号)、日本評論社)

脚注[編集]

  1. このサイト(Enpedia)が「謎の百科事典もどき」を名乗っているためである。