Biasanya dalam algoritma kami tidak peduli tentang perbandingan, penambahan, atau pengurangan angka - kami menganggap mereka berjalan dalam waktu . Sebagai contoh, kita mengasumsikan ini ketika kita mengatakan bahwa pengurutan berbasis perbandingan adalah , tetapi ketika angka terlalu besar untuk masuk ke dalam register, kita biasanya mewakili mereka sebagai array sehingga operasi dasar memerlukan perhitungan tambahan per elemen.
Apakah ada bukti yang menunjukkan bahwa perbandingan dua angka (atau fungsi aritmatika primitif lainnya) dapat dilakukan dalam ? Jika tidak mengapa kita mengatakan bahwa penyortiran berbasis perbandingan adalah ?
Saya mengalami masalah ini ketika saya menjawab pertanyaan SO dan saya menyadari bahwa algoritma saya tidak karena cepat atau lambat aku harus berurusan dengan besar-int, itu juga tidak semu polinomial waktu algoritma, itu .
Jawaban:
Bagi orang-orang seperti saya yang mempelajari algoritma untuk mencari nafkah, model komputasi standar abad ke-21 adalah integer RAM . Model ini dimaksudkan untuk mencerminkan perilaku komputer nyata lebih akurat daripada model mesin Turing. Komputer dunia nyata memproses bilangan bulat banyak-bit dalam waktu konstan menggunakan perangkat keras paralel; bukan bilangan bulat sembarang , tetapi (karena ukuran kata tumbuh dengan mantap dari waktu ke waktu) juga bukan bilangan bulat ukuran tetap .
Model tergantung pada satu parameter , yang disebut ukuran kata . Setiap alamat memori memiliki integer bit tunggal , atau kata . Dalam model ini, ukuran input adalah jumlah kata dalam input, dan waktu berjalan suatu algoritma adalah jumlah operasi pada kata-kata . Operasi aritmatika standar (penambahan, pengurangan, perkalian, pembagian bilangan bulat, sisanya, perbandingan) dan operasi boolean (bitwise dan, atau, xor, shift, rotate) pada kata-kata memerlukan waktu menurut definisi .w n O ( 1 )w w n O ( 1 )
Secara formal, ukuran kata adalah TIDAK konstanw untuk tujuan menganalisis algoritma dalam model ini. Untuk membuat model konsisten dengan intuisi, kita memerlukan , karena jika tidak kita bahkan tidak dapat menyimpan integer dalam satu kata. Namun demikian, untuk sebagian besar algoritma non-numerik, waktu berjalan sebenarnya independen dari , karena algoritma tersebut tidak peduli dengan representasi biner yang mendasari input mereka. Mergesort dan heapsort keduanya berjalan dalam waktu ; median-of-3-quicksort berjalan dalam waktu dalam kasus terburuk. Satu pengecualian penting adalah jenis radix biner, yang berjalan dalam waktu .n w O ( n log n ) O ( n 2 ) O ( n w )w ≥ log2n n w O(nlogn) O(n2) O(nw)
Pengaturan memberi kita model RAM biaya logaritmik tradisional. Tetapi beberapa algoritma integer RAM dirancang untuk ukuran kata yang lebih besar, seperti algoritma pengurutan integer linear-waktu dari Andersson et al. , yang membutuhkan .w = Ω ( log 2 + ε n )w=Θ(logn) w=Ω(log2+εn)
Untuk banyak algoritme yang muncul dalam praktiknya, ukuran kata sama sekali bukan masalah, dan kita dapat (dan memang) kembali pada model RAM seragam yang jauh lebih sederhana. Satu-satunya kesulitan yang serius berasal dari perkalian bersarang, yang dapat digunakan untuk membangun sangat bilangan bulat besar sangat cepat. Jika kita dapat melakukan aritmatika pada bilangan bulat sewenang-wenang dalam waktu konstan, kita dapat menyelesaikan masalah di PSPACE dalam waktu polinomial .w
Pembaruan: Saya juga harus menyebutkan bahwa ada pengecualian pada "model standar", seperti algoritma pengganda integer Fürer , yang menggunakan mesin Turing multitape (atau setara, "bit RAM"), dan sebagian besar algoritma geometris, yang dianalisis secara teoritis model "RAM nyata" yang bersih namun ideal .
Ya, ini adalah sekaleng cacing.
sumber
Itu tergantung pada konteksnya. Ketika berhadapan dengan kompleksitas algoritma level bit , kami tidak mengatakan bahwa penambahan dua angka bit adalah O ( 1 ) , kami mengatakan itu adalah O ( n ) . Demikian pula untuk multiplikasi dll.n O ( 1 ) O ( n )
sumber
Untuk menjawab pertanyaan sebagaimana dinyatakan: algoritme cukup melakukannya, cukup sering, dengan menggunakan model RAM. Untuk menyortir, dalam banyak kasus, orang bahkan menganalisis model perbandingan yang lebih sederhana , yang saya bahas sedikit lebih dalam jawaban terkait.
Untuk menjawab pertanyaan implisit tentang mengapa mereka melakukannya: Saya akan mengatakan bahwa model ini memiliki daya prediksi yang cukup baik untuk beberapa jenis algoritma kombinatorial, di mana angkanya semua "kecil" dan, pada mesin nyata, cocok dengan register.
Untuk menjawab tindak lanjut tersirat tentang algoritma numerik: Tidak, model RAM lama yang biasa bukan standar di sini. Bahkan eliminasi Gaussian dapat membutuhkan perawatan. Biasanya, untuk perhitungan peringkat, Lemma Schwartz akan masuk (misalnya, Bagian 5 di sini ). Contoh kanonik lainnya adalah analisis Algoritma Ellipsoid, yang membutuhkan kehati - hatian untuk dianalisis.
Dan akhirnya: Orang-orang telah memikirkan penyortiran string sebelumnya , bahkan baru-baru ini.
Pembaruan: Masalah dengan pertanyaan ini adalah bahwa "kami" dan "menganggap" tidak ditentukan secara tepat. Saya akan mengatakan bahwa orang-orang yang bekerja dalam model RAM tidak melakukan algoritma numerik atau teori kompleksitas (di mana menentukan kompleksitas pembagian adalah hasil yang dirayakan ).
sumber
Saya tidak dapat menemukan studi ini, tetapi Kozen mengatakan dalam pengantar "Desain dan Analisis Algoritma" bahwa model "mencerminkan pengamatan eksperimental yang lebih akurat [daripada model log-cost] untuk data moderat ukuran (karena perkalian benar-benar membutuhkan satu unit waktu). " Dia juga memberikan referensi pada makalah ini sebagai contoh bagaimana model O ( 1 ) dapat disalahgunakan.O ( 1 ) O ( 1 )
Ini benar-benar bukan evaluasi legit (paling tidak karena itu Python), tapi inilah beberapa nomor dari berjalan10{ 1 , 2 , . . . , 66 }
python -mtimeit "$a * $b"
untuk$a
di dan . (Saya berhenti di 66 karena sintaksis Python berhenti menerima integer literal dan saya harus sedikit mengganti kode evaluasi saya, jadi saya tidak.: P)$b = 2*$a
sumber
sumber
Saya akan mengatakan bahwa kita biasanya mengasumsikan O (1) operasi aritmatika karena kita biasanya melakukan hal-hal dalam konteks bilangan bulat 32-bit atau bilangan bulat 64-bit atau angka floating point IEEE 754. O (1) mungkin merupakan pendekatan yang cukup bagus untuk jenis aritmatika tersebut.
Tetapi secara umum, itu tidak benar. Secara umum Anda membutuhkan algoritma untuk melakukan penjumlahan, pengurangan, perkalian, dan pembagian. Boolos, Burgess and Jefferies ' Computability and Logic muncul dalam pikiran sebagai cara untuk memahami bukti dari itu, dalam hal beberapa sistem formal yang berbeda, Fungsi Rekursif dan Mesin Abacus, setidaknya, dalam salinan Edisi ke-4 saya.
Anda dapat melihat istilah lambda-calculus untuk pengurangan dan pembagian dengan Angka Gereja untuk penjelasan yang mudah dilihat mengapa kedua operasi itu bukan O (1). Agak sulit untuk melihat penambahan dan penggandaan serta eksponensial, tetapi ada di sana jika Anda mempertimbangkan bentuk Angka Gereja sendiri.
sumber