递归计算集合成员的GCD

时间:2014-12-06 18:03:28

标签: python algorithm greatest-common-divisor

我们有一组正整数。

我们通过计算此集合中所有可能的整数对的最大公约数来创建一个新集合。

我们重做上述步骤,直到只有一个成员留在集合中。

是否有O(n)方法来计算此过程创建的新集合数以及最后一个集合中的成员是否为1?

一些python代码演示了我描述的过程。

from itertools import combinations
from fractions import gcd
import random

def gen_new_set(a):
    count = 0
    while len(a) != 0:
       print str(count)+':\t'+str(len(a))+'\t'+str(a)
       a = set(gcd(x[0], x[1]) for x in combinations(a,2))  
       count += 1

if __name__ == '__main__':
    a = set( random.sample(range(1,40), 10))
    gen_new_set(a)

1 个答案:

答案 0 :(得分:0)

没有。在第一次迭代中有O(n*n)对,并且它们中的任何一个都可能具有共同的素数因子,而这是其他地方共享的。所以一般来说,这是一个O(n*n)量的必要工作来区分集合S的数量为1或2。

当然,有一个O(n)算法可以找到整个集合的GCD,它会告诉你整个集合是否为1。

现在当你说"整数"时,任意整数都很难分解(密码学很好地利用了这个事实)。但是如果你的整数具有合理的大小,那么因子分解实际上是一种相当有效的操作,并且每个整数的素数因子很少。因此,作为预处理步骤,您可以存储数字与其分解的关系。然后创建一个哈希表,将每个素数p映射到它所分割的数字。而且现在很容易遍历素数,因为每个素数取出除去它的事物的子集,然后递归地计算那个素数。

此算法应该类似O(n*k + n*s),其中n是整数,k是将它们分解的平均成本,而s是您生成的子集数。对于位n和小整数,哪个比执行您描述的操作更有效。