2016-11-19 2 views
0

Я изо всех сил пытаюсь исправить ошибки. Код, который я написал ниже, крайне неудобен и уродлив.Более эффективные вычислительные вероятности

Мой вопрос: Как это можно сделать более эффективно? То, как я выбрал это, довольно неэффективно. Обратите внимание на раздел кода 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 

''' 
+0

Возможно, вам нужен список (массив) вместо использования переменных M, A, ... P, D. – LarsH

+0

Ну, например, вы могли бы заменить все операторы 'if' на' dict', например. 's_values_dict = {2: 'M', 3: 'A', 4: 'E', 5: 'R', ...}' Тогда вы можете просто ссылаться на любой ключ в словаре вместо того, чтобы иметь все эти ' if's. – blacksite

+0

Я пытался это сделать. Сделав его «dict», я не знал, как реализовать 'n' и' N' в этой функции. Как и в 'xrange (n)' и 'xrange (N)', я просто не знал, как его записать. – FrenziedMango

ответ

1

Вы используете неправильный N во втором цикле, это выглядит, как он должен быть n, т.е. 100000 пробегов метания 2 кости.
Вам действительно не нужны все переменные, вы просто хотите подсчитать баллы, используйте dict со счетом в качестве ключа.
Вы звоните freq_2dice() за каждые print, что означает, что 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 ... использовать xrange, from __future__ import print_function и 100.0 в Python2

+0

Спасибо за отзыв! Я уже редактировал 'N', чтобы' n', но я думаю, вы писали, что вы отвечали, когда я это делал. То, что вы только что сделали, похоже на отличное решение, я просто не знаю, как это реализовать в моем коде, а не в моих неудобных кучах ненужного кода. Я совершенно новый. Поучайте, чтобы объяснить дальше? Или это слишком много, чтобы спросить? EDIT: О, кстати, я попытался сделать словарь для подсчета очков, однако я потерпел неудачу. Я не видел, где бы я реализовал 'N' и' n' в функции, где я определил dict. – FrenziedMango

+0

@FrenziedMango Реструктурировал ответ, возможно, более понятным. Рад ответить на любые другие вопросы. Примечание: '_' - это просто соглашение в python, указывающее неиспользованную переменную, в которой вы можете использовать любое имя переменной, например. 'i' – AChampion