Anda dapat menggunakan pohon pencarian. Bukan yang "standar", seperti yang digunakan untuk semesta yang dipesan (bilangan real, string ...) tetapi tipe yang lebih umum, seperti yang ditunjukkan oleh proyek GiST . Ada pohon pencarian untuk pertanyaan spasial, serta yang didasarkan pada aksioma metrik , untuk mengindeks ruang metrik (jarak). Gagasan umum (yang "kurang dari / lebih besar dari," pendekatan berorientasi interval dari pohon pencarian teratur, adalah spesialisasi) adalah untuk menguraikan kumpulan data menjadi himpunan bagian, biasanya secara hierarkis. Hierarki himpunan bagian ini (jelas) diwakili oleh pohon, di mana anak-anak dari setiap simpul mewakili himpunan bagian, dan setiap node memiliki beberapa bentuk predikat, yang memungkinkan Anda untuk memeriksa apakah ada tumpang tindih antara set (konseptual) objek yang relevan dengan permintaan Anda, dan yang ditemukan dalam subtree itu (yaitu, subset).
Sebagai contoh, untuk pohon spasial dalam bidang Euclidean, setiap objek dapat berupa titik, dan predikatnya bisa berupa garis bujur , yang berisi semua titik yang ditemukan di atau di bawah simpul itu. Jika kueri adalah sebuah persegi panjang (dan Anda ingin menemukan semua poin dalam persegi panjang itu), Anda dapat secara rekursif menghilangkan subtree yang persegi yang terikat tidak tumpang tindih dengan kueri Anda.
Dalam kasus Anda, Anda bisa membangun pohon di mana setiap node berisi beberapa struktur yang akan memungkinkan Anda untuk mendeteksi apakah permintaan Anda adalah subset. Jika tidak, seluruh subtree dapat dihilangkan, karena permintaan Anda tidak akan pernah menjadi subset dari node anak (dan tentu saja bukan daun, yang mungkin akan mewakili data yang sebenarnya).
Berbeda dengan pohon pencarian biasa, tidak ada jaminan waktu pencarian secara umum di sini — Anda mungkin akan mengunjungi beberapa cabang, jadi bahkan jika Anda memiliki pohon yang sangat seimbang, Anda mungkin akan memiliki waktu berjalan superlogaritmik. Ini lebih dari pendekatan heuristik, tetapi bisa jadi efektif.
Apa yang Anda butuhkan, untuk membangun pohon ini, akan menjadi beberapa bentuk metode pengelompokan hierarkis yang sesuai dengan data Anda. Proyek GiST sebenarnya memiliki pohon yang sangat mirip dengan yang Anda butuhkan, dengan implementasi C (meskipun memeriksa apakah kueri tumpang tindih, bukan jika itu adalah subset; harus mudah dimodifikasi). Pohon seimbang, B-tree-style balanced GiST mungkin berlebihan. Anda mungkin hanya ingin mengelompokkan set yang sama bersama-sama, secara hierarkis, dan Anda bisa melakukannya dengan menggunakan algoritma pengelompokan off-the-shelf, menggunakan sesuatu seperti jarak Hamming (atau sesuatu yang lebih mewah). Node saudara kandung yang lebih mirip adalah, "lebih ketat" predikat pembatas dari induk (yaitu, himpunan yang mewakili serikat mereka) akan — dan oleh karena itu, pencarian Anda akan lebih efisien.
Singkatnya, saran saya adalah:
- Sajikan set Anda sehingga Anda dapat memeriksa tumpang tindih dengan kueri (vektor bit, tabel hash).
- Gugurkan set Anda secara hierarkis, menggunakan jarak yang sesuai (misalnya, Hamming) dan algoritme yang tidak tersedia.
- Di setiap simpul internal, simpan gabungan set simpul anak.
- Selama pencarian, lintasi subkursif, pangkas / abaikan sub pohon yang akarnya memiliki set yang tidak tumpang tindih dengan permintaan Anda.
Jika Anda ingin pohon menjadi dinamis, ada banyak cara untuk melakukannya juga. Misalnya, Anda dapat melintasi pohon secara rekursif, menemukan lokasi yang paling cocok (dengan melewati node dengan jarak Hamming tumpang tindih / terkecil), memperbarui serikat pekerja (predikat pembatas) saat Anda pergi. Penghapusan sedikit lebih rumit, mungkin; Anda bisa menandai objek sebagai hilang, dan kemudian membangun kembali subtree (atau seluruh struktur) ketika jumlah objek yang ditandai mencapai ambang tertentu.
Apakah ini bekerja dengan baik untuk aplikasi Anda mungkin sulit untuk mengatakan apriori, tetapi harus mudah untuk memeriksa secara eksperimental. Juga, ada banyak ruang untuk tweaker.