Qual è un modo compatto per rappresentare una partizione di un set?


11

Esistono strutture dati efficienti per rappresentare partizioni impostate. Queste strutture di dati presentano una buona complessità temporale per operazioni come Union e Find, ma non sono particolarmente efficienti in termini di spazio.

Qual è un modo efficiente in termini di spazio per rappresentare una partizione di un set?

Ecco un possibile punto di partenza:

So che il numero di partizioni di un set con elementi è , il numero - Bell . Quindi la complessità dello spazio ottimale per rappresentare una partizione di un set con elementi è bit. Per trovare una tale rappresentazione, potremmo cercare un mapping uno a uno tra (il set di partizioni di un set di elementi) e (il set di numeri interi da a ).B N N N log 2 ( B N ) N 1 B NNBNNNlog2(BN)N1BN

Esiste una mappatura così efficiente da calcolare? Quello che intendo per "efficiente" è che voglio convertire questa rappresentazione compatta in / da una rappresentazione facile da manipolare (come un elenco di elenchi) in un polinomio temporale in o .log 2 ( B N )Nlog2(BN)


chiedendosi, quanto lontano potrebbe essere dalla codifica ingenua / naturale dell'assegnazione di interi univoci a ciascun elemento dell'insieme in cui l'intero rappresenta la partizione #? forse non è "non molta differenza" ...log2(BN)
vzn

Risposte:


7

Puoi usare il modo in cui la formula di ricorrenza seguente viene derivata per trovare la tua codifica: Ciò è dimostrato considerando quanti altri elementi ci sono nella parte che contiene l'elemento . Se ce ne sono , allora abbiamo scelte per loro e scelte per partizionare il resto.

Bn+1=k=0n(nk)Bk.
n+1nk(nnk)=(nk)Bk

Usando questo, possiamo dare un algoritmo ricorsivo per convertire qualsiasi partizione di in un numero nell'intervallo . Presumo che tu abbia già un modo di convertire un sottoinsieme di dimensioni di in un numero nell'intervallo (un tale algoritmo può essere ideato allo stesso modo usando la ricorrenza di Pascal ).n+10,,Bn+11k{1,,n}0,,(nk)1(nk)=(n1k)+(n1k1)

Supponiamo che la parte contenente contenga altri elementi. Trova il loro codice . Calcola una partizione di "comprimendo" tutti gli elementi rimanenti in quell'intervallo. Calcola ricorsivamente il suo codice . Il nuovo codice èn+1kC1{1,,nk}C2

C=l=0nk1(nl)Bl+C1Bnk+C2.

Nell'altra direzione, dato un codice , trova il unico tale che e definisci Dal momento che , può essere scritto come , dove . Ora codifica gli elementi nella parte contenente e codifica una partizione diCk

l=0nk1(nl)BlC<l=0nk(nl)Bl,
C=Cl=0nk1(nl)Bl.
0C<(nk)BnkC1Bnk+C20C2<BnkC1n+1C2{1,,nk}n+1, che può essere decodificato in modo ricorsivo. Per completare la decodifica, è necessario "decomprimere" quest'ultima partizione in modo che contenga tutto l'elemento che non appare nella parte contenente .n+1


Ecco come utilizzare la stessa tecnica per codificare un sottoinsieme di di dimensione , ricorsivamente. Se il codice è , quindi supponiamo che . Se allora lascia che sia un codice di , come sottoinsieme della dimensione di ; il codice di è . Se allora lascia che sia un codice di , come un sottoinsieme di dimensioni di ; il codice diS{1,,n}kk=00k>0nSC1S{n}k1{1,,n1}SC1nSC1Sk{1,,n1}SC 1 +è .C1+(n1k1)

Per decodificare un codice , ci sono due casi. Se quindi decodifica un sottoinsieme di di dimensioni cui codice è e genera . Altrimenti, decodifica un sottoinsieme di di dimensione cui codice è e .CC<(n1k1)S{1,,n1}k1CS{n}S{1,,n1}kC(n1k1)S


Risposta eccellente; grazie. Bug minore: nello schizzo di prova per la formula di ricorrenza in alto, penso che tu intenda "ci sono di quelli" invece di "ci sono k di quelli" - quindi i restanti k elementi possono essere partizionati in B k modi. nkkkBk
cberzan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.