Стиснення двох цілих чисел, не враховуючи порядок


20

Якщо порівнювати впорядковану пару (x, y) з не упорядкованою парою {x, y} (безліч), то теоретично інформація є різницею лише в одному біті, тому що, якщо x приходить першим, або y потрібен рівно один біт для представлення.

Отже, якщо нам задають набір {x, y}, де x, y - це два різних 32-бітових цілих числа, чи можемо ми спакувати їх у 63 біти (а не 64)? Повинно бути можливим відновити початкові 32-бітні цілі числа з результату 63 біт, але без можливості відновити їх порядок.

Відповіді:


27

Так, можна. Якщо , наведіть набір на число{ x , y }x<y{x,y}

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

Неважко показати, що бієктивна, і тому це можна однозначно розшифрувати. Також, коли 0 x < y < 2 32 , маємо 0 f ( x , y ) < 2 63 - 2 31 , тому це відображає множину { x , y } на 63-бітове число f ( x , y ) . Для розшифровки можна використовувати двійковий пошук на y або взяти квадратний корінь: y має бути приблизно f0x<y<2320f(x,y)<263231{x,y}f(x,y)yy.2f(x,y)


1
так само, як 1 + 2 + 3 + ... + y + x приємно!
Troy McClure

1
будь-яке узагальнення до n не упорядкованих ints? :) по-друге, багато чотирикутників з досить великими частковими похідними зроблять цю роботу
Трой МакКлур

4
Ще одна відповідь, яка може бути привабливою своєю низькою вартістю обчислень: якщо xі yрізні, то або x-y-1або y-x-1(і мод , звичайно) вкладається в 31 біт. Якщо мало, то з'єднайте і останні 31 біт ; в іншому випадку з'єднати і останні 31 біт . Відновіть два числа, взявши перші 32 біти за одне число і додавши перші 32 біти, останні 31 біт та постійну 1 (mod 2 32 ) як інше. 232x-y-1yx-y-1xy-x-1232
Даніель Вагнер

1
ваш метод також непогано узагальнить додавання більшої кількості цифр, оскільки перше число "просто там", так що може ланцюг
Трой МакКлур

4
@DW: Не могли б ви також додати, як ви придумали це представництво? Інакше здається, що ти витягнув його з повітря.
Мехрдад

9

Як додаток до відповіді DW, зауважимо, що це окремий випадок Комбінаторної системи чисел , яка компактно відображає суворо зменшується послідовність невід’ємних цілих чисел c k > > c 1 до N = k i = 1 ( c ikck>>c1

N=i=1k(cii).

Це число має просте тлумачення. Якщо ми упорядкуємо ці послідовності лексикографічно, то підраховує кількість менших послідовностей.N

Для декодування просто призначте найбільше значення, таке що ( c kckі декодуємоN- ( ck(ckk)N як a(k-1)-наслідок.N(ckk)(k1)


4

Загальна кількість невпорядкованих пар чисел у наборі дорівнює N ( N + 1 ) / 2 . Загальна кількість не упорядкованих пар різних чисел становить N ( N - 1 ) / 2 . Це займає 2 журналу 2 ( N ) = увійти 2 ( N 2 ) біта для представлення впорядкованої пари чисел, і якщо ви маєте один менше біт, ви можете представляти елементи простору до N 2 / 2NN(N+1)/2N(N1)/22log2(N)=log2(N2)N2/2. Кількість не упорядкованих не обов'язково розрізнених пар трохи більше половини кількості впорядкованих пар, тому ви не можете трохи заощадити в поданні; кількість не упорядкованих окремих пар трохи менше половини, тому ви можете трохи заощадити.

Для практичної схеми, яку легко обчислити, має потужність 2, ви можете працювати над бітовим поданням. Візьміть a = x y, де - оператор XOR (бітовий ексклюзив або). Пару { x , y } можна відновити з ( a , x ) або ( a , y ) . Тепер ми шукатимемо хитрість, щоб зберегти один біт у другій частині, і надамо симетричну роль x і yNa=xy{x,y}(a,x)(a,y)xyщоб замовлення не вдалося відновити. Зважаючи на обчислення кардинальності вище, ми знаємо, що ця схема не працюватиме у випадку, коли .x=y

Якщо то там є якесь бітове положення, де вони відрізняються. Я напишу x i для i- го біта x (тобто x = i x i 2 i ), а також y . Нехай k займає найменше бітове положення, де х і у різняться: k - найменше i таке, що x iy i . k - найменший i такий, що a i 1xyxiixx=ixi2iykxykixiyikiai=1kabxykb=i<kxi2i+i>kxi2i1b=i<kyi2i+i>kyi2i1) — to make the construction symmetric, pick x if xk=0 and yk=1, and pick y if xk=1 and yk=0. Use (a,b) as the compact representation of the pair. The original pair can be recovered by computing the lowest-order bit that is set in a, inserting a 0 bit at this position in b (yielding one of x or y), and taking the xor of that number with a (yielding the other element of the pair).

In this representation, a can be any nonzero number, and b can be any number with half the range. This is a sanity check: we get exactly the expected number of representations of unordered pairs.

In pseudocode, with ^, &, |, <<, >>, ~ being C-like bitwise operators (xor, and, or, left-shift, right-shift, complement):

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)

0

A nonconstructive proof: there are (232×232232)/2=231(2321)<263 unordered pairs of different 32-bit integers.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.