Esiste una funzione hash per una raccolta (ad es. Multi-set) di numeri interi con buone garanzie teoriche?


36

Sono curioso di sapere se esiste un modo per memorizzare un hash di un set multiplo di numeri interi che abbia le seguenti proprietà, idealmente:

  1. Usa lo spazio O (1)
  2. Può essere aggiornato per riflettere un inserimento o una cancellazione nel tempo O (1)
  3. Due raccolte identiche (ovvero raccolte che hanno gli stessi elementi con le stesse molteplicità) devono sempre avere lo stesso valore e due raccolte distinte devono avere hash a valori diversi con alta probabilità (ovvero la funzione è indipendente o indipendente dalla coppia)

Un primo tentativo sarebbe quello di memorizzare il modulo modulo in un numero casuale casuale di hash dei singoli elementi. Questo soddisfa 1 e 2 ma non è chiaro se esso, o una variazione stretta, soddisferebbe 3.

Inizialmente l'ho pubblicato su StackOverflow .

* Le proprietà 1 e 2 potrebbero essere leggermente rilassate, ad esempio O (log n) o un piccolo polinomio sublineare. Il punto è vedere se siamo in grado di identificare più insiemi e testare in modo affidabile l'uguaglianza senza memorizzare gli elementi stessi.


Qual è la tua rappresentazione di multiset? Cioè, come si codifica un multiset come stringa di bit? Se vuoi davvero ottenere operazioni -time (indipendentemente dalle dimensioni del multiset), penso che dovresti rendere esplicita la codifica. O(1)
Jukka Suomela,

La codifica dei set non è importante. La funzione hash dovrebbe essere indipendente dalla rappresentazione degli insiemi. Se stavo usando una rappresentazione canonica di un set di hash, allora qualsiasi hash standard sulla rappresentazione in bit del set soddisferebbe 3 e probabilmente 1, ma non 2. Dovrei aggiungere che due raccolte uguali dovrebbero sempre avere lo stesso valore.
jonderry,

Cosa intendi esattamente con 2? Ottieni il vecchio set, il vecchio codice hash e il nuovo elemento e vuoi calcolare il nuovo codice hash? O ottieni solo il vecchio codice hash e il nuovo elemento?
Mihai,

Idealmente, non avresti bisogno del vecchio set. Non è nemmeno necessario essere in grado di eseguire query sui membri (importante, dati i limiti di spazio), solo test di uguaglianza, probabilmente attraverso il confronto di valori hash che hanno una bassa probabilità di un falso positivo.
jonderry,

Risposte:


17

Se pensi ai set come a vivere nell'universo , è abbastanza facile risolvere il tuo problema con il tempo di aggiornamento di O ( lg u ) . Tutto ciò di cui hai bisogno è una funzione hash veloce per un vettore di numeri u , con rapidi "aggiornamenti locali".[u]O(lgu)u

Wikipedia / Universal hashing suggerisce , dove p è un numero primo abbastanza grande e a è uniformemente disegnato da [ p ] . Quando aggiungi o rimuovi elemento i , devi aggiungere / sottrarre una i dal codice hash, che richiede tempo O ( lg i ) usando divide e conquistare per l'espiazione. Dal momento che un polinomio di grado uh(X)=(Σio=1uXioun'io)modppun'[p]ioun'ioO(lgio)upuò avere solo radici, la probabilità di collisione per due insiemi distinti è O ( u / p ) . Questo può essere reso molto piccolo prendendo p in modo che sia abbastanza grande (per esempio, p = u 2 e lavori in "doppia precisione"). Se i set sono molto più piccoli di [ u ] , puoi ovviamente iniziare con l'hashing dell'universo in un universo più piccolo.uO(u/p)pp=u2[u]

Qualcuno conosce una soluzione con probabilità di collisione quando hashing per range [ p ] ? Questo dovrebbe essere possibile.O(1/p)[p]


0

Carter e Wegman trattano questo nelle nuove funzioni hash e nel loro uso nell'autenticazione e impostano l'uguaglianza ; è molto simile a quello che descrivi. In sostanza una funzione hash commutativa può essere aggiornata un elemento alla volta per inserimenti ed eliminazioni e corrispondenze ad alta probabilità, in O (1).


Penso che questo funzioni solo sui set, non sui multiset (come richiesto dalla domanda). Dalla sezione 5, nella parte inferiore della pagina 274: "AGGIUNGI (x, S) -Aggiunta l'elemento x all'insieme denominato S. Questa operazione non può essere utilizzata se x è già membro di S."
jbapple

Hai ragione; Ho perso la parte "multi". Sembra probabile che una funzione hash possa gestire i duplicati, anche se non ne ho una citazione.
KWillets,

-2

La qualità di una funzione hash dipenderà sempre dalle proprietà degli elementi che deve avere. Puoi dire qualcosa a riguardo? Ad esempio, il tuo suggerimento sul prodotto è probabilmente una funzione hash scadente se gli elementi x_i del tuo multiset presentano in genere molti piccoli fattori primi. Ma puoi migliorarlo in questo caso semplicemente prendendo il prodotto di tutti x_i + p mod q per alcuni numeri primi p e q.


1
Sì, questa è la ragione per prendere gli hash dei singoli elementi prima di moltiplicarli insieme.
jonderry,

Che cosa? Il suggerimento del PO è semplicemente di moltiplicarli tutti insieme, no? Sto dicendo che se aggiungi una costante a ciascuno prima di farlo, probabilmente otterrai un hash migliore.
TonyK,

-5
A = 0x4F1BBCDD
B = 0x314EFB75
A*B = 1 
N = size of set before addition/removal<P>
Add X
H = (H-N)*B
U = H >> 16
V = H & 0xFFFF
H = (((U+X)&M)<<16) + ((V^X)&M)
H *= A
H += N+1

Remove X
H = (H-N)*B
U = H >> 16
V = H & 0xFFFF
H = (((U-X)&M)<<16) + ((V^X)&M)
H *= A
H += N-1

la somma ci consente di avere più occorrenze dello stesso valore che
xor ci consente di avere insiemi che sommano allo stesso importo

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.