Effizientes Finden der maximalen paarweisen GCD eines Satzes natürlicher Zahlen

9

Betrachten Sie das folgende Problem:

Sei eine endliche Teilmenge der natürlichen Zahlen.S.={s1,s2,...sn}}

Sei | wobei der größte gemeinsame Teiler von undg c d ( s i , s j ) s i , s jS , s is j } g c d ( x , y ) x yG={ Gcd(sich,sj)sich,sjS., sichsj}}Gcd(x,y)xy

Finden Sie das maximale Element von .G

Dieses Problem kann gelöst werden, indem der größte gemeinsame Teiler jedes Paares unter Verwendung des Euklid-Algorithmus genommen und der größte verfolgt wird.

Gibt es eine effizientere Möglichkeit, dies zu lösen?

Tommy
quelle
3
Vielleicht möchten Sie einen Blick auf Abschnitt 3.3 des Mining Ihrer Ps und Qs werfen : Erkennung weit verbreiteter schwacher Schlüssel in Netzwerkgeräten (Heninger et al., Usenix Security 2012). Sie beschreiben einen Algorithmus zum Berechnen paarweiser GCDs in GCDs in einer bestimmten Einstellung unter Verwendung von Produktbäumen und Restbäumen. Ich weiß jedoch nicht, ob es sich auf Ihr Problem erstreckt. Ö(nlgn)
DW
Haben Sie etwas mit Primfaktoren versucht?
Ryan
1
Angenommen, alle Zahlen sind relativ prim, aber schwer zu (z. B. ist jedes gleich für große unterschiedliche Primzahlen ). Dann scheint es schwierig zu sein, nicht alle paarweisen GCDs zu überprüfen. (Angenommen, ich sage Ihnen, dass nach Überprüfung aller Paare, aber alle paarweisen GCDs . Wie können Sie erraten ohne es zu berechnen?)sichpiqipi,qi(sn1,sn)1gcd(sn1,sn)
Usul
Der Link von @usul DW ist genau dieses Problem. Eine große Anzahl von beispielsweise einer Milliarde Verschlüsselungsschlüsseln sollte aus zwei unterschiedlichen Primzahlen bestehen. Wir vermuten jedoch, dass einige Verschlüsselungsschlüssel einen gemeinsamen Hauptfaktor haben (dies wäre die GCD beider Schlüssel, wodurch beide leicht zu faktorisieren sind). Mit diesem Algorithmus können Sie die Schlüssel mit dem gemeinsamen Faktor finden, ohne n (n-1) / 2 gcd für n = 1 Milliarde zu berechnen.
Gnasher729

Antworten:

-2

Hier ist ein effizienter Algorithmus (in Python ). Die Erklärung finden Sie unten.

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

Erläuterung des obigen Codeausschnitts:

Bei diesem Problem stellen wir Folgendes fest:

  1. Das Ergebnis kann nicht mehr als sein max(S)
  2. Das Ergebnis ist eine Zahl, die zwei oder mehr Vielfache in dieser Liste enthält S
  3. Tatsächlich ist das Ergebnis maxall dieser Zahlen mit der oben erwähnten Eigenschaft.

Mit diesen Beobachtungen führt das Programm Folgendes aus:

  1. Machen Sie eine setaus der Liste. As Sets können effizient in gesucht werdenO(log(n))
  2. Suchen Sie das Maximum der Liste und speichern Sie es in der Variablen m.
  3. Suchen Sie von mbis bis 1zur ersten Zahl, die zwei oder mehr Vielfache im Satz enthält. Die erste gefundene Zahl ist das Ergebnis.

Ich hoffe das ist klar. Bitte lassen Sie mich wissen, wenn Sie eine ausführlichere Erklärung benötigen.

Subhendu Ranjan Mishra
quelle
1
Können Sie Ihren Algorithmus in Worten erklären? Dies ist keine Programmierseite.
Yuval Filmus
@ YuvalFilmus Ich habe die Erklärung hinzugefügt. Hoffe das hilft.
Subhendu Ranjan Mishra
2
{2,4}}
@YuvalFilmus für jeden iBeginn mit mbis 1wir prüfen, ob zwei oder mehr Vielfache von iim Set sind. In diesem Beispiel befinden sich zwei Vielfache von 2 in der Menge '2 und 4'. Die Antwort lautet also 2. Die innere whileSchleife überprüft alle Vielfachen von ibis m' as m` ist der Masx der Liste.
Subhendu Ranjan Mishra
1
x,yn