Düşük bellek yükü ile kopyaları verimli bir şekilde kaldırma


9

Ben sadece sonuç kümesi saklanması gereken bir şekilde kopyalar için bir tamsayı listesi verimli bir şekilde filtre istiyorum.

Bunun bir yolu görülebilir:

  • bir dizi tamsayı var S={1,,N} ile N büyük 240)
  • bir fonksiyonumuz var f:SS sözde birçok çarpışma ile (görüntüler S)
  • o zaman depolamamız gerek f[S], yani {f(x)|xS}

Ne hakkında oldukça doğru (olasılıklı) bir tahminim var |f[S]| bu nedenle veri yapılarını önceden tahsis edebilir ( |f[S]|230).

Birkaç fikrim oldu, ama en iyi yaklaşımın ne olacağından emin değilim:

  • giriş kümesi belleğe sığmadığı için bir bit kümesi söz konusu değildir.
  • karma tablo, ancak (1) bellekte bir miktar ek yük gerektirir, örneğin% 150 |f[S]| ve (2) bellek ek yükü nedeniyle ek zaman gerektiren tablo oluşturulduğunda araştırılmalıdır.
  • bir "anında" tür, tercihen ile O(N)karmaşıklık (karşılaştırma olmayan sıralama). Bununla ilgili olarak, kova sıralama ve flashsort arasındaki en büyük farkın ne olduğundan emin değilim .
  • ikili arama ağacına sahip basit bir dizi, ancak bu O(Nlog|f[S]|) saati.
  • belki Bloom filtreleri veya benzer bir veri yapısı kullanmak problemin gevşemesinde (yanlış pozitiflerle) faydalı olabilir.

Stackoverflow ile ilgili bazı soruların bu tür şeylerle başa çıktığı görülüyor ( /programming/12240997/sorting-array-in-on-run-time , /programming/3951547/java -array-find-duplicates ), ancak hiçbiri gereksinimlerimle eşleşmiyor gibi görünüyor.


2
F [S] 'yi (ne olursa olsun) numaralandırmanız veya içinde bazı x olup olmadığını hızlıca söyleyebilmeniz mi gerekiyor?
Gilles 'SO- kötü olmayı bırak'

@Gilles: İnanıyorum ki f [S] 'de belirgin bir yapı bulunamadığından, iki çözüm eşdeğerdir.
doc

Numaralarınız toplanmaz. Boyut alanında rastgele bir işlevin beklenen görüntüsüN kabaca (11/e)N. Başka bir sorun,256elinizde süper bir bilgisayar veya büyük bir küme yoksa çok uzun sürecektir.
Yuval Filmus

1
İkili arama ağacının zamanı O(Nlog|f[S]|), yakın veya yakın olabilir O(NlogN)ama yine de daha doğrudur.
jmad

1
İle N256, doğrusal bir zaman algoritması da engelleyici olmayacak mı? (Hesaplamalarımdan,S1 nano-saniyede, iyi bir 2 yıl sürecek!).
Aryabhata

Yanıtlar:


1

Neden çöp kutusu ve zincir değil?

Fikir, temsil edebilecek pozitif tamsayıları saklamaktır n=k+m bir dizideki bit sayısı A nın-nin 2k değer aralıklarını temsil eden girişler: giriş A[y], y0, aralığı temsil eder [2my,2m(y+1)1]. Herhangi1x<2n yazabiliriz x=2my+z nerede y vardır k bit ve z vardır mbit. Depolamaya çalışınz (değil x!) konumunda y:

  • Ne zaman A[y]=z zaten hiçbir şey yapma: x bir kopya.

  • Ne zaman bir[y] başlatılmamış, mağaza z en bir[y].

  • Aksi takdirde, dizini zincirlemek için kullanılan ayrı bir dizide saklayın zadlı kişinin ( y) bağlı listelerde. Başlıklı listede doğrusal olarak arama yapmanız gerekecekbir[y] ve aramanın ne ortaya çıkardığına bağlı olarak, potansiyel olarak z listeye girin.

Sonunda, f(S) başlatılan girişler arasında döngü yaparak kurtarması kolaydır bir ve - sadece iki bit dizisini birleştirerek - her birini yeniden birleştirerek z konumda bulundu y (doğrudan veya orada referans verilen bir zincir içinde) orijinal değere x=2my+z.

Dağıtım tekdüze olduğunda ve 2k aşan N-, çok fazla zincirleme olmayacak (bu olağan yollarla değerlendirilebilir) ve zincirler kısa olma eğilimindedir. Dağıtım tekdüze olduğunda, algoritma hala çalışır, ancak ikinci dereceden zamanlamaya ulaşabilir. Bu bir olasılıksa, zincirlerden daha verimli bir şey kullanın (ve depolama için biraz ek yük ödeyin).

Gerekli depolama alanı en fazla 2n için bit bir ve 22k zincirler için bitler (varsayarak) mk). Bu tam olarak depolamak için gereken alandır2k değerleri nher biri bit. Tekdüzelikten eminseniz, zincirler için depolama alanının yerini değiştirebilirsiniz. Tekdüzelik bir olasılık ise, artırmak isteyebilirsinizk ve zincir deposunu tamamen savunmak.

Bu çözeltinin düşünmeye alternatif yolu olmasıdır olduğunu özellikle güzel bir hash fonksiyonu ile bir karma tablo (almakk en önemli bitler) ve bu nedenle yalnızca en az anlamlı olanı m=n-k bitleri tablo.

Zincirler için depolamayı, bir ama zahmete değmez, çünkü fazla tasarruf etmeyecek (varsayarak) m daha küçük k) ve kodun geliştirilmesini, hata ayıklamasını ve bakımını zorlaştırır.


1
Sanırım ikinci-son paragraf burada merkezi olan ve muhtemelen en üstte olmalıdır (fikir olarak). "Bin ve zincir" terimini bilmiyorum (yazı okuduktan sonra mantıklı olmasına rağmen). Bu fikir denemelere kadar genişletilebilir .
Raphael

Yani, bu Θ(n2)zayıf dağıtılmış girişlerde. Bunun nasıl etkili olduğunu anlamıyorum.
einpoklum

@einpoklum Bu cevap, çözümün etkili olduğu koşulları açıkça tanımlamaktadır.
whuber
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.