Le nombre total de paires non ordonnées de nombres dans un ensemble de est . Le nombre total de paires non ordonnées de nombres distincts est . Il faut bits pour représenter une paire ordonnée de nombres, et si vous avez un bit de moins, vous pouvez représenter des éléments d'un espace allant jusqu'à . Le nombre de paires non ordonnées non nécessairement distinctes est légèrement supérieur à la moitié du nombre de paires ordonnées, vous ne pouvez donc pas enregistrer un peu dans la représentation; le nombre de paires distinctes non ordonnées est légèrement inférieur à la moitié, vous pouvez donc économiser un peu.NN(N+1)/2N(N−1)/22log2(N)=log2(N2)N2/2
Pour un schéma pratique facile à calculer, étant une puissance de 2, vous pouvez travailler sur la représentation au niveau du bit. Prenez où est l'opérateur XOR (bitwise exclusif ou). La paire peut être récupérée à partir de ou . Nous allons maintenant chercher une astuce pour enregistrer un bit dans la deuxième partie, et donner un rôle symétrique à et afin que l'ordre ne puisse pas être récupéré. Étant donné le calcul de cardinalité ci-dessus, nous savons que ce schéma ne fonctionnera pas dans le cas où .Na=x⊕y⊕{x,y}(a,x)(a,y)xyx=y
Si alors il y a une position de bits où ils diffèrent. J'écrirai pour le ème bit de (ie ), et de même pour . Soit la plus petite position binaire où et diffèrent: est le plus petit tel que . est le plus petit tel que : on peut récupérer partir de . Soit soit soitx≠yxiixx=∑ixi2iykxykixi≠yikiai=1kabxyavec le ème bit effacé (ie ou ) - pour rendre la construction symétrique, choisissez si et , et choisissez si et . Utilisez comme représentation compacte de la paire. La paire d'origine peut être récupérée en calculant le bit de poids faible défini dans , en insérant un bit 0 à cette position en (donnant l'un de ou ) et en prenant le xor de ce nombre aveckb=∑i<kxi2i+∑i>kxi2i−1b=∑i<kyi2i+∑i>kyi2i−1xxk=0yk=1yxk=1yk=0(a,b)abxya (donnant l'autre élément de la paire).
Dans cette représentation, peut être n'importe quel nombre différent de zéro et peut être n'importe quel nombre avec la moitié de la plage. Il s'agit d'un test de cohérence: nous obtenons exactement le nombre attendu de représentations de paires non ordonnées.ab
En pseudocode, avec ^
, &
, |
, <<
, >>
, ~
étant C-like opérateurs binaires (XOR, et, ou, à décalage à gauche, décalage à droite, complément):
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)