Rozgrzewanie: losowe wektory bitowe
Jako rozgrzewkę możemy zacząć od przypadku, w którym każdy bitvector jest wybierany losowo równomiernie. Potem okazuje się, że problem można rozwiązać w czasie (a dokładniej można zastąpić ).O ( N : 1,6 min ( k , lg n ) ) 1,6 lg 3O(n1.6min(k,lgn))1.6lg3
Rozważymy następujący dwuczęściowy wariant problemu:
Podane zestawy z bitvectors określić, gdzie istnieje nienakładające się para .S , T ⊆ { 0 , 1 } k s ∈ S , t ∈ TS,T⊆{0,1}ks∈S,t∈T
Podstawową techniką rozwiązania tego jest dzielenie i podbijanie. Oto algorytm czasowy przy użyciu funkcji dziel i zwycięż:O ( n 1,6 k )O(n1.6k)
Podziel i podstawie pierwszej pozycji bitu. Innymi słowy, formularz , , , .S T S 0 = { s ∈ S : s 0 = 0 } S 1 = { s ∈ S : s 0 = 1 } T 0 = { t ∈ T : t 0 = 0 } T 1 = { t ∈ T : t 0 = 1 }STS0={s∈S:s0=0}S1={s∈S:s0=1}T0={t∈T:t0=0}T1={t∈T:t0=1}
Teraz rekurencyjnie szukaj pary nienakładającej się z , z oraz z . Jeśli jakieś wywołanie rekurencyjne znajdzie parę, która się nie nakłada, wyślij ją, w przeciwnym razie wyślij „Nie ma pary nakładających się”.S 0 , T 0 S 0 , T 1 T 1 , S 0S0,T0S0,T1T1,S0
Ponieważ wszystkie wektory bitowe są wybierane losowo, możemy spodziewać się i . Mamy więc trzy rekurencyjne wywołania i zmniejszyliśmy rozmiar problemu dwa razy (oba zestawy są zmniejszone dwa razy). Po jeden z dwóch zestawów ma rozmiar 1, a problem można rozwiązać w czasie liniowym. Otrzymujemy relację powtarzalności wzdłuż linii , których rozwiązaniem jest . Uwzględniając czas wykonywania dokładniej w przypadku dwóch zestawów, widzimy, że czas działania wynosi .| S b | ≈ | S | / 2 | 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)=3T(n/2)+O(nk)T(n)=O(n1.6k) ( min ( | S | , | T | ) 0,6 maks. ( | S | , | T | ) k )O(min(|S|,|T|)0.6max(|S|,|T|)k)
Można to jeszcze poprawić, zauważając, że jeśli , prawdopodobieństwo istnienia pary, która się nie pokrywa, jest wykładniczo małe. W szczególności, jeśli są dwoma losowymi wektorami, prawdopodobieństwo, że się nie pokrywają, wynosi . Jeśli , istnieje takich par, więc przez związanie, prawdopodobieństwo istnienia pary, która się nie nakłada, wynosi najwyżej . Kiedy , to . Tak więc, jako etap wstępnego przetwarzania, jeślik ≥ 2,5 lg n + 100 x , r ( 3 / 4 ), k | S | = | T | = N n 2 n 2 ( 3 / 4 ) k k ≥ 2,5 lg n + 100k≥2.5lgn+100x,y(3/4)k|S|=|T|=nn2n2(3/4)kk≥2.5lgn+100 ≤ 1 / 2 100 K ≥ 2,5 lg n + 100≤1/2100k≥2.5lgn+100, wówczas możemy natychmiast zwrócić „Nie ma pary nienakładającej się” (prawdopodobieństwo, że jest to niepoprawne, jest pomijalnie małe), w przeciwnym razie uruchomimy powyższy algorytm.
W ten sposób osiągamy czas działania (lub dla wariantu dwóch zestawów zaproponowanego powyżej), dla specjalnego przypadku, w którym bitwektory są wybierane równomiernie losowo.O ( n 1,6 min ( k , lg n ) ) O ( min ( | S | , | T | ) 0,6 maks. ( | S | , | T | ) min ( k , lg n ) )O(n1.6min(k,lgn))O(min(|S|,|T|)0.6max(|S|,|T|)min(k,lgn))
Oczywiście nie jest to najgorsza analiza. Losowe wektory bitowe są znacznie łatwiejsze niż najgorszy przypadek - ale traktujmy to jako rozgrzewkę, aby uzyskać kilka pomysłów, które być może moglibyśmy zastosować w przypadku ogólnym.
Lekcje z rozgrzewki
Możemy nauczyć się kilku lekcji z powyższej rozgrzewki. Po pierwsze, pomocna jest funkcja dziel i zwyciężaj (dzielenie na pozycję bitową). Po drugie, chcesz podzielić się na pozycji bitowej z jak największą liczbą w tej pozycji; im więcej , tym mniejsze zmniejszenie wielkości podproblemu.1 010
Po trzecie, sugeruje to, że problem staje się trudniejszy, gdy gęstość jest mniejsza - jeśli wśród bitvektorów jest bardzo niewiele (są to w większości ), problem wygląda dość trudny, ponieważ każdy podział zmniejsza się wielkość podproblemów trochę. Zdefiniuj więc gęstość jako ułamek bitów, które są (tj. Spośród wszystkich bitów ), a gęstość pozycji bitu aby była ułamkiem wektorów bitowych, które są w pozycji .1 1 0 Δ 1 n k i 1 i110Δ1nki1i
Obsługa bardzo niskiej gęstości
W kolejnym kroku możemy zastanawiać się, co się stanie, jeśli gęstość będzie wyjątkowo mała. Okazuje się, że jeśli gęstość w każdej pozycji bitowej jest mniejsza niż , gwarantujemy, że istnieje para nie nakładająca się: istnieje (niekonstruktywny) argument istnienia wskazujący, że niektóre nie nakładające się para musi istnieć. To nie pomaga nam go znaleźć, ale przynajmniej wiemy, że istnieje.1 / √k1/k−−√
Dlaczego tak jest? Powiedzmy, że para wektorów bitowych jest objęta pozycją bitu jeśli . Zauważ, że każda para nakładających się wektorów bitowych musi być zakryta przez jakąś pozycję bitu. Teraz, jeśli naprawimy określoną pozycję bitu , liczba par, które mogą być objęte tą pozycją bitu, wynosi co najwyżej . Podsumowując wszystkie pozycji bitów, stwierdzamy, że łączna liczba par objętych pewną pozycją bitową wynosix , y i x I = Y i = 1 i ( n Δ ( I ) )x,yixi=yi=1i 2 < n 2 / k k < n 2(nΔ(i))2<n2/kk<n2. Oznacza to, że musi istnieć para, która nie jest objęta żadną pozycją bitową, co oznacza, że ta para się nie nakłada. Jeśli więc gęstość jest wystarczająco niska w każdej pozycji bitowej, z pewnością istnieje para, która się nie nakłada.
Jednak nie mogę zidentyfikować szybkiego algorytmu, aby znaleźć taką nie nakładającą się parę w tych reżimach, nawet jeśli jedna z nich istnieje. Nie widzę od razu żadnych technik, które zapewniłyby czas działania zależny od kwadratury od . Jest to więc miły szczególny przypadek, na którym można się skoncentrować, jeśli chcesz poświęcić trochę czasu na przemyślenie tego problemu.nn
W kierunku algorytmu ogólnego przypadku
W ogólnym przypadku naturalna heurystyka wydaje się być: wybierz pozycję bitu z największą liczbą (tj. O największej gęstości) i podziel na nią. Innymi słowy:i 1i1
Znajdź pozycję bitową która maksymalizuje .i Δ ( i )iΔ(i)
Podział i podstawie pozycji bitu . Innymi słowy, formularz , , , .S 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}
Teraz rekurencyjnie szukaj pary nienakładającej się z , z oraz z . Jeśli jakieś wywołanie rekurencyjne znajdzie parę, która się nie nakłada, wyślij ją, w przeciwnym razie wyślij „Nie ma pary nakładających się”.S 0 , T 0 S 0 , T 1 T 1 , S 0S0,T0S0,T1T1,S0
Wyzwanie polega na analizie jego wydajności w najgorszym przypadku.
Załóżmy, że jako krok przetwarzania wstępnego najpierw obliczamy gęstość każdej pozycji bitu. Ponadto, jeśli dla każdego , przyjmijmy, że krok wstępnego przetwarzania daje wynik „Istnieje nakładająca się para” (zdaję sobie sprawę, że nie pokazuje to przykładu nakładającej się pary, ale odłóżmy to na bok jako osobne wyzwanie). Wszystko to można zrobić w czasie . Informacje o zagęszczeniu mogą być skutecznie utrzymywane, gdy wykonujemy połączenia rekurencyjne; nie będzie dominującym czynnikiem wpływającym na czas działania.Δ ( i ) < 1 / √k iO(nk)Δ(i)<1/k−−√iO(nk)
Jaki będzie czas trwania tej procedury? Nie jestem pewien, ale oto kilka spostrzeżeń, które mogą pomóc. Każdy poziom rekurencji zmniejsza rozmiar problemu o około bitvectors (np. Od bitvectors do bitvectors). Dlatego rekurencja może wchodzić tylko na głębokości około . Jednak nie jestem od razu pewny, jak policzyć liczbę liści w drzewie rekurencyjnym (jest dużo mniej niż liści), więc nie jestem pewien, jaki czas powinien to prowadzić do.n / √kn/k−−√ n n - n / √nk √n−n/k−−√k 3 √k−−√k3k√