Gostaria de saber se existe uma função de números de n bits para números de n bits que possui as seguintes características:
- deve ser bijetivo
- Ambos e deve ser calculável rápido bastantef - 1
- deve retornar um número que não tem correlação significativa com sua entrada.
A lógica é esta:
Eu quero escrever um programa que opera com dados. Algumas informações dos dados são armazenadas em uma árvore de pesquisa binária em que a chave de pesquisa é um símbolo de um alfabeto. Com o tempo, adiciono mais símbolos ao alfabeto. Novos símbolos simplesmente obtêm o próximo número gratuito disponível. Portanto, a árvore sempre terá um pequeno viés para chaves menores, o que causa mais reequilíbrio do que eu acho que deveria ser necessário.
Minha idéia é alterar os números dos símbolos com modo que eles estejam amplamente espalhados por todo o intervalo de . Como os números dos símbolos são importantes apenas durante a entrada e a saída, o que ocorre apenas uma vez, a aplicação dessa função não deve ser muito cara.
Pensei em uma iteração do gerador de números aleatórios Xorshift, mas realmente não sei como desfazê-lo, embora teoricamente seja possível.
Alguém conhece essa função?
isso é uma boa ideia?
fonte
Respostas:
Você pode usar o hash Fibonacci ,
.hF(k)=k⋅5√−12−⌊k⋅5√−12⌋
Para , você obtém n números distintos por pares (aproximadamente) espalhados igualmente em [ 0 , 1 ] . Ao escalar para [ 1 .. M ] e arredondar (para baixo), você obtém números uniformemente distribuídos nesse intervalo.k=1,…,n n [0,1] [1..M]
Por exemplo, estes são redimensionados para [ 0..10000 ] (sequência original esquerda, classificação à direita):hF(1),…,hF(200) [0..10000]
Esta é uma instância do que Knuth chama de hash multiplicativo . Para o tamanho das palavras do computador, A um número inteiro relativamente primo w e M o número de endereços necessários, usamosw A w M
como função de hash. O exemplo acima é apresentado com (certifique-se de poder computá-lo com precisão suficiente). Embora isso também funcione com qualquer outro número irracional além de , é um dos dois únicos números que leva aos números "mais uniformemente distribuídos". ϕ-1A/w=ϕ−1=5√−12 ϕ−1
Encontre mais em The Art of Computer Programming , Volume 3, de Donald Knuth (capítulo 6.4 da página 513 na segunda edição). Em particular, você descobrirá por que os números resultantes são distintos entre pares (pelo menos se ) e como calcular a função inversa se você usar e naturais em vez de .A w ϕ - 1n≪M A w ϕ−1
fonte
Para entradas de bits, esta função funciona:k
Isso é reversível, pois e possui pares não sequenciais , em que . Cuidado que saída e entrada podem estar correlacionadas, especialmente se sua entrada estiver em .{ n , m } , n < m h a s h ( m ) < h a s h ( n ) { 1 , … , 2 ⌈ khash(hash(n))=n {n,m},n<m hash(m)<hash(n) {1,…,2⌈k2⌉−1}
Ref: Função hash reversível
fonte