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 ∀x∈S, d∤x .

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)≤log⁡xSF(S)=S

F(S)≤F(lcm⁡(S))≤F(Cn)≤nlog⁡C.

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

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(n⋅min(C,nlog⁡C)+nlog⁡C)O(nlog⁡C)nlog⁡CnC

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,

    ∀x∈S ∀f≤n⋅log⁡C, (f∣x→f∈S^)
    Bu, O(n⋅min(C,nlog⁡C)) zamanı ve O(nlog⁡C) 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 nlog⁡C 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,nlog⁡C))
  2. Minimum sayı bulun . Bu adım, in zamanda yapılıp yapılamayacağını kontrol ediyorsanız zamanı gerektirir.d∉S^O(|S^|)=O(nlog⁡C)x∈S^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(log⁡C)1/3(log⁡log⁡C)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). nCn≫C/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).≤nlog⁡CO(Lnlog⁡C[0.5,1.41])O(log⁡C/log⁡(nlog⁡C))

Burada .Ln[α,c]=exp⁡{c(log⁡n)α(log⁡log⁡n)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]C≤CLnlog⁡C[0.5,1.41]nlog⁡C≤nlog⁡C

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],Lnlog⁡C[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−(1−1/d)N1−(1−1/d)N

D << N ise, .1−(1−1/d)N≈1−exp(−N/d)

D ≈ N / N ln sonra ise .1−exp(−N/d)≈1−exp(−lnN)=1−1/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.