Python彩票号码生成

时间:2019-05-10 11:17:49

标签: python numpy combinations

我正在开发彩票号码生成程序。我有一个固定的允许数字列表(1-80),用户可以从中选择6个数字。每个数字只能被选择一次。我想高效地生成所有可能的组合。如果allowed_numbers为[1,...,60],当前的实现将花费超过30秒的时间。除此之外,它冻结了我的系统。

from itertools import combinations
import numpy as np


LOT_SIZE = 6


allowed_numbers = np.arange(1, 61)
all_combinations = np.array(list(combinations(allowed_numbers, LOT_SIZE)))
print(len(all_combinations))

我想我需要一个numpy数组(不确定2D)。像

[[1,2,3,4,5,6],
[1,2,3,4,5,,7],...]

因为我想(快速)对这些组合执行几个操作。这些操作可能包括

  • 删除仅具有偶数的组合
  • 删除总和大于150的组合,等等。
  • 检查是否只有一对连续的数字(可接受:[1,2,4,6,8,10] {对:(1,2)} |不可接受:[1,2,4, 5,7,9] {对:(1,2)和(4,5)})

任何帮助将不胜感激。

谢谢

2 个答案:

答案 0 :(得分:0)

一些选项:

1)使用filter在可迭代对象而不是数据上应用过滤器:

def filt(x):
    return sum(x) < 7

list(filter(filt, itertools.combinations(allowed, n)))
与构建列表并应用过滤器相比,

将节省大约15%的时间,即:

[i for i in itertools.combinations(allowed, n) if filt(i) if filt(i)]

2)使用np.fromiter

arr = np.fromiter(itertools.chain.from_iterable(itertools.combinations(allowed, n)), int).reshape(-1, n)
return arr[arr.sum(1) < 7]

3)处理生成器对象本身。在上面的示例中,当第一个数字大于7时(例如),您可以停止itertools.combinations

def my_generator():
    for i in itertools.combinations(allowed, n):
        if i[0] >= 7:
            return
        elif sum(i) < 7:
            yield i
list(my_generator())   # will build 3x times faster than option 1

请注意,np.fromiter在复合表达式上的效率较低,因此此后将应用掩码

答案 1 :(得分:-1)

您可以使用itertools.combinations(allowed_numbers, 6)从列表中获取长度6的所有组合(这是完成此操作的最快方法)。