前回は確率の数学の言葉を一通りおさらいしました。今回はその確認に役立つ道具となるシミュレーション用ソフトウエアを作りましょう。そして完成したものを利用して、
問題1 さいころの働きをするクラスを作りましょう
今後確率の学習を進める中で、
以下に肝心の部分を省略した未完成版のコードを掲載します。コンパイル・
さいころは任意の面数のものを作成できるようにしてください。負の面数や、
//サンプルコード
//さいころクラスを作ろう
//filename : Q_Sample_DiceRoll.java
import java.util.Random;
class Q_Sample_DiceRoll {
public static void main(String[] args) {
//4 面、6 面、20 面のダイス
Dice d4 = new Dice(4);
Dice d6 = new Dice(6);
Dice d20 = new Dice(20);
//不適切なダイス。roll を呼ぶと0 を返すはず。
Dice d0 = new Dice(0);
Dice dError = new Dice(Integer.MAX_VALUE);
//それぞれ1 回、2 回、3 回振った結果を表示する。
System.out.println("Dice roll test");
System.out.println("正常に動作する場合");
for (int i=1; i <= 3; ++i){
System.out.println(i + "回振ったら"
+ d4.roll(i) + "," + d6.roll(i)
+ "," + d20.roll(i));
}
System.out.println("正常に動作しない場合");
System.out.println(d0.roll(1));
System.out.println(dError.roll(1));
System.out.println(d6.roll(Integer.MAX_VALUE/6 + 1));
System.out.println(d6.roll(-5));
System.out.println("さいころの面数を確認");
System.out.println(d4.getSize());
System.out.println(d6.getSize());
System.out.println(dError.getSize());
System.out.println(d0.getSize());
}// end of main
}// end of class Q_Sample_DiceRoll
/*
* class Dice
* 目的: さいころをシミュレートするクラス
* コンストラクタに整数値を指定して、
* さいころの面数を指示できる。
*/
class Dice {
/*
* 目的: コンストラクタ
* 引数: s ダイスの面数
* 不適当な値なら、面数0 のダイスとなる。
*/
Dice(int s){
}// end of Constructor Dice(s)
/*
* 目的: ダイスを振る
* 引数: n ダイスを振る回数
* 戻り値: 出たダイスの目の合計
*/
public int roll(int n){
return 0;
}// end of roll
/*
* 目的: ダイスの面数を返す
* 戻り値: ダイスの面数
*/
public int getSize(){
return 0;
}// end of getSize
} // end of class Dice
問題2 さいころを振って確率の値を確かめましょう
2つのことを確かめましょう。
(1)
解説
問題1 さいころの働きをするクラスを作りましょう
完成したDiceクラスのみを示します。このクラスがあれば、
大変シンプルなクラスですので、
/*
* 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にしなければなりませんから、
> javac Dice.java
コンパイルを実行したディレクトリ内にDice.
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
//サンプルコード
//..「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
シミュレーションの結果得られた
シミュレーションは試行回数が多ければ多いほど、
試行回数が十分に大きいのに、