Python 排除项的有效笛卡尔积

Python 排除项的有效笛卡尔积,python,itertools,cartesian-product,Python,Itertools,Cartesian Product,我试图让11个值的所有可能组合重复80次,但过滤掉总和大于1的情况。下面的代码实现了我的目标,但需要几天时间才能运行: import numpy as np import itertools unique_values = np.linspace(0.0, 1.0, 11) lst = [] for p in itertools.product(unique_values , repeat=80): if sum(p)<=1: lst.append(p) 将n

我试图让11个值的所有可能组合重复80次,但过滤掉总和大于1的情况。下面的代码实现了我的目标,但需要几天时间才能运行:

import numpy as np
import itertools

unique_values = np.linspace(0.0, 1.0, 11)

lst = []
for p in itertools.product(unique_values , repeat=80):
    if sum(p)<=1:
        lst.append(p)
将numpy导入为np
进口itertools
唯一_值=np.linspace(0.0,1.0,11)
lst=[]
对于itertools.product中的p(唯一的_值,重复=80):

if sum(p)OP只需要10的分区,但这里有一些我同时编写的通用代码

def find_combinations(values, max_total, repeat):
    if not (repeat and max_total > 0):
        yield ()
        return
    for v in values:
        if v <= max_total:
            for sub_comb in find_combinations(values, max_total - v, repeat - 1):
                yield (v,) + sub_comb


def main():
    all_combinations = find_combinations(range(1, 11), 10, 80)
    unique_combinations = {
        tuple(sorted(t))
        for t in all_combinations
    }
    for comb in sorted(unique_combinations):
        print(comb)

main()
def find_组合(值,最大值,重复):
如果不是(重复且最大值总和>0):
产量()
返回
对于v值:

如果v好的话,这会更有效率,您可以像这样使用生成器,并根据需要获取您的值:

def get_solution(uniques, length, constraint):
    if length == 1:
        for u in uniques[uniques <= constraint + 1e-8]:
            yield u
    else:
        for u in uniques[uniques <= constraint + 1e-8]:
            for s in get_solution(uniques, length - 1, constraint - u):
                yield np.hstack((u, s))
印刷品

[0. 0. 0. 0.]
[0.  0.  0.  0.1]
[0.  0.  0.  0.2]
[0.  0.  0.  0.3]
[0.  0.  0.  0.4]
与您的功能相比:

def get_solution_product(uniques, length, constraint):
    return np.array([p for p in product(uniques, repeat=length) if np.sum(p) <= constraint + 1e-8])

unique\u values=np.linspace(0.0,1.0,11)
real还是这是一个例子?在numpy中有几个关于itertools.product的stackoverflow的实现,可能会更快,否则,我将尝试用C或其他快速语言来实现。另外,为什么
np.linspace(0.0,1.0,11)
而不是
range(12)
np.linspace(0.0,1.0,11)
是真实的。上面的例子正是我想要得到的。如果我使用
范围(12)
我将无法检查总和是否低于1@Stergios然后你只需要把42个10的分区缩小10倍:这最终是为了什么?存储千兆字节的大部分为零的列表真的是你最好的选择吗?我并不是在寻找10的分区。例如,在我的例子中,接受向量[0.1,0,0,0…](只要总数是@Stergios,我理解,我就不会再讨论这个问题,因为这个问题很难处理。没关系。我只是在您的解决方案下添加了我以前的评论,供其他人参考。@Viachesav您的解决方案不会返回我需要的所有值。例如,它不会返回解决方案[0.8 0.2 0.0 0 0.0 0 0.0]或[0.8 0.0 0.0 0 0.2 0.0]都是有效的。事实上,它只返回可能的解决方案的一半。我接受你的答案。我需要添加的是运行循环两次。一次用于
唯一_值
一次用于
唯一_值[:-1]
@Stergios这很奇怪,因为它实际上生成了所有正确的答案。检查
列表(过滤器(lambda x:x[0]==0.8,获取解决方案(唯一值,5,1))
def get_solution_product(uniques, length, constraint):
    return np.array([p for p in product(uniques, repeat=length) if np.sum(p) <= constraint + 1e-8])
%timeit np.vstack(list(get_solution(unique_values, 5, 1)))
346 ms ± 29.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit get_solution_product(unique_values, 5, 1)
2.94 s ± 256 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)