Sebelum membaca The Art of Computer Programming (TAOCP) , saya belum mempertimbangkan pertanyaan-pertanyaan ini secara mendalam. Saya akan menggunakan kode pseudo untuk menggambarkan algoritma, memahaminya dan memperkirakan waktu berjalan hanya tentang pesanan pertumbuhan. The TAOCP secara menyeluruh berubah pikiran saya.
TAOCP menggunakan bahasa Inggris yang dicampur dengan langkah-langkah dan goto untuk menggambarkan algoritma, dan menggunakan diagram alur untuk menggambarkan algoritma dengan lebih mudah. Tampaknya level rendah, tetapi saya menemukan bahwa ada beberapa keuntungan, terutama dengan diagram alur, yang telah saya abaikan banyak. Kami dapat memberi label pada masing-masing panah dengan pernyataan tentang keadaan saat ini pada saat perhitungan melintasi panah itu, dan membuat bukti induktif untuk algoritme. Penulis mengatakan:
Ini adalah pendapat penulis bahwa kita benar-benar mengerti mengapa suatu algoritma hanya valid ketika kita mencapai titik yang secara implisit mengisi semua pikiran kita, seperti yang dilakukan pada Gambar.4.
Saya belum mengalami hal seperti itu. Keuntungan lain adalah bahwa, kita dapat menghitung berapa kali setiap langkah dieksekusi. Sangat mudah untuk memeriksa dengan hukum pertama Kirchhoff. Saya belum menganalisis waktu berjalan dengan tepat, sehingga beberapa mungkin telah dihapus ketika saya memperkirakan waktu berjalan.
Analisis pesanan pertumbuhan terkadang tidak berguna. Sebagai contoh, kita tidak dapat membedakan quicksort dari heapsort karena semuanya adalah , di mana adalah jumlah yang diharapkan dari variabel acak , jadi kita harus menganalisis konstanta, katakanlah, dan , sehingga kita dapat membandingkan dan lebih baik. Dan juga, terkadang kita harus membandingkan jumlah lain, seperti varian. Hanya analisis kasar dari pesanan pertumbuhan waktu berjalan tidak cukup. Sebagai TAOCPE X X E ( T 1 ( n ) ) = A 1 n lg n + B 1 n + O ( log n ) E ( T 2 ( n ) ) = A 2 lg n + B 2 n + O (T 1 T 2 menerjemahkan algoritma ke dalam bahasa rakitan dan menghitung waktu berjalan, Ini terlalu sulit bagi saya, jadi saya ingin tahu beberapa teknik untuk menganalisis waktu berjalan sedikit lebih kasar, yang juga berguna, untuk bahasa tingkat yang lebih tinggi seperti C, C ++ atau kode palsu.
Dan saya ingin tahu gaya deskripsi apa yang terutama digunakan dalam karya penelitian, dan bagaimana cara mengatasi masalah ini.
sumber
Jawaban:
Ada berbagai macam pendekatan yang layak. Yang paling cocok tergantung pada
Jika algoritme adalah yang dikenal luas yang Anda gunakan sebagai subrutin, Anda sering tetap berada pada level yang lebih tinggi. Jika algoritme adalah objek utama yang sedang diselidiki, Anda mungkin ingin lebih detail. Hal yang sama dapat dikatakan untuk analisis: jika Anda memerlukan batas atas runtime yang kasar, Anda melanjutkan secara berbeda dari saat Anda menginginkan jumlah pernyataan yang tepat.
Saya akan memberi Anda tiga contoh untuk algoritma Mergesort yang terkenal yang mudah-mudahan menggambarkan ini.
Level tinggi
Algoritma Mergesort mengambil daftar, membaginya dalam dua (sekitar) bagian yang sama-sama panjang, berulang pada daftar parsial tersebut dan menggabungkan hasil (diurutkan) sehingga hasil akhirnya diurutkan. Pada daftar tunggal atau kosong, ini mengembalikan input.
Algoritma ini jelas merupakan algoritma pengurutan yang benar. Memisahkan daftar dan menggabungkannya masing-masing dapat diimplementasikan dalam waktu , yang memberi kita perulangan untuk runtime kasus terburuk T ( n ) = 2 T ( nΘ(n) . Dengan teorema Master, ini dievaluasi menjadiT(n)∈Θ(nlogn).T(n)=2T(n2)+Θ(n) T(n)∈Θ(nlogn)
Tingkat Sedang
Algoritma Mergesort diberikan oleh pseudo-code berikut:
Kami membuktikan kebenaran dengan induksi. Untuk daftar panjang nol atau satu, algoritme itu sepele benar. Sebagai hipotesis induksi, anggapn n>1 L n+1 L L
mergesort
berkinerja benar pada daftar panjang paling banyak untuk beberapa arbitrer, tetapi tetap alami n > 1 . Sekarang mari L menjadi daftar panjang n + 1 . Dengan hipotesis induksi, dan tahan (tidak menurun) versi yang diurutkan dari resp pertama. paruh kedua L setelah panggilan rekursif. Oleh karena itu, loop memilih di setiap iterasi elemen terkecil yang belum diselidiki dan menambahkannya ; dengan demikian adalah daftar yang tidak diurutkan yang mengandung semua elemen darileft
right
while
result
result
left
danright
. Kebalikannya adalah versi yang tidak diurutkan secara bertahap , yang merupakan hasil - dan yang diinginkan - yang dikembalikan.Sedangkan untuk runtime, mari kita hitung perbandingan elemen dan operasi daftar (yang mendominasi runtime tanpa gejala). Daftar panjangnya kurang dari dua tidak menyebabkan keduanya. Untuk daftar panjang , kami memiliki operasi yang disebabkan oleh menyiapkan input untuk panggilan rekursif, yang dari panggilan rekursif sendiri ditambah loop dan satu . Kedua parameter rekursif dapat dihitung dengan paling banyak n operasi daftar masing-masing. The loop dieksekusi persis n kali dan setiap iterasi penyebab paling banyak satu perbandingan elemen dan tepat dua operasi daftar. Final dapat diimplementasikan menggunakan 2 nn>1 n n 2n operasi daftar - setiap elemen dihapus dari input dan dimasukkan ke dalam daftar output. Oleh karena itu, hitungan operasi memenuhi pengulangan berikut:
while
reverse
while
reverse
Karena jelas tidak menurun, cukup untuk mempertimbangkan n = 2 k untuk pertumbuhan asimptotik. Dalam hal ini , perulangan disederhanakan menjadiT n=2k
Dengan teorema Master, kita mendapatkan yang meluas ke runtime .T∈Θ(nlogn)
mergesort
Tingkat sangat rendah
Pertimbangkan penerapan Mergesort di Isabelle / HOL ini :
Ini sudah termasuk bukti-bukti yang jelas dan terminasi. Temukan (hampir) bukti kebenaran lengkap di sini .
Untuk "runtime", yaitu jumlah perbandingan, perulangan yang serupa dengan yang ada di bagian sebelumnya dapat diatur. Alih-alih menggunakan teorema Master dan melupakan konstanta, Anda juga dapat menganalisisnya untuk mendapatkan perkiraan yang secara asimtotik sama dengan kuantitas sebenarnya. Anda dapat menemukan analisis lengkap dalam [1]; di sini adalah garis besar kasar (tidak sesuai dengan kode Isabelle / HOL):
Seperti di atas, pengulangan untuk jumlah perbandingan adalah
di mana adalah jumlah perbandingan yang diperlukan untuk menggabungkan hasil parsial². Untuk menyingkirkan lantai dan langit-langit, kami melakukan perbedaan kasus tentang apakah n genap:en n
Menggunakan perbedaan maju / mundur bersarang dari dan e n kita mendapatkan itufn en
.∑k=1n−1(n−k)⋅Δ∇fk=fn−nf1
Jumlahnya cocok dengan sisi kanan rumus Perron . Kami mendefinisikan Dirichlet pembangkit seri dari sebagaiΔ∇fk
yang bersama-sama dengan formula Perron membawa kita ke
sumber
"Disiplin Pemrograman" Dijkstra adalah tentang menganalisis dan membuktikan algoritma dan merancang untuk kemampuan. Dalam kata pengantar untuk buku itu, Dijkstra menjelaskan bagaimana sebuah bahasa mini yang sangat sederhana yang dirancang dengan baik untuk dianalisis cukup untuk menjelaskan banyak algoritma secara formal:
Kemudian dia menjelaskan betapa kecilnya dia berhasil mendapatkan bahasa mini.
sumber