我一直在想这个但似乎无法弄明白。我需要选择1到50(包括)之间的随机整数,使得它中的每个整数都具有相同的可能性。我将不得不使用8面骰子和15面骰子。
我读过与骰子随机数发生器有关的类似问题,但我仍感到困惑。我认为这是将数字分成几组的界限。然后,我会掷骰子,然后,根据结果,决定再次掷骰子。
有人可以帮我这个吗?
答案 0 :(得分:1)
作为一个简单的 - 不一定是“最佳”解决方案,滚动8面模具,然后是15面:
8 sided 15 sided 1..50 result
1 or 2 1..15 1..15
3 or 4 1..15 16..30 (add 15 to 15-sided roll)
5 or 6 1..15 31..45 (add 30 to 15-sided roll)
7 or 8 1..5 46..50 (add 45 to 15-sided roll)
7 or 8 6..15 start again / reroll both dice
答案 1 :(得分:1)
假设你有两个函数:d8()
,它返回一个从0到7的数字,d15()
,它返回一个从0到14的数字。你想写一个{{1}返回0到49之间的数字。
在所有简单的方法中,对于你需要掷多少骰子来说,这个方法可能效率最高,这样的东西对于你拥有的骰子和你想要的骰子都适用:
d50()
如果你想要非常恒定的时间,你可以这样做:
int d50()
{
int result;
do
{
result = d8()*8+d8(); //random from 0 to 63
} while(result >=50);
return result;
}
这种方式组合骰子直到可能性数量(1800)可被50整除,因此相同数量的可能性对应于每个结果。这种方法在这种情况下运行正常,但是如果您拥有的骰子的素数因素(在这种情况下为2,3和5)不起作用,则不能覆盖您想要的骰子因素(2,5)< / p>
答案 2 :(得分:0)
我认为您可以将每个骰子结果视为更大间隔的细分。所以扔掉一个8面骰子,你可以在8个主要区间中选择一个除以你的价值范围。投掷15个骰子意味着从15个子区间中选择一个,依此类推。 考虑到15 = 3 * 5,8 = 2 * 2 * 2和50 = 2 * 5 * 5你可以选择36 = 3 * 3 * 2 * 2作为50的方便倍数,以便:
15 * 15 * 8 = 50 * 36 = 1800
您甚至可以考虑在基数15中表示0到1799之间的数字,并选择ramdomly这三个数字:
选择= [0-7] * 15 ^ 2 + [0-14] * 15 ^ 1 + [0-14] * 15 ^ 0
所以我的建议,测试分布,是(用c ++语言):
#include <iostream>
#include <random>
#include <map>
int main() {
std::map<int, int> hist;
int result;
std::random_device rd;
std::mt19937 gen(rd()); // initialiaze the random generator
std::uniform_int_distribution<> d8(0, 7); // istantiate the dices
std::uniform_int_distribution<> d15(0, 14);
for (int i = 0; i < 20000; ++i) { // make a lot of throws...
result = d8(gen) * 225;
result += d15(gen) * 15; // add to result
result += d15(gen);
++hist[ result / 36 + 1]; // count each result
}
for (auto p : hist) { // show the occurences of each result
std::cout << p.first << " : " << p.second << '\n';
}
return 0;
}
输出应该是这样的:
1 : 387
2 : 360
3 : 377
4 : 393
5 : 402
...
48 : 379
49 : 378
50 : 420