Алгоритм поиска подмножества


9

Предположим, у меня есть список подмножеств . Я могу сделать предварительную обработку в этом списке, если это необходимо. После этой предварительной обработки мне предоставляется другой набор . Я хочу , чтобы определить , какие - либо множества с .X{1,...,n}A{1,...,n}BXBA

Очевидный алгоритм (без какой-либо предварительной обработки) занимает время - вы просто проверяете на каждом отдельно. Есть ли что-нибудь лучше, чем это?О(N|Икс|)AВИкс

Если это поможет, вы можете предположить, что для любого общее число совпадений ограничено чем-то вроде .AВИксО(1)

Ответы:


3

Это не ответ. Это простое, но длительное наблюдение. Надеюсь это будет полезно.

Вариант решения вашей проблемы: содержит ли подмножество ?XA

Эта проблема связана с проблемой оценки монотонных булевых функций от переменных. Подмножество эквивалентно битной строке, поэтому семейство эквивалентно булевой функцииn{1,,n}nXf от переменных. Для данной функции можно определить наименьшую монотонную функцию, которая не больше , а именно . Исходная задача затем сводится к оценке . И наоборот, проблема оценки монотонной булевой функции может быть сведена к исходной задаче, либо наивно, если взятьnffg(y)=(xy,f(x))g(A)f=gили выбрав который делает меньше.fX

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

Но (1) возможен более качественный анализ и (2) могут быть изменения в этом подходе, которые делают его лучше. Например, я никоим образом не использовал корреляцию между размером и размером BDD . (Должна быть корреляция, но я не знаю, является ли она простой или пригодной для использования здесь.)Иксг

Для полноты простой алгоритм для вычисления BDD для из BDD для является следующим. Здесь - стандартная операция or для BDD.ге

м(Икс?е1:е0)знак равноИкс?(м(е0)м(е1)):м(е0)

2
Разве это не более или менее эквивалентно предварительному вычислению ответа для каждого подмножества , кэшированию всех результатов в двоичном дереве размером , а затем поиску правильного результат (за время ), когда вам дают ? {1,2,,,,,N}2NО(N)A
mjqxxxx

Использование экспоненциального пространства для хранения предварительно обработанных данных звучит для меня как обман, хотя в этом вопросе это не запрещено. Но я могу быть предвзятым к Церкви наихудшего Сложности.
Tsuyoshi Ito

mjqxxxx и Tsuyoshi: я согласен с вами обоими. Я переписал текст так, чтобы, надеюсь, было более понятно, что я согласен. :)
Раду GRIGore

3

Возможно, вы можете использовать метод «поиска информации»: на этапе предварительной обработки построить инвертированный индекс (в вашем случае простойN×|Икс| достаточно двумерного массива), который отображает элемент Икся{1,,,,,N} к наборам в Икс которые содержат это: яNv(Икся)знак равно{ИксJИкс|ИксяИксJ},

Установить целочисленный массив осс длины |Икс|,

Тогда для каждого YяA извлекать яNv(Yя)и для каждого ИксJяNv(Yя) делать осс[J]знак равноосс[J]+1

В конце концов, вам нужны те наборы, для которых |ИксJ|знак равноосс[J],

Вы можете произвольно ускорить процесс (за счет экспоненциального пространства) путем индексации двух или более элементов вместе.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.