Jaki jest kompaktowy sposób reprezentowania partycji zestawu?


11

Istnieją wydajne struktury danych do reprezentowania ustawionych partycji. Te struktury danych charakteryzują się dużą złożonością czasową dla operacji takich jak Union i Find, ale nie są szczególnie efektywne pod względem przestrzeni.

Jaki jest oszczędny przestrzennie sposób reprezentowania partycji zestawu?

Oto jeden z możliwych punktów wyjścia:

Wiem, że liczba partycji zestawu z N elementami to , numer ty Bell . Zatem optymalna złożoność przestrzeni do reprezentowania partycji zestawu z elementami to bitów. Aby znaleźć taką reprezentację, moglibyśmy poszukać odwzorowania jeden na jednego między (zestawem partycji zestawu elementów) a (zestawem liczb całkowitych od do ). NBNNlog 2 ( B N ) N 1 B NNlog2⁡(BN)N1BN

Czy istnieje takie mapowanie, które jest wydajne w obliczeniach? Rozumiem przez „wydajny” to, że chcę przekonwertować tę zwartą reprezentację na / z łatwej w obsłudze reprezentacji (takiej jak lista list) w wielomianie czasowym w lub .log 2 ( B N )Nlog2⁡(BN)


zastanawiasz się, jak daleko może być od naiwnego / naturalnego kodowania polegającego na przypisaniu unikalnych liczb całkowitych do każdego elementu zestawu, w którym liczba całkowita reprezentuje partycję #? może to „niezbyt duża różnica” ...log2⁡(BN)
— wer 16'13

Odpowiedzi:


7

Aby znaleźć kodowanie, możesz użyć sposobu wyprowadzenia poniższej formuły rekurencyjnej:

bn+1=∑k=0n(nk)bk.
Dowodzi tego rozważenie, ile innych elementów znajduje się w części zawierającej elementn+1. Jeśli jest ichn-k, to mamy(nn-k)=(nk) wybory dla nich, ibkwybory dla podziału pozostałych.

Korzystając z tego, możemy podać algorytm rekurencyjny do konwersji dowolnej partycji n+1 na liczbę z zakresu 0,…,Bn+1−1 . Zakładam, że masz już sposób konwertowania podzbiór rozmiarze k z {1,…,n} na liczbę w zakresie 0,…,(nk)−1(taki algorytm można opracować w ten sam sposób, korzystając z powtarzalności Pascala(nk)=(n−1k)+(n−1k−1) ).

Załóżmy, że część zawierająca n+1 zawiera k innych elementów. Znajdź ich kod C1 . Oblicz partycję {1,…,n−k} , „kompresując” wszystkie pozostałe elementy do tego zakresu. Rekurencyjnie oblicz kod C2 . Nowy kod to

C=∑l=0n−k−1(nl)Bl+C1Bn−k+C2.

W przeciwnym kierunku, biorąc pod uwagę kod C , znajdź unikalne k takie, że

∑l=0n−k−1(nl)Bl≤C<∑l=0n−k(nl)Bl,
i określają
C′=C−∑l=0n−k−1(nl)Bl.
Ponieważ0≤C′<(nk)Bn−k, można zapisać jakoC1Bn−k+C2, gdzie0≤C2<Bn−k. TerazC1koduje elementy w części zawierającejn+1, aC2koduje partycję{1,…,n−k}, które można dekodować rekurencyjnie. Aby zakończyć dekodowanie, musisz „zdekompresować” drugą partycję, aby zawierała cały element nie pojawiający się w części zawierającej n+1 .


Oto jak zastosować tę samą technikę do rekurencyjnego kodowania podzbioru S wielkości {1,…,n} o rozmiarze k . Jeśli k=0 wówczas kod wynosi 0 , więc załóżmy, że k>0 . Jeśli n∈S niech C1 będzie kodem S∖{n} , jako podzbiorem wielkości k−1 z {1,…,n−1}; kod S to C1 . Jeśli n∉S niech C1 będzie kod S , jako podzbiór o rozmiarze k o {1,…,n−1} ; kod S to C1+(n−1k−1) .

Aby zdekodować kod C , istnieją dwa przypadki. Jeśli C<(n−1k−1) a następnie zdekoduj podzbiórS′o wartości{1,…,n−1}o rozmiarzek−1którego kodem jestC, iwyślijS′∪{n}. W przeciwnym razie zdekoduj podzbiórS′o wartości{1,…,n−1}o rozmiarzekktórego kod toC−(n−1k−1) i wyjścieS′.


Doskonała odpowiedź; Dziękuję Ci. Drobny błąd: w szkicu wzoru dla formuły rekurencyjnej u góry myślę, że masz na myśli „jest tych” zamiast „jest ich k ” - wtedy pozostałe k elementów można podzielić na B k sposoby n−kkkBk
— cberzan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.