Kompresowanie dwóch liczb całkowitych z pominięciem kolejności

20

Porównując parę uporządkowaną (x, y) z parą nieuporządkowaną {x, y} (zestaw), a następnie teoretycznie, różnica wynosi tylko jeden bit, ponieważ to, czy x jest pierwsze, czy y wymaga dokładnie jednego bitu do przedstawienia.

Więc jeśli otrzymamy zestaw {x, y}, gdzie x, y to dwie różne 32-bitowe liczby całkowite, czy możemy spakować je w 63 bitach (raczej 64)? Powinno być możliwe odzyskanie oryginalnych 32-bitowych liczb całkowitych z wyniku 63-bitowego, ale bez możliwości odzyskania ich kolejności.

Troy McClure
źródło

Odpowiedzi:

27

Tak, można. Jeśli x<y , zamapuj zestaw {x,y} na liczbę

f(x,y)=y(y1)/2+x.

Łatwo jest wykazać, że f jest bijectywny, a zatem można go jednoznacznie odkodować. Ponadto, gdy 0x<y<232 , mamy 0f(x,y)<263231 , więc mapuje to zestaw {x,y} na 63-bitową liczbę f(x,y) . Aby zdekodować, możesz użyć wyszukiwania binarnego na y lub użyć pierwiastka kwadratowego: y powinno wynosić około 2f(x,y).

DW
źródło
1
tak jak 1 + 2 + 3 + ... + y + x fajnie!
Troy McClure
1
jakieś uogólnienie na nieuporządkowane ints? :) z drugiej strony, wiele quadform z wystarczająco dużymi częściowymi pochodnymi wykona zadanie
Troy McClure
4
Inna odpowiedź, która może być atrakcyjna ze względu na niski koszt obliczeń: jeśli xi ysą różne, to jeden x-y-1lub y-x-1(oba mod , oczywiście) mieści się w 31 bitach. Jeśli jest mały, to konkatenuj i ostatnie 31 bitów ; w przeciwnym razie konkatenuje i ostatnie 31 bitów . Odzyskaj dwie liczby, biorąc pierwsze 32 bity jako jedną liczbę i dodając pierwsze 32 bity, ostatnie 31 bitów i stałą 1 (mod 2 32 ) jako drugą. 232x-y-1yx-y-1xy-x-1232
Daniel Wagner,
1
twoja metoda również ładnie uogólnia dodawanie kolejnych liczb, ponieważ pierwsza liczba jest „właśnie tam”, więc może zostać połączona
Troy McClure
4
@DW: Czy możesz również dodać, jak wymyśliłeś tę reprezentację? W przeciwnym razie wygląda na to, że wyciągnąłeś go z powietrza.
Mehrdad
9

Jako dodatek do odpowiedzi DW, zauważ, że jest to szczególny przypadek kombinatorycznego systemu liczb , który zwięźle odwzorowuje ściśle malejącą sekwencję liczb całkowitych nieujemnych c k > > c 1 do kck>>c1

N=i=1k(cii).

Liczba ta ma prostą interpretację. Jeśli uporządkujemy te sekwencje leksykograficzne, wówczas zlicza liczbę mniejszych sekwencji.N

Aby zdekodować, po prostu przypisz największą wartość, taką jak i zdekoduj jako sekwencję .ck(ckk)NN(ckk)(k1)

filipos
źródło
4

Całkowita liczba nieuporządkowanych par liczb w zbiorze wynosi . Całkowita liczba nieuporządkowanych par odrębnych liczb wynosi . Potrzeba bitów do przedstawienia uporządkowanej pary liczb, a jeśli masz jeden bit mniej, możesz reprezentować elementy przestrzeni do . Liczba nieuporządkowanych niekoniecznie odrębnych par jest nieco większa niż połowa liczby uporządkowanych par, więc nie możesz zapisać trochę w reprezentacji; liczba nieuporządkowanych odrębnych par jest nieco mniejsza niż połowa, więc możesz trochę zaoszczędzić.NN(N+1)/2N(N1)/22log2(N)=log2(N2)N2/2

Aby uzyskać praktyczny schemat, który jest łatwy do obliczenia, przy czym jest potęgą 2, możesz pracować z reprezentacją bitową. Weźmy gdzie jest operatorem XOR (bitowe wykluczenie lub). Pary można odzyskać z lub . Teraz szukamy sposobu na zaoszczędzenie jednego bitu w drugiej części i nadanie i symetrycznej roli, aby nie można było odzyskać kolejności. Biorąc pod uwagę powyższe obliczenia liczności, wiemy, że ten schemat nie zadziała w przypadku, gdy .Na=xy{x,y}(a,x)(a,y)xyx=y

Jeśli to jest trochę pozycji, w której się różnią. Napiszę dla tego bitu (tj. ), i podobnie dla . Niech przyjmie najmniejszą pozycję bitu, w której i różnią się: jest najmniejszą taką, że . jest najmniejszym takim, że : możemy odzyskać z . Niech będzie albo alboxyxiixx=ixi2iykxykixiyikiai=1kabxyz tym bitem skasowanym (tj. lub ) - aby konstrukcja była symetryczna, wybierz jeśli i , i wybierz jeśli i . Użyj jako zwartej reprezentacji pary. Pierwotną parę można odzyskać, obliczając bit najniższego rzędu ustawiony w , wstawiając bit 0 w tej pozycji (uzyskując jeden z lub ) i biorąc xor tej liczby za pomocąkb=i<kxi2i+i>kxi2i1b=i<kyi2i+i>kyi2i1xxk=0yk=1yxk=1yk=0(a,b)abxya (uzyskując drugi element pary).

W tej reprezentacji może być dowolną liczbą niezerową, a może być dowolną liczbą o połowie zakresu. Jest to kontrola rozsądku: otrzymujemy dokładnie oczekiwaną liczbę reprezentacji nieuporządkowanych par.ab

W Pseudokod, z ^, &, |, <<, >>, ~to C-like operatorów bitowe (XOR, AND, OR, lewy shift prawym zmianowych, dopełniacza):

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)
Gilles „SO- przestań być zły”
źródło
0

Niekonstruktywny dowód: istnieją nieuporządkowane pary różnych 32-bitowych liczb całkowitych.(232×232232)/2=231(2321)<263

Martín-Blas Pérez Pinilla
źródło