Sie könnten einen Suchbaum verwenden. Kein „Standard“, wie er für geordnete Universen (reelle Zahlen, Strings…) verwendet wird, sondern ein allgemeinerer Typ, wie er vom GiST- Projekt angedeutet wird . Es gibt Suchbäume für räumliche Abfragen sowie solche, die auf den metrischen Axiomen basieren , um metrische (Entfernungs-) Räume zu indizieren. Die allgemeine Idee (von der der intervallorientierte Ansatz "kleiner als / größer als" gewöhnlicher, geordneter Suchbäume eine Spezialisierung ist) besteht darin, den Datensatz in Teilmengen zu zerlegen, normalerweise hierarchisch. Diese Hierarchie von Teilmengen wird (offensichtlich) durch einen Baum dargestellt, in dem die Kinder jedes Knotens Teilmengen darstellen und jeder Knoten eine Form von Prädikat hatHiermit können Sie überprüfen, ob es eine Überlappung zwischen der für Ihre Abfrage relevanten (konzeptionellen) Gruppe von Objekten und den in diesem Teilbaum gefundenen Objekten (dh der Teilmenge) gibt.
Beispielsweise könnte für einen räumlichen Baum in der euklidischen Ebene jedes Objekt ein Punkt sein, und die Prädikate könnten Begrenzungsrechtecke sein , die alle Punkte enthalten, die in oder unter diesem Knoten gefunden werden. Wenn eine Abfrage ein Rechteck ist (und Sie alle Punkte in diesem Rechteck finden möchten), können Sie Teilbäume rekursiv entfernen, deren Begrenzungsrechtecke sich nicht mit Ihrer Abfrage überschneiden.
In Ihrem Fall könnten Sie einen Baum erstellen, in dem jeder Knoten eine festgelegte Struktur enthält, mit der Sie erkennen können, ob Ihre Abfrage eine Teilmenge ist. Wenn nicht, kann dieser gesamte Teilbaum entfernt werden, da Ihre Abfrage niemals eine Teilmenge eines der untergeordneten Knoten sein könnte (und sicherlich nicht die Blätter, die wahrscheinlich die wahren Daten darstellen würden).
Im Gegensatz zu normalen Suchbäumen gibt es hier im Allgemeinen keine Garantie für die Suchzeit. Sie werden wahrscheinlich mehrere Zweige besuchen. Selbst wenn Sie einen perfekt ausbalancierten Baum haben, haben Sie wahrscheinlich eine superlogarithmische Laufzeit. Dies ist eher ein heuristischer Ansatz, könnte aber trotzdem effektiv sein.
Um diesen Baum zu erstellen, benötigen Sie eine hierarchische Clustering-Methode, die zu Ihren Daten passt. Das GiST-Projekt hat tatsächlich einen Baum, der dem sehr ähnlich ist, was Sie benötigen, mit einer C-Implementierung (obwohl es prüft, ob sich die Abfrage überschneidet, nicht, ob es sich um eine Teilmenge handelt; sollte leicht zu ändern sein). Der festplattenbasierte, ausgeglichene Baum im B-Baum-Stil von GiST könnte jedoch übertrieben sein. Sie möchten wahrscheinlich nur ähnliche Mengen hierarchisch zusammenfassen, und Sie können dies mit einem handelsüblichen Clustering-Algorithmus tun, der beispielsweise die Hamming-Distanz (oder etwas ausgefalleneres) verwendet. Je ähnlicher die Geschwisterknoten sind, desto „enger“ wird das Begrenzungsprädikat des Elternteils (dh die Menge, die ihre Vereinigung darstellt) - und desto effizienter ist Ihre Suche.
Zusammenfassend ist mein Vorschlag:
- Stellen Sie Ihre Mengen dar, damit Sie nach Überlappungen mit Abfragen suchen können (Bitvektoren, Hash-Tabellen).
- Gruppieren Sie Ihre Sets hierarchisch, indem Sie einen geeigneten Abstand (z. B. Hamming) und einen Standardalgorithmus verwenden.
- Speichern Sie in jedem internen Knoten die Vereinigung der untergeordneten Knotensätze.
- Durchlaufen Sie während der Suche rekursiv und beschneiden / ignorieren Sie Teilbäume, deren Wurzeln Mengen haben, die sich nicht mit Ihrer Abfrage überschneiden.
Wenn der Baum dynamisch sein soll, gibt es auch viele Möglichkeiten, dies zu tun. Sie können beispielsweise den Baum rekursiv durchlaufen, den Ort finden, der am besten passt (indem Sie Knoten mit der höchsten Überlappung / kleinsten Hamming-Entfernung durchlaufen) und die Gewerkschaften (Begrenzungsprädikate) aktualisieren, während Sie fortfahren. Löschungen sind vielleicht etwas kniffliger; Sie können Objekte einfach als fehlend markieren und dann Teilbäume (oder die gesamte Struktur) neu erstellen, wenn die Anzahl der markierten Objekte einen bestimmten Schwellenwert erreicht.
Ob dies für Ihre Anwendung gut funktioniert, kann von vornherein schwer zu sagen sein, sollte aber experimentell leicht zu überprüfen sein. Außerdem gibt es viel Raum für Optimierungen.