Un algorithme de recherche de sous-ensemble

9

Supposons que j'ai une liste de sous-ensembles de . Je peux faire un prétraitement sur cette liste si nécessaire. Après ce prétraitement, on me présente un autre ensemble . Je veux identifier tous les jeux avec .X{1,...,n}A{1,...,n}BXBA

L'algorithme évident (sans aucun prétraitement) prend du temps - vous testez simplement contre chaque séparément. Y a-t-il quelque chose de mieux que cela?O(n|X|)ABX

Si cela aide, vous pouvez supposer que, pour tout , le nombre total de correspondances est limité par quelque chose comme .ABXO(1)

David Harris
la source

Réponses:

3

Ce n'est pas une réponse. C'est une observation simple mais longue. J'espère que ce sera utile.

La version de décision de votre problème est la suivante: contient-il un sous-ensemble de ?AXA

Ce problème est lié au problème de l'évaluation des fonctions booléennes monotones de variables. Un sous-ensemble de est équivalent à une chaîne de bits, donc la famille est équivalente à une fonction booléenne de variables. Étant donné une fonction , on peut définir la fonction la moins monotone qui n'est pas plus grande que , à savoir . Le problème d'origine se réduit alors à évaluer . A l'inverse, le problème de l'évaluation d'une fonction booléenne monotone peut être réduit au problème d'origine, soit naïvement en prenant{ 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=gou en choisissant un qui rend plus petit.fX

Dans la pratique, les BDD fonctionnent généralement bien. Donc, une approche possible est de construire le BDD pour , d'en dériver le BDD pour , puis d'évaluer . La taille moyenne du BDD pour doit être , car il existe de nombreuses fonctions booléennes monotones . Par conséquent, en théorie, c'est une mauvaise solution.g g gfgggΩ((nn/2))

Mais (1) une meilleure analyse pourrait être possible et (2) il pourrait y avoir des ajustements à cette approche qui la rendent meilleure. Par exemple, je n'ai utilisé en aucune façon la corrélation entre la taille de et la taille du BDD de . (Il doit y avoir une corrélation, mais je ne sais pas si elle est simple ou utilisable ici.)Xg

Pour être complet, un algorithme simple pour calculer le BDD pour partir du BDD pour est le suivant. Ici est l'opération standard ou sur les BDD.gf

m(x?f1:f0)=x?(m(f0)m(f1)):m(f0)
Radu GRIGore
la source
2
N'est-ce pas plus ou moins équivalent au précalcul de la réponse pour chaque sous-ensemble de , la mise en cache de tous les résultats dans un arbre binaire de taille , puis la recherche vers la droite résultat (au temps ) quand on vous donne ? {1,2,...,n}2nO(n)A
mjqxxxx
Utiliser de l'espace exponentiel pour stocker des données prétraitées me semble être une tricherie, même si ce n'est pas interdit dans la question. Mais je peux être partisan de la complexité de l'Église du pire des cas.
Tsuyoshi Ito
mjqxxxx et Tsuyoshi: Je suis d'accord avec vous deux. J'ai réécrit le texte pour que, j'espère, il soit plus clair que je suis d'accord. :)
Radu GRIGore
3

Vous pouvez peut-être utiliser une technique de "récupération d'informations": dans la phase de prétraitement, créez un index inversé (dans votre cas un simple tableau bidimensionnel suffit) qui mappe un élément aux ensembles dans qui le contiennent: .n×|X|xi{1,...,n}Xinv(xi)={XjX|xiXj}

Mettre en place un tableau d'entiers de longueur.occ|X|

Ensuite, pour chaque récupérez , et pour chaque ,yiAinv(yi)Xjinv(yi)occ[j]=occ[j]+1

À la fin, les ensembles dont vous avez besoin sont ceux pour lesquels .|Xj|=occ[j]

Vous pouvez accélérer arbitrairement le processus (au prix d'un espace exponentiel) en indexant deux ou plusieurs éléments ensemble.

Marzio De Biasi
la source