首页 > 解决方案 > 不包括项目的高效笛卡尔积

问题描述

我试图让 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)

上面的解决方案可行,但需要太多时间。此外,在这种情况下,我必须定期将“lst”保存到磁盘中并释放内存以避免任何内存错误。后一部分很好,但代码需要几天(或几周)才能完成。

有没有其他选择?

标签: pythonitertoolscartesian-product

解决方案


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

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))
g = get_solution(unique_values, 4, 1)
for _ in range(5):
    print(next(g))

印刷

[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])
%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)

推荐阅读