Aufwärmen: Zufällige Bitvektoren
Zum Aufwärmen können wir mit dem Fall beginnen, in dem jeder Bitvektor gleichmäßig zufällig ausgewählt wird. Dann stellt sich heraus, dass das Problem in der Zeit gelöst werden kann (genauer gesagt, die kann durch ).O(n1.6min(k,lgn))lg 31.6lg3
Wir werden die folgende zweistufige Variante des Problems betrachten:
Bestimmen Sie bei gegebenen Mengen von Bitvektoren, wo es ein nicht überlappendes Paar . s ≤ S , t ≤ TS,T⊆{0,1}ks∈S,t∈T
Die grundlegende Technik, um dies zu lösen, ist das Teilen und Erobern. Hier ist ein -Zeitalgorithmus mit Divide-and-Conquer:O(n1.6k)
Split und auf der Basis der ersten Bit - Position. Mit anderen Worten, Form , , , .T S 0 = { s ∈ S : s 0 = 0 } S 1 = { s ∈ S : s 0 = 1 } T 0 = { t ∈ T : t 0 = 0 }STS0= { s ∈ S: s0= 0 }S1= { s ∈ S: s0= 1 }T0= { t ∈ T: t0= 0 }T1= { t ∈ T: t0= 1 }
Suchen Sie nun rekursiv nach einem nicht überlappenden Paar aus , und . Wenn ein rekursiver Aufruf ein nicht überlappendes Paar findet, geben Sie es aus. Anderenfalls wird "Kein überlappendes Paar vorhanden" ausgegeben.S 0 , T 1 T 1 , S 0S0, T0S0, T1T1, S0
Da alle Bitvektoren zufällig ausgewählt werden, können wir erwarten und . Wir haben also drei rekursive Aufrufe und haben das Problem um den Faktor zwei verkleinert (beide Mengen sind um den Faktor zwei verkleinert). Nach der hat eine der beiden Mengen die Größe 1, und das Problem kann in linearer Zeit gelöst werden. Wir erhalten eine Wiederholungsrelation nach , deren Lösung . Wenn wir die Laufzeit genauer in dem Fall mit zwei Mengen berücksichtigen, sehen wir, dass die Laufzeit .| T b | ≈ | T | / 2 lg min ( | S | , | T | ) T ( n ) = 3 T ( n / 2 ) + O ( n k ) T ( n ) = O ( n 1,6 k ) O| Sb| ≈ | S| / 2| Tb| ≈ | T| / 2lgmin ( | S| , | T| )T( n ) = 3 T(n/2)+O(nk)T(n)=O(n1.6k)O(min(|S|,|T|)0.6max(|S|,|T|)k)
Dies kann weiter verbessert werden, indem bemerkt wird, dass die Wahrscheinlichkeit, dass ein nicht überlappendes Paar existiert, exponentiell klein ist , wenn ist. Insbesondere wenn zwei Zufallsvektoren sind, ist die Wahrscheinlichkeit, dass sie sich nicht überlappen, . Wenn , gibt es solcher Paare, so dass durch eine Vereinigungsgrenze die Wahrscheinlichkeit, dass ein nicht überlappendes Paar existiert, höchstens beträgt . Wenn , ist dies . Also als Vorverarbeitungsschritt, wennx , y ( 3 / 4 ) k | S | = | T | = N n 2 n 2 ( 3 / 4 ) k k ≥ 2,5 lg n + 100 ≤ 1 / 2 100 k ≥ 2,5 lg n + 100k≥2.5lgn+100x , y(3/4)k|S|=|T|=nn2n2(3/4)kk≥2.5lgn+100≤1/2100k≥2.5lgn+100, dann können wir sofort "Kein nicht überlappendes Paar existiert" zurückgeben (die Wahrscheinlichkeit, dass dies falsch ist, ist vernachlässigbar gering), andernfalls führen wir den obigen Algorithmus aus.
Somit erreichen wir eine Laufzeit von (oder für die oben vorgeschlagene Zwei-Mengen-Variante), für den Sonderfall, dass die Bitvektoren gleichmäßig zufällig gewählt werden.O ( min ( | S | , | T | ) 0,6 max ( | S | , | T | ) min ( k , lg n ) )O(n1.6min(k,lgn))O(min(|S|,|T|)0.6max(|S|,|T|)min(k,lgn))
Dies ist natürlich keine Worst-Case-Analyse. Zufällige Bitvektoren sind erheblich einfacher als der schlimmste Fall - aber betrachten wir es als Aufwärmen, um einige Ideen zu erhalten, die wir vielleicht auf den allgemeinen Fall anwenden können.
Lehren aus dem Aufwärmen
Wir können ein paar Lektionen aus dem obigen Aufwärmen lernen. Zunächst scheint das Teilen und Erobern (Aufteilen auf eine Bitposition) hilfreich zu sein. Zweitens wollen Sie auf eine Bit - Position teilen mit so vielen ‚s in dieser Position wie möglich; desto mehr ist da sind, können Sie die weniger Reduktion in Subproblem Größe.010
Drittens legt dies nahe , dass das Problem wird noch schwieriger als die Dichte von ‚s wird kleiner - wenn es nur sehr wenige ist ‘ s unter dem bitvectors (sie sind meist ‚s), das Problem sieht ziemlich hart, da jede Spaltung reduziert die größe der subprobleme ein wenig. Definieren Sie also die Dichte als den Bruchteil der Bits, die (dh von allen Bits), und die Dichte der Bitposition als den Bruchteil der Bitvektoren, die an Position .1 0 Δ 1 n k i 1 i110Δ1nki1i
Handhabung sehr geringer Dichte
Als nächster Schritt könnten wir uns fragen, was passiert, wenn die Dichte extrem klein ist. Es stellt sich heraus, dass, wenn die Dichte an jeder Bitposition kleiner als , wir garantiert sind, dass ein nicht überlappendes Paar existiert: Es gibt ein (nicht konstruktives) Existenzargument, das zeigt, dass sich einige nicht überlappen Paar muss existieren. Das hilft uns nicht, es zu finden, aber zumindest wissen wir, dass es existiert.1/k−−√
Warum ist das so? Angenommen, ein Paar von Bitvektoren wird durch die Bitposition abgedeckt, wenn . Beachten Sie, dass jedes Paar überlappender Bitvektoren durch eine Bitposition abgedeckt sein muss. Wenn wir nun eine bestimmte Bitposition festlegen , beträgt die Anzahl der Paare, die von dieser Bitposition abgedeckt werden können, höchstens . Summiert man über alle der Bitpositionen, so ergibt sich, dass die Gesamtzahl der Paare, die von einer Bitposition abgedeckt werden,i x i = y i = 1 i ( n & Dgr; ( i ) ) 2 < n 2 / k k < n 2x,yixi=yi=1i(nΔ(i))2<n2/kk<n2. Dies bedeutet, dass es ein Paar geben muss, das von keiner Bitposition abgedeckt wird, was bedeutet, dass sich dieses Paar nicht überlappt. Wenn also die Dichte in jeder Bitposition ausreichend niedrig ist, dann existiert mit Sicherheit ein nicht überlappendes Paar.
Ich bin jedoch nicht in der Lage, einen schnellen Algorithmus zu finden, um ein solches nicht überlappendes Paar in diesem Regime zu finden, obwohl garantiert ist, dass eines existiert. Ich sehe nicht sofort irgendwelche Techniken, die eine Laufzeit ergeben würden, die eine subquadratische Abhängigkeit von . Dies ist also ein netter Spezialfall, auf den Sie sich konzentrieren sollten, wenn Sie etwas Zeit zum Nachdenken über dieses Problem verwenden möchten.n
Hin zu einem allgemeinen Algorithmus
Im allgemeinen Fall scheint eine natürliche Heuristik zu sein: die Bit - Position holen mit der größten Anzahl an (mit der höchsten Dichte dh) ‚s und Split auf sich. Mit anderen Worten:1i1
Suchen Sie eine Bitposition , die maximiert .Δ ( i )iΔ(i)
Teile und basierend auf der Bitposition . Mit anderen Worten, Form , , , .T i S 0 = { s ∈ S : s i = 0 } S 1 = { s ∈ S : s i = 1 } T 0 = { t ∈ T : t i = 0 } T 1 = { t ∈ T : t i = 1 }STiS0={s∈S:si=0}S1={s∈S:si=1}T0={t∈T:ti=0}T1={t∈T:ti=1}
Suchen Sie nun rekursiv nach einem nicht überlappenden Paar aus , und . Wenn ein rekursiver Aufruf ein nicht überlappendes Paar findet, geben Sie es aus. Anderenfalls wird "Kein überlappendes Paar vorhanden" ausgegeben.S 0 , T 1 T 1 , S 0S0,T0S0,T1T1,S0
Die Herausforderung besteht darin, die Leistung im schlimmsten Fall zu analysieren.
Nehmen wir an, dass wir als Vorverarbeitungsschritt zuerst die Dichte jeder Bitposition berechnen. Auch wenn für jedes , wird angenommen, dass der Vorverarbeitungsschritt "Ein überlappendes Paar existiert" ausgibt (ich stelle fest, dass dies kein Beispiel für ein überlappendes Paar darstellt, Aber lassen Sie uns das als separate Herausforderung beiseite stellen. All dies kann in Zeit erledigt werden. Die Dichteinformationen können bei rekursiven Aufrufen effizient verwaltet werden. Es wird nicht der dominierende Beitrag zur Laufzeit sein. iO(nk)Δ(i)<1/k−−√iO(nk)
Wie wird die Laufzeit dieses Verfahrens sein? Ich bin nicht sicher, aber hier sind einige Beobachtungen, die helfen könnten. Jede Rekursionsstufe verringert die Problemgröße um ungefähr Bitvektoren (z. B. von Bitvektoren zu Bitvektoren). Daher kann die Rekursion nur ungefähr Ebenen tief gehen. Ich bin mir jedoch nicht sofort sicher, wie ich die Anzahl der Blätter im Rekursionsbaum zählen soll (es gibt viel weniger als Blätter), daher bin ich mir nicht sicher, zu welcher Laufzeit dies führen soll zu. nn-n/ √n/k−−√n √n−n/k−−√ 3 √k−−√3k√