O número total de pares de números não ordenados em um conjunto de é . O número total de pares não ordenados de números distintos é . São necessários bits para representar um par ordenado de números e, se você tiver um bit a menos, poderá representar elementos de um espaço de até . O número de pares não ordenados não necessariamente distintos é um pouco mais da metade do número de pares ordenados, portanto você não pode economizar um pouco na representação; o número de pares distintos não ordenados é um pouco menos da metade, para que você possa economizar um pouco.NN(N+1)/2N(N−1)/22log2(N)=log2(N2)N2/2
Para um esquema prático fácil de calcular, com sendo uma potência de 2, você pode trabalhar na representação bit a bit. Tome que é o operador XOR (exclusivo bit a bit ou). O par pode ser recuperado de ou . Agora, procuraremos um truque para economizar um bit na segunda parte e atribuir uma função simétrica a e para que o pedido não possa ser recuperado. Dado o cálculo da cardinalidade acima, sabemos que esse esquema não funcionará no caso em que .Na=x⊕y⊕{x,y}(a,x)(a,y)xyx=y
Se , há alguma posição de bit onde eles diferem. Escreverei para o ésimo bit de (ie ) e da mesma forma para . Seja a menor posição de bit onde e diferem: é a menor tal que . é o menor tal que : podemos recuperar de . Seja ou oux≠yxiixx=∑ixi2iykxykixi≠yikiai=1kabxycom o bit apagado (ou seja, ou ) - para tornar a construção simétrica, escolha se e e escolha se e . Use como a representação compacta do par. O par original pode ser recuperado calculando o bit de ordem mais baixa definido em , inserindo um bit 0 nesta posição em (produzindo um de ou ) e levando o xor desse número comkb=∑i<kxi2i+∑i>kxi2i−1b=∑i<kyi2i+∑i>kyi2i−1xxk=0yk=1yxk=1yk=0(a,b)abxya (produzindo o outro elemento do par).
Nesta representação,a pode ser qualquer número diferente de zero pode ser qualquer número com metade do intervalo. Esta é uma verificação de sanidade: obtemos exatamente o número esperado de representações de pares não ordenados.b
Em pseudocódigo, com ^
, &
, |
, <<
, >>
, ~
sendo C-como operadores de bits (XOR, e, ou, desvio para a esquerda, direita-shift, complemento):
encode(x, y) =
let a = x ^ y
let k = lowest_set_bit_position(a)
let low_mask = (1 << k) - 1
let z = if x & (1 << k) = 0 then x else y
return (a, (z & low_mask) | (z & ~low_mask) >> 1)
decode(a, b) =
let k = lowest_set_bit_position(a)
let low_mask = (1 << k) - 1
let x = (b & low_mask) | ((b & ~low_mask) << 1)
return (x, a ^ x)