C言語的な乱数のラッパークラス

[2005/03/29]

Java での Math クラスの関数 rand() は Random クラスを基に実装されてお り,なんと seed を与えることができません.また,Random クラスのオブジェ クトを生成すれば setSeed() メソッドを使用することはできますが,これだ と与える種の影響は個々のオブジェクトに限定され,生成乱数を一気に統一的 に初期化したい場合には不適当です.そこで Random クラスと同様に使え,種 を統一的に与えられるラッパークラス MRand を作成してみました.

※だけどこれだとこのクラスを使ってどこでも種を与えることが可能で,それ により全体の挙動が変わってしまうので,オブジェクト指向的な観点からはよ くないんだろうなぁ... →このクラスはデザインパターンで言う Singleton(風?)になるんですね.

[MRand でのクラスメソッドとしたもの]
// 
// RandomSample.java: 乱数値の初期化の連続性を見る
// 
//     [2006/10/17] OSHIRO Naoki.
// 

import java.util.Random;

class MRand { // 乱数へのラッパークラス
  private static Random r=new Random();

  static void setSeed(long seed) {r.setSeed(seed);}
  static float nextFloat() {return r.nextFloat();}
  static double nextDouble() {return r.nextDouble();}
  static double random() {return r.nextDouble();}
}

class Foo {
  double random() {return MRand.random();}
}

public class RandomSample {
  public static void main(String args[]) {
    Foo f=new Foo();

    MRand.setSeed(5); // 乱数初期化
    for (int i=0; i<4; i++)
      System.out.println(i+": "+MRand.random()+" Foo:"+f.random());
    System.out.println("");
    MRand.setSeed(5); // 乱数初期化
    for (int i=0; i<4; i++)
      System.out.println(i+": "+MRand.random()+" Foo:"+f.random());
  }
}


実行結果
MRand クラスをそのまま使用 (r) しても,他クラスを経由して使用 (f) し ても,setSeed() 後には同じ乱数列が得られている.
0 r:0.730519863614471 f:0.08825840967622589
1 r:0.4889045498516358 f:0.461837214623537
2 r:0.4485983912283127 f:0.6977123432245299
3 r:0.2777673057578094 f:0.7599608278137966

0 r:0.730519863614471 f:0.08825840967622589
1 r:0.4889045498516358 f:0.461837214623537
2 r:0.4485983912283127 f:0.6977123432245299
3 r:0.2777673057578094 f:0.7599608278137966


[MRand でのインスタンスメソッドとしたもの]
// 
// RandomSample.java: 乱数値の初期化の連続性を見る
// 
//     [2005/01/27] OSHIRO Naoki.
// 

import java.util.Random;

class MRand { // 乱数へのラッパークラス
  static Random r=new Random(); // ← static にすること.
  //Random r; // ← static なしだとダメ.

  void setSeed(long seed) {r.setSeed(seed);}
  float nextFloat() {return r.nextFloat();}
  double nextDouble() {return r.nextDouble();}
  double random() {return r.nextDouble();}
}

class Foo { // このクラスの中でも乱数関数を呼び出してみる
  MRand f=new MRand();
  double nextDouble() {return f.nextDouble();}
}

public class RandomSample {
  public static void main(String args[]) {
    MRand r=new MRand(); // 乱数ラッパークラス
    Foo f=new Foo();     // 他クラス経由の乱数ラッパークラス使用

    r.setSeed(5); // 乱数初期化
    for (int i=0; i<4; i++)
      System.out.println(i+" r:"+r.random()+" f:"+f.random());
    System.out.println("");
    r.setSeed(5); // 乱数初期化
    for (int i=0; i<4; i++)
      System.out.println(i+" r:"+r.random()+" f:"+f.random());
  }
}

上へ