在C++和Python中,我有两个函数,它决定在某个卷上发生某个概率的事件的次数。
python版本:
def get_loot(rolls):
drops = 0
for i in range(rolls):
# getting a random float with 2 decimal places
roll = random.randint(0, 10000) / 100
if roll < 0.04:
drops += 1
return drops
for i in range(0, 10):
print(get_loot(1000000))
python输出:
371
396
392
406
384
392
380
411
393
434
C++版本:
int get_drops(int rolls){
int drops = 0;
for(int i = 0; i < rolls; i++){
// getting a random float with 2 decimal places
float roll = (rand() % 10000)/100.0f;
if (roll < 0.04){
drops++;
}
}
return drops;
}
int main()
{
srand(time(NULL));
for (int i = 0; i <= 10; i++){
cout << get_drops(1000000) << "\n";
}
}
C++输出:
602
626
579
589
567
620
603
608
594
610
626
这只乌鸦看起来一模一样(至少在我看来)。这两个函数都模拟1000000次转鼓的概率为0.04的事件发生。然而,Python版本的输出比C++版本低30%左右。这两个版本有何不同?为什么它们有不同的输出?
3条答案
按热度按时间evrscar21#
在C++(0)和RANDMAX之间的范围内返回一个伪随机整数。
RAND_MAX
是“依赖于库,但保证在任何标准库实现上至少为32767。”我们开始吧
RAND_MAX
32767。当计算[0,32767)%10000时,随机数生成是倾斜的。
值0-2767在范围(%10000)->
值计算结果11%10000110001%100001000120001%10000130001%10000130001%100001
其中,值2768-9999在范围(%10000)内仅出现3次->
值计算结果27682768%10000276812768%10000276882276822768%1000027768
这使得值0-2767比值2768-9999(假设)更可能出现25%
rand()
事实上,会在0和rand_max)之间产生一个均匀分布。另一方面,python使用randint在开始和结束之间生成一个均匀的分布
randint
是“randrange(a,b+1)的别名”randrange(在python 3.2及更新版本中)将生成均匀分布的值:
在版本3.2中进行了更改:randrange()在生成均匀分布的值方面更加复杂。以前它使用int(random()*n)这样的样式,这可能会产生稍微不均匀的分布。
在C++中有几种生成随机数的方法。也许最类似于
python
将使用mersenne twister引擎(与python相同,但有一些不同)。通过
uniform_int_distribution
具有mt19937
:值得注意的是,这两个引擎的底层实现以及种子和分发都略有不同,但是,这将更接近python。
或者,正如matthias fripp所建议的那样,按比例放大兰德并除以
RAND_MAX
:这也更接近python输出(同样,在底层实现中生成随机数的方式上存在一些差异)。
laik7k3q2#
结果是倾斜的,因为
rand() % 10000
这不是实现均匀分布的正确方法(另见stephan t.认为有害的rand()。在现代C++中,首选头文件中提供的伪随机数生成库。<random>
. 例如:g9icjywg3#
两种语言都使用不同的伪随机生成器。如果要统一性能,可能需要确定地生成自己的伪随机值。
以下是它在python中的外观:
然而,在C++中,应该成为: