Python 中的 randint 函数与 % 技巧不同吗?

Is randint function in Python different from % trick?

在此先感谢您的帮助。

我用python写了一个概率计算器。 Prob 我想计算的是:当你尝试 6 次获胜机会为 1% 的游戏时,获胜的概率是多少?所以下面这段代码就是我写的。

import random as rand

total = 0
count = 0

p = pSum = 0

k = 6
n = 10000
m = 100

def pick(attemptPerIteration):
    global total, count
    for _ in range(attemptPerIteration):
        temp = rand.randint(1, 100)
        if (temp == 1):
            count += 1
            total += 1
            return 0
    return 1

for t in range(m):
    for u in range(n):
        total += pick(k)
    p = count / total
    print(str(t + 1) + ": " + str(p * 100))
    pSum += p
    p = 0
print(pSum / m * 100)

在这段代码中,我使用了 randint 函数来模拟 100 分之一的机会。我预期的概率约为 5.8%,但该程序的输出约为 6.3%。但是如果我使用 randint(1, 1000) % 6 + 1 而不是 randint(1, 6),程序告诉我概率是 5.8,这是我预期的。

这个 randint 函数到底发生了什么?为什么旧的 % 技巧有效但 randint 无效?

这个问题的数学公式是这样的:

看起来你在递增 counttotal 时犯了错误。我更改了您的代码以计算正确的结果:

Try it online!

import random as rand

total = 0
count = 0

p = pSum = 0

k = 6
n = 10000
m = 100

def pick(attemptPerIteration):
    for _ in range(attemptPerIteration):
        temp = rand.randint(1, 100)
        if (temp == 1):
            return 1
    return 0

for t in range(m):
    for u in range(n):
        count += pick(k)
        total += 1
    p = count / total
    print(str(t + 1) + ": " + str(p * 100))
    pSum += p
    p = 0
print(pSum / m * 100)

输出:

.......
90: 5.822555555555556
91: 5.8221978021978025
92: 5.822608695652174
93: 5.824193548387097
94: 5.822446808510638
95: 5.822631578947368
96: 5.824166666666667
97: 5.825670103092784
98: 5.8254081632653065
99: 5.826969696969697
100: 5.8306
5.825542887205491

看起来 m = 100n = 10000 太少了,无法收敛。

import random

def did_win(attempts):
    return any(random.random() < .01 for attempt in range(attempts))

tries = [did_win(6) for x in range(1_000_000)]
print(tries.count(True) / len(tries))

打印出大约 0.058039,这似乎足够接近了。

如果您想更实时地观察解的收敛,

import random
import itertools


def did_win(attempts):
    return any(random.random() < 0.01 for attempt in range(attempts))


wins = 0
for x in itertools.count(0):
    if did_win(6):
        wins += 1
    if x and x % 10_000 == 0:
        print(x, wins / x)

(按 ctrl-c 打断它——否则它会很高兴 运行 永远)。

实际上,公式要简单得多。 获胜的概率是(99 / 100) ** 6,大约是0.941。它的补数是中奖概率1 - 0.941... = 0.058....

因为您正在以一种奇怪的方式增加全局计数,所以您很可能在不止一个地方出现差一错误。例如

total += pick(k)

其中 pick 也修改 total...

你应该 return 0 或 1 然后从外面数。