Ein Teilmengen-Suchalgorithmus

9

Angenommen, ich habe eine Liste von Teilmengen von { 1 , . . . , n } . Bei Bedarf kann ich diese Liste vorverarbeiten. Nach dieser Vorverarbeitung wird mir eine weitere Menge A { 1 , . . . , n } . Ich möchte alle Mengen B X mit B A identifizieren .X{1,...,n}A{1,...,n}BXBA

Der offensichtliche Algorithmus (ohne Vorverarbeitung) benötigt Zeit - Sie testen A einfach gegen jedes B X separat. Gibt es etwas Besseres als das?O(n|X|)ABX

Wenn es hilft, können Sie davon ausgehen, dass für jedes die Gesamtzahl der Übereinstimmungen B X durch etwas wie O ( 1 ) begrenzt ist .ABXO(1)

David Harris
quelle

Antworten:

3

Dies ist keine Antwort. Es ist eine einfache, aber lange Beobachtung. Ich hoffe es wird nützlich sein.

Die Entscheidungsversion Ihres Problems lautet: Enthält eine Teilmenge von A ?XA

n{1,,n}nXfnffg(y)=(xy,f(x))g(A)f=gfX

fgggΩ((nn/2))

Aber (1) eine bessere Analyse könnte möglich sein und (2) es könnte Verbesserungen an diesem Ansatz geben, die ihn besser machen. Zum Beispiel habe ich die Korrelation zwischen der Größe von und der Größe von BDD in keiner Weise verwendet . (Es muss eine Korrelation geben, aber ich weiß nicht, ob es hier einfach oder verwendbar ist.)Xg

Der Vollständigkeit halber ist ein einfacher Algorithmus zum Berechnen der BDD für aus der BDD für der folgende. Hier ist die Standard- oder Operation für BDDs.gf

m(x?f1:f0)=x?(m(f0)m(f1)):m(f0)
Radu GRIGore
quelle
2
Ist dies nicht mehr oder weniger gleichbedeutend mit der Vorberechnung der Antwort für jede Teilmenge von , dem Zwischenspeichern aller Ergebnisse in einem Binärbaum der Größe und dem anschließenden Nachschlagen nach rechts? Ergebnis (in Zeit ), wenn Sie ? {1,2,...,n}2nO(n)A
mjqxxxx
Die Verwendung von exponentiellem Speicherplatz zum Speichern vorverarbeiteter Daten klingt für mich nach Betrug, obwohl dies in der Frage nicht verboten ist. Aber ich bin vielleicht voreingenommen gegenüber der Kirche der schlimmsten Komplexität.
Tsuyoshi Ito
mjqxxxx und Tsuyoshi: Ich stimme Ihnen beiden zu. Ich habe den Text so umgeschrieben, dass ich hoffe, es ist klarer, dass ich damit einverstanden bin. :)
Radu GRIGore
3

Vielleicht können Sie eine "Information Retrieval" -Technik verwenden: Erstellen Sie in der Vorverarbeitungsphase einen invertierten Index (in Ihrem Fall reicht ein einfaches zweidimensionales Array aus), der ein Element abbildet zu den Mengen in , die es enthalten: .n×|X|xi{1,...,n}Xinv(xi)={XjX|xiXj}

Set eines Integer - Array up der Länge.occ|X|

Dann für jede abrufen , und für jede doyiAinv(yi)Xjinv(yi)occ[j]=occ[j]+1

Am Ende benötigen Sie die Mengen, für die .|Xj|=occ[j]

Sie können den Prozess beliebig beschleunigen (auf Kosten des exponentiellen Raums), indem Sie zwei oder mehr Elemente zusammen indizieren.

Marzio De Biasi
quelle