Rastgele karşılaştırıcı kabul eden sıralama algoritmaları


22

Genel sıralama algoritmaları genellikle sıralanacak bir veri kümesi ve iki ayrı öğeyi karşılaştırabilecek bir karşılaştırıcı işlevi alır. Karşılaştırıcı bir sipariş ilişkisi¹ ise, algoritmanın çıktısı bir sıralama listesi / dizisidir.

Hangi sıralama algoritmalarının aslında bir sipariş ilişkisi olmayan bir karşılaştırıcı ile çalışacağını merak ediyorum (özellikle her bir karşılaştırmada rastgele bir sonuç veren). "İş" derken, girişlerinin bir permütasyonunu geri döndürdüklerini ve tipik olarak belirtilen zaman karmaşıklıklarında çalıştıklarını kastediyorum (her zaman en kötü senaryoya indirgemek veya sonsuz bir döngüye veya eksik elemanlara girmek yerine). Ancak sonuçların sırası tanımlanmayacaktır. Daha da iyisi, sonuçta sıralama, karşılaştırıcı bir madeni para çevirme olduğunda eşit bir dağılım olacaktır.

Kaba zihinsel hesaplamama göre, bir birleştirme sıralamasının bunun için iyi olduğu ve aynı çalışma zamanı maliyetini koruduğu ve adil bir rastgele sipariş ürettiği anlaşılıyor. Ben hızlı bir sıralama gibi bir şey ancak yozlaşmak, muhtemelen bitirmek ve adil olmayacağını düşünüyorum.

Başka hangi sıralama algoritmaları (birleştirme sıralama dışında) rasgele bir karşılaştırıcı ile tanımlandığı şekilde çalışır?


  1. Başvuru için, karşılaştırıcı uygun bir fonksiyon ise (deterministik) bir sipariş ilişkisidir ve bir sipariş ilişkisinin aksiyomlarını karşılar:

    • deterministiktir: compare(a,b)belirli bir şey için ave bher zaman aynı sonucu verir.
    • geçişli: compare(a,b) and compare(b,c) implies compare( a,c )
    • antisimetrik compare(a,b) and compare(b,a) implies a == b

(Tüm girdi öğelerinin farklı olduğunu varsayalım, bu nedenle yansıma sorunu değil.)

Rasgele bir karşılaştırıcı tüm bu kuralları ihlal eder. Bununla birlikte, sıra ilişkileri olmayan henüz rastgele olmayan karşılaştırıcılar vardır (örneğin, yalnızca bir kuralı ihlal edebilirler ve yalnızca kümedeki belirli öğeler için).


(1) Karşılaştırma fonksiyonunun kararlı olması ile ne demek istiyorsunuz? (2) “Kararsız” ve “rastgele” eş anlamlı mı?
Tsuyoshi Ito

"tipik olarak belirtilen zaman karmaşıklıklarında koşun (en kötü durum senaryosuna indirgemek yerine" - tipik olarak belirtilen zaman karmaşıklığı en kötü durumdur! ", siparişin adil rastgele bir sırada mı olacağını belirtirsiniz -" "TARAFINDAN" adil "olur mu? - Karşılaştırıcının da tek tip olduğunu varsayıyor musunuz?
Raphael

Belki biçimsel teoride değil, pratikte (programlama dilleri) itfa edilmiş bir zamanda kote edilmiş birçok şey vardır. Örneğin, hızlı bağlantı sık sık olarak gösterilir, ancak gerçekte O ( n 2 ) 'dir . O(günlükn)O(n2)
edA-qa mort-ora-y 12:12

4
@ edA-qamort-ora-y: (1) Yani , O ( log n ) değil . (2) " İtfa edilmiş zamanın " anlamı bu değildir; " Beklenen süre " veya daha az resmi olarak "tipik süre" anlamına geliyorsunuz . O(ngünlükn)O(günlükn)
JeffE

1
Kimse yukarıda bana verilen daha ilginç soruya değinmedi: hangi sıralama algoritmalarının (eğer varsa) karşılaştırıcı bir madeni para çevirme ise o zaman sonuç tek biçimli bir permütasyon olma özelliğini taşıyor.
Joe,

Yanıtlar:


13

Temel olarak, eğer benzer bir karşılaştırma işlevi verilirse, ortalama durumundan düşmeyecek herhangi bir sıralama algoritması olup olmadığını bilmek istersiniz:

int Compare(object a, object b) { return Random.Next(-1,1); }

... burada Random.Next (), belirtilen kapsayıcı alt ve üst sınır arasında rasgele oluşturulmuş bir tamsayı üreten bir yöntemdir.

Cevap, çoğu temel sıralama algoritmalarının ortalama durumlarına göre gerçekleştirileceğidir, çünkü aşağıdaki iki koşuldan en az birine uyuyorlar:

  1. İki benzersiz eleman arasında bir karşılaştırma asla sıralamada iki kez yapılmaz ve / veya
  2. Her bir yinelemede, en az bir elemanın doğru pozisyonu belirlenir ve böylece eleman bir daha asla karşılaştırılmaz.

Örneğin, SelectionSort, sıralanmamış öğelerin alt listesinde yinelenir, "en az" ve / veya "en büyük" öğeyi bulur (her birini en büyük değerle karşılaştırarak), doğru konumuna yerleştirir ve tekrarlar. Sonuç olarak, deterministik olmayan bir karşılaştırıcı ile bile, her yinelemenin sonunda, algoritma en az veya en büyük olduğunu düşündüğü, onu belirlemeye çalıştığı konumda elemanla değiştirdiği ve asla göz önünde bulundurmadığı bir değeri buldu. bu eleman tekrar, Durum 2'ye uyuyor. Ancak, A ve B, bu işlem sırasında birçok kez karşılaştırılabilir (en aşırı örnek olarak, ters sırada sıralanan bir dizide SelectionSort'un birkaç geçişini düşünün), bu nedenle Koşul 1'i ihlal eder. .

MergeSort, Koşul 1'e uyuyor ancak 2'ye uymuyor; Alt diziler birleştirildiğinde, aynı alt dizideki öğeler (sol veya sağ tarafta) birbirleriyle karşılaştırılmaz çünkü dizinin bu tarafındaki öğelerin kendi aralarında sıralandıkları belirlenmiştir; algoritma, hangisinin daha az olduğunu ve birleştirilmiş listede daha sonra gitmesi gerektiğini belirlemek için yalnızca her alt dizinin en az ayrıksız elemanını diğerine karşılaştırır. Bu, herhangi iki benzersiz A ve B nesnesinin en fazla bir defa birbirleriyle karşılaştırılacağı, ancak tam koleksiyondaki belirli bir öğenin "son" dizininin algoritma tamamlanana kadar bilinmediği anlamına gelir.

Genel stratejisi ve karmaşıklığı daha çok SelectionSort'a benzese de, InsertionSort, yalnızca Koşul 1'e uyar. Her ayrılmamış eleman, kontrol edilen elemandan daha az bulunan bulunana kadar, en büyük ilk olarak sıralanmış elemanlarla karşılaştırılır. eleman bu noktaya yerleştirilir ve bir sonraki eleman dikkate alınır. Sonuç, herhangi bir A ve B'nin göreceli sırasının bir karşılaştırma ile belirlendiği ve bu A ile B arasındaki diğer karşılaştırmaların hiçbir zaman gerçekleştirilmediği, ancak herhangi bir elemanın son pozisyonunun tüm elemanlar göz önüne alınana kadar bilinemediği sonucudur.

QuickSort her ikisine de uyarKoşullar. Her seviyede, bir "Pivot", "sol" taraf, pivottan daha az elemanlar içerecek ve "sağ" taraf, pivottan daha büyük elemanlar içerecek şekilde düzenlenir ve düzenlenir. Bu seviyenin sonucu, temel olarak pivot elemanının pozisyonunun bilindiği anlamına gelen (sol tarafın uzunluğundan bir indeks), pivotun hiçbir zaman diğer elementlerle karşılaştırılmadığı anlamına gelen QuickSort (sol) + pivot + QuickSort (sağ) şeklindedir. bir pivot olarak seçildikten sonra (önceki pivot elemanları ile karşılaştırılmış olabilir, ancak bu elemanlar da bilinir ve herhangi bir alt diziye dahil edilmezler) VE Pivotun zıt taraflarında biten A ve B'ler asla karşılaştırdık. Saf QuickSort'un uygulamalarının çoğunda, temel durum, şu andaki endeksinin son endeksi olduğu ve başka bir karşılaştırma yapılmayan bir unsurdur.

Her iki koşula da uymayacağını düşünebildiğim tek karşılaştırmalı sıralama, optimize edilmemiş bir BubbleSort. Sıralama, X geçişlerinden sonra en büyük X öğesinin uygun yerde olduğunu kabul etmiyorsa ve / veya listenin sıralandığını doğrulamak için "çift kontrol" geçişi kullanıyorsa, sıralama yalnızca "yapıldığında" kabul edilir. rastgele karşılaştırıcı bir takas gerçekleştirilebilir ve bu suretle, her iki bitişik bir geçiş sırasında listesindeki elemanları ve (gerçekten rastgele ise, olasılıkla ortaya çıkabilecek bir olay için geri-1 ya da 0 olan , nispeten için 25 elementin küçük bir listesi, bu 2000 şansta bir tane, 100 element için olasılık ise 3.7 * 10 -18(2/3)N1). Karşılaştırıcının sonucunun maksimum mutlak değeri arttıkça, herhangi bir karşılaştırmanın negatif veya sıfırı döndürme olasılığı .5'e düşer ve algoritmayı sona erdirme şansı çok daha düşüktür (99 jeton şansı tüm iniş kafalarını çevirir) temelde bunun kaynama noktası nedir, 1.2'de 1 * 10 30 )

UZUN ZAMANLI BİR SONRA DÜZENLEME: Rastgele bir karşılaştırıcı içeren ve ne yapmamaya örnek olarak özel olarak tasarlanmış birkaç "çeşit" vardır; belki de en ünlüsü BogoSort'tur. Msgstr "Liste sırayla değilse, listeyi karıştır ve tekrar kontrol et". Teorik olarak edecektir sonunda hemen üstünde "optimize edilmemiş BubbleSort" gibi değerlerin doğru permütasyonu çarptı ama ortalama vaka yeterince rastgele permütasyon sonra (N! / 2) ve çünkü doğum günü sorununun faktöryel zamanlı (size yinelenen permütasyonlarla benzersiz olanlardan daha fazla karşılaşmak daha muhtemel hale gelir). Algoritmanın resmen tamamlamayı asla tamamlama olasılığı sıfırdır.


Koşul 2 aynı zamanda hızlı sıralamayı da kapsayabilir mi? Yoksa her yinelemenin öncekinden daha küçük olmasının üçüncü bir şartı mı olur?
edA-qa mort-ora-y

QuickSort, bence her iki koşulda da ele alınacaktı. Verimli QuickSorts'ta, pivotu seçersiniz, ardından her bir elemanı onunla karşılaştırırsınız ve pivotun yanlış "tarafında" olan öğeleri değiştirirsiniz. Öğeler düzenlendikten sonra, işlev QuickSort (sol) + pivot + QuickSort (sağ) döndürür ve pivot daha düşük seviyelere indirilmez. Yani, her iki koşul da doğru; hiçbir zaman benzersiz bir a ve b'yi bir kereden fazla karşılaştırmazsınız ve diğer öğeleri düzenlemeyi tamamladığınızda pivotun indeksini belirlersiniz.
KeithS

Harika cevap, ama BubbleSort konusunda seninle aynı fikirde değilim. Tutarlı bir karşılaştırıcı kullanırken, i-yinelemede BubbleSort, i-1'in son elemanlarının nihai yerinde olduğunu ve herhangi bir yinelemeden sonra BubbleSort'un herhangi bir makul uygulamasının daha az elemandan geçeceğini bildiğinden, yinelemelerden sonra da durması gerekir. .
Boris Trayvas, 14.06.2012

Biraz daha düşündükten sonra seninle aynı fikirdeyim; X geçtikten sonra Koşulu 2. Her geçişte sorun alanını azaltabilir ve böylece verimli bir algoritma itaat diye, en büyük X değerleri düzenleyebilir edeceğiz Onların doğru yerde vardır
Keiths

Quicksort uygulamasına dikkat etmeniz gerekir. Pivottan veya pivottan daha büyük bir elementle karşılaştığımızda, pivottan daha az olmayan bir element arayışının sona ereceği varsayımı olabilir; Bu mutlaka böyle olmaz.
gnasher729

10

O(n2)

n


Düzenleme: Sorun ilk düşündüğüm gibi daha ilginç, işte bir başka yorum:

cOmpbirrecOmpbirre(x,y)=true1/2fbirlse1/2

insert x [] = [x]
insert x y:ys = if x < y then x:y:ys
                else y:insert x ys

sort_aux l e = match l with
                 [] -> e
                 x:xs -> sort_aux xs (insert x ys)

sort l = sort_aux l []

Σk=1nf(k)nlf(k)bennsertk:

cOmpbirre

Σben=1kben2-benΣben=1ben2-ben=2

O(2n)O(n2)

Bu tek tip karşılaştırma fonksiyonu verilen farklı algoritmaların ortalama çalışma sürelerini hesaplamak eğlenceli olacaktır.


Aynı öğe birden fazla pivot olarak seçilirse, Quicksort karşılaştırmaları tekrarlayabilir (listede birden çok kez olabilir).
Raphael

2
@Raphael: Kelime seçimim zayıftı: Quicksort'ta bir kereden fazla gerçekleşmeyen elementlerin oluşumları arasındaki tekrarlamaları kastettim .
cody

1
@Gilles: Yanlış olabilirim ama karşılaştırmanın geçiciliğinin çoğu sıralama algoritmasının çalışma zamanı için çok önemli olduğuna inanmıyorum ; elbette doğruluk , ancak bu sorunun amacı değildi.
cody

@Gilles: OP gerçekten sıralanan algoritmalar hakkında soru sormuyor. Tüm karşılaştırmalar yazı turaları ile değiştirilirken standart sıralama algoritmalarına ne olacağını soruyor. Sonuçta ortaya çıkan algoritmalar sıralama yapmaz (küçük olasılık dışında), ancak yine de iyi tanımlanmış algoritmalardır.
JeffE

@JeffE Bunu şimdi anlıyorum. Başlangıçta soruyu böyle okudum, ancak sorucunun yorumları göz önüne alındığında kastedilen bu değildi.
Gilles 'SO- kötülük yapmayı bırak'

2

Adil rastgele karşılaştırıcılı Mergesort adil değil. Kanıtım yok, ama çok güçlü deneysel kanıtlarım var. (Adil, eşit olarak dağıtılmış demektir.)

module Main where

import Control.Monad
import Data.Map (Map)
import qualified Data.Map as Map
import System.Random (randomIO)

--------------------------------------------------------------------------------

main :: IO ()
main = do
  let xs = [0..9]
  xss <- replicateM 100000 (msortRand xs)
  print $ countFrequencies xss

msortRand :: [a] -> IO [a]
msortRand = msort (\_ _ -> randomIO)

countFrequencies :: (Ord a) => [[a]] -> [Map a Int]
countFrequencies [] = []
countFrequencies xss = foldr (\k m -> Map.insertWith (+) k 1 m) Map.empty ys : countFrequencies wss
  where
    ys = map head xss
    zss = map tail xss
    wss = if head zss == []
      then []
      else zss

--------------------------------------------------------------------------------

msort :: (Monad m) => (a -> a -> m Bool) -> [a] -> m [a]
msort (<) [] = return []
msort (<) [x] = return [x]
msort (<) xs = do
  ys' <- msort (<) ys
  zs' <- msort (<) zs
  merge (<) ys' zs'
  where
    (ys, zs) = split xs

merge :: (Monad m) => (a -> a -> m Bool) -> [a] -> [a] -> m [a]
merge (<) [] ys = return ys
merge (<) xs [] = return xs
merge (<) (x:xs) (y:ys) = do
  bool <- x < y
  if bool
    then liftM (x:) $ merge (<) xs (y:ys)
        else liftM (y:) $ merge (<) (x:xs) ys

split :: [a] -> ([a], [a])
split [] = ([], [])
split [x] = ([x], [])
split (x:y:zs) = (x:xs, y:ys)
  where
    (xs, ys) = split zs

Haskell veya Caml şimdi moda mı?
Yai0Phah

Hiç bir fikrim yok. Ama Haskell benim en sevdiğim dil, bu yüzden bunu programladım; desen eşleştirme bunu kolaylaştırdı.
Thomas Eding

0

Çok fazla ilgili soru, Christiansen, Danilenko ve Dylus tarafından Her Türdeki Permütasyonlarda (İşlevsel İnci) cevaplanmaktadır. Monad listesinde , belirli bir giriş listesinin tüm permütasyonlarını döndürerek belirsizliği simüle eden bir sıralama algoritması kullanırlar . İlginç olan özellik, her permütasyonun tam olarak bir kez döndürülmesidir.

Özetten alıntı:

...

Bu yazıda determinizm olmayan ve sıralama farklı bir ışıkta kombinasyonuna bakıyoruz: bir sıralama fonksiyonu verildiğinde, onu giriş listesinin permütasyonlarını sağlayan bir fonksiyon elde etmek için deterministik olmayan bir yüklemeye uygularız. Sıralama algoritmalarının ve özelliklerinin gerekli özelliklerinin altına inip modellenmiş determinizm modelinin varyasyonlarını tartışıyoruz.

Bunun üzerine, hangi sıralama işlevini kullanırsak kullanın, karşılık gelen permütasyon fonksiyonunun giriş listesinin tüm permütasyonlarını numaralandırdığını belirten bir teoremi formüle eder ve ispat ederiz. İfadeyi ispatlamak için yalnızca bir fonksiyon türünden türetilen serbest teoremleri kullanırız.

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.