Знайдіть усі пари значень, близькі під відстань Хеммінга


11

У мене є кілька мільйонів 32-бітних значень. Для кожного значення я хочу знайти всі інші значення в межах відстані 5. У наївному підході для цього потрібні порівняння , яких я хочу уникати.O(N2)

Я зрозумів, що якщо я просто ставлюся до цих 32-бітових значень як цілі числа і сортував список один раз, то значення, які відрізнялися лише найменшими значущими бітами, закінчуються дуже близько. Це дозволяє мені мати коротше "вікно" або діапазон чисел, в межах яких я можу виконати фактичні пара-зіставлення для точної відстані забивання. Однак, коли 2 значення змінюються лише у бітах вищого порядку, вони опиняються поза цим "вікном" і з'являються в протилежних кінцях відсортованого списку. Напр

11010010101001110001111001010110

01010010101001110001111001010110

було б дуже далеко один від одного, навіть якщо їх відстань забивання дорівнює 1. Оскільки відстань удару між двома значеннями зберігається при обертанні обох, я зрозумів, що, роблячи 32 обертання ліворуч і потім кожного разу сортуючи список, цілком ймовірно, що 2 значення виявиться достатньо близько в упорядкованому списку хоча б в одному з них.

  1. Хоча такий підхід дає хороші результати, я намагаюся формально встановити правильність такого підходу.

  2. З огляду на те, що я шукаю відповідні значення, що мають відстань kming ham або менше, чи дійсно мені потрібно зробити всі 32 бітові обертання? Наприклад, якщо а розмір вікна - 1000, мені потрібно робити максимум 24-бітові обертання, оскільки навіть якщо бродячий біт з'явився в будь-якому з 8 бітів нижчого порядку, отримані цифри не будуть відрізнятися більш ніж на 1000.k = 1kk=1


Просто ідеї за 20 секунд роздумів: А як щодо сорту за Грей-Кодом? А як розділити список 32-розрядних растрових зображень на чотири списки 8-бітових растрових зображень, а потім використовувати вашу техніку?
Карл Дамгаард Асмуссен

1
Не могли б ви бути більш точними щодо дуже великої кількості растрових зображень? Це близько до , чи що завгодно? 2 30220230
мін

@minar: У мене є 3-4 мільйони таких 32-розрядних растрових зображень.
karterk

Я не впевнений, про що ви питаєте. Ви говорите про те, що у вас є масив з 32-буквових булевих рядків (великий, але не містить усіх можливих рядків), і ви хочете відзначити пари, які мають відстань Хеммінга не більше 5 в деяких Таким чином, можливо, створивши пов'язаний список індексів сусідніх сусідів для кожного рядка ? 4 × 10 9 iA[i]4×109A[i].closei
Андрас Саламон

думаю, існує аналогічне поняття "квадри", за винятком гіперкубів, що застосовується. алгоритм знаходить & рекурсивно розташовує вектори в гіперкубах, і тоді, коли ви хочете шукати "довколишні" бітвектори, ви шукаєте лише "довколишні" гіперкуби. підозрюєте, що це може бути вивчено і в папері десь .... не впевнені в правильних умовах ....
vzn

Відповіді:


9

Як зазначалося, ваш підхід є проблематичним, оскільки якщо 2 растрових карти мають рівномірно розташовані відмінності, то в будь-якому обертанні будуть різниці на деяких бітах високого порядку.

Ви можете узагальнити свій підхід, перетворивши позицію бітів у більш складний спосіб. Дійсно, якщо вибрати випадкову перестановку бітів, то всі відмінності між двома бітовими картами з відстані з'являться у 16 ​​бітах низького порядку з ймовірністю кращою . Отже, повторюючи кілька сотень разів, ви повинні знайти дуже велику частку своїх растрових пар. Для кожного випробування кількість пар для тестування (з тими ж 16 високими бітами) близька до (для ).1 / 50 64 Н Н 2 2251/5064NN222

Однак я б також спробував наступний підхід. Створіть список ваших растрових зображень, змінених у щонайбільше 2 бітових позиціях, і сортуйте цей список. Якщо в цьому списку є зіткнення, ви маєте два растрових карти на відстані . Потім перерахуйте всі значення початкових растрових зображень, модифікованих у трьох положеннях, і пошукайте їх у списку, щоб знайти пари растрових зображень на відстані . Вартість пам'яті цього підходу вимагає зберігання елементів і кількість елементів для пошуку в другій фазі .5 529 N 4960 N45529N4960N


Додаткова інформація:

  1. Ймовірність того, що розбіжностей розміщені в біт низького порядку після випадкової перестановки бітових позицій, є лише коефіцієнтом двох біномів: 16 32 ( 1651632
    (165)(325)0.0217
  2. Побудова списків для кожного елемента в оригінальному списку міститься в доповненому списку: сам елемент, всі елементи, що відрізняються в одній позиції, і всі елементи, що відрізняються в двох положеннях (зберігаючи інформацію про початковий елемент). Кількість копій для кожного елемента дорівнюєБудь-яке зіткнення в цьому списку (виявлене після сортування) відповідає двом вихідним елементам на відстані не більше . Зауважте, що кожну пару можна виявити кілька разів, тому вам потрібно буде видалити дублікати (але це вже було у випадку з вашим початковим алгоритмом).41+32+(322)=529.4
  3. Для остаточного проходу бажано обрізати доповнений список елементів, щоб тримати лише ті, що знаходяться на точній відстані від їх початкового елемента. Потім для кожного оригінального елемента створіть елементів на відстані та шукайте їх у розширеному списку. Ще раз вам потрібно видалити дублікати, оскільки кожна пара буде виявлена разів. [З особливою обережністю ви, напевно, можете передбачити / уникати більшості дублікатів, але я не впевнений, чи варто цього докладати.]( 322(323)=49603(53)=10

Щодо першого підходу, ви кажете, що я перестановлюю растрову карту в деяких заздалегідь визначених замовленнях, а не роблячи лише бітові обертання? Чи можете ви пояснити, як ви отримали 1/50 ймовірності? Також для другого підходу мені потрібно спочатку створити індекс мого списку, а потім для кожного елемента - генерувати (32C1 + 32C2) комбінації та перевірити їх проти цього індексу, щоб виявити всі растрові карти, що відрізняються на відстань 2? Було б чудово, якщо ви зможете пояснити це далі. Дякую.
karterk

5

Відповідь мінара відмінна і, мабуть, правильний підхід до цієї конкретної проблеми. Однак я згадаю ще один можливий підхід:

Ви можете використовувати функцію хеш-чутливості (LSH). Під цим терміном чутливий хеш - функція розроблений таким чином , що якщо близькі відстані Хеммінга, то . Якщо у вас є такий хеш , ви можете зберігати всі свої значення в хеш-таблиці (використовуючи хеш-функцію і відкритий хеш), і тоді ви дуже швидко зможете знайти всі пари значень, близькі на відстань Хеммінга . Існують різні методики побудови ЛШ; ви можете переглянути посилання на цю тему, щоб знайти декілька кандидатів.Нх,уН(х)=Н(у)НН

Однак, для вашої конкретної проблеми (з конкретними параметрами, які ви згадали), я очікую, що два алгоритми мінара виявляться на практиці кращими, ніж будь-яка схема на основі LSH. Я згадую про це лише у випадку, якщо інші читачі приходять сюди до цього питання з подібною проблемою, але з різними параметрами, де LSH може мати більше сенсу.

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