Trouver efficacement le GCD par paire maximum d'un ensemble de nombres naturels

9

Considérez le problème suivant:

Soit un sous-ensemble fini des nombres naturels.S={s1,s2,...sn}

Soit | où est le plus grand diviseur commun de etG={ gcd(si,sj)si,sjS, sisj}gcd(x,y)xy

Trouver l'élément maximum de .g

Ce problème peut être résolu en prenant le plus grand diviseur commun de chaque paire en utilisant l'algorithme d'Euclide et en gardant une trace du plus grand.

Existe-t-il un moyen plus efficace de résoudre ce problème?

Tommy
la source
3
Vous voudrez peut-être jeter un oeil à la section 3.3 de l' exploration de vos ps et Qs: détection des clés faibles généralisées dans les périphériques réseau (Heninger et al, Usenix Security 2012). Ils décrivent un algorithme pour calculer les gcd par paire dans les gcd , dans un certain contexte, en utilisant des arbres de produits et des arbres restants. Je ne sais pas si cela s'étend à votre problème. O(nlgn)
DW
Avez-vous essayé quelque chose avec des factorisations principales?
Ryan
1
Supposons que tous les nombres soient relativement premiers mais difficiles à factoriser (par exemple, chaque est égal à p i q i pour les grands nombres premiers distincts p i , q i ). Il semble alors difficile d'éviter de vérifier tous les GCD par paire. (Supposons que je vous dis qu'après avoir vérifié toutes les paires mais ( s n - 1 , s n ) que tous les GCD par paire sont 1. Comment pourriez-vous deviner g c d ( s n - 1 , s n ) sans le calculer?)sipiqipi,qi(sn1,sn)1gcd(sn1,sn)
usul
Le lien de @usul DW est exactement ce problème. Un grand nombre, disons un milliard, de clés de chiffrement devraient toutes être le produit de deux nombres premiers distincts. Mais nous soupçonnons que certaines clés de chiffrement ont un facteur premier en commun (qui serait le gcd des deux clés, ce qui rend les deux faciles à factoriser). Cet algorithme vous permet de trouver les clés avec un facteur commun sans calculer n (n-1) / 2 pgc pour n = 1 milliard.
gnasher729

Réponses:

-2

Voici un algorithme efficace (en Python ). Veuillez trouver l'explication ci-dessous.

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

Explication de l'extrait de code ci-dessus:

Nous observons ce qui suit dans ce problème:

  1. Le résultat ne peut être supérieur à max(S)
  2. Le résultat est un nombre, qui a deux ou plusieurs multiples dans cette liste S
  3. En fait, le résultat est maxde tous ces numéros avec la propriété mentionnée ci-dessus.

Avec ces observations, le programme fait ce qui suit:

  1. Faites un setde la liste. Comme les ensembles peuvent être recherchés efficacement dansO(log(n))
  2. Trouvez le maximum de la liste et stockez-le dans la variable m.
  3. À partir de mjusqu'à 1, trouvez le premier nombre qui a deux ou plusieurs multiples dans l'ensemble. Le premier tel nombre trouvé est le résultat.

J'espère que cela est clair. Veuillez me faire savoir si vous avez besoin d'une explication plus détaillée.

Subhendu Ranjan Mishra
la source
1
Pouvez-vous expliquer votre algorithme avec des mots? Ce n'est pas un site de programmation.
Yuval Filmus
@YuvalFilmus J'ai ajouté l'explication. J'espère que cela t'aides.
Subhendu Ranjan Mishra
2
{2,4}
@YuvalFilmus pour chaque idébut avec mjusqu'à ce que 1nous vérifions si deux ou plusieurs multiples de isont dans l'ensemble. Dans cet exemple, deux multiples de 2 sont dans l'ensemble «2 et 4». donc la réponse est 2. La whileboucle interne vérifie tous les multples de itill m' as m` est le masx de la liste.
Subhendu Ranjan Mishra
1
X,yn