有效地找到一组自然数的最大成对GCD


9

考虑以下问题:

令是自然数的有限子集。S={s1,s2,...sn}

令 | 其中是和最大公约数G={ gcd(si,sj)si,sjS, sisj}gcd(x,y)xy

找到的最大元素。G

这个问题可以通过使用Euclid算法获取每对最大公约数并跟踪最大对数来解决。

有更有效的解决方法吗?


3
您可能需要看一下挖掘P和Q:在网络设备中检测广泛的弱密钥的第3.3节(Heninger等,Usenix Security 2012)。他们描述了一种在特定设置下使用乘积树和余数树计算 gcd中成对gcd的算法。不过,我不知道它是否扩展到您的问题上。O(nlgn)
DW

您是否尝试过使用质分解进行任何操作?
Ryan

1
假设所有数字都是相对质数但很难(例如,对于大的不同质数每个等于)。那么似乎很难避免检查所有成对的GCD。(假设我告诉您,在检查了所有对之后,除了,所有成对的GCD都是如何计算而不计算出?)sipiqipi,qi(sn1,sn)1gcd(sn1,sn)
usul 2014年

@usul DW的链接正是这个问题。十亿个加密密钥应该都是两个不同素数的乘积。但是我们怀疑某些加密密钥具有共同的主要因素(这将是两个密钥的gcd,这使得两者都很容易分解)。该算法可让您找到具有公因数的密钥,而无需为n = 10亿计算n(n-1)/ 2 gcd。
gnasher729

Answers:


-2

这是一个高效的算法(在Python中)。请在下面找到说明。

def max_gcd_pair(S):
    # Assumption 1: S is the list of numbers
    # Assumption 2: There are no duplicates in S

    s = set(S)
    m = max(S)

    res = 0
    i = m

    while(i > 0):
        a = i
        cnt = 0
        while (a<=m): # a maxed at max of the list
            if a in s:   
               cnt += 1
            a += i

        if cnt >= 2:  # we have found the result
            res = i
            break

        i = i -1 

    return res

以上代码段的说明:

我们在此问题中观察到以下几点:

  1. 结果不能超过 max(S)
  2. 结果是一个数字,此列表中有两个或多个倍数 S
  3. 实际上,结果是max具有上述属性的所有此类数字。

基于这些观察,该程序执行以下操作:

  1. 做一个set清单。可以有效地搜索集合O(log(n))
  2. 找到列表的最大值并将其存储在变量中m
  3. m直到开始1,找到集合中具有两个或多个倍数的第一个数字。找到的第一个这样的数字是结果。

我希望这很清楚。如果您需要更详细的说明,请告诉我。


1
您可以用语言解释您的算法吗?这不是编程站点。
Yuval Filmus

@YuvalFilmus我已经添加了解释。希望这可以帮助。
Subhendu Ranjan Mishra'17年

2
如果所有元素都是唯一的怎么办?这并不意味着最大GCD是1。例如,考虑集合,其中最大GCD是2{2,4}
尤瓦Filmus

@YuvalFilmus每一个i有开始m,直到1我们检查,如果两个或更多倍数i一套中。在这个例子中,2的两个倍数在集合'2和4'中。因此答案是2。内部while循环检查i直到m' as m`是列表的masx的所有多重。
Subhendu Ranjan Mishra'17年

1
好吧,这是一个糟糕的算法。对于每个长度为位的两个数字的数组,计算GCD花费多项式时间,而在最坏的情况下(当数字相对质数时),算法花费指数时间。x,yn
Yuval Filmus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.