Un algoritmo de búsqueda de subconjuntos

9

Supongamos que tengo una lista de subconjuntos de . Puedo hacer un preprocesamiento en esta lista si es necesario. Después de este preprocesamiento, se me presenta otro conjunto . Quiero identificar cualquier conjuntos con .{ 1 , . . . , N } A { 1 , . . . , n } B X B AX{1,...,n}A{1,...,n}BXBA

El algoritmo obvio (sin preprocesamiento) lleva tiempo : simplemente prueba contra cada separado. ¿Hay algo mejor que esto?A B XO(n|X|)ABX

Si ayuda, puede suponer que, para cualquier , el número total de coincidencias está limitado por algo como .B X O ( 1 )ABXO(1)

David Harris
fuente

Respuestas:

3

Esta no es una respuesta. Es una observación simple pero larga. Espero que te sea útil.

La versión de decisión de su problema es: ¿ contiene un subconjunto de ?AXA

Este problema está relacionado con el problema de evaluar funciones booleanas monótonas de variables. Un subconjunto de es equivalente a una -bitstring, por lo que la familia es equivalente a una función booleana de variables. Dada una función , se puede definir la función menos monótona que no sea mayor que , es decir, . El problema original se reduce a la evaluación de . Por el contrario, el problema de evaluar una función booleana monótona puede reducirse al problema original, ya sea ingenuamente tomando{ 1 , ... , n } n X f n f f g ( y ) = ( x y ,n{1,,n}nXfnffg ( A ) f = g f Xg(y)=(xy,f(x))g(A)f=go eligiendo una que haga más pequeña.fX

En la práctica, los BDD tienden a funcionar bien. Entonces, un enfoque posible es construir el BDD para , derivar de él el BDD para luego evaluar . El tamaño promedio de la BDD para debe ser , porque hay muchas funciones booleanas monótonas . Por lo tanto, en teoría, esta es una mala solución.g g gfgggΩ((nn/2))

Pero (1) podría ser posible un mejor análisis y (2) podría haber ajustes en este enfoque que lo hagan mejor. Por ejemplo, no utilicé de ninguna manera la correlación entre el tamaño de y el tamaño de BDD de . (Debe haber una correlación, pero no sé si es simple o utilizable aquí).Xg

Para completar, un algoritmo simple para calcular el BDD para desde el BDD para es el siguiente. Aquí es la operación estándar en BDD.gf

m(x?f1:f0)=x?(m(f0)m(f1)):m(f0)
Radu GRIGore
fuente
2
¿No es esto más o menos equivalente a calcular previamente la respuesta para cada subconjunto de , almacenar en caché todos los resultados en un árbol binario de tamaño , y luego buscar hacia la derecha resultado (en el tiempo ) cuando recibe ? {1,2,...,n}2nO(n)A
mjqxxxx
Usar espacio exponencial para almacenar datos preprocesados ​​me parece una trampa, aunque no está prohibido en la pregunta. Pero puedo estar predispuesto hacia la Iglesia de la peor complejidad.
Tsuyoshi Ito
mjqxxxx y Tsuyoshi: Estoy de acuerdo con los dos. Reescribí el texto para que, espero, quede más claro que estoy de acuerdo. :)
Radu GRIGore
3

Quizás pueda utilizar una técnica de "recuperación de información": en la fase de preprocesamiento, cree un índice invertido (en su caso, una simple matriz bidimensional es suficiente) que mapea un elemento a los conjuntos en que lo contienen: .n×|X|xi{1,...,n}Xinv(xi)={XjX|xiXj}

Configure una matriz entera de longitud.occ|X|

Luego, por cada recupera , y por cada hazyiAinv(yi)Xjinv(yi)occ[j]=occ[j]+1

Al final, los conjuntos que necesita son aquellos para los cuales .|Xj|=occ[j]

Puede acelerar arbitrariamente el proceso (a costa del espacio exponencial) indexando dos o más elementos juntos.

Marzio De Biasi
fuente