Menemukan subset dari himpunan dalam koleksi set


8

Struktur data apa yang akan Anda rekomendasikan yang mewakili koleksi subset dan mendukung operasi berikut?{1,,n}

  • : menyisipkan S dalam koleksi.insert(S)S
  • : mengembalikan true jika ada S dalam koleksi sehingga S S , false jika tidak.query(S)SSS

Kriteria utama saya adalah efisiensi waktu praktis.


3
Rekomendasi memerlukan kriteria. Apa kriteria Anda? Misalnya, kesederhanaan, ruang, atau waktu? Semakin spesifik Anda, semakin besar kemungkinan Anda mendapatkan jawaban yang bermanfaat bagi Anda.
Tsuyoshi Ito

Anda benar, terima kasih telah menunjukkannya. Kriteria utama saya adalah efisiensi waktu praktis.
Caleb Poucher

1
Apakah Anda tahu berapa banyak penyisipan yang akan Anda lakukan relatif terhadap jumlah kueri yang akan Anda lakukan? Dimungkinkan untuk membangun struktur data yang sangat besar (ukuran eksponensial dalam ) yang akan memungkinkan Anda meminta set S dalam O ( n ) waktu. Di sisi lain, jika m adalah jumlah total himpunan bagian yang dimasukkan, Anda dapat melakukan pencarian naif tanpa penyimpanan tambahan dalam waktu O ( n m ) . Segala sesuatu di antaranya, saya pikir, akan menjadi trade off. nSO(n)mO(nm)
James King

100{0,1}nnnm

nm

Jawaban:


1

Masalah Anda bagi saya sangat mirip dengan Information Retrieval (IR). Di sana Anda memiliki kumpulan set kata (juga dikenal sebagai dokumen) dan Anda ingin menemukan tidak hanya keberadaan, tetapi semua set / dokumen yang memenuhi kondisi permintaan.

Karena elemen yang ditetapkan adalah angka, Anda dapat mengambil keuntungan dari struktur yang terlihat, sehingga indeks tanda tangan akan banyak digunakan.

Saya akan merekomendasikan untuk melihat makalah IR, terutama terkait dengan struktur kamus, seperti pohon, tetapi perhatikan bahwa ruang biasanya menjadi masalah untuk sistem tersebut, sedangkan itu mungkin tidak menjadi masalah untuk kasus Anda.


Poin baiknya, ini memang sangat mirip dengan pencarian istilah dalam dokumen, dan cara penyelesaian yang paling umum adalah menggunakan apa yang disebut file terbalik , yang berfungsi seperti indeks buku. Anda mencari setiap istilah dalam kueri Anda di file terbalik dan mendapatkan daftar / set dokumen yang mengandung istilah itu. Anda kemudian memotong daftar ini untuk mendapatkan hasilnya. (Anda bisa, misalnya, menggunakan ID item pemetaan tabel hash untuk mengurutkan daftar ID yang ditetapkan; pengurutan membantu dengan persimpangan.)
Magnus Lie Hetland

0

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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.