Un algoritmo di ricerca di un sottoinsieme


9

Supponiamo di avere un elenco di sottoinsiemi di . Posso eseguire la preelaborazione in questo elenco, se necessario. Dopo questa preelaborazione, mi viene presentato un altro set . Voglio individuare eventuali gruppi con .{ 1 , . . . , N } A { 1 , . . . , n } B X B AX{1,...,n}A{1,...,n}BXBA

L'algoritmo ovvio (senza alcuna preelaborazione) richiede tempo - si prova semplicemente contro ogni separatamente. C'è qualcosa di meglio di questo?A B XO(n|X|)ABX

Se aiuta, puoi supporre che, per ogni , il numero totale di corrispondenze sia limitato da qualcosa come .B X O ( 1 )ABXO(1)

Risposte:


3

Questa non è una risposta È un'osservazione semplice ma lunga. Spero sia utile.

La versione decisionale del problema è: contiene un sottoinsieme di A ?XA

Questo problema è correlato al problema della valutazione di funzioni booleane monotone di variabili. Un sottoinsieme di { 1 , ... , n } equivale a una n -bitstring, quindi la famiglia X è equivalente a una funzione booleana f di n variabili. Data una funzione f , si può definire la funzione meno monotona che non è più grande di f , vale a dire g ( y ) = ( x y ,n{1,,n}nXfnff . Il problema originale viene quindi ridotto alla valutazione di g ( A ) . Al contrario, il problema di valutare una funzione booleana monotona può essere ridotto al problema originale, ingenuamente prendendo f = g o scegliendo una f che rende X più piccolo.g(y)=(xy,f(x))g(A)f=gfX

In pratica i BDD tendono a funzionare bene. Quindi un possibile approccio è costruire il BDD per , derivarne da esso il BDD per g e quindi valutare g . La dimensione media del BDD per g deve essere , perché ci sono molte funzioni booleane monotone . Quindi, in teoria questa è una cattiva soluzione.fgggΩ((nn/2))

Ma (1) potrebbe essere possibile un'analisi migliore e (2) potrebbero esserci delle modifiche a questo approccio che lo rendono migliore. Ad esempio, non ho usato in alcun modo la correlazione tra la dimensione di e la dimensione del BDD di . (Deve esserci una correlazione, ma non so se sia semplice o utilizzabile qui.)gXg

Per completezza, un semplice algoritmo per calcolare il BDD per dal BDD per è il seguente. Ecco è l'operazione standard o sui BDD.f m ( x ? f 1 : f 0 ) = x ? ( m ( f 0 ) m ( f 1 ) ) : m ( f 0 ) gf

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

2
Questo non equivale più o meno al precalcolando la risposta per ciascun sottoinsieme di , memorizzando tutti i risultati nella cache in un albero binario di dimensioni , e poi guardando in alto a destra risultato (nel tempo ) quando ti viene dato ? {1,2,...,n}2nO(n)A
mjqxxxx,

L'uso dello spazio esponenziale per archiviare i dati preelaborati mi sembra un tradimento, sebbene non sia proibito nella domanda. Ma potrei essere di parte nei confronti della Chiesa della peggiore complessità.
Tsuyoshi Ito,

mjqxxxx e Tsuyoshi: sono d'accordo con entrambi. Ho riscritto il testo in modo che, spero, sia più chiaro che sono d'accordo. :)
Radu GRIGore il

3

Forse puoi usare una tecnica di "recupero delle informazioni": nella fase di preelaborazione, costruisci un indice invertito (nel tuo caso basta un semplice matrice bidimensionale) che mappa un elemento agli insiemi in che lo contengono: .n×|X|xi{1,...,n}Xinv(xi)={XjX|xiXj}

Imposta un array intero di lunghezza.occ|X|

Poi per ogni recuperare , e per ogni farei n v ( y i ) X ji n v ( y i ) o c c [ j ] = o c c [ j ] + 1yiAinv(yi)Xjinv(yi)occ[j]=occ[j]+1

Alla fine i set di cui hai bisogno sono quelli per cui .|Xj|=occ[j]

Puoi accelerare arbitrariamente il processo (a costo dello spazio esponenziale) indicizzando insieme due o più elementi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.