Önbelleği bilmeyen dağıtım sıralaması - Cache-oblivious distribution sort

Önbellekten habersiz dağıtım sıralaması bir karşılaştırmaya dayalı sıralama algoritması. Benzer hızlı sıralama ama bu bir önbellekten habersiz algoritma, sıralanacak öğe sayısının bir sayfaya sığmayacak kadar büyük olduğu bir ortam için tasarlanmıştır. önbellek operasyonların yapıldığı yer. İçinde harici bellek modeli, bir tür gerçekleştirmesi için gereken bellek aktarımlarının sayısı önbelleğe sahip bir makinedeki öğeler ve uzunluktaki satırları önbellekleyin dır-dir , uzun önbellek varsayımına göre . Bu sayıda bellek aktarımının, karşılaştırma sıralamaları için asimptotik olarak optimal olduğu gösterilmiştir. Bu dağıtım sıralaması aynı zamanda asimptotik olarak optimum çalışma zamanı karmaşıklığını da sağlar. .

Algoritma

Genel Bakış

Dağıtım sıralaması bitişik bir dizi üzerinde çalışır elementler. Öğeleri sıralamak için aşağıdakileri gerçekleştirir:

  1. Diziyi bölümlere ayır bitişik boyut alt dizileri ve her bir alt diziyi yinelemeli olarak sıralayın.
  2. Sıralanmış alt dizilerin elemanlarını şu şekilde dağıtın: kovalar her boyutta en fazla öyle ki 1'den q-1'e kadar her i için kovanın her elemanı içindeki herhangi bir elementten daha büyük değil Bu dağıtım adımı, bu algoritmanın ana adımıdır ve aşağıda daha ayrıntılı olarak ele alınmıştır.
  3. Her bir kovayı yinelemeli olarak sıralayın.
  4. Paketlerin birleşimini çıktı olarak alın.


Dağıtım adımı

Yukarıdaki 2. adımda bahsedildiği gibi, dağıtım adımının amacı, sıralanan alt dizileri q kovalarına dağıtmaktır. Dağıtım adımı algoritması iki değişmezi korur. Birincisi, her kepçenin en fazla boyuta sahip olmasıdır. herhangi bir zamanda ve kovadaki herhangi bir öğe kovadaki herhangi bir elemandan daha büyük değildir İkincisi, her kovanın ilişkili bir eksen, paketteki tüm öğelerden daha büyük bir değer.

Başlangıçta algoritma, pivot içeren bir boş paketle başlar . Kovaları doldururken, aşırı dolu hale geleceği zaman bir kovayı ikiye bölerek yeni kovalar oluşturur (en azından içine yerleştirilmiş elemanlar). Bölme işlemi gerçekleştirilerek yapılır doğrusal zaman medyan bulma algoritma ve bu medyana göre bölümleme. Alt kepçenin ekseni, bulunan medyana ayarlanacak ve daha yüksek kepçenin ekseni, bölmeden önceki kepçeyle aynı olacak şekilde ayarlanacaktır. Dağıtım adımının sonunda, tüm elemanlar kovalar içindedir ve iki değişmez hala tutulur.

Bunu başarmak için, her alt dizi ve kovanın kendisiyle ilişkilendirilmiş bir durumu olacaktır. Bir alt dizinin durumu bir dizinden oluşur Sonraki alt diziden okunacak sonraki eleman ve bir kova numarası bnum öğenin hangi klasör dizinine kopyalanacağını belirtir. Kongre tarafından, alt dizideki tüm öğeler dağıtılmışsa. (Bir kovayı böldüğümüzde, hepsini artırmamız gerektiğini unutmayın. bnum tüm alt dizilerin değerleri bnum değer, bölünmüş paketin dizininden daha büyüktür.) Bir bölümün durumu, bölüm pivotunun değerinden ve şu anda pakette bulunan öğelerin sayısından oluşur.

Aşağıdaki temel stratejiyi göz önünde bulundurun: her bir alt diziyi yineleyin, konumdaki öğesini kopyalamaya çalışın Sonraki. Öğe, kepçenin ekseninden daha küçükse bnum, sonra muhtemelen bir kova yarılmasına neden olacak şekilde o kovaya yerleştirin. Aksi takdirde artış bnum kadar pivotu yeterince büyük olan bir kova bulunana kadar. Bu, tüm öğeleri doğru bir şekilde dağıtsa da, iyi bir önbellek performansı sergilemiyor.

Bunun yerine, dağıtım adımı yinelemeli bir böl ve yönet yöntemiyle gerçekleştirilir. Adım, işleve çağrı olarak gerçekleştirilecektir dağıtmaki, j ve m olmak üzere üç parametre alır. dağıtmak(i, j, m), öğeleri i-th ile (i + m-1) -th alt dizileri arasında . Aralıktaki her bir alt dizinin bir ön koşul olarak Lara sahip . İnfazı dağıtmak(i, j, m) her birinin . Tüm dağıtım adımı dağıtmak. Dağıtmanın uygulanması için sözde kod aşağıda gösterilmiştir:

def dağıtmak(ben, j, m: int) -> Yok:    "" "Yinelemeli böl ve yönet yoluyla dağıtın." ""    Eğer m == 1:        copy_elems(ben, j)    Başka:        dağıtmak(ben, j, m / 2)        dağıtmak(ben + m / 2, j, m / 2)        dağıtmak(ben, j + m / 2, m / 2)        dağıtmak(ben + m / 2, j + m / 2, m / 2)

M = 1 olan temel durum, alt yordama bir çağrıya sahiptir copy_elems. Bu temel durumda, i alt dizisinden j kovasına ait olan tüm öğeler bir defada eklenir. Bu, kova j'nin çok fazla elemana sahip olmasına yol açarsa, önceden anlatılan prosedürle kovayı böler.

Ayrıca bakınız

Referanslar