Öklid Algoritmasının zaman karmaşıklığı


101

Öklid'in en büyük ortak payda algoritmasının zaman karmaşıklığının ne olduğuna karar vermekte güçlük çekiyorum. Sözde koddaki bu algoritma:

function gcd(a, b)
    while b ≠ 0
       t := b
       b := a mod b
       a := t
    return a

A ve b'ye bağlı görünüyor . Benim düşünceme göre zaman karmaşıklığı O (a% b). Bu doğru mu? Bunu yazmanın daha iyi bir yolu var mı?


14
Bkz. Knuth TAOCP, 2. Cilt - kapsamlı bir haber veriyor . Sadece FWIW, birkaç haber: orantılı değil a%b. En kötü durumda ave bardışık Fibonacci sayıları.
Jerry Coffin

3
@JerryCoffin Not: Eğer en kötü durumun gerçekten de Fibonacci sayıları olduğunu ispatlamak istiyorsanız, sonlandırmadan önce n'inci adımın en az matematiksel tümevarım ile n'inci Fibonacci sayısının gcd katı kadar büyük olması gerektiğini kanıtlamayı düşünün.
Mygod

Yanıtlar:


75

Öklid algoritmasının zaman karmaşıklığını analiz etmenin bir püf noktası, iki yinelemede neler olduğunu takip etmektir:

a', b' := a % b, b % (a % b)

Şimdi a ve b tek bir yerine azalacak ve bu da analizi kolaylaştıracak. Bunu vakalara ayırabilirsiniz:

  • Küçük A: 2a <= b
  • Küçük B: 2b <= a
  • Küçük A: 2a > bamaa < b
  • Küçük B: 2b > aamab < a
  • Eşit: a == b

Şimdi her bir vakanın toplamı a+ben az dörtte bir azalttığını göstereceğiz :

  • Tiny A: b % (a % b) < ave 2a <= bbu nedenle ben az yarı yarıya a+bazalır , bu nedenle en az25%
  • Küçük B: a % b < bve 2b <= abu nedenle aen az yarı yarıya a+bazalır , bu nedenle en az25%
  • Küçük A: bolur b-adaha az olan b/2azalan, a+ben azından tarafından 25%.
  • Küçük B: aolur a-bdaha az olan a/2azalan, a+ben azından tarafından 25%.
  • Eşit: en azından açık bir şekilde azalmakta olan a+bdüşüyor .0a+b25%

Bu nedenle, vaka analizi ile her çift adım a+ben az azalır 25%. a+bAşağıya düşmeye zorlanmadan önce bunun gerçekleşebileceği maksimum sayı vardır 1. S0'a ulaşana kadar toplam adım sayısı ( ) karşılanmalıdır (4/3)^S <= A+B. Şimdi sadece çalışın:

(4/3)^S <= A+B
S <= lg[4/3](A+B)
S is O(lg[4/3](A+B))
S is O(lg(A+B))
S is O(lg(A*B)) //because A*B asymptotically greater than A+B
S is O(lg(A)+lg(B))
//Input size N is lg(A) + lg(B)
S is O(N)

Dolayısıyla, yineleme sayısı, giriş basamaklarının sayısında doğrusaldır. Cpu yazmaçlarına uyan sayılar için, yinelemeleri sabit zamanlı olarak modellemek ve gcd'nin toplam çalışma süresinin doğrusal olduğunu varsaymak mantıklıdır .

Elbette, büyük tam sayılarla uğraşıyorsanız, her yinelemedeki modül işlemlerinin sabit bir maliyeti olmadığı gerçeğini hesaba katmalısınız. Kabaca konuşursak, toplam asimptotik çalışma süresi bir polilogaritmik faktörün n ^ 2 katı olacaktır. Gibi bir şey n^2 lg(n) 2^O(log* n) . Polilogaritmik faktör, bunun yerine ikili bir gcd kullanılarak önlenebilir .


Lütfen neden "b% (a% b) <a" olduğunu açıklar mısınız?
Michael Heidelberg

3
@MichaelHeidelberg x % y, daha fazla olamaz xve daha az olmalıdır y. Yani a % ben fazla olduğu azorlayarak, b % (a%b)en fazla bir şey altında olması adolayısıyla ve daha genel olarak daha az olduğu a.
Craig Gidney

@ Cheersandhth.-Alf Tercih edilen terminolojideki küçük bir farkın "ciddi şekilde yanlış" olduğunu mu düşünüyorsunuz? Tabii ki CS terminolojisini kullandım; bu bir bilgisayar bilimi sorusu. Her şeye rağmen, "basamak sayısı" cevabını netleştirdim.
Craig Gidney

@CraigGidney: Bunu düzelttiğiniz için teşekkürler. Şimdi, tamamen akademisyenler tarafından yazılan birçok Wikipedia makalesinden iletişim problemini tanıyorum. Şunu bir düşünün: Yorumumda yaptığım gibi, sadece O (log (min (a, b)) yazmak yerine, rakamların sayısından bahsetmenin ana nedeni, matematiksel olmayan kişiler için şeyleri daha kolay anlaşılır hale getirmektir. endişe sadece var vs. “log”, So yazma amaçlı ne zaman. o meydan millet yardımcı basamak sayısının, isim bu kavramı “boyutu” ve diğer yerlerde tanımı var ve en “log” hakkında konuşmak yok sonunda, yardım etmek yerine belirsizleşiyorsun.
Şerefe ve hth. - Alf

Son paragraf yanlış. İlgili teleskop serisini toplarsanız, okul kitabındaki ikinci dereceden zaman bölme algoritmasını kullansanız bile, zaman karmaşıklığının sadece O (n ^ 2) olduğunu göreceksiniz.
Emil Jeřábek

28

Bir algoritmayı analiz etmenin uygun yolu, en kötü durum senaryolarını belirlemektir. Öklid GCD'sinin en kötü durumu, Fibonacci Çiftleri dahil olduğunda ortaya çıkar. void EGCD(fib[i], fib[i - 1]), nerede i> 0.

Örneğin, temettünün 55 ve bölenin 34 olduğu durumu seçelim (hala fibonacci sayılarıyla uğraştığımızı hatırlayın).

görüntü açıklamasını buraya girin

Fark edebileceğiniz gibi, bu işlem 8 iterasyona (veya yinelemeli çağrılara) mal oldu.

Daha büyük Fibonacci sayıları, yani 121393 ve 75025 deneyelim. Burada 24 yineleme (veya özyinelemeli çağrı) aldığını da görebiliriz.

görüntü açıklamasını buraya girin

Her yinelemenin bir Fibonacci numarası verdiğini de fark edebilirsiniz. Bu yüzden bu kadar çok operasyonumuz var. Gerçekten de sadece Fibonacci sayılarıyla benzer sonuçlar elde edemeyiz.

Dolayısıyla, zaman karmaşıklığı bu sefer küçük Oh (üst sınır) ile temsil edilecek. Alt sınır sezgisel olarak Omega (1) 'dir: örneğin 500 bölü 2 durumu.

Tekrarlama ilişkisini çözelim:

görüntü açıklamasını buraya girin

Öklid GCD'nin en fazla log (xy) işlemi yapabildiğini söyleyebiliriz .


2
Bu analizin yanlış olduğunu düşünüyorum çünkü temel, girdiye bağlı.
HopefullyHelpful

Bağımlı bir tabanın bir sorunu temsil ettiğini kanıtlayabilir misiniz?
Mohamed Ennahdi El Idrissi

1
Temel, tabii ki altın orandır. Neden? Çünkü nod (13,8) ile nod (8,5) arasındaki farkı hesaplamak için fazladan bir adım gerekir. Sabit bir x için, y <x ise en kötü durum performansı x = fib (n + 1), y = fib (n) 'dir. Burada y x'e bağlıdır, bu yüzden sadece x'e bakabiliriz.
Stepan

17

Wikipedia makalesinde buna harika bir bakış var .

Hatta değer çiftleri için güzel bir karmaşıklık planına sahiptir.

O değil O(a%b) .

Hiçbir zaman küçük sayıdaki basamak sayısının beş katından fazla adım atmayacağı bilinmektedir (makaleye bakın). Böylece maksimum adım sayısı basamak sayısı arttıkça artar (ln b). Her adımın maliyeti de basamak sayısı arttıkça artar, bu nedenle karmaşıklık O(ln^2 b)b'nin daha küçük sayı olduğu yere bağlıdır . Bu bir üst sınırdır ve gerçek süre genellikle daha azdır.


Neyi ntemsil ediyor?
IVlad

@IVlad: Basamak sayısı. Cevabı netleştirdim, teşekkür ederim.
JoshD

OP'nin algoritması için, (büyük tamsayı) bölmeleri kullanmak (ve çıkarmaları değil) aslında O (n ^ 2 log ^ 2n) gibi bir şeydir.
Alexandre C.

@Alexandre C .: Unutmayın n = ln b. Big int için modülün düzenli karmaşıklığı nedir? O mu (log n log ^ 2 log n)
JoshD

@JoshD: böyle bir şey, sanırım bir log n terimini kaçırdım, son karmaşıklık (bölünmeli algoritma için) bu durumda O (n ^ 2 log ^ 2 n log n).
Alexandre C.

13

Buraya bakın .

Özellikle bu kısım:

Lamé, n'den küçük iki sayı için en büyük ortak bölene ulaşmak için gereken adım sayısının

alternatif metin

Yani O(log min(a, b))üst bağlanmış bir iyidir.


4
Bu adım sayısı için doğrudur, ancak basamak sayısıyla (ln n) ölçeklenen her adımın karmaşıklığını hesaba katmaz.
JoshD

9

İşte Euclid algoritmasının çalışma zamanı karmaşıklığının sezgisel olarak anlaşılması. Biçimsel kanıtlar, Algoritmalara Giriş ve TAOCP Cilt 2 gibi çeşitli metinlerde ele alınmıştır.

Önce iki Fibonacci sayısı F (k + 1) ve F (k) olan gcd'yi almaya çalışırsak ne olduğunu düşünün. Euclid'in algoritmasının F (k) ve F (k-1) 'e yinelendiğini hemen gözlemleyebilirsiniz. Yani, her yinelemede Fibonacci serisinde bir sayı aşağıya iniyoruz. Phi'nin altın oran olduğu Fibonacci sayıları O (Phi ^ k) olduğundan, OBEB'in çalışma zamanının O (log n) olduğunu görebiliriz, burada n = max (a, b) ve log Phi tabanına sahiptir. Daha sonra, Fibonacci sayılarının tutarlı bir şekilde, kalanların her yinelemede yeterince büyük kaldığı ve serinin başlangıcına gelene kadar asla sıfır olmadığı çiftler ürettiğini gözlemleyerek bunun en kötü durum olacağını kanıtlayabiliriz.

O (log n) 'yi n = max (a, b)' nin daha sıkı bağlanması durumunda yapabiliriz. B> = a olduğunu varsayalım, böylece O (log b) 'ye sınır yazabiliriz. Önce OBEB (ka, kb) = OBEB (a, b) olduğuna dikkat edin. K'nin en büyük değerleri gcd (a, c) olduğu için, çalışma zamanımızda b'yi b / gcd (a, b) ile değiştirebiliriz ve bu da O'nun daha sıkı sınırına (log b / gcd (a, b)) yol açar.


Fibonacci no'larının Öklidler algo için en kötü durumu oluşturduğuna dair resmi bir kanıt verebilir misiniz?
Akash

4

Öklid Algoritmasının en kötü durumu, kalanların her adımda mümkün olan en büyük olduğu zamandır, yani. Fibonacci dizisinin iki ardışık terimi için.

N ve m, a ve b'nin basamak sayısı olduğunda, n> = m varsayılarak, algoritma O (m) bölümlerini kullanır.

Karmaşıklıkların her zaman girdi boyutları , bu durumda basamak sayısı cinsinden verildiğini unutmayın .


4

En kötü durum, hem n hem de m ardışık Fibonacci sayıları olduğunda ortaya çıkar.

gcd (Fn, Fn − 1) = gcd (Fn − 1, Fn − 2) = ⋯ = gcd (F1, F0) = 1 ve n'inci Fibonacci sayısı 1.618 ^ n'dir, burada 1.618 Altın orandır.

Yani, gcd (n, m) 'yi bulmak için, özyinelemeli çağrıların sayısı Θ (logn) olacaktır.


3

İşte kitabın içinde analizidir C Veri Yapıları ve Algoritma Analizi ile Mark Allen Weiss (ikinci baskı, 2.4.4):

Öklid'in algoritması, 0'a ulaşılana kadar kalanları sürekli olarak hesaplayarak çalışır. Son sıfır olmayan kalan cevaptır.

İşte kod:

unsigned int Gcd(unsigned int M, unsigned int N)
{

    unsigned int Rem;
    while (N > 0) {
        Rem = M % N;
        M = N;
        N = Rem;
    }
    Return M;
}

İşte kullanacağımız bir TEOREM :

Eğer M> K, daha sonra M mod N <M / 2.

KANIT:

İki durum var. N <= M / 2 ise, kalan kısım N'den küçük olduğundan teorem bu durum için doğrudur. Diğer durum N> M / 2'dir. Ama sonra N, teoremi kanıtlayan, kalan M - N <M / 2 ile M'ye gider.

Böylece şu çıkarımı yapabiliriz:

Variables    M      N      Rem

initial      M      N      M%N

1 iteration  N     M%N    N%(M%N)

2 iterations M%N  N%(M%N) (M%N)%(N%(M%N)) < (M%N)/2

Bu nedenle, iki yinelemeden sonra kalan, orijinal değerinin en fazla yarısı kadardır. Bu, yineleme sayısının en fazla olduğunu gösterir 2logN = O(logN).

Algoritmanın, M> = N varsayılarak Gcd (M, N) 'yi hesapladığını unutmayın (N> M ise, döngünün ilk yinelemesi bunları değiştirir.)


2

Gabriel Lame'in Teoremi, adım sayısını log (1 / sqrt (5) * (a + 1/2)) - 2 ile sınırlar, burada logun tabanı (1 + sqrt (5)) / 2'dir. Bu, algoritma için en kötü durum senaryosu içindir ve girişler ardışık Fibanocci sayıları olduğunda ortaya çıkar.

Biraz daha liberal bir sınır şudur: log a, burada logun tabanı (sqrt (2)) Koblitz tarafından ima edilir.

Kriptografik amaçlar için, bit boyutunun yaklaşık olarak k = loga ile verildiğini hesaba katarak, genellikle algoritmaların bitsel karmaşıklığını dikkate alırız.

İşte Öklid Algoritmasının bitsel karmaşıklığının ayrıntılı bir analizi:

Çoğu referansta Öklid Algoritmasının bitsel karmaşıklığı O (loga) ^ 3 ile verilse de, O (loga) ^ 2 olan daha sıkı bir sınır vardır.

Düşünmek; r0 = a, r1 = b, r0 = q1.r1 + r2. . . , ri-1 = qi.ri + ri + 1,. . . , rm-2 = qm-1.rm-1 + rm rm-1 = qm.rm

şuna dikkat edin: a = r0> = b = r1> r2> r3 ...> rm-1> rm> 0 .......... (1)

ve rm, a ve b'nin en büyük ortak bölenidir.

Koblitz'in kitabındaki bir İddia ile (Sayı Teorisi ve Kriptografi dersi) şu kanıtlanabilir: ri + 1 <(ri-1) / 2 ................. ( 2)

Yine Koblitz'de bir k-bit pozitif tamsayıyı bir l-bit pozitif tamsayıya bölmek için gereken bit işlemlerinin sayısı (k> = l varsayılarak) şu şekilde verilir: (k-l + 1) .l ...... ............. (3)

(1) ve (2) ile bölme sayısı O (loga) ve dolayısıyla (3) ile toplam karmaşıklık O (loga) ^ 3'tür.

Şimdi bu, Koblitz'deki bir açıklama ile O (loga) ^ 2'ye indirgenebilir.

ki = logri +1 olarak düşünün

(1) ve (2) 'ye göre: ki + 1 <= ki for i = 0,1, ..., m-2, m-1 ve ki + 2 <= (ki) -1 i = 0 için , 1, ..., m-2

ve (3) ile m bölmelerinin toplam maliyeti şu şekilde sınırlandırılır: SUM [(ki-1) - ((ki) -1))] * ki i = 0,1,2, .., m için

bunu yeniden düzenlersek: TOPLA [(ki-1) - ((ki) -1))] * ki <= 4 * k0 ^ 2

Öyleyse, Öklid Algoritmasının bitsel karmaşıklığı O (loga) ^ 2'dir.


1

Yinelemeli algoritma için elimizde:

int iterativeEGCD(long long n, long long m) {
    long long a;
    int numberOfIterations = 0;
    while ( n != 0 ) {
         a = m;
         m = n;
         n = a % n;
        numberOfIterations ++;
    }
    printf("\nIterative GCD iterated %d times.", numberOfIterations);
    return m;
}

Fibonacci çiftleri ile arasında hiçbir fark yoktur iterativeEGCD()ve iterativeEGCDForWorstCase()aşağıdaki gibi ikincisi görünüyor:

int iterativeEGCDForWorstCase(long long n, long long m) {
    long long a;
    int numberOfIterations = 0;
    while ( n != 0 ) {
         a = m;
         m = n;
         n = a - n;
        numberOfIterations ++;
    }
    printf("\nIterative GCD iterated %d times.", numberOfIterations);
    return m;
}

Evet, Fibonacci Çiftleri ile n = a % nven = a - n tamamen aynı şey.

Aynı soru için daha önceki bir yanıtta, hakim bir azalan faktör olduğunu da biliyoruz: factor = m / (n % m) .

Bu nedenle, Öklid GCD'nin yinelemeli versiyonunu tanımlanmış bir biçimde şekillendirmek için aşağıdaki gibi bir "simülatör" olarak tasvir edebiliriz:

void iterativeGCDSimulator(long long x, long long y) {
    long long i;
    double factor = x / (double)(x % y);
    int numberOfIterations = 0;
    for ( i = x * y ; i >= 1 ; i = i / factor) {
        numberOfIterations ++;
    }
    printf("\nIterative GCD Simulator iterated %d times.", numberOfIterations);
}

Dr. Jauhar Ali'nin çalışmasına (son slayt) dayanarak, yukarıdaki döngü logaritmiktir.

görüntü açıklamasını buraya girin

Evet, küçük Oh, çünkü simülatör en fazla yineleme sayısını söyler . Fibonacci olmayan çiftler, Öklid GCD üzerinde incelendiğinde, Fibonacci'den daha az sayıda yineleme alır.


Bu çalışma C dili kullanılarak yapıldığından, kesinlik sorunları hatalı / kesin olmayan değerler verebilir. Bu nedenle , faktör adlı kayan nokta değişkenine daha iyi uyması için uzun uzun kullanılmıştır . Kullanılan derleyici MinGW 2.95'tir.
Mohamed Ennahdi El Idrissi

1

Her adımda iki durum vardır

b> = a / 2, o zaman a, b = b, a% b, b'yi önceki değerinin en fazla yarısı yapar

b <a / 2, sonra a, b = b, a% b, b, a / 2'den küçük olduğu için önceki değerinin en fazla yarısını yapacaktır

Yani her adımda, algoritma en az bir sayıyı en az yarıya indirecektir.

En fazla O (log a) + O (log b) adımında, bu basit durumlara indirgenecektir. Hangi bir O (log n) algoritması verir, burada n, a ve b'nin üst sınırıdır.

Onu bulduk burada

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.