在python中实现itertools.compositions计算多进程?

在python中实现itertools.compositions计算多进程?,python,decimal,multiprocessing,combinations,itertools,Python,Decimal,Multiprocessing,Combinations,Itertools,我正在使用这种算法对小数数组进行一些计算: fkn = Decimal('0') for bits in itertools.combinations(decimals_array, elements_count): kxn = reduce(operator.mul, bits, Decimal('1')) fkn += kxn 我使用的是Python 3.4 x64。 小数的精度大于300(这是必须的)。 len(十进制数组)在大多数情况下都超过40。 元素计数大部分时间为

我正在使用这种算法对小数数组进行一些计算:

fkn = Decimal('0')
for bits in itertools.combinations(decimals_array, elements_count):
    kxn = reduce(operator.mul, bits, Decimal('1'))
    fkn += kxn
我使用的是Python 3.4 x64。 小数的精度大于300(这是必须的)。 len(十进制数组)在大多数情况下都超过40。 元素计数大部分时间为len(小数数组)/2

计算需要很长时间。 我想让它们成为多进程的,所以首先我想制作一个包含所有组合的数组,并将该数组的一部分发送给多个进程——但在制作这样的数组的过程中,我很快就会遇到MemoryError异常

现在,我正在寻找更好的方法,使这段代码具有多进程性

在多核上运行此算法的好方法是什么?

或者也许有更好(更快)的方法来进行这样的计算


提前感谢您的一些想法。

为了真正实现并行化,您需要避免使用顺序的
组合()
,以便每个流程都可以生成自己的组合。问题的其余部分已经并行化了

40选择20大约是1380亿个组合,所以预先生成或在每个过程中生成它都会带来伤害。一个包含20个元素的列表大约需要224个字节(比如说
sys.getsizeof()
),如果你一次就生成了整个列表,那么这个列表大约需要30 TB。怪不得你的记性都用完了。您也不能在进程之间真正拆分生成器;或者更确切地说,如果您这样做,每个进程将获得自己的生成器副本

解决方案1是让一个进程的唯一任务是生成组合并将其推入队列,可能是成批地将其推入队列以节省IPC开销,并让其他进程使用该队列中的组合

解决方案2是编写一个非顺序版本的
组合
,返回第n个组合,而不计算其余组合。这是绝对可能的,因为它可能与排列,组合是一个内部排序的排列子集。然后,
池中的每个进程可以基于N的开始和步骤生成自己的进程-例如,进程一个计数组合
0、3、6…
,进程两个计数组合
1、4、7…
等等。除非使用C/Cython,否则这可能会更慢


解决方案3(或者可能是解决方案0?)是转到数学堆栈交换,询问这个问题是否有数学解决方案而不是计算解决方案。

我将尝试使用您的解决方案2,但稍作修改;我想我找到了一个解决方案,可以在多个进程之间“拆分”生成器。在Python3中,借助pickle和itertools.islice在某种程度上是可能的。我会在完成后发布我的结果。谢谢你的回答。你成功了吗?你公布结果了吗?@Deepstop我不知道这是否对你有帮助,但有一个函数
binom\u combi
,允许从选定的组合开始,它还具有一个特殊的计数方案,组合之间的单个位置不会假设>+/-1位置差。