はじめMath! Javaでコンピュータ数学

第47回 確率の数学 確率とは [後編]

この記事を読むのに必要な時間:およそ 4 分

解説

問題1 さいころの働きをするクラスを作りましょう

完成したDiceクラスのみを示します。このクラスがあれば,さいころを使った確率の実験やゲームに役立つことでしょう。

大変シンプルなクラスですので,クラスを作るのが初めてだ,という人にもチャレンジしやすい問題だったことでしょう。このDiceクラスは,ファイルDice.javaとして保存し,今後の演習問題で活用できるよう保管しておいてください。

ソースコード:Sample DiceRoll.java 完成版(部分)

/*
 * class Dice
 * 目的: さいころをシミュレートするクラス
 *      コンストラクタに整数値を指定して,
 *      さいころの面数を指示できる。
 */
class Dice {

    //プライベートな変数・オブジェクトの宣言
    private int size = 6; // default
    private Random rd = new Random();

/*
 * 目的: コンストラクタ
 * 引数: s ダイスの面数
 *      不適当な値なら,面数0 とする。
 */
  Dice(int s){
    if ((s > 1) && (s < (Integer.MAX_VALUE / s))) {
      size = s;
    } else {
      size = 0;
    }
  }// end of Constructor Dice(s)


/*
 * 目的: ダイスを振る
 * 引数: n ダイスを振る回数
 * 戻り値: 出たダイスの目の合計
 */
  public int roll(int n){
    int sum = 0;
    if ((size != 0) && (n < (Integer.MAX_VALUE/size))
                    && (n > 0) ){
      for (int i=0; i<n; ++i){
        sum += rd.nextInt(size) + 1;
      }
    }
    return sum;
  }// end of roll


/*
 * 目的: ダイスの面数を返す
 * 戻り値: ダイスの面数
 */
  public int getSize(){
    return size;
  }// end of getSize


} // end of class Dice

問題2 さいころを振って確率の値を確かめましょう。

問題1で作成したDiceクラスをひとつのファイルとして保存しましょう。ファイル名はクラス名+.javaにしなければなりませんから,Dice.javaとします。保存した後,次のようにコマンドラインでコンパイルします。

> javac Dice.java

コンパイルを実行したディレクトリ内にDice.classが作成されます。その後,同じディレクトリで,確率の計算を実行するプログラムをコンパイルすると良いでしょう。以下にそのプログラム例 Sample_TestProbabilityByDiceRoll.javaを示します。

ソースコード:Dice.java

import java.util.Random;

/*
 * class Dice
 * 目的: さいころをシミュレートするクラス
 *      コンストラクタに整数値を指定して,
 *      さいころの面数を指示できる。
 */
class Dice {

    //プライベートな変数・オブジェクトの宣言
    private int size = 6; // default
    private Random rd = new Random();

/*
 * 目的: コンストラクタ
 * 引数: s ダイスの面数
 *      不適当な値なら,面数0 とする。
 */
  Dice(int s){
    if ((s > 1) && (s < (Integer.MAX_VALUE / s))) {
      size = s;
    } else {
      size = 0;
    }
  }// end of Constructor Dice(s)


/*
 * 目的: ダイスを振る
 * 引数: n ダイスを振る回数
 * 戻り値: 出たダイスの目の合計
 */
  public int roll(int n){
    int sum = 0;
    if ((size != 0) && (n < (Integer.MAX_VALUE/size))
                    && (n > 0) ){
      for (int i=0; i<n; ++i){
        sum += rd.nextInt(size) + 1;
      }
    }
    return sum;
  }// end of roll


/*
 * 目的: ダイスの面数を返す
 * 戻り値: ダイスの面数
 */
  public int getSize(){
    return size;
  }// end of getSize


} // end of class Dice

ソースコード:Sample TestProbabilityByDiceRoll.java

//サンプルコード
//..「1 の目の出る確率と,2 の目の出る確率が同じことを確認する。」
//..「2 回さいころを振って出た目の合計が,3 であるときと5 である
//  ときで確率が異なることを確認する。」
//filename : Sample_TestProbabilityByDiceRoll.java

class Sample_TestProbabilityByDiceRoll {

  public static void main(String[] args) {

    Dice d6 = new Dice(6);
    int REPEAT = 1000000;
    int ROH1 = REPEAT / d6.getSize();

    //---------------------------------
    System.out.println("6 面のダイスを1000 回振り,"
             + "それぞれの目が出た数を表示する。");
    int num[] = new int[6];
    for (int i=0; i<REPEAT; ++i){
      ++num[d6.roll(1)-1];
    }
    for (int i=0; i<6; ++i)
      System.out.println(i+1+"の目は"+num[i]+"回出ました");
    System.out.println("試行回数は"+REPEAT+",場合の数は"+ROH1+"程度になるべきです。");

    //---------------------------------
    System.out.println("2 回ダイスを振って出た目の合計が"
                             + "3 か5 かの場合を数える。");
    int num3 = 0;
    int num5 = 0;
    int result;
    for (int i=0; i<REPEAT; ++i){
      result = d6.roll(2);
      if(result == 3){
        ++num3;
      } else if(result == 5) {
        ++num5;
      }
    }
    System.out.println("3 になった回数は"+num3);
    System.out.println("5 になった回数は"+num5);
    System.out.println("後者は前者の2 倍になるべきです。");
    System.out.println("後者は前者の"+((float)num5/(float)num3)+"倍になりました。");
  }// end of main


}// end of class Sample_DiceRoll

シミュレーションの結果得られた(目的の場合の数)/(試行回数)の値が,確率の数学で求めた値と近ければ,確率の数学は実際的な事柄に適用しても有意義であると言えます。確率の数学知識は,膨大な数の試行を行わなくとも,理論的に結果を推測できるのですから,役にたちます。

シミュレーションは試行回数が多ければ多いほど,確率の計算で求めた値と近くなるはずです。試行の数が多ければ多いほど理論計算値と試行の結果が近くなる,という状況を,確率の数学では大数の法則※1といいます。逆にとらえれば,試行回数が少ない場合は確率の数学はあてにならないと言えます。

試行回数が十分に大きいのに,確率の数学を用いた値と,シミュレーション結果との間に大きな違いがあるならば,確率の数学の考え方,あるいは問題のとらえ方に問題があるかもしれません。逆に,シミュレーションの手順にどこか問題があるのかもしれません。基本に立ち戻って,原因の究明に努めてみてください。問題が起こったときこそが,最高の学習の機会です。

※1)
law of large numbers

今回のまとめ

  • 確率の数学の教材,さいころシミュレーション・プログラムを作成しました。
  • 大数の法則を確認しました。

著者プロフィール

平田敦(ひらたあつし)

地方都市の公立工業高等学校教諭。趣味はプログラミングと日本の端っこ踏破旅行。2010年のLotYはRuby。結城浩氏のような仕事をしたいと妄想する30代後半♂。