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)

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)

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.