Saya terjebak dengan menganalisis kompleksitas waktu dari algoritma berikut:
def fun (r, k, d, p):
if d > p:
return r
if d = 0 and p = 0:
r <- r + k
return r
if d > 0:
fun (r, k + 1, d - 1, p)
if p > 0:
fun (r, k - 1, d, p - 1)
Panggilan root akan menjadi fun (0, 0, n, n)
, dan n
merupakan ukuran masalah.
Saya kira itu: Relasi perulangan adalah , yang setara dengan , dan .
Apakah analisis saya benar (saya tahu itu tidak terlalu lengkap dan tepat)? Jika memang ada cacat serius, tunjukkan atau tunjukkan saya bukti yang benar dan lengkap tentang kompleksitas waktu dari algoritma ini.
d>0
danp>0
. Anda tidak menunjukkan apa fungsi kembali jika kita mencapai pernyataan if ke-3 dan ke-4. Apakah Anda bermaksud memilikireturn
pernyataan setelah setiap doa rekursiffun
? (Apakah Anda bermaksudfun (r, k + 1, d - 1, p)
menjadireturn fun (r, k + 1, d - 1, p)
?) Atau apakah Anda bermaksud memilikireturn
pernyataan di akhir fungsi tubuh? Harap edit kodesemu Anda untuk memperjelas dan memastikan Anda menunjukkan apa yang dikembalikan dalam semua kasus yang mungkin.d<=p
dand>0
danp>0
semua pegang. Apa yang seharusnya terjadi? Apakah algoritma membuat 2 doa rekursif ke fungsi? Atau apakah itu secara rekursif memohonfun(r, k + 1, d - 1, p)
dan kemudian segera kembali, tanpa memohon secara rekursiffun(r, k - 1, d, p - 1)
? Jika saya mengambil pseudocode Anda secara harfiah, tampaknya itu membuat 2 doa rekursif dan kemudian kembali dengan nilai pengembalian yang tidak ditentukan - tapi itu aneh dan membuat saya bertanya-tanya apakah ada kesalahan ketik / bug dalam pseudocode.Jawaban:
Dua argumen yang relevan dengan analisis asimptotik adalahd dan hal . Argumen-argumen ini (secara virtual) memuaskand, p ≥ 0 dan d≤ p (kita perlu mengocok logika dalam fungsi sedikit untuk mendapatkan ini). Di setiap titik dalam eksekusi, Anda mengambil pasangan saat ini( d, p ) dan kemudian secara rekursif memanggil fungsi dengan pasangan ( d- 1 , p ) , ( d, p - 1 ) , menghindari pasangan yang membatalkan batasan yang disebutkan di atas.
Kita bisa menggambarkan pohon panggilan yang dihasilkan sebagai jalan mulai dari( 0 , 0 ) . Setiap kali Anda mengurangihal , tambahkan / langkah. Setiap kali Anda mengurangid , tambahkan \ langkah. Kondisid≤ p menjamin bahwa Anda tidak pernah pergi di bawah sumbu X. Selain itu, Anda memiliki "anggaran" sebesarn dari setiap langkah. Jumlah total daun di pohon panggilan ini persis nomor Catalan(2 nn) /(n+1)=Θ(4n/n3 / 2) , dan ini memberi kita batas bawah pada waktu menjalankan fungsi.
Untuk mendapatkan batas atas, perhatikan bahwa dalam perjalanan ke setiap daun yang kita lewati2 n node, dan ini memberi batas atas 2 n lebih besar dari batas bawah, yaitu, Θ (4n/n--√) .
Kami memiliki batas bawahΩ (4n/n3 / 2) dan batas atas O (4n/n--√) . Apa asimptotik yang tepat? Mereka tumbuh seperti jumlah total jalur yang tidak melewati sumbu X yang paling banyakn langkah di setiap arah. Dengan menggunakan teorema surat suara Bertrand kita bisa mendapatkan ungkapan yang tepat untuk ini:
sumber
Kasus per kasus:
fun
berulang pada d-1 hingga d ≯ 0; sejak p> 0, ini adalah Linear dalam d + (kasus 4) .fun
berulang pada p-1 hingga p ≯ 0; ini Linear dalam p + (salah satu dari kasus 1, 2, atau 5)Dimulai dengan d = p = n> 0 hits case 3, yang diikuti oleh case 4. Jika n adalah bilangan bulat, case terakhir adalah 2, jika case terakhir adalah 5. Total waktu untuk kasus tersebut adalah d + p +1, atau 2n +1.
sumber
if
s untuk menjadi "melakukan salah satu dari ini" sementara @Yuval menganggap mereka "mempertimbangkan masing-masing dalam urutan". Yang terakhir, tentu saja, apa artinyaif
(tanpaelse
) dalam kode aktual; Saya terbiasa dengan yang pertama dalam hampir semua konteks selain kode aktual (termasuk dalam pseudocode, meskipun penggunaan dalam pseudocode tidak konsisten).return
pernyataan di bagian akhir kode membuat ini sangat membingungkan.