以分布式方式枚举组合

时间:2011-01-15 08:15:37

标签: c++ algorithm distributed combinatorics hpc

我有一个问题,我必须分析500C5组合(255244687600)的东西。将其分布在10个节点的集群中,每个集群每秒处理大约10 ^ 6个组合,这意味着该作业将在大约7个小时内完成。

我遇到的问题是在10个节点上分发255244687600组合。我想给每个节点提供25524468760,但是我使用的算法只能顺序生成组合,我希望能够传递元素集和一系列组合指标,例如,[0 -10 ^ 7),[10 ^ 7,2.0 10 ^ 7]等,并让节点自己找出组合。

我目前使用的算法来自以下内容:

我考虑过使用一个主节点,它枚举每个组合并将工作发送到每个节点。但是,从单个节点迭代组合并来回通信工作所产生的开销是巨大的,并且随后会导致主节点成为瓶颈。

是否有任何良好的组合迭代算法可以实现有效/最佳的分布式枚举?

3 个答案:

答案 0 :(得分:3)

combinatorial numbers您可能会取得一些成功,它可以让您检索 N '( n / 10th) k - 用简单的算法组合;然后在十个节点中的每个节点上运行next_combination算法 n / 10次以进行迭代。

示例代码(在C#中,但对于C ++程序员来说非常易读)可以在MSDN找到。

答案 1 :(得分:0)

从第n个开始,每十个组合都有一个节点号n进程。

答案 2 :(得分:0)

我知道这个问题已经过时了,但这是如何有效地完成的。

目前使用Python的所有代码,我相信它很容易转换为C ++。
- 您可能希望从使用特征向量的整数转换为使用位数组,因为整数使用将需要500位(在Python中不是问题)
- 随意更新到C ++任何人。

  1. 向节点分配其组合范围(start数字和要处理的length),要从中选择组合的items集合,以及数字{{ 1}},要选择的项目。
  2. 通过直接从kstart找到其初始组合来初始化每个节点。
  3. 运行每个节点,让它为第一个组合完成工作,然后迭代其余的组合,并完成相关的工作。
  4. 要执行 1 ,请按照建议找到n-choose-k并将其划分为范围 - 在您的情况下,500-Choose-5就像您所说的255244687600所以,对于node = 0到9你分发:
    items

    要执行 2 ,您可以使用组合数系统直接找到起始组合(不进行迭代),并找到组合特征向量的整数表示(用于中的迭代) 3 )同时:

    (start=node*25524468760, length=25524468760, items=items, k=5)

    特征向量的整数表示在组成组合的项目的位置设置了k位。

    要执行 3 ,您可以使用Gosper的hack迭代到相同数字系统中组合的下一个特征向量(下一个组合将出现在相对于反向排序组合的排序列表中def getCombination(index, items, k): '''Returns (combination, characteristicVector) combination - The single combination, of k elements of items, that would be at the provided index if all possible combinations had each been sorted in descending order (as defined by the order of items) and then placed in a sorted list. characteristicVector - an integer with chosen item's bits set. ''' combination = [] characteristicVector = 0 n = len(items) nCk = 1 for nMinusI, iPlus1 in zip(range(n, n - k, -1), range(1, k + 1)): nCk *= nMinusI nCk //= iPlus1 curIndex = nCk for k in range(k, 0, -1): nCk *= k nCk //= n while curIndex - nCk > index: curIndex -= nCk nCk *= (n - k) nCk -= nCk % k n -= 1 nCk //= n n -= 1 combination .append(items[n]) characteristicVector += 1 << n return combination, characteristicVector )并同时创建组合:

    items

    重复此def nextCombination(items, characteristicVector): '''Returns the next (combination, characteristicVector). combination - The next combination of items that would appear after the combination defined by the provided characteristic vector if all possible combinations had each been sorted in descending order (as defined by the order of items) and then placed in a sorted list. characteristicVector - an integer with chosen item's bits set. ''' u = characteristicVector & -characteristicVector v = u + characteristicVector if v <= 0: raise OverflowError("Ran out of integers") # <- ready for C++ characteristicVector = v + (((v ^ characteristicVector) // u) >> 2) combination = [] copiedVector = characteristicVector index = len(items) - 1 while copiedVector > 0: present, copiedVector = divmod(copiedVector, 1 << index) if present: combination.append(items[index]) index -= 1 return combination, characteristicVector 次(因为您已经直接找到了第一个)。

    例如:

    五个节点处理7-choose-3字母:

    length-1