更有效地计算概率

2024-06-25 23:12:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我在和一些缺乏编码经验的人斗争。我在下面写的代码,是非常不方便和丑陋的看。你知道吗

我的问题是: 如何才能更有效地做到这一点?我选择的方法效率很低。注意代码的def freq_2dice(n, N):部分,以及print语句。在这些方面,我需要更高的效率和更好看的代码。你知道吗

谢谢!你知道吗

EDIT:赋值是创建一个函数,它记录并存储在抛出2个骰子n次时获得每个可能和的概率。你知道吗

代码的其余部分将这些概率与精确概率进行比较。你知道吗

EDIT2:代码错误

from random import randint
import sys

def freq_2dice(n, N):
    M, A, E, R, T, Y, U, I, O, P, D = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    for reps in xrange(N):
        s = 0
        for dice in xrange(n):
            outcome = randint(1, 6)
            s += outcome
        if s==2:
            M += 1
        if s==3:
            A += 1
        if s==4:
            E += 1
        if s==5:
            R += 1
        if s==6:
            T += 1
        if s==7:
            Y += 1
        if s==8:
            U += 1
        if s==9:
            I += 1
        if s==10:
            O += 1
        if s==11:
            P += 1
        if s==12:
            D += 1
    return N*(float(M)/N), N*(float(A)/N), N*(float(E)/N), N*(float(R)/N), N*(float(T)/N), N*(float(Y)/N), N*(float(U)/N), N*(float(I)/N), N*(float(O)/N), N*(float(P)/N), N*(float(D)/N)

def chance_die():
    frequencies = {}
    for s in range(2, 13):
        frequency = 0
        for die1 in range(1, 7):
            for die2 in range(1, 7):
                if die1 + die2 == s:
                    frequency += 1
        frequencies[s] = frequency
    return frequencies


n = int(sys.argv[1])
N = int(sys.argv[2])

print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[0], freq_2dice(n, N)[0]/(N/100), chance_die()[2]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[1], freq_2dice(n, N)[0]/(N/100), chance_die()[3]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[2], freq_2dice(n, N)[0]/(N/100), chance_die()[4]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[3], freq_2dice(n, N)[0]/(N/100), chance_die()[5]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[4], freq_2dice(n, N)[0]/(N/100), chance_die()[6]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[5], freq_2dice(n, N)[0]/(N/100), chance_die()[7]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[6], freq_2dice(n, N)[0]/(N/100), chance_die()[8]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[7], freq_2dice(n, N)[0]/(N/100), chance_die()[9]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[8], freq_2dice(n, N)[0]/(N/100), chance_die()[10]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[9], freq_2dice(n, N)[0]/(N/100), chance_die()[11]/.36)
print 'No. of twos: %d, probability: %.2f, expected: %.2f' % (freq_2dice(n, N)[10], freq_2dice(n, N)[0]/(N/100), chance_die()[12]/.36)

'''

MacBook-Air:python Leroy$ python freq_2dice.py 2 100000
No. of twos: 2680, probability: 2.80, expected: 2.78
No. of threes: 5612, probability: 5.51, expected: 5.56
No. of fours: 8169, probability: 8.43, expected: 8.33
No. of fives: 11099, probability: 10.96, expected: 11.11
No. of sixes: 13827, probability: 13.91, expected: 13.89
No. of sevens: 16610, probability: 16.51, expected: 16.67
No. of eights: 13808, probability: 13.72, expected: 13.89
No. of nines: 10947, probability: 11.22, expected: 11.11
No. of tens: 8249, probability: 8.35, expected: 8.33
No. of elevens: 5540, probability: 5.59, expected: 5.56
No. of twelves: 2805, probability: 2.74, expected: 2.78

'''

Tags: ofno代码inforifdeffloat
1条回答
网友
1楼 · 发布于 2024-06-25 23:12:05

你在第二个循环中使用了错误的N,看起来应该是n,即100000掷骰子。
你真的不需要所有的变量,你只需要计算分数,用一个dict和分数作为一个键。
您正在为每个print调用freq_2dice(),这意味着为每个打印调用N*n。你只要叫它一次:

result = freq_2dice(n, N)
print ... result[0] ...
print ... result[1] ...
...

尽管骰子的数量是一个参数,但是有许多区域假设是2个骰子。你知道吗

使用dict保持{score: count}的示例:

from random import randint

def freq_ndice(n, N):
    d = {}
    for _ in range(N):
        score = sum(randint(1, 6) for _ in range(n))
        d[score] = d.get(score, 0) + 1
    return d

但是最后你可以用collections.Counter()来简化频率计算,这是dict的一种形式,可以计算出事件的发生次数:

from collection import Counter

def freq_ndice(n, N):
    return Counter(sum(random.randint(1, 6) for _ in range(n)) for _ in range(N))

>>> n, N = 2, 100000
>>> for score, count in freq_ndice(n, N).items():
...     print('No. of {}s: {}, probability: {:.2f}%'.format(score, count, 100*count/N))
No. of 2s: 2870, probability: 2.87%
No. of 3s: 5533, probability: 5.53%
No. of 4s: 8386, probability: 8.39%
No. of 5s: 11081, probability: 11.08%
No. of 6s: 13947, probability: 13.95%
No. of 7s: 16649, probability: 16.65%
No. of 8s: 13850, probability: 13.85%
No. of 9s: 11166, probability: 11.17%
No. of 10s: 8166, probability: 8.17%
No. of 11s: 5496, probability: 5.50%
No. of 12s: 2856, probability: 2.86%
1 loop, best of 3: 900 ms per loop

注:Python3。。。在Python2中使用xrangefrom __future__ import print_function100.0

相关问题 更多 >