(Ne zaman) karma tablo araması O (1) 'dir?


70

Genellikle karma tablo aramasının sabit bir süre içinde çalıştığı söylenir: dizi araması için bir dizin veren karma değerini hesaplarsınız. Ancak bu çarpışmaları görmezden gelir; En kötü durumda, her madde aynı kovaya iner ve arama süresi doğrusallaşır ( Θ(n) ).

Veri tablosunda gerçekten araması yapabilen verilerde koşullar var O(1)mı? Bu sadece ortalama mı yoksa bir hash tablosu O(1) en kötü durum arama özelliğine sahip mi?

Not: Burada bir programcının bakış açısından geliyorum; Bir karma tablosunda veri sakladığımda, neredeyse her zaman dizeleri veya bazı bileşik veri yapılarını gösterir ve veriler karma tablosunun ömrü boyunca değişir. Bu yüzden, kusursuz karmaşayla ilgili cevapları takdir ederken, sevimli ama anekdotlar ve benim açımdan pratik değiller.

PS Takibi: Karma tablo işlemleri için ne tür veriler için O (1)?


3
itfa edilmiş erişim süresiyle yaşayabilir misiniz ? Genel olarak, hash tablo performansı büyük ölçüde tolere etmeye hazır olduğunuz seyrek hashtables için ne kadar ek yüke ve gerçek hash değerlerinin nasıl dağıldığına bağlı olacaktır. Ö(1)
Raphael

5
Oh, btw: Listeler yerine (dengeli) arama ağaçları kullanarak doğrusal en kötü davranışlardan kaçınabilirsiniz.
Raphael

1
@Raphael amortize edildiğinde ve ne zaman yapamayacağımı açıklayabileceğimi (geniş hatlar boyunca) açıklayan bir cevaba çok ilgi duyardım . Karma değerlerin nasıl dağıldığına gelince, bu gerçekten sorumun bir parçası: nasıl bilebilirim? Karma fonksiyonların değerleri iyi dağıtması gerektiğini biliyorum; ama her zaman en kötü durumda olsaydı asla ulaşılmazdı, bu hiç mantıklı gelmiyordu. Ö(1)
Gilles

1
Ayrıca erken optimizasyona dikkat edin; ufacık (birkaç bin element) veri için sık sık dengelenmiş ikili ağaçlardan daha düşük ek yük nedeniyle hashforlardan daha iyi performans gösterdiğimi gördüm (dize karşılaştırmaları dize karmalarından çok daha ucuzdur). Ö(kütükn)
isturdy

Yanıtlar:


41

en kötü durum zamanlarında elde edebileceğiniz iki ayar vardır .Ö(1)

  1. Eğer kurulumunuz statikse, FKS hash, en kötü durumda garantisini alır. Ancak belirttiğiniz gibi, ayarınız statik değil.Ö(1)

  2. Cuckoo karma kullanıyorsanız, sorgular ve silme işlemleri en kötü durumudur, ancak ekleme yalnızca O ( 1 ) beklenir. Toplam kesici uç sayısını üste bağladıysanız ve toplam boyutunda kabaca% 25 daha büyük olacak şekilde ayarladıysanız guguk karmaşası oldukça iyi çalışır.Ö(1)Ö(1)

Burada daha fazla bilgi var .


3
FKS ve Cuckoo’da genişleyebilir misiniz? Her iki terim de benim için yeni.
Gilles

1
Peki ya dinamik mükemmel karma? Bu sahip , en kötü durum aramaları ve O ( 1 ) yerleştirilmesini ve silme itfa. ( citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.30.8165 )Ö(1)Ö(1)
Joe

2
FKS (Fredman, Komlós, Szemerédi) 'nin baş harfleridir ve Cuckoo bir köprü türünün adıdır. Bu tür bir karmaşa için kullanılır, çünkü guguklu civcivler kardeşleri yumurtalarını yuvadan iterler. Bu biraz bu hasing metodunun nasıl çalıştığını andırıyor.
uli

1
@Suresh: Gerçekten mi? İhtiyacın düşünce hep ihtiyacı genişleticiler ile ilişkili-bağımsız fonksiyonları. Düzeltilmiş duruyorum. Yorumumu biraz silecek. logn
Louis

1
@Suresh'in işaret ettiği gibi, bu cevaba daha faydalı bir yorum yapmak için guguk hash, teorik olarak analiz etmek için kullanılan süslü (ve büyük) hash fonksiyonları olmadan iyi çalışacaktır .
Louis

21

Bu cevap, TAoCP Cilt 3, Bölüm 6.4'ün bölümlerini özetlemektedir .

Bir değerler kümesi sahip varsayalım , N olan bir diziye depolamak istediğiniz A boyutu m . H işlevini kullanırız h : V [ 0 .. M ) ; genellikle, M | V | . Α = n diyoruzVnAmh:V[0..M)M|V| yük faktörüarasındaA. Burada doğalm=M; Pratik senaryolarda, elimizdekim«Molsa da, ve aşağı harita zorundamkendimizi.α=nmAm=MmMm

İlk gözlem, üniform özelliklere sahip olsa bile ¹ aynı karma değere sahip iki değerin olasılığının yüksek olduğu; Bu aslında rezil doğum günü paradoksunun bir örneğidir . Bu nedenle, genellikle çatışmalarla uğraşmak zorunda kalacağız ve O ( 1 ) en kötü vaka erişim zamanı umudunu bırakabiliriz .hO(1)

Peki ya ortalama durum? den gelen her tuşun aynı olasılıkta gerçekleştiğini varsayalım . Ortalama kontrol edilen giriş sayısı C S n (başarılı arama) Cı- U , n (başarısız arama) kullanılan çakışma çözünürlüğü yöntemine bağlıdır.[0..M)CnSCnU

zincirleme

Her dizi girişi, bağlı listelerden birini (başında işaretçi) içerir. Beklenen liste uzunluğu küçük olduğundan bu iyi bir fikirdir ( ) Çarpışma olasılığı yüksek olsa da. Sonunda, elde S , n1+anm Bu, listeleri (kısmen ya da tamamen) masanın içine depolayarak biraz geliştirilebilir.

CnS1+α2 and CnU1+α22.

Doğrusal Sondalama

girerken (bir değeri ararken) v , boş bir konuma (cevap verene kadar) bu sırayla h ( v ) , h ( v ) - 1 , , 0 , m - 1 , , h ( v ) + 1 konumlarını kontrol edin. . h ) söz konusu olmaktadır. Bunun avantajı, yerel olarak ve ikincil veri yapıları olmadan çalışmamızdır; ancak, ortalama erişim sayısı α 1 için farklılıklar gösterir : C S n1v

h(v),h(v)1,,0,m1,,h(v)+1
vα1 İçina<0.75, ancak, performans chaining² karşılaştırılabilir.
CnS12(1+11α) and CnU12(1+(11α)2).
α<0.75

Çift karma

Doğrusal sondama benzer, ancak arama adımı boyutu, kopyalanan ikinci bir karma işlevi tarafından kontrol edilir . Hiçbir resmi türetme verilen ancak ampirik gözlemler olduğunu C S n1M Bu yöntem Brent tarafından uyarlanmıştır; onun değişken amortismanları, daha ucuz aramalarla artan ekleme maliyetlerini içerir.

CnS1αln(11α) and CnU11α.

Elemanların çıkarılması ve tabloların uzatılması, ilgili yöntemler için farklı zorluk derecelerindedir.

Sonuç olarak, tipik kullanım durumunuza iyi uyan bir uygulama seçmelisiniz. Her zaman garanti edilmezse , de beklenen erişim süresi mümkündür. Kullanılan yönteme bağlı olarak α'nın düşük tutulması esastır; Genel giderlere karşı (beklenen) erişim zamanını değiştirmelisin. Açıkçası, h için iyi bir seçim de merkezidir.O(1)αh


1] Keyfi olarak aptalca bilgisiz programcılar sağlayabilir , onun kalitesi ile ilgili herhangi bir varsayım pratikte bir gerginliktir. 2] Bunun Java'ların kullanımıyla ilgili önerilere nasıl denk geldiğine dikkat edin .h
Hashtable


10

S{0,1,2,...,n}Ö(1)Ö(1)lSlxxSÖ(|l|)SÖ(|S|)Ö(|l|+|S|)Ö(|l||S|)Ö(kütük(|l|)|S|)Ö(|l|)l

Ö(|l|)

lUN-SUxSllh:U{true,fbirlse}hh(x)=fbirlsexUylh(y)=trueÖ(|l|)Ö(|U|)

lÖ(|U|)Ö(|1|)Ö(|U|)

Uh


Karma tabloyu oluşturduğunuz kısmı genişletir misiniz Ö(|l|)Ö(|S|)Ö(|l||S|)

hh:U{fbirlse,true}h

@Gilles Temelde liste üyeliği için bir arama tablosu olarak kullanılıyor. Bilinen ve ucuz bir tersine sahip mükemmel bir karma işleviniz olduğunda, bir şeyin kendisini saklamak yerine, yalnızca 1 bit saklamanız gerekir (benzersiz karma olan eklenmiş olsun). Eğer çarpışmalar mümkün ise, bunu yapmanın bir Bloom filtresi olarak adlandırıldığını düşünüyorum, ancak her durumda, birçok senaryoda hala yararlı olan üyelik sorununa kesin bir "hayır" sağlayabilir.
Patrick87

9

Ö(1)

Ö(1)Ö(1)Ö(1)Ö(1)


Mükemmel bir karma işlevi mükemmel olurdu, ama nasıl bir tane alabilirim? Bana ne kadara mal olacak? Ve maksimum veya beklenen çarpışma sayısının ne olduğunu nasıl bilebilirim?
Gilles

2
@Gilles, mükemmel bir karma işlevi, tüm olası girişler için benzersiz bir karma üretecek herhangi bir işlevdir. Olası girişleriniz sınırlı (ve benzersiz) ise, bunu yapmak kolaydır.
Rafe Kettler

1
@RafeKettler Girişlerim tipik olarak dizeler veya bileşik veri yapılarıdır ve verilerim geliştikçe genellikle giriş ekler ve kaldırırım. Bunun için nasıl mükemmel bir karma yapabilirim?
Gilles

4
Evet, ama mesele bu. Etki alanı aralıktan büyükse deterministik bir mükemmel karma işlevi yoktur.
Suresh

@Suresh: Herhangi bir çarpışma olduğunda yeni bir karma işlevi seçip tablonun boyutunu büyütmenize izin verilirse, her zaman (deterministik) bir karma işlevini bulabilirsiniz - zaten tablodaki veriler için eklemeye çalıştığınız öğe - çarpışma yok ("mükemmel"). Dinamik mükemmel karmanın periyodik olarak rastgele yeni bir karma işlevi seçmesinin nedeni budur .
David Cary,
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.