Algoritma pencarian subset

9

Misalkan saya memiliki daftar dari himpunan bagian dari . Saya dapat melakukan preprocessing pada daftar ini jika perlu. Setelah preprocessing ini, saya diberikan satu set . Saya ingin mengidentifikasi set dengan .{ 1 , . . . , N } A { 1 , . . . , n } B X B AX{1,...,n}A{1,...,n}BXBA

Algoritma yang jelas (tanpa preprocessing apa pun) membutuhkan waktu - Anda cukup menguji terhadap setiap secara terpisah. Adakah yang lebih baik dari ini?A B XO(n|X|)ABX

Jika ini membantu, Anda dapat mengasumsikan bahwa, untuk apa pun , jumlah total kecocokan dibatasi oleh sesuatu seperti .B X O ( 1 )ABXO(1)

David Harris
sumber

Jawaban:

3

Ini bukan jawaban. Ini pengamatan sederhana namun panjang. Semoga bermanfaat.

Versi keputusan masalah Anda adalah: Apakah berisi subset dari ?AXA

Masalah ini terkait dengan masalah mengevaluasi fungsi monoton boolean dari variabel. Subset dari setara dengan bitstring, sehingga keluarga setara dengan fungsi boolean dari variabel. Diberikan fungsi f , kita dapat mendefinisikan fungsi monoton paling kecil yang tidak lebih besar dari f , yaitu g ( y ) = ( x y ,{ 1 , ... , n } n X f nn{1,,n}nXfnff . Masalah aslinya kemudian dikurangi menjadi evaluasi g ( A ) . Sebaliknya, masalah mengevaluasi fungsi monoton boolean dapat dikurangi menjadi masalah asli, baik secara naif dengan mengambil f = g atau dengan memilih f yang membuat X lebih kecil.g(y)=(xy,f(x))g(A)f=gfX

Dalam praktiknya, BDD cenderung bekerja dengan baik. Jadi salah satu pendekatan yang mungkin adalah membangun BDD untuk , berasal dari itu BDD untuk g , dan kemudian mengevaluasi g . Ukuran rata-rata BDD untuk g harus , karena ada banyak fungsi boolean monoton . Oleh karena itu, secara teori ini adalah solusi buruk.fgggΩ((nn/2))

Tetapi (1) analisis yang lebih baik mungkin dilakukan dan (2) mungkin ada perubahan pada pendekatan ini yang membuatnya lebih baik. Sebagai contoh, saya sama sekali tidak menggunakan korelasi antara ukuran dan ukuran BDD . (Pasti ada korelasi, tetapi saya tidak tahu apakah itu sederhana atau dapat digunakan di sini.)gXg

Untuk kelengkapan, algoritma sederhana untuk menghitung BDD untuk dari BDD untuk adalah sebagai berikut. Di sini adalah standar atau operasi pada BDD.f m ( x ? f 1 : f 0 ) = x ? ( m ( f 0 ) m ( f 1 ) ) : m ( f 0 ) gf

m(x?f1:f0)=x?(m(f0)m(f1)):m(f0)
Radu GRIGore
sumber
2
Bukankah ini kurang lebih sama dengan menghitung ulang jawaban untuk setiap subset dari , menyimpan semua hasil dalam pohon biner ukuran , dan kemudian mencari ke kanan hasil (dalam waktu ) ketika Anda diberi ? {1,2,...,n}2nO(n)A
mjqxxxx
Menggunakan ruang eksponensial untuk menyimpan data pra-pemrosesan terdengar seperti menipu saya, meskipun tidak dilarang dalam pertanyaan. Tetapi saya mungkin bias terhadap Gereja Kompleksitas Kasus Terburuk.
Tsuyoshi Ito
mjqxxxx dan Tsuyoshi: Saya setuju dengan Anda berdua. Saya menulis ulang teks sehingga, saya harap, lebih jelas bahwa saya setuju. :)
Radu GRIGore
3

Mungkin Anda dapat menggunakan teknik "pencarian informasi": pada fase preprocessing, buat indeks terbalik (dalam kasus Anda, array bidimensional sudah cukup) yang memetakan elemen ke set di yang berisi itu: .n×|X|xi{1,...,n}Xinv(xi)={XjX|xiXj}

Mendirikan sebuah array integer panjang.occ|X|

Kemudian untuk setiap ambil , dan untuk setiap lakukani n v ( y i ) X ji n v ( y i ) o c c [ j ] = o c c [ j ] + 1yiAinv(yi)Xjinv(yi)occ[j]=occ[j]+1

Pada akhirnya set yang Anda butuhkan adalah yang .|Xj|=occ[j]

Anda dapat mempercepat proses secara sewenang-wenang (dengan biaya ruang eksponensial) dengan mengindeks dua elemen atau lebih secara bersamaan.

Marzio De Biasi
sumber