Как я могу оптимизировать это моделирование Монте-Карло работает на 10.000.000 итераций?


Я пишу это моделирование по методу Монте-Карло и я сталкиваются с этой проблемой при запуске кода на 10.000.000 итераций. вот код:

import random as rnd
from time import time

#get user input on number of iterations
numOfIterations = raw_input('Enter the number of iterations: ')
numOfIterations = int(numOfIterations)

start = time()

#initialize bag (44 green, 20 blue, 15 yellow,  11 red, 2 white, 1 black
#a counter
#and question counter
bag = 44*'g'+ 20*'b' + 15*'y' + 11*'r' + 2*'w' + 'k'
counter = {'g':0, 'b':0,'y':0 ,'r':0,'w':0,'k':0}
question = {'one':0,'two':0,'three':0,'four':0,'five':0}

for i in range(0,numOfIterations):
  for j in xrange(0,5):
    draw = rnd.sample(bag,5)
    for x in draw: counter[x]+=1
  if counter['w'] >0 and counter['k'] >0: question['one']+=1
  if counter['b'] > counter['r']: question['two']+=1
  if counter['b'] > counter['y']: question['three']+=1
  if counter['y'] > counter['r']: question['four']+=1
  if counter['g'] < (counter['b']+counter['y']+counter['r']+counter['w']+counter['k']): question['five']+=1
  for k in counter: counter[k] = 0

p1 = float(question['one'])/float(numOfIterations)
p2 = float(question['two'])/float(numOfIterations)
p3 = float(question['three'])/float(numOfIterations)
p4 = float(question['four'])/float(numOfIterations)
p5 = float(question['five'])/float(numOfIterations)

print 'Q1 \t Q2 \t Q3 \t Q4 \t Q5'
print str(p1)+'\t'+str(p2)+'\t'+str(p3)+'\t'+str(p4)+'\t'+str(p5)

end = time()

print 'it took ' +str(end-start)+ ' seconds'

любые предложения/критика будет оценили.



1518
4
задан 26 ноября 2011 в 12:11 Источник Поделиться
Комментарии
1 ответ

import random as rnd

Мне не нравится аббревиатура такой, они делают код трудно читать

from time import time

#get user input on number of iterations
numOfIterations = raw_input('Enter the number of iterations: ')
numOfIterations = int(numOfIterations)

Какой-либо причине вы не объединить эти две линии?

start = time()

#initialize bag (44 green, 20 blue, 15 yellow, 11 red, 2 white, 1 black
#a counter
#and question counter
bag = 44*'g'+ 20*'b' + 15*'y' + 11*'r' + 2*'w' + 'k'
counter = {'g':0, 'b':0,'y':0 ,'r':0,'w':0,'k':0}
question = {'one':0,'two':0,'three':0,'four':0,'five':0}

Просмотр данных строк все время будет несколько медленнее. Вместо этого, я предлагаю вам сохранить списки и хранить данные таким образом.

for i in range(0,numOfIterations):

Учитывая, что numOfIterations будет очень большим, его, вероятно, хорошая идея использовать xrange здесь.

  for j in xrange(0,5):

В общем, необходимо поместить логику внутри функции. Это особенно верно для какой-либо цикл, так как он будет работать быстрее в функции.

    draw = rnd.sample(bag,5)
for x in draw: counter[x]+=1

Я не люблю класть содержимое петли на одной линии. Я думаю, что это делает это тяжелее, чтобы читать.

  if counter['w'] >0 and counter['k'] >0: question['one']+=1
if counter['b'] > counter['r']: question['two']+=1
if counter['b'] > counter['y']: question['three']+=1
if counter['y'] > counter['r']: question['four']+=1
if counter['g'] < (counter['b']+counter['y']+counter['r']+counter['w']+counter['k']): question['five']+=1
for k in counter: counter[k] = 0

p1 = float(question['one'])/float(numOfIterations)
p2 = float(question['two'])/float(numOfIterations)
p3 = float(question['three'])/float(numOfIterations)
p4 = float(question['four'])/float(numOfIterations)
p5 = float(question['five'])/float(numOfIterations)

Не создать пять отдельных переменных, создать список. Также, если вы добавляете линии от __будущее__ импорт дивизии в начале файла после деления двух целых чисел будет производить флоат. Тогда вам не нужно конвертировать их в поплавки здесь.

print 'Q1 \t Q2 \t Q3 \t Q4 \t Q5'
print str(p1)+'\t'+str(p2)+'\t'+str(p3)+'\t'+str(p4)+'\t'+str(p5)

Смотрите, если вы имели П1 список, это будет намного легче

end = time()

print 'it took ' +str(end-start)+ ' seconds'

Для улучшения скорости вы хотите посмотреть с помощью библиотеки numpy. Это позволяет реализовать эффективные операции над массивами.

В этом конкретном случае я бы использовал мультиномиальное распределение и аналитически решить проблемы, а затем с использованием метода Монте-Карло.

8
ответ дан 26 ноября 2011 в 03:11 Источник Поделиться