微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决Python 中的 randint 函数与 % 技巧不同吗?

我提前感谢您的帮助。

我用python写了一个概率计算器。我想计算的概率是:当你尝试 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 insted 而不是 randint(1,6),程序会告诉概率是 5.8,这是我预期的。

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

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

enter image description here

解决方法

看起来您在增加 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...

您应该只返回 0 或 1,然后从外部计数。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。