ページ 11

大学の乱数についての課題

Posted: 2022年12月22日(木) 13:04
by C初心者AAAANNtT
大学の課題で、
「結婚したての夫婦が,最初に生まれた子供と同性の子供が生まれるまで子供を作ることにした.
男子の生まれる確率をpとすると,p = 0 および p = 1 の時は子供の数は明らかに2人である.
それでは 0 < p < 1 の時に子供の数の平均は何人になるか,pを色々変化させてシミュレーションを行い,調査せよ.」
という課題がでて自分なりにコードを書いてみたのですが、実行結果がずっと200という同じ値にしかなりません。どこを改善すればよいか教えていただきたいです。
見にくいコードで申し負けありません。

コード:



#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main() {

	double i, p, r, a, b = 0, girl, boy;
	srand((unsigned int)time(NULL));

	printf(" 0 < p < 10000の範囲でpの値を入力してください\n");
	scanfs("p = %lf", &p);

	p = p / 10000;

	for (i = 0; i < 10000; i++) {

		r = (double)rand() / RAND_MAX;

		boy = 0;
		girl = 0;

		if (p > r) {

			girl++;

		}
		else {

			boy++;

		}
		if (girl == 0) {

			while (boy < 2) {

				r = (double)rand() / RAND_MAX;

				if (p > r) {

					girl++;

				}
				else {

					boy++;

				}
			}
		}
		else if (girl == 1) {

			while (girl < 2) {

				r = (double)rand() / RAND_MAX;

				if (p > r) {

					girl++;

				}
				else {

					boy++;

				}
			}
		}

		a = boy + girl;
		b = b + a;

	}

	b = b / 100;
	printf("子供の平均の数 = %f\n", b);

	return 0;

}

Re: 大学の乱数についての課題

Posted: 2022年12月22日(木) 14:07
by dic
で、答えは何になるのが正しいのですか?

Re: 大学の乱数についての課題

Posted: 2022年12月22日(木) 14:14
by C初心者AAAANNtT
申し訳ありません、詳しい答えはわからないです

Re: 大学の乱数についての課題

Posted: 2022年12月22日(木) 15:33
by box

コード:

	boy = 0;
	girl = 0;
これらの変数を0で初期化している箇所、
ループの「中」でいいんでしょうか。何か疑問です。

Re: 大学の乱数についての課題

Posted: 2022年12月22日(木) 18:48
by usao
> b = b / 100;

100で除す理由は何なの?
「平均」を求めるなら試行回数で除すべきちゃうん?
オフトピック
あと,少なくとも他人にコード見せる必要が生じたならば,aだのbだのいう無意味な変数名をまともな名称にしてから投稿すべき.
それを行ったうえでも,他人に「今現在まともに動かないコード」だけを示して「本来の」処理内容を推測させよう,というのはどうなのか? と思うが.

Re: 大学の乱数についての課題

Posted: 2022年12月22日(木) 18:50
by usao
それはそれとして,本来の解がわからんというのでは,何をもって結果の成否を判断するのであろうか?

Re: 大学の乱数についての課題

Posted: 2022年12月23日(金) 20:36
by みけCAT
とりあえずPythonで自分で実装してみました。

コード:

import random

# 確率pでTrue、1-pでFalseを返す
def randBool(p):
	return random.random() < p

# 男子の生まれる確率がpのときのシミュレーションを1回行い、子供の数を返す
def simulate(p):
	numChildren = 1
	firstChild = randBool(p)
	while True:
		numChildren += 1
		newChild = randBool(p)
		if firstChild == newChild:
			return numChildren

# 男子の生まれる確率がpのときのシミュレーションをnum回行い、子供の数の平均を返す
def repeatSimulation(p, num):
	results = [simulate(p) for _ in range(num)]
	return sum(results) / len(results)

numSimulation = 100000
# p = 0.01 から 0.99 まで 0.01 刻みでシミュレーションを行う
for i in range(1, 100):
	p = i / 100.0
	print("%.2f %f" % (p, repeatSimulation(p, numSimulation)))
実行結果

コード:

0.01 3.053620
0.02 3.011690
0.03 2.993910
0.04 3.037800
0.05 2.971620
0.06 3.018160
0.07 3.000110
0.08 2.990430
0.09 3.022200
0.10 3.005660
0.11 2.999660
0.12 3.011140
0.13 3.015850
0.14 2.978760
0.15 2.996060
0.16 2.996070
0.17 3.006340
0.18 2.998220
0.19 2.986060
0.20 3.004720
0.21 3.000840
0.22 3.003630
0.23 2.992840
0.24 2.995920
0.25 3.001060
0.26 2.999150
0.27 2.992830
0.28 3.002380
0.29 3.005200
0.30 3.014490
0.31 2.997380
0.32 2.990870
0.33 2.993910
0.34 3.000160
0.35 2.996810
0.36 3.004260
0.37 2.996420
0.38 2.993200
0.39 2.998120
0.40 3.003820
0.41 3.000870
0.42 2.994020
0.43 3.000610
0.44 2.996700
0.45 2.994600
0.46 2.998030
0.47 2.998260
0.48 2.991130
0.49 3.012400
0.50 3.007970
0.51 2.996500
0.52 3.004880
0.53 3.005360
0.54 2.995460
0.55 2.997430
0.56 2.996730
0.57 2.995340
0.58 3.000500
0.59 2.991520
0.60 3.004460
0.61 3.003800
0.62 3.003170
0.63 3.003530
0.64 2.996680
0.65 2.993340
0.66 2.997740
0.67 3.006910
0.68 2.997690
0.69 2.999090
0.70 2.993060
0.71 2.999760
0.72 2.998020
0.73 2.992980
0.74 2.983850
0.75 2.994730
0.76 3.013340
0.77 2.994420
0.78 3.000630
0.79 2.993440
0.80 3.000710
0.81 3.017460
0.82 3.001210
0.83 3.001580
0.84 3.003550
0.85 3.011010
0.86 2.998420
0.87 2.995380
0.88 2.979570
0.89 3.008700
0.90 2.999220
0.91 2.981940
0.92 3.003340
0.93 3.008350
0.94 3.015690
0.95 3.015350
0.96 2.986300
0.97 2.967750
0.98 2.985260
0.99 2.996780
結果はpの値にかかわらず約3になりそうかな…?

Re: 大学の乱数についての課題

Posted: 2022年12月23日(金) 21:35
by みけCAT
C初心者AAAANNtT さんが書きました:
1年前
実行結果がずっと200という同じ値にしかなりません。どこを改善すればよいか教えていただきたいです。
・scanfs という関数はC言語の標準ライブラリに無いので、scanfに置換する
・指定された書式に合った入力を与える
ことで、200でない値を出力させることができました。
改善するべき点は与える入力であると予想します。
また、scanfの戻り値により、期待する数の入力を読み込めたかをチェックするべきです。

https://wandbox.org/permlink/8K0G5iQN7f5A8TTi
box さんが書きました:
1年前

コード:

	boy = 0;
	girl = 0;
これらの変数を0で初期化している箇所、
ループの「中」でいいんでしょうか。何か疑問です。
シミュレーション1回ごとに初期化するべきなので、ループの「中」でいいと思います。
usao さんが書きました:
1年前
> b = b / 100;

100で除す理由は何なの?
「平均」を求めるなら試行回数で除すべきちゃうん?
同意します。

Re: 大学の乱数についての課題

Posted: 2022年12月24日(土) 19:24
by dic
大学だから何の単元ですか?
私はまだ大学までいってない