Çok çeşitli uygulanabilir yaklaşımlar vardır. Hangisi daha uygun?
- ne göstermeye çalışıyorsun,
- ne kadar detay istediğiniz veya ihtiyacınız.
Algoritma, altyordam olarak kullandığınız yaygın olarak biliniyorsa, genellikle daha yüksek bir seviyede kalırsınız. Algoritma araştırılan ana nesne ise, muhtemelen daha ayrıntılı olmak istersiniz. Aynı şey analizler için de söylenebilir: kaba bir üst çalışma zamanı sınırına ihtiyacınız varsa, ifadelerin tam olarak sayılmasını istediğinizden farklı şekilde devam edersiniz.
Size umarım bunu gösteren iyi bilinen algoritma Mergesort için üç örnek vereceğim.
Yüksek seviye
Mergesort algoritması bir liste alır, iki (yaklaşık) eşit uzunlukta uzun parçaya ayırır, bu kısmi listelerde geri çekilir ve sonuçların sıralanması için (sıralanmış) sonuçları birleştirir. Tekli veya boş listelerde girdiyi döndürür.
Bu algoritma açık bir şekilde doğru bir sıralama algoritmasıdır. Listeyi bölmek ve birleştirmek her zaman zamanında uygulanabilir , bu da bize en kötü çalışma zamanı için bir yineleme sağlar . Ana teorem ile bu değerlendirilir .T ( n ) = 2 T ( nΘ ( n )T(n)∈Θ(nlogn)T( N ) = 2 , T( n2) +Θ(n)T( n ) ∈ Θ ( n günlüğün )
Orta düzey
Mergesort algoritması aşağıdaki sahte kodla verilir:
procedure mergesort(l : List) {
if ( l.length < 2 ) {
return l
}
left = mergesort(l.take(l.length / 2)
right = mergesort(l.drop(l.length / 2)
result = []
while ( left.length > 0 || right.length > 0 ) {
if ( right.length == 0 || (left.length > 0 && left.head <= right.head) ) {
result = left.head :: result
left = left.tail
}
else {
result = right.head :: result
right = right.tail
}
}
return result.reverse
}
Doğruluğu tümevarım ile kanıtlarız. Sıfır veya bir uzunluktaki listeler için algoritma önemsizdir. Tümevarım hipotezi olarak, bazı keyfi, ancak sabit doğal için mergesort
uzunluk listelerinde en fazla doğru çalıştığını varsayın . Şimdi uzunluğunun bir listesi olsun . Tümevarım hipotezleri ve ilk azalan (azalan olmayan) sıralanmış versiyonları tutun. özyinelemeli çağrılardan sonra ikinci yarısı . Bu nedenle, döngü her yinelemede henüz araştırılmamış en küçük elemanı seçer ve ekler ; böylece , tüm öğeleri içeren ven > 1 L n + 1 L Lnn >1Ln + 1left
right
Lwhile
result
result
left
right
. Bunun tersi, döndürülen ve istenen sonuç olan azaltılmayan bir versiyonudur .L
Çalışma zamanına gelince, öğe karşılaştırmalarını ve çalışma zamanlarını asimptotik olarak domine eden işlemleri listeleyelim. İkiden az uzunluk listeleri de neden olmaz. uzunluk listelerinde , yinelemeli çağrılar için girişlerin, özyinelemeli çağrıların kendileri artı döngü ve bir için girişlerin hazırlanmasından kaynaklanan bu işlemlere sahibiz . Her iki özyinelemeli parametrenin her biri en fazla liste işlemi ile hesaplanabilir . Döngü tam olarak yürütülür en fazla bir elemanı karşılaştırma zamanları ve her yineleme nedenlerini ve tam iki liste operasyonları. Final kullanmak için uygulanabilirn n 2 nn > 1while
reverse
nwhile
nreverse
2 nliste işlemleri - her eleman girişten çıkarılır ve çıkış listesine eklenir. Bu nedenle, işlem sayısı aşağıdaki yinelemeyi karşılar:
T(0)=T(1)T(n)=0≤T(⌈n2⌉)+T(⌊n2⌋)+7n
Olarak açık azalmayan, değerlendirmek yeterlidir; asimptotik büyüme için. Bu durumda , nüks basitleşirn = 2 kTn=2k
T(0)=T(1)T(n)=0≤2T(n2)+7n
Ana teorem ile, çalışma zamanına kadar uzanan da alırız .T∈Θ(nlogn)mergesort
Ultra düşük seviye
Mergesort'un Isabelle / HOL'daki bu (genelleştirilmiş) uygulamasını düşünün :
types dataset = "nat * string"
fun leq :: "dataset \<Rightarrow> dataset \<Rightarrow> bool" where
"leq (kx::nat, dx) (ky, dy) = (kx \<le> ky)"
fun merge :: "dataset list \<Rightarrow> dataset list \<Rightarrow> dataset list" where
"merge [] b = b" |
"merge a [] = a" |
"merge (a # as) (b # bs) = (if leq a b then a # merge as (b # bs) else b # merge (a # as) bs)"
function (sequential) msort :: "dataset list \<Rightarrow> dataset list" where
"msort [] = []" |
"msort [x] = [x]" |
"msort l = (let mid = length l div 2 in merge (msort (take mid l)) (msort (drop mid l)))"
by pat_completeness auto
termination
apply (relation "measure length")
by simp+
Bu zaten iyi tanımlanmış ve feshedilmiş kanıtları da içermektedir. Burada (neredeyse) tam bir doğruluk kanıtı bulun .
"Çalışma zamanı", yani karşılaştırma sayısı için, önceki bölümdekine benzer bir yineleme ayarlanabilir. Master teoremini kullanmak ve sabitleri unutmak yerine, asemptotik olarak gerçek miktara eşit bir yaklaşım elde etmek için analiz edebilirsiniz. Analizin tamamını [1] 'de bulabilirsiniz; İşte kaba bir taslak (mutlaka Isabelle / HOL koduna uymuyor):
Yukarıdaki gibi, karşılaştırma sayısının tekrarlaması
f0=f1fn=0=f⌈n2⌉+f⌊n2⌋+en
burada , kısmi sonuçların birleştirilmesi için gerekli karşılaştırma sayısı²'dir. Zemin ve tavanlardan kurtulmak için eşit olup olmadığı konusunda bir vaka ayrımı yaparız : nenn
{f2mf2m+1=2fm+e2m=fm+fm+1+e2m+1
İç içe kullanma ileri / geri farklılıkları arasında ve bunu almake nfnen
∑k=1n−1(n−k)⋅Δ∇fk=fn−nf1 .
Toplam, Perron formülünün sağ tarafıyla eşleşir . Bu tanımlar Dirichlet üreten serisi arasında olarakΔ∇fk
W( s ) = ∑k ≥ 1Δ∇ fkk- s= 11 - 2- s⋅ ∑k ≥ 1Δ∇ ekks= : ⊟ ( s )
Perron'un formülü ile birlikte bizi
fn= n f1+ n2 πben∫3 - i ∞3 + i ∞⊟ ( s ) ns( 1 - 2- s) s ( s + 1 )ds .
değerlendirilmesi hangi vakanın analiz edildiğine bağlıdır. Bunun dışında - bazı hilelerden sonra - elde etmek için kalıntı teoremini uygulayabiliriz⊟ ( s )
fn~ N ⋅ günlük2( n ) + n ⋅ A ( günlük2( n ) ) + 1
burada , daki değerlere sahip periyodik bir fonksiyondur .bir[ - 1 , - 0.9 ]
- Mellin dönüşümleri ve asimptotikler: Flajolet ve Golin tarafından yapılan birleşmenin tekrarlanması (1992)
- En iyi durum:
En kötü durum:
Ortalama vaka:en= ⌊ n2⌋
en= n - 1
en= n - ⌊ n2⌋⌈ n2⌉ +1- ⌈ n2⌉⌊ n2⌋ +1