Python - 仅在条件适用时才进行组合

时间:2015-02-03 14:06:04

标签: python math combinations combinatorics

假设我有一个庞大的元组列表:

tuples = ([1, 2], [2, 1], [3, 2], [25, 73], [1, 3]...)

此列表截至目前有360000个元素(它们是一个互质数字列表)。我需要组合3个元组,这样每个组合只有3个不同的数字,例如:

([2, 1], [3, 1], [3, 2])
([2, 1], [5, 1], [5, 2])

我需要在生成组合列表时丢弃包含4个或更多不同数字的组合。

如果我尝试强制执行此操作并测试每个组合,我最终会使用360000 choose 3 7.77 * 10^15可能的组合进行测试。

编辑: 我想解决的问题是:

在表单中找到所有互质对的组合:

(a, b), (a, c), (b, c)

对于c< 120000

我采取的步骤:

  1. 为所有Coprime对生成三元树,其中数字小于120000
  2. (问题 - 生成组合,强制它赢了)

2 个答案:

答案 0 :(得分:4)

让我们制作一个集合的字典,将所有较大的元素映射到元组中较小的元素:

d = {}
for tup in tuples:
    # here you may limit max(tup) to 120000
    d.setdefault(min(tup), set()).add(max(tup))

# {1: {2, 3}, 2: {3}, 25: {73}}

这也消除了所有对称对:(1, 2), (2, 1)

然后搜索所有工作组合:

for a, bc in d.iteritems():
    for b, c in it.combinations(sorted(bc), 2):
        if b in d and c in d[b]:
            print(a, b, c) # or yield or append to a list

应该比你的蛮力更快......

答案 1 :(得分:1)

for a in range(1, 120000):
  for b in range(a+1, 120000):
    if (gcd(a, b) > 1):
      continue;
    for c in range(b+1, 120000):
      if (gcd(a, c) = 1 and gcd(b, c) = 1):
        print (a, b, c)

当N = 120000时,这需要大约N ^ 3 / pi ^ 2的时间。对所有元组进行强力检查需要N ^ 6/48的时间,因此速度要快得多 - 大约快3 * 10 ^ 14倍。