Алгоритм пошуку підмножини


9

Припустимо, у мене є список X підмножини {1,...,n}. Я можу зробити попередню обробку в цьому списку, якщо необхідно. Після цієї попередньої обробки мені представлений ще один набірA{1,...,n}. Я хочу визначити будь-які набориBX з BA.

Очевидний алгоритм (без будь-якої попередньої обробки) вимагає часу O(n|X|) - ти просто тестуєш A проти кожного BXокремо. Чи є щось краще, ніж це?

Якщо це допомагає, ви можете припустити, що для будь-якого A, загальна кількість матчів BX межує чимось на кшталт O(1).

Відповіді:


3

Це не відповідь. Це просте, але тривале спостереження. Сподіваюся, це стане в нагоді.

Версія вашої проблеми є: чи X містять підмножину A?

Ця проблема пов'язана з проблемою оцінки монотонних булевих функцій nзмінні. Підмножина{1,,n} еквівалентний n-бістринг, так що сім'я X еквівалентна булева функція f з nзмінні. Дана функціяf, можна визначити найменш монотонну функцію, яка не більша за f, а саме g(y)=(xy,f(x)). Первісна проблема зводиться до оцінюванняg(A). І навпаки, проблема оцінки монотонної булевої функції може бути зведена до початкової задачі, або наївно, приймаючиf=g або вибравши f що робить X менший.

На практиці BDD мають тенденцію працювати добре. Тож один можливий підхід - це створення BDD дляf, походять від нього BDD для g, а потім оцініть g. Середній розмір BDD заgповинна бути , тому що існує багато монотонних булевих функцій . Отже, теоретично це погане рішення.Ω((nn/2))

Але (1) можливий кращий аналіз та (2) можливий підхід до цього підходу, який робить його кращим. Наприклад, я жодним чином не використовував кореляцію між розміром та розміром 's BDD. (Має бути відповідна кореляція, але я не знаю, чи вона тут проста чи зручна.)Xg

Для повноти простий алгоритм обчислення BDD для з BDD для є наступним. Тут є стандартом або операцією на BDD.gf

m(x?f1:f0)=x?(m(f0)m(f1)):m(f0)

2
Чи не це більш-менш рівнозначно перерахунку відповіді для кожного підмножини , кешування всіх результатів у двійковому дереві розміром , а потім пошук праворуч результат (за часом ), коли вам дано ? {1,2,...,n}2nO(n)A
mjqxxxx

Використання експоненціального простору для зберігання попередньо оброблених даних звучить для мене як обман, хоча це не заборонено в питанні. Але я можу бути упередженим до церкви найскладнішої складності.
Цуйосі Іто

mjqxxxx та Цуйосі: Я з вами згоден. Я переписав текст, щоб, сподіваюсь, було зрозуміліше, що я згоден. :)
Раду ГРИГо

3

Можливо, ви можете використовувати техніку "пошуку інформації": на етапі попередньої обробки побудуйте інвертований індекс (у вашому випадку достатньо простого двовимірного масиву), який відображає елемент до множин у які містять його: .n×|X|xi{1,...,n}Xinv(xi)={XjX|xiXj}

Встановіть цілий масив довжини.occ|X|

Тоді для кожного вилучення , і для кожного роблятьyiAinv(yi)Xjinv(yi)occ[j]=occ[j]+1

Зрештою, потрібні набори - це ті, для яких .|Xj|=occ[j]

Ви можете довільно прискорити процес (ціною експоненціального простору), індексуючи два чи більше елементів разом.

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