Pemanasan: bitvektor acak
Sebagai pemanasan, kita bisa mulai dengan kasus di mana setiap bitvector dipilih secara seragam secara acak. Kemudian ternyata masalah tersebut dapat diselesaikan dalam waktu (lebih tepatnya, dapat diganti dengan ).O(n1.6min(k,lgn))1.6lg3
Kami akan mempertimbangkan varian dua set masalah berikut:
Set diberikan dari bitvectors, menentukan di mana terdapat non-tumpang tindih pasangan .S,T⊆{0,1}ks∈S,t∈T
Teknik dasar untuk menyelesaikan ini adalah membagi-dan-taklukkan. Berikut ini adalah algoritma waktu menggunakan divide-and-conquer:O(n1.6k)
Split dan berdasarkan posisi bit pertama. Dengan kata lain, bentuk , , , .STS0={s∈S:s0=0}S1={s∈S:s0=1}T0={t∈T:t0=0}T1={t∈T:t0=1}
Sekarang cari secara rekursif untuk pasangan yang tidak tumpang tindih dari , dari , dan dari . Jika ada panggilan rekursif menemukan pasangan yang tidak tumpang tindih, output itu, jika tidak output "Tidak ada pasangan yang tumpang tindih".S0,T0S0,T1T1,S0
Karena semua bitvektor dipilih secara acak, kita dapat mengharapkan dan . Dengan demikian, kami memiliki tiga panggilan rekursif, dan kami telah mengurangi ukuran masalah dengan faktor dua (kedua set ukurannya dikurangi dengan faktor dua). Setelah terpecah, salah satu dari dua set turun ke ukuran 1, dan masalahnya dapat diselesaikan dalam waktu linier. Kami mendapatkan relasi berulang di sepanjang garis , yang solusinya adalah . Akuntansi untuk menjalankan waktu lebih tepatnya dalam kasus dua set, kita melihat waktu berjalan adalah .|Sb|≈|S|/2|Tb|≈|T|/2lgmin(|S|,|T|)T(n)=3T(n/2)+O(nk)T(n)=O(n1.6k)O(min(|S|,|T|)0.6max(|S|,|T|)k)
Ini dapat ditingkatkan lebih lanjut, dengan mencatat bahwa jika , maka probabilitas bahwa pasangan yang tidak tumpang tindih ada secara eksponensial kecil. Secara khusus, jika adalah dua vektor acak, probabilitas bahwa mereka tidak tumpang tindih adalah . Jika , ada pasangan demikian, maka dengan ikatan gabungan, probabilitas ada pasangan yang tidak tumpang tindih adalah paling banyak . Ketika , ini adalah . Jadi, sebagai langkah pra-pemrosesan, jikak≥2.5lgn+100x,y(3/4)k|S|=|T|=nn2n2(3/4)kk≥2.5lgn+100≤1/2100k≥2.5lgn+100, maka kita dapat segera mengembalikan "Tidak ada pasangan yang tidak tumpang tindih" (probabilitas ini salah adalah sangat kecil), jika tidak kita jalankan algoritma di atas.
Dengan demikian kita mencapai waktu berjalan (atau untuk varian dua set yang diusulkan di atas), untuk kasus khusus di mana bitvektor dipilih secara seragam secara acak.O(n1.6min(k,lgn))O(min(|S|,|T|)0.6max(|S|,|T|)min(k,lgn))
Tentu saja, ini bukan analisis kasus terburuk. Bitvektor acak jauh lebih mudah daripada kasus terburuk - tetapi mari kita perlakukan itu sebagai pemanasan, untuk mendapatkan beberapa ide yang mungkin bisa kita terapkan pada kasus umum.
Pelajaran dari pemanasan
Kita bisa belajar beberapa pelajaran dari pemanasan di atas. Pertama, bagi-dan-taklukkan (pemisahan pada posisi bit) tampaknya membantu. Kedua, Anda ingin membagi pada posisi bit dengan sebanyak mungkin dalam posisi itu; semakin banyak ada, semakin sedikit pengurangan dalam ukuran subproblem yang Anda dapatkan.10
Ketiga, ini menunjukkan bahwa masalahnya semakin sulit karena kepadatan semakin kecil - jika ada sangat sedikit di antara bitvectors (sebagian besar adalah 's), masalahnya terlihat cukup sulit, karena setiap split mengurangi ukuran subproblem sedikit. Jadi, tentukan densitas menjadi fraksi bit yang (yaitu, dari semua bit ), dan densitas posisi bit menjadi fraksi bitvektor yang pada posisi .110Δ1nki1i
Penanganan kepadatan sangat rendah
Sebagai langkah selanjutnya, kita mungkin bertanya-tanya apa yang terjadi jika kepadatannya sangat kecil. Ternyata jika kepadatan di setiap posisi bit lebih kecil dari , kami dijamin bahwa ada pasangan non-tumpang tindih: ada argumen keberadaan (non-konstruktif) yang menunjukkan bahwa beberapa non-tumpang tindih pasangan harus ada. Ini tidak membantu kami menemukannya, tetapi setidaknya kami tahu itu ada.1/k−−√
Mengapa demikian? Mari kita mengatakan bahwa sepasang bitvectors adalah ditutupi demi sedikit posisi jika . Perhatikan bahwa setiap pasangan bitvektor yang tumpang tindih harus dilindungi oleh beberapa posisi bit. Sekarang, jika kita memperbaiki posisi bit tertentu , jumlah pasangan yang dapat dicakup oleh posisi bit tersebut paling banyak . Menjumlahkan semua dari posisi bit, kami menemukan bahwa jumlah total pasangan yang dicakup oleh beberapa posisi bit adalahx,yixi=yi=1i(nΔ(i))2<n2/kk<n2. Ini berarti harus ada beberapa pasangan yang tidak dicakup oleh posisi bit apa pun, yang menyiratkan bahwa pasangan ini tidak tumpang tindih. Jadi jika kepadatan cukup rendah di setiap posisi bit, maka pasangan yang tidak tumpang tindih pasti ada.
Namun, saya bingung untuk mengidentifikasi algoritma cepat untuk menemukan pasangan yang tidak tumpang tindih, dalam rezim ini, meskipun satu dijamin ada. Saya tidak segera melihat teknik yang akan menghasilkan waktu berjalan yang memiliki ketergantungan sub-kuadrat pada . Jadi, ini adalah kasus khusus yang bagus untuk difokuskan, jika Anda ingin meluangkan waktu memikirkan masalah ini.n
Menuju algoritma kasus umum
Dalam kasus umum, heuristik alami tampaknya adalah: memilih posisi bit dengan jumlah paling banyak (yaitu, dengan kepadatan tertinggi), dan membaginya. Dengan kata lain:i1
Temukan posisi bit yang memaksimalkan .iΔ(i)
Split dan berdasarkan posisi bit . Dengan kata lain, bentuk , , , .STiS0={s∈S:si=0}S1={s∈S:si=1}T0={t∈T:ti=0}T1={t∈T:ti=1}
Sekarang cari secara rekursif untuk pasangan yang tidak tumpang tindih dari , dari , dan dari . Jika ada panggilan rekursif menemukan pasangan yang tidak tumpang tindih, output itu, jika tidak output "Tidak ada pasangan yang tumpang tindih".S0,T0S0,T1T1,S0
Tantangannya adalah untuk menganalisis kinerjanya dalam kasus terburuk.
Mari kita asumsikan bahwa sebagai langkah pra-pemrosesan, pertama-tama kita menghitung kepadatan setiap posisi bit. Juga, jika untuk setiap , asumsikan bahwa langkah pra-pemrosesan menghasilkan "Pasangan yang tumpang tindih ada" (Saya menyadari bahwa ini tidak menunjukkan contoh pasangan yang tumpang tindih, tapi mari kita kesampingkan itu sebagai tantangan tersendiri). Semua ini dapat dilakukan dalam waktu . Informasi kepadatan dapat dipertahankan secara efisien karena kami melakukan panggilan rekursif; itu tidak akan menjadi kontributor dominan untuk waktu berjalan.Δ(i)<1/k−−√iO(nk)
Apa yang akan menjadi waktu berjalan dari prosedur ini? Saya tidak yakin, tapi di sini ada beberapa pengamatan yang mungkin bisa membantu. Setiap tingkat rekursi mengurangi ukuran masalah sekitar bitvectors (mis., Dari bitvectors ke bitvectors). Oleh karena itu, rekursi hanya dapat mencapai kedalaman . Namun, saya tidak segera yakin bagaimana cara menghitung jumlah daun di pohon rekursi (ada banyak kurang dari daun), jadi saya tidak yakin berapa lama waktu berjalan ini seharusnya mengarah untuk.n/k−−√nn−n/k−−√k−−√3k√