Bir dizi doğal sayının maksimum ikili GCD'sini verimli bir şekilde bulma


9

Aşağıdaki sorunu düşünün:

İzin Vermek S={s1,s2,...sn} doğal sayıların sonlu bir alt kümesi olabilir.

İzin Vermek G={ gcd(si,sj) | si,sjS, sisj} nerede gcd(x,y) en büyük ortak bölen x ve y

Öğesinin maksimum öğesini bulun G.

Bu problem, Euclid'in algoritmasını kullanarak her bir çiftin en büyük ortak bölenini alarak ve en büyük olanı takip ederek çözülebilir.

Bunu çözmenin daha etkili bir yolu var mı?


3
Ps ve Q'larınızın Madenciliğinin 3.3 . GCD'leri çift olarak hesaplamak için bir algoritma tanımlarlar.O(nlgn)gcd'ler, belirli bir ortamda, ürün ağaçları ve kalan ağaçlar kullanılarak. Ama senin sorununun kapsamına girip girmediğini bilmiyorum.
DW

Asal çarpanlarına ayırma yöntemiyle bir şey denediniz mi?
Ryan

1
Tüm sayıların nispeten asal olduğunu ancak faktörlerinin zor olduğunu varsayalım (örneğin, her biri si eşittir piqi büyük farklı astarlar için pi,qi). Sonra tüm çiftli GCD'leri kontrol etmekten kaçınmak zor görünüyor. (Diyelim ki bütün çiftleri kontrol ettikten sonra(sn1,sn) tüm çift GCD'lerin 1. Nasıl tahmin edebilirsingcd(sn1,sn)hesaplamadan?)
usul

@usul DW'nin bağlantısı tam da bu problem. Bir milyar dolar gibi çok sayıda şifreleme anahtarının hepsi iki farklı asalın ürünü olmalıdır. Ancak bazı şifreleme anahtarlarının ortak bir ana faktöre sahip olduğundan şüpheleniyoruz (her iki anahtarın da gcd'si olacak ve her ikisinin de faktörleştirilmesini kolaylaştıracaktır). Bu algoritma n = 1 milyar için n (n-1) / 2 gcd'leri hesaplamadan ortak faktörlü anahtarları bulmanızı sağlar.
gnasher729

Yanıtlar:


-2

İşte verimli bir algoritma ( Python'da ). Lütfen aşağıdaki açıklamayı bulun.

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

Yukarıdaki kod snippet'inin açıklaması:

Bu problemde aşağıdakileri gözlemliyoruz:

  1. Sonuç daha fazla olamaz max(S)
  2. Sonuç, bu listede iki veya daha fazla kat içeren bir sayıdır S
  3. Aslında sonuç, maxyukarıda belirtilen özellik ile tüm bu sayıların sonucudur .

Bu gözlemlerle, program aşağıdakileri yapar:

  1. Bir olun setlistenin. Setler verimli bir şekilde aranabildiğindenO(log(n))
  2. Listenin maks. Değerini bulun ve değişkene kaydedin m.
  3. Başlayarak mkadar 1, sette iki veya daha fazla katları vardır ilk sayısını bulmak. Bulunan ilk sayı, sonuçtur.

Umarım açık olmuştur. Daha ayrıntılı bir açıklamaya ihtiyacınız varsa lütfen bize bildirin.


1
Algoritmanızı kelimelerle açıklayabilir misiniz? Bu bir programlama sitesi değil.
Yuval Filmus

@YuvalFilmus Açıklamayı ekledim. Bu yardımcı olur umarım.
Subhendu Ranjan Mishra

2
Tüm öğeler benzersizse ne olur? Bu, maksimum GCD'nin 1 olduğu anlamına gelmez. Örneğin,{2,4}, maksimum GCD 2'dir.
Yuval Filmus

Her için @YuvalFilmus iile başlayan mdek 1iki veya daha fazla olmadığını kontrol katları arasında igrubundad. Bu örnekte 2'nin iki katı '2 ve 4' kümesinde bulunur. böylece cevap 2'dir. İç whiledöngü m` ye ikadar olan tüm katları kontrol eder m' as , listenin maskesidir.
Subhendu Ranjan Mishra

1
Bu korkunç bir algoritma. İki sayılık bir dizi içinx,y uzunluk nHer biri bit olduğunda, GCD'nin hesaplanması polinom zaman alırken, algoritmanız en kötü durumda üstel zaman alır (sayılar nispeten prime olduğunda).
Yuval Filmus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.