你介意帮我解决下面这个问题吗?感谢。
问题: 一次性滚动3个骰子的百分比可以用数学方法找到 模拟。蒙特卡罗方法是一个计算机过程,以找出一个解决方案 计算机模拟的问题。写一个滚三个骰子的程序,计算它们 总和,并找出滚动每个可能结果的概率。
给你一个骨架程序q1dskeleton.c,它生成滚动a的统计数据 骰子六面10000次。修改程序,使其生成滚动三个六面骰子之和的统计数据。程序输出的一个例子在 以下。请注意,由于骰子滚动的随机性。
提示:每次掷骰子时调用rand()三次,每个骰子一次。
骨架:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 7
int main() {
int face, roll, frequency[SIZE] = { 0 };
srand( time(NULL) );
for (roll = 1; roll <= 10000; roll++) {
face = rand() % 6 + 1;
++frequency[face];
}
printf("%s%12s\n", "Face", "Frequency");
for (face = 1; face <= SIZE - 1; face++)
printf("%4d%12d\n", face, frequency[face]);
getchar();
}
输出:
Face Frequency
3 49
4 129
5 276
6 481
7 669
8 994
9 1131
10 1213
11 1269
12 1197
13 962
14 707
15 464
16 268
17 144
18 47
答案 0 :(得分:3)
显然,你必须增加SIZE
,因为不再有6种可能性,但是18 - 我将包括不可能的总数1和2,因为你的原始解决方案包括不可能的零值:-)
然后,不是扔一个骰子,而是抛出三个,然后将这些值相加。所以像(伪代码):
dice1 = first random number
dice2 = second random number
dice3 = third random number
face = dice1 plus dice2 plus dice3
添加是您用于增加特定数组元素的内容。
对于奖励积分,您应该避免打印出不可能的结果。这是对最终for
语句的起始位的一个相当简单的修改。
顺便说一下,您期望的比率为{1, 3, 6, 10, 15, 21, 25, 27, 27, 25, 21, 15, 10, 6, 3, 1}
,因此“理想”输出应该合理地接近:
Face Frequency
3 46
4 138
5 277
6 462
7 694
8 972
9 1157
10 1250
11 1250
12 1157
13 972
14 694
15 462
16 277
17 138
18 46
(即使只增加了9992个样本 - 这是其他八个样本出现的地方的背景。)
答案 1 :(得分:2)
另外,在计算rand()时你需要意识到它并非像我们希望的那样随机。
来自http://www.cplusplus.com/reference/clibrary/cstdlib/rand/的文档 “请注意,此模运算不会在跨度中生成真正均匀分布的随机数(因为在大多数情况下,较低的数字稍微更可能),但它通常是短跨度的良好近似值。”
因此,为了获得更好的结果,最好为获得随机结果概率较高的兰特范围的不同公式做一些工作。
例如,对于骰子,你得到一个30到90之间的随机数,公式是(int)(((float)result - 30)/ 10)+ 0.5或者这些行的东西。
然后对于骰子2,你可以得到500到50000之间的数字并制作另一个公式。
为了让您的家庭作业更有趣,您可以了解不同的在线赌场/扑克室如何做到这一点。 http://www.fulltiltpoker.com/random-number-generator