我创建了一个python彩票模拟器,它可以生成一个由0-75组成的5个随机数的数组('中奖号码'):
for n in xrange(0, 5):
winning_number.append(randint(0, 75))
然后,它会检查用户定义的票数' ('计数'变量)对抗'胜利'阵列。
while count > 0:
for n in xrange(0, 5):
result.append(randint(0, 75))
if result == winning_number:
wingame += 1
count -= 1
del result[:]
else:
count -= 1
del result[:]
正如预期的那样,大约1000万以上的计数值开始花费很长时间并开始对我的系统资源征税,但我真的想要运行更大的计数值。我是否有任何修改可以帮助避免多余的步骤?使用像PyCUDA或pyOpenCl这样的东西会有效和/或在编码新手的范围内吗?
我感谢您提供的任何帮助或您可以指出的资源。谢谢!
答案 0 :(得分:1)
你的彩票数学有点奇怪;
首先,random.randint(0, 75)
生成包含两个端点的值 - 因此您要从76个值(0 ... 75)中进行选择。也许你的意思是(1, 75)
?
其次,您允许重复的值,即3, 3, 3, 3, 3
是有效的票证。彩票通常不允许重复。请查看random.sample
,即random.sample(range(1, 76), 5)
第三,您选择值的顺序显然很重要 - 1, 2, 3, 4, 5
与1, 3, 2, 4, 5
不同。彩票通常不考虑订单(除了可能的奖金号码)。在Python术语中,您应该比较集而不是列表。
第四,实际生成值列表涉及大量分配和释放内存;通过操作枚举状态而不是实际生成每个状态,可以更便宜地获得相同的效果。例如,您可以说{1, 4, 7, 19, 21}
是百万分之一和第三组合,然后测试randvalue == 1000003
而不是randset == {1, 4, 7, 19, 21}
。
实施这些更改,您可以简化逻辑,如
from random import randrange
from math import factorial
VALUES = 75
PICKS = 5
TICKETS = 10000000
# calculate number of unique tickets
num_combos = factorial(VALUES) // (factorial(VALUES - PICKS) * factorial(PICKS))
winner = randrange(num_combos)
num_winners = sum(randrange(num_combos) == winner for _ in range(TICKETS))
编辑:快速思考并测试了它;
num_winners = sum(1 for _ in range(TICKETS) if randrange(num_combos) == winner)
快5%左右。 (超过85%的运行时现在只用于生成随机值。)
Edit2:另一个想法 - 如果我们任意说“0是获胜状态”,那么我们的主循环变为
num_winners = sum(1 for _ in range(TICKETS) if not randrange(num_combos))
再加快2.5%。
或者你可以直接进入最终解决方案,
from numpy.random import poisson
num_winners = poisson(TICKETS / num_combos)