En Küçük Ortak Bölen Olmayan


11

Temel olarak, problem, bir dizi için S pozitif sayılar, minimum bir sayıda bulmak d herhangi bir elemanın bir bölen değildir S , yani xS, dx .

Göstermek n=|S|ve C=max(S) . F (x) = x'iF(x)= bölmeyen en küçük asal sayı işlevini düşünün . F (x) \ leq \ log x'ini görmek kolaydır . Ve bir dizi için S , let F (S) = hiçbir öğesini bölmez az asal S . Üst sınırımız varxF(x)logxSF(S)=S

F(S)F(lcm(S))F(Cn)nlogC.

Bu nedenle tüm numaraları sıralar basit bir kaba kuvvet algoritması, 1 ile nlogC o herhangi bir unsur bölmek değilse ve kontroller S , polinomdur ve zaman karmaşıklığı sahiptir O(n2logC) .

Sorunu çözmenin diğer yolu, S'nin her elemanı için tüm faktörleri hesaplamak Sve bunları kaba kuvvet algoritmasında kullanarak x'in O (1) zamanında xbir cevap olup olmadığını kontrol etmektir . Bu algoritma zaman karmaşıklığına O (n \ cdot \ min (\ sqrt {C}, n \ log C) + n \ log C) sahiptir ve O (n \ log C) belleği kullanır, çünkü n \ log C'den büyük mağaza faktörleri . Küçük n ve C için daha iyi performans gösterir.O(1)O(nmin(C,nlogC)+nlogC)O(nlogC)nlogCnC

Ayrıntılı olarak, algoritma iki bölümden oluşur:

  1. Bir dizi Construct S^ tüm elemanlarının tüm faktörler oluşan S örneğin,

    xS fnlogC, (fxfS^)
    Bu, O(nmin(C,nlogC)) zamanı ve O(nlogC) belleğinde yapılabilir. ? (Burada, bu herhangi bir element için gelen yapar S , biz tüm numaraları ile her iki test çarpanlara kullanarak faktör olabilir C ve tüm asal kadar nlogC hangisi daha küçükse; böylece her bir eleman S O (\ min (\ sqrt {C}, n \ log C)) zamanında Sfaktörlü olabilir .)O(min(C,nlogC))
  2. Minimum sayı bulun . Bu adım, in zamanda yapılıp yapılamayacağını kontrol ediyorsanız zamanı gerektirir.dS^O(|S^|)=O(nlogC)xS^O(1)

İlgilendiğim iki sorum var:

  1. Sorunu çözmek için daha hızlı bir algoritma var mı?
  2. Verilen ve , en küçük ortak bölen olmayan bir setini nasıl oluşturabiliriz ?nCS

1. "Precompute" ile kaba kuvvet algoritmasına başlamadan önce kastediyorum. 2. Faktoringin karmaşıklığı gerçekten de üsteldir, bkz. tanımı . C
SkyterX

@DW 2'de, faktoring karmaşıklığı sayıyı temsil eden bit dizisinin uzunluğu üzerinde üsteldir, ancak SkyterX bunun , yani boyutunun kare köküyle orantılı olduğunu doğru bir şekilde söylüyor . numara. O(C)
Lieuwe Vinkhuijzen

@LieuweVinkhuijzen, Bana doğru görünmüyor. GNFS kullanarak faktoring karmaşıklığı gibi bir şey olacaktır. . Bkz. En.wikipedia.org/wiki/… . O(exp{1.9(logC)1/3(loglogC)2/3})O(C)
DW

İkinci yöntemin "küçük ve " daha iyi performans gösterdiği ifadesi pek doğru değil. Yalnızca olduğunda daha iyi performans gösterir . Bu nedenle, daha iyi performans göstermesi için ikinci yöntemin büyük olması gerekir (küçük değil). nCnC/log(C)n
DW

@DW Haklısın, GNFS'nin karmaşıklığının farkında değildim.
Lieuwe Vinkhuijzen

Yanıtlar:


6

Tamsayı çarpanlarına ayırma için daha iyi algoritmalar kullanarak ikinci algoritmanızda iyileştirme yapmak mümkündür.

Burada tamsayı çarpanlarına ayırma için iki algoritma vardır:

  • GNFS , çalışma süresiyle bir tamsayıyı .CO(LC[0.33,1.92])

  • ECM , çalışma süresi bir faktör (varsa ; tüm faktörleri bulmak sürelerini alır (ECM'nin çalışma süresine kıyasla nispeten küçüktür).nlogCO(LnlogC[0.5,1.41])O(logC/log(nlogC))

Burada .Ln[α,c]=exp{c(logn)α(loglogn)1α}

Bu, çalışma süresi için oldukça korkunç görünümlü bir ifade, ancak önemli olan, bunun bahsettiğiniz yöntemlerden daha hızlı olmasıdır. Özellikle, asimptotik olarak den çok daha küçüktür , yani GNFS, olası tüm faktörleri denemekten çok daha hızlıdır . Ayrıca daha asimptotik çok daha küçük yani, ECM çok daha hızlı olası tüm faktörlerin çalışırken daha .LC[0.33,1.92]CCLnlogC[0.5,1.41]nlogCnlogC

Bu nedenle, bu yöntemin toplam çalışma süresi kabaca ve bu asimptotik olarak daha iyidir ilk yöntem ve asemptotik olarak ikinci yöntemden daha iyi. Daha iyisini yapmanın mümkün olup olmadığını bilmiyorum.O~(nmin(LC[0.33,1.92],LnlogC[0.5,1.41]))


Sanırım, bu sorun için herhangi bir hızlı algoritma, giriş kümesinin bir tür çarpanlarına ayırma işlemini içermelidir . Bu çarpanlara ayırma algoritmalarını kontrol edeceğim, ancak hala düzgün bir şekilde test etme sorunu var, ki bu da setini maksimum cevapla inşa etmekten bahsettiğim ikinci bir sorunu arttırıyor. SS
SkyterX

ECM verdiğiniz sürede bir faktör bulur . Bir sayının tüm faktörleri log n log C ise, C / log (n log C) sürelerine kadar algoritmayı tekrarlamanız gerekir.
gnasher729

3

En az ortak bölen olmayan N log C kadar büyük olabilir, ancak N sayıları rastgele dağıtılırsa, en az bölen olmayan bölen muhtemelen çok daha küçüktür, muhtemelen N'den çok daha azdır. asal sayılar hangi bölenlerdir.

Her asal sayı p için, bir endekse olan tüm sayıların p ile bölünebilirlik açısından incelendiği anlamına gelen bir indeksine sahibiz ve tarafından bölünebilen tüm sayıların bir listesine sahibiz.kp

Sonra d = 2, 3, 4, ... için d ile bölünebilir bir sayı bulmaya çalışırız veya hiç yok. D'nin en büyük asal çarpanını p alıyoruz. Sonra, p ile bölünebilen tüm sayıları d ile bölünüp bölünmediğini kontrol ederiz. Hiçbiri bulunamazsa, p ile bölünebilirlik, ve p ile bölünebilen sayıların listesi ve her sayının d ile bölünebilir olup olmadığını kontrol eden indeksler> olan diğer sayıları kontrol ederiz .kpkp

P ile bölünebilir bir sayı olup olmadığını kontrol etmek için ortalama p sayılarını kontrol ederiz. Daha sonra 2p ile bölünebilir bir sayı olup olmadığını kontrol edersek, sadece bir sayıyı (p ile bölünebilir olan) kontrol etme ihtiyacımız% 50 ve ortalama 2p daha fazla sayıyı kontrol etme şansımız% 50'dir. 3p ile bölünebilir bir sayı bulmak oldukça hızlıdır ve bu şekilde devam eder ve asla p ile bölünebilirlik için N'den fazla sayı kontrol etmeyiz, çünkü sadece N sayıları vardır.

Bu bölünebilirlik kontrolleri ile çalışır umuyoruz .N2/logN

PS. Rasgele sayılar için sonuç ne kadar büyük olurdu?

N rasgele sayım olduğunu varsayalım. N numaralarından birinin d ile bölünebilme olasılığı 1 - (1 - 1 / d) ^ N'dir. 1 ≤ d ≤ k sayılarının her birinin rastgele sayılardan birinin bir faktörü olması olasılığını varsayıyorum (bu olasılıkların oldukça bağımsız olmadığı için tamam, bu biraz tehlikeli değil).

Bu varsayımla, N = 1000 ile, 1..244 rakamlarından birinin herhangi bir rakamı bölmeme şansı% 50 ve 507'ye kadar olan her rakamın rakamlardan birini bölme milyarda bir şans vardır. N = 10.000 ile 1..1726 rakamlarından birinin herhangi bir rakamı bölmemesi ve 2979'a kadar olan her sayının rakamlardan birini bölmesi milyarda bir şans% 50'dir.

N rasgele girişler için, sonucun boyutunun N / ln N'den biraz daha büyük olmasını öneriyorum; belki N / ln N * (ln ln N) ^ 2 gibi bir şey olabilir. İşte nedeni:

N rasgele sayıdan en az birinin rasgele d ile bölünebilme olasılığı . D N civarındaysa, o zaman yaklaşık 1 - exp (-1) ≈ 0.6321'dir. Bu tek bir bölen için; d-N sayısının her birinin N sayısından en az birinin bölücü olması ihtimali oldukça incedir, bu nedenle maksimum d N'den önemli ölçüde küçük olacaktır.1(11/d)N1(11/d)N

D << N ise, .1(11/d)N1exp(N/d)

D ≈ N / N ln sonra ise .1exp(N/d)1exp(lnN)=11/N

Bu olasılıkları yaklaşık N / ln N değerleri d için ekleriz, ancak çoğu d için sonuç önemli ölçüde daha büyük olacaktır, bu nedenle en büyük d, bir şekilde N / ln N'den daha büyük, ancak N'den önemli ölçüde daha küçük olacaktır.

PS. D ile bölünebilir bir sayı bulma:

D'nin en büyük asal faktörünü seçiyoruz ve sonra önce p ile bölünebilir olduğu bilinen sayıları inceliyoruz. D = kp deyin. Daha sonra ortalama olarak sadece bu belirli d'yi kontrol ederken p ile bölünebilen k sayılarını kontrol ederiz ve en fazla tüm N değerlerini p ile bölünebilirlik açısından, p ile bölünebilen tüm d için kontrol ederiz. Aslında, çoğu prim p için N değerinden daha azını kontrol ediyoruz, çünkü tüm N değerlerini kontrol ettikten sonra algoritma büyük olasılıkla sona erer. Sonuç R ise, o zaman N değerinin daha azının her bir asal değerin R'den daha az bölünmesini beklerim. R ≤ N varsayıldığında, bu N ^ 2 / log N kontrolleri ile ilgilidir.

PS. Bazı testleri çalıştırma

Bu algoritmayı birkaç kez N = 1.000.000 rasgele sayılar> 0 ile çalıştırdım. En az ortak bölen olmayan 68.000 ile 128.000 arasındaydı ve büyük çoğunluğu 100.000 ile 120.000 arasındaydı. Bölüm sayısı 520 milyon ile 1800 milyon arasındaydı ve bu da (N / ln N) ^ 2'den çok daha azdı; davaların çoğunluğu 1000 ile 1500 milyon arasında bölünmüştü.

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.