Розминка: випадкові бітректори
Як розминка, ми можемо почати з того випадку, коли кожен бітвектор вибирається в однаковому порядку рівномірно. Тоді виявляється, що задачу можна вирішити за час (точніше, 1,6 можна замінити на lg 3 ).O(n1.6min(k,lgn))1.6lg3
Ми розглянемо наступний двоскладовий варіант проблеми:
З урахуванням безлічі з бітвекторов, визначити , де існує неперекривающійся пари сек ∈ S , T ∈ T .S,T⊆{0,1}ks∈S,t∈T
Основний прийом для вирішення цього питання - розділити і перемогти. Ось алгоритм часу використанням ділення та перемоги:O(n1.6k)
Розділити і T на основі першого положення біта. Іншими словами, форма S 0 = { s ∈ S : s 0 = 0 } , S 1 = { s ∈ S : s 0 = 1 } , T 0 = { t ∈ T : t 0 = 0 } , T 1 = { t ∈ T : tSTS0={s∈S:s0=0}S1={s∈S:s0=1}T0={t∈T:t0=0} .T1={t∈T:t0=1}
Тепер рекурсивно шукайте пару, що не перекривається, від , від S 0 , T 1 і від T 1 , S 0 . Якщо будь-який рекурсивний виклик знайде пару, що не перекривається, виведіть його, інакше виведіть "Немає пари, що перекривається".S0,T0S0,T1T1,S0
Оскільки всі бітвектори вибираються випадковим чином, ми можемо очікувати та | Т б | ≈ | Т | / 2 . Таким чином, у нас є три рекурсивні дзвінки, і ми зменшили розмір проблеми в два рази (обидва набори зменшуються в розмірі в два рази). Після розбиття lg min ( | S | , | T | ) одна з двох множин зменшується до розміру 1, і проблему можна вирішити за лінійним часом. Ми отримуємо відношення рецидиву за лініями|Sb|≈|S|/2|Tb|≈|T|/2lgmin(|S|,|T|) , рішення якого T ( n ) = O ( n 1,6 k ) . Точніше, враховуючи час роботи у двоскладному випадку, ми бачимо, що час виконання - O ( хв ( | S | , | T | ) 0,6 макс. ( | S | , | T)T(n)=3T(n/2)+O(nk)T(n)=O(n1.6k) .O(min(|S|,|T|)0.6max(|S|,|T|)k)
Це можна вдосконалити, зазначивши, що якщо , то ймовірність існування пари, що не перекривається, експоненціально мала. Зокрема, якщо х , у двох випадкових векторів, ймовірність того, що вони не перекриваються є ( 3 / 4 ) K . Якщо | S | = | Т | = n , є n 2 таких пар, тому при зв'язанні об'єднанням ймовірність існування пари, що не перекривається, становить щонайбільше n 2 ( 3k≥2.5lgn+100x,y(3/4)k|S|=|T|=nn2 . Коли до ≥ 2,5 Л.Г. п + 100 , це ≤ 1 / 2 100 . Отже, як крок перед обробкою, якщо k ≥ 2,5 lg n + 100 , ми можемо негайно повернути "Не існує пари, що не перекривається," (ймовірність, що це неправильно, незначно мала), інакше ми запустимо вищевказаний алгоритм.n2(3/4)kk≥2.5lgn+100≤1/2100k≥2.5lgn+100
Таким чином , ми досягаємо час роботи (або O ( хв ( | S | , | Т | ) 0,6 Макс ( | S | , | Т | ) хв ( K , Lg п ) ) для двох заданих варіантів, запропонованих вище), для особливого випадку, коли біттектори вибираються рівномірно випадково.O(n1.6min(k,lgn))O(min(|S|,|T|)0.6max(|S|,|T|)min(k,lgn))
Звичайно, це не найгірший аналіз. Випадкові bitvectors значно простіше, ніж найгірший випадок - але давайте розглянемо це як розминку, щоб отримати деякі ідеї, які, можливо, ми можемо застосувати до загального випадку.
Уроки розминки
Ми можемо засвоїти кілька уроків з розминки вище. По-перше, корисним є поділ і перемогу (розкол на бітову позицію). По-друге, ви хочете розділити на бітову позицію якомога більше -х у цій позиції; чим більше їх у 0 , тим менше зменшення розміру підпроблеми.10
По-третє, це говорить про те, що проблема стає все складніше, коли щільність s зменшується - якщо серед бітвекторів дуже мало 1 -х (вони в основному 0 '), проблема виглядає досить важко, оскільки кожен розкол зменшується розмір підпроблем небагато. Отже, визначте, що щільність Δ є часткою бітів, що дорівнює 1 (тобто, з усіх n k біт), а щільність бітового положення i - частка бітвекторів, що є 1 у положенні i .110Δ1nki1i
Поводження з дуже низькою щільністю
На наступному кроці ми можемо задатися питанням, що станеться, якщо щільність надзвичайно мала. Виявляється, якщо щільність у кожному бітовому положенні менша за , ми гарантуємо, що існує пара, що не перекривається: є аргумент існування (неконструктивний), який показує, що повинна існувати якась пара, що не перекривається. Це не допомагає нам його знайти, але, принаймні, ми знаємо, що воно існує.1/k−−√
Чому це так? Скажімо , що пара бітвекторов буде покрита на бітової позиції я , якщо х я = у я = 1 . Зверніть увагу, що кожна пара бітректорів, що перекриваються, повинна бути охоплена деяким положенням бітів. Тепер, якщо ми зафіксуємо конкретне бітове положення i , кількість пар, які можуть бути охоплені цим бітовим положенням, становить щонайбільше ( n Δ ( i ) ) 2 < n 2 / k . Підведення підсумків по всіх kx,yixi=yi=1i(nΔ(i))2<n2/kkз бітових позицій ми знаходимо, що загальна кількість пар, охоплених деяким бітовим положенням, становить . Це означає, що повинна існувати пара, яка не охоплена жодною бітовою позицією, що означає, що ця пара не перекривається. Отже, якщо щільність є достатньо низькою у кожному бітовому положенні, то, безумовно, існує пара.<n2
Однак я в збитті визначити швидкий алгоритм пошуку такої пари, що не перекривається, в цьому режимі, навіть якщо такий гарантовано існує. Я не одразу бачу жодної техніки, яка б дала час роботи, що має субквадратичну залежність від . Отож, це приємний особливий випадок, на який слід зосередитися, якщо ви хочете витратити якийсь час на роздуми над цією проблемою.n
До алгоритму загального випадку
У загальному випадку, схоже, природний евристичний виглядає так: виберіть бітове положення з найбільшою кількістю 1 's (тобто з найбільшою щільністю), і розділіть його. Іншими словами:i1
Знайдіть бітове положення яке максимізує Δ ( i ) .iΔ(i)
Розщеплення і T на основі бітового положення i . Іншими словами, форма S 0 = { s ∈ S : s i = 0 } , S 1 = { s ∈ S : s i = 1 } , T 0 = { t ∈ T : t i = 0 } , T 1 = { t ∈ T :STiS0={s∈S:si=0}S1={s∈S:si=1}T0={t∈T:ti=0} .T1={t∈T:ti=1}
Тепер рекурсивно шукайте пару, що не перекривається, від , від S 0 , T 1 і від T 1 , S 0 . Якщо будь-який рекурсивний виклик знайде пару, що не перекривається, виведіть його, інакше виведіть "Немає пари, що перекривається".S0,T0S0,T1T1,S0
Завдання полягає в аналізі його ефективності в гіршому випадку.
Припустимо, що в якості етапу попередньої обробки спочатку обчислюємо щільність кожної бітової позиції. Також, якщо для кожногоi, припустимо, що етап попередньої обробки виводить "Пара, що перекривається, існує" (я розумію, що це не є прикладом пари, що перекривається, але давайте відкладемо це як окремий виклик). Все це можна зробити заO(nk)час. Інформацію про щільність можна ефективно підтримувати, коли ми робимо рекурсивні дзвінки; це не буде домінуючим фактором часу роботи.Δ(i)<1/k−−√iO(nk)
Яким буде час роботи цієї процедури? Я не впевнений, але ось кілька спостережень, які можуть допомогти. Кожен рівень рекурсії зменшує розмір проблеми приблизно на bitvectors (наприклад, відnbitvectors доn-n/ √n/k−−√n bitvectors). Тому рекурсія може тривати лише √n−n/k−−√ рівні глибокі. Однак я не одразу впевнений, як підрахувати кількість листя в дереві рекурсії (їх набагато менше3 √k−−√ відходить), тому я не впевнений, до якого часу роботи це повинно призвести.3k√