Apakah ada algoritma dunia nyata yang sangat unggul di kelas di bawah ini? [Tutup]

39

Tadi malam saya berdiskusi dengan programmer lain bahwa meskipun sesuatu mungkin O (1), sebuah operasi yang O (n) dapat mengungguli itu jika ada konstanta besar dalam algoritma O (1). Dia tidak setuju, jadi saya membawanya ke sini.

Apakah ada contoh algoritma yang sangat mengungguli mereka yang ada di kelas di bawahnya? Misalnya, O (n) lebih cepat dari O (1) atau O (n 2 ) lebih cepat dari O (n).

Secara matematis ini dapat ditunjukkan untuk fungsi dengan batas atas asimptotik, ketika Anda mengabaikan faktor konstan, tetapi apakah algoritma seperti itu ada di alam liar? Dan di mana saya akan menemukan contohnya? Untuk situasi apa mereka digunakan?

KyleWpppd
sumber
15
Bahkan untuk algoritma "besar", ukuran yang lebih kecil belum tentu lebih baik. Sebagai contoh, eliminasi gaussian adalah O (n ^ 3), tetapi ada algoritma yang dapat melakukannya dalam O (n ^ 2), tetapi koefisien untuk waktu kuadrat algo begitu besar sehingga orang hanya pergi dengan O (n ^) 3) satu.
BlackJack
11
Anda harus menambahkan "... untuk masalah dunia nyata" atau semacamnya untuk menjadikan ini pertanyaan yang masuk akal. Kalau tidak, Anda hanya perlu membuat ncukup besar untuk mengimbangi konstanta (yang merupakan titik notasi O besar).
starblue
8
Jangan mengambil notasi O besar untuk kecepatan.
Codism
16
Maksud dari notasi O-besar bukan untuk memberi tahu Anda seberapa cepat suatu algoritma berjalan, tetapi seberapa baik skala itu.
BlueRaja - Danny Pflughoeft
4
Saya terkejut tidak ada yang menyebutkan algoritma Simplex untuk menyelesaikan LP. Ia memiliki kasus terburuk yang eksponensial dengan perkiraan waktu berjalan linier. Dalam praktiknya, ini cukup cepat. Itu sepele untuk membangun masalah yang menunjukkan run-time terburuk. Juga, ini banyak digunakan.
ccoakley

Jawaban:

45

Cari di tabel data yang sangat kecil dan sudah diperbaiki. Tabel hash yang dioptimalkan mungkin O (1) namun lebih lambat dari pencarian biner atau bahkan pencarian linear karena biaya perhitungan hash.

Loren Pechtel
sumber
14
Lebih tepatnya, pencarian hashtable adalah O (m) di mana m adalah ukuran kunci. Anda hanya dapat memanggil O itu (1) jika ukuran kunci konstan. Juga, biasanya itu diamortisasi - jika tidak tabel tidak dapat tumbuh / menyusut. Pohon ternary sering dapat mengalahkan tabel hash untuk pencarian string dalam konteks di mana string cukup sering tidak ditemukan - pencarian pohon ternary akan sering menemukan bahwa kunci tidak ada saat masih memeriksa karakter pertama atau dua dari string, di mana versi hashtabel belum menghitung hash.
Steve314
2
Saya suka jawaban Loren Pechtel dan komentar pertama Steve314. Saya sebenarnya melihat ini terjadi. Jika Anda membuat kelas Java yang memiliki metode kode hash () yang membutuhkan waktu terlalu lama untuk mengembalikan nilai hash (dan tidak / tidak bisa cache itu), kemudian menggunakan contoh kelas semacam itu dalam koleksi tipe hash (seperti HashSet) akan membuat koleksi tersebut ALOT lebih lambat dari koleksi tipe array (seperti ArrayList).
Shivan Dragon
1
@ Steve314: mengapa Anda menganggap fungsi hash adalah O (m) di mana m adalah ukuran kunci? Fungsi hash dapat berupa O (1) bahkan jika Anda berurusan dengan string (atau tipe kompleks lainnya). Tidak ada terlalu banyak nilai untuk dimasukkan ke dalam definisi formal daripada hanya menyadari fungsi hash secara signifikan dapat mengubah kompleksitas jika struktur data yang salah (tabel hash) dipilih untuk input Anda (ukuran kunci tidak dapat diprediksi).
Codism
1
@ Steve314: Perhatikan bahwa saya mengatakan tabel data tetap. Mereka tidak tumbuh. Selain itu, Anda hanya mendapatkan kinerja O (1) dari tabel hash jika Anda dapat mengoptimalkan kunci untuk memastikan tidak ada tabrakan.
Loren Pechtel
1
@ Loren - ketat, jika tabel memiliki ukuran tetap, ada jumlah maksimum yang konstan yang dapat Anda habiskan untuk mencari ruang kosong. Artinya, paling banyak, Anda perlu memeriksa n-1 slot yang sudah terisi di mana n adalah ukuran tabel konstan. Jadi tabel hash ukuran tetap benar-benar O (1), tanpa perlu analisis diamortisasi. Ini tidak berarti Anda tidak peduli dengan akses menjadi lebih lambat karena tabel terisi - hanya saja bukan itu yang diungkapkan oleh O besar.
Steve314
25

Perkalian matriks. Algoritma naif O (n ^ 3) sering digunakan dalam praktiknya lebih cepat dari pada Strassen O (n ^ 2.8) untuk matriks kecil-ish; dan Strassen's digunakan alih-alih algoritma Coppersmith-Winograd O (n ^ 2.3) untuk matriks yang lebih besar.

Peter Taylor
sumber
2
Coppersmith-Winograd TIDAK PERNAH digunakan. Menerapkannya akan menjadi tugas yang mengerikan dalam dirinya sendiri dan konstannya sangat buruk sehingga tidak mungkin bahkan untuk masalah matriks ilmiah modern.
tskuzzy
24

Contoh sederhana adalah perbedaan antara berbagai algoritma pengurutan. Mergesort, Heapsort, dan beberapa lainnya adalah O (n log n) . Quicksort adalah kasus terburuk O (n ^ 2) . Tetapi seringkali Quicksort lebih cepat, dan ternyata berkinerja rata-rata seperti O (n log n) . Info lebih lanjut .

Contoh lain adalah pembuatan angka Fibonacci tunggal. Algoritma iteratif adalah O (n) , sedangkan algoritma berbasis matriks adalah O (log n) . Namun, untuk pasangan pertama dari ribuan angka Fibonacci, algoritma berulang mungkin lebih cepat. Ini juga tergantung pada implementasi tentunya!

Algoritma dengan kinerja asimptotik yang lebih baik mungkin mengandung operasi yang mahal yang tidak perlu dengan algoritma dengan kinerja yang lebih buruk tetapi operasi yang lebih sederhana. Pada akhirnya, notasi- O hanya memberi tahu kita sesuatu tentang kinerja ketika argumen yang dioperasikan meningkat secara dramatis (mendekati tak terhingga).

molf
sumber
Ini adalah penjelasan yang bagus tentang Big-O, tetapi gagal untuk menjawab pertanyaan, yaitu untuk kasus-kasus tertentu di mana algoritma O (n) akan lebih cepat daripada O (1).
KyleWpppd
Fibonacci nomor satu sedikit tidak aktif. Ukuran output eksponensial dalam ukuran input, jadi ini merupakan perbedaan antara O (lg n * e ^ n) vs O (lg lg n * e ^ n).
Peter Taylor
Tambahan: terbaik. Algoritma berbasis matriks melakukan perkalian dengan angka-angka pada urutan 1,5 ^ n, jadi O (lg lg n * ne ^ n) mungkin menjadi yang terbaik yang dapat dibuktikan.
Peter Taylor
1
Quicksort biasanya digambarkan sebagai O (n log n) kinerja yang diharapkan - kasus terburuk sangat tidak mungkin untuk input acak, dan membangun beberapa keacakan menjadi prepass atau ke dalam pemilihan pivot berarti kasus terburuk secara keseluruhan sangat tidak mungkin untuk ukuran input yang signifikan. Kasus terburuk kurang relevan daripada fakta bahwa quicksort (1) sangat sederhana, dan (2) sangat ramah-cache, yang keduanya mengarah pada faktor-faktor konstan yang jauh lebih baik daripada di banyak algoritma pengurutan lainnya.
Steve314
(2) justru jenis pertimbangan eksternal yang harus diperhitungkan ketika melihat kinerja big-O. Secara algoritma, Mergesort harus selalu mengungguli Quicksort, tetapi penggunaan sumber daya dan lokalitas cache umumnya membalikkan posisi kinerja dunia nyata mereka.
Dan Lyons
18

Catatan: Silakan baca komentar oleh @ back2do di bawah ini dan guru-guru lain, karena sebenarnya lebih bermanfaat daripada apa yang saya tulis - Terima kasih untuk semua kontributor.

Saya pikir dari tabel di bawah ini (diambil dari: notasi Big O , cari "Sifat Pesimis Algoritma:"), Anda dapat melihat bahwa O (log n) tidak selalu lebih baik daripada mengatakan, O (n). Jadi, saya kira argumen Anda valid.

Pic-1

Emmad Kareem
sumber
6
Pertanyaannya ingin contoh algoritma nyata dunia nyata. Ini tidak seperti apa adanya.
Megan Walker
19
Anda tidak dapat melihat apa pun pada grafik itu, yang akan menjawab pertanyaan itu. Itu menyesatkan. Grafik ini hanya memplot fungsi y = 1, y = log xdan seterusnya dan persimpangan y = 1dan y = xsebenarnya intinya (1,1). Jika ini benar, daripada memberi tahu Anda, bahwa algoritma dengan kompleksitas yang lebih tinggi dapat lebih cepat untuk entri 0 hingga 2, yang merupakan sesuatu yang sulit dipedulikan orang. Apa grafik sepenuhnya gagal untuk memperhitungkan (dan apa perbedaan kinerja yang dapat dilihat dalam pertanyaan berasal) adalah faktor konstan.
back2dos
@Samuel Walker, terima kasih atas komentarnya. Tautan yang disediakan (Tautan-1) memiliki beberapa contoh algoritma per kategori.
NoChance
5
@ back2dos: Grafiknya sendiri tidak menjawab pertanyaan, tetapi dapat digunakan untuk menjawabnya. Bentuk setiap fungsi yang ditampilkan adalah sama untuk semua skala dan faktor konstan. Dengan ini, grafik menunjukkan kombinasi fungsi yang diberikan, terdapat rentang input yang satu lebih kecil dan rentang input yang lainnya.
Jan Hudec
2
@dan_waterworth, Anda benar, saya akan mengakui titik itu dan menghapus komentar itu. Namun demikian, jawabannya tidak benar atau menyesatkan dalam dua hal: 1) Inti dari Big-O adalah memberikan batas atas kompleksitas; itu hanya bermakna untuk n besar karena kita secara eksplisit membuang istilah yang lebih kecil yang dibanjiri oleh istilah terbesar saat n tumbuh. 2) Inti dari pertanyaan ini adalah untuk menemukan contoh dari dua algoritma di mana yang memiliki ikatan Big-O lebih tinggi mengungguli yang memiliki batas yang lebih rendah. Jawaban ini gagal karena tidak memberikan contoh seperti itu.
Caleb
11

Untuk nilai praktisnya n, ya. Ini banyak muncul dalam teori CS. Seringkali ada algoritma yang rumit yang secara teknis memiliki kinerja big-Oh yang lebih baik, tetapi faktor konstannya sangat besar sehingga tidak praktis.

Saya pernah meminta profesor geometri komputasional saya mendeskripsikan sebuah algoritma untuk melakukan triangulasi sebuah poligon dalam waktu linear, tetapi ia selesai dengan "sangat rumit. Saya tidak berpikir ada orang yang benar-benar mengimplementasikannya" (!!).

Selain itu, tumpukan fibonacci memiliki karakteristik yang lebih baik daripada tumpukan normal, tetapi tidak terlalu populer karena mereka tidak berkinerja baik dalam praktik seperti tumpukan biasa. Ini dapat mengalir ke algoritme lain yang menggunakan tumpukan - misalnya, jalur terpendek Dijkstra secara matematis lebih cepat dengan tumpukan fibonacci, tetapi biasanya tidak dalam praktik.

Gabe Moothart
sumber
Lebih cepat untuk grafik besar dengan urutan 100.000 simpul.
tskuzzy
Tumpukan Fibonacci adalah pemikiran pertama saya (sebenarnya, kedua) juga.
Konrad Rudolph
10

Bandingkan memasukkan ke dalam daftar tertaut dan memasukkan ke dalam array yang bisa diubah ukurannya.

Jumlah data harus cukup besar agar daftar tertaut O (1) menjadi berharga.

Daftar tertaut memiliki overhead tambahan untuk petunjuk dan referensi tambahan berikutnya. Array resizable harus menyalin data sekitar. Penyalinan itu O (n), tetapi dalam praktiknya sangat cepat.

Winston Ewert
sumber
1
Array yang dapat diubah ukurannya menjadi dua kali lipat setiap kali diisi, sehingga biaya rata-rata untuk mengubah ukuran per penyisipan adalah O (1).
kevin cline
2
@ kevincline, ya tetapi O (n) berasal dari keharusan untuk memindahkan semua elemen setelah titik penyisipan maju. Alokasi diamortisasi O (1) kali. Maksud saya adalah bahwa gerakan itu masih sangat cepat, jadi dalam praktiknya biasanya ketukan daftar terkait.
Winston Ewert
Alasan array yang berdekatan sangat cepat dibandingkan dengan daftar tertaut adalah karena cache prosesor. Melintasi daftar tertaut akan menyebabkan kehilangan cache untuk setiap elemen. Untuk mendapatkan yang terbaik dari kedua dunia, Anda harus menggunakan daftar tertaut yang belum dibuka .
dan_waterworth
Array yang dapat diubah ukurannya tidak selalu menyalin. Itu tergantung pada apa yang sedang berjalan dan jika ada sesuatu yang menghalangi. Sama untuk ukuran penggandaan, implementasi spesifik. Hal yang berguling adalah masalah. Linked linked biasanya terbaik untuk antrian dengan ukuran yang tidak diketahui meskipun rotary buffers mengantri untuk mendapatkan uang mereka. Dalam kasus lain, daftar yang ditautkan berguna karena alokasi atau ekspansi tidak akan membiarkan Anda memiliki hal-hal yang berdekatan setiap saat sehingga Anda tetap membutuhkan penunjuk.
jgmjgm
@ jgmjgm, jika Anda memasukkan ke tengah array yang dapat diubah ukurannya, itu benar-benar menyalin elemen setelah itu.
Winston Ewert
8

Notasi Big-Oh digunakan untuk menggambarkan laju pertumbuhan suatu fungsi, sehingga ada kemungkinan bahwa algoritma O (1) akan lebih cepat, tetapi hanya sampai pada titik tertentu (faktor konstan).

Notasi umum:

O (1) - Jumlah iterasi (kadang-kadang Anda dapat menyebutnya sebagai waktu pengguna yang dihabiskan oleh fungsi) tidak tergantung pada ukuran input, dan pada kenyataannya konstan.

O (n) - Jumlah iterasi tumbuh dalam proporsi linier dengan ukuran input. Berarti - jika algoritme itu berulang melalui input N, 2 * N kali, itu masih dianggap O (n).

O (n ^ 2) (kuadrat) - Jumlah iterasi adalah ukuran input kuadrat.

Yam Marcovic
sumber
2
Untuk menambahkan contoh ke jawaban lain yang luar biasa: metode O (1) mungkin butuh 37 tahun per panggilan, sedangkan metode O (n) mungkin membutuhkan 16 * n mikrodetik per panggilan. Mana yang lebih cepat?
Kaz Dragon
16
Saya benar-benar gagal melihat bagaimana ini menjawab pertanyaan.
avakar
7
Saya mengerti big-O. Ini tidak menjawab pertanyaan aktual, yang merupakan contoh spesifik dari fungsi di mana algoritma dengan O besar lebih besar dikalahkan oleh mereka dengan O besar besar.
KyleWpppd
Ketika Anda mengajukan pertanyaan dalam bentuk "Apakah ada contoh ...", seseorang pasti akan menjawab "Ya." tanpa memberi.
rakslice
1
@ Goraksice: Mungkin begitu. Namun situs ini menuntut penjelasan (atau lebih baik bukti) dari setiap pernyataan yang Anda buat. Sekarang cara terbaik untuk membuktikan, bahwa ada contoh-contoh seperti itu adalah memberikan satu;)
back2dos
6

Perpustakaan Regex biasanya diimplementasikan untuk melakukan backtracking yang memiliki waktu terburuk kasus eksponensial daripada generasi DFA yang memiliki kompleksitas O(nm).

Backtracking naif dapat menjadi pemain yang lebih baik ketika inputnya tetap berada di jalur cepat atau gagal tanpa perlu mundur secara berlebihan.

(Meskipun keputusan ini tidak hanya berdasarkan kinerja, itu juga untuk memungkinkan referensi kembali.)

dan_waterworth
sumber
Saya pikir ini juga sebagian historis - algoritma untuk mengubah ekspresi reguler menjadi DFA dipatenkan ketika beberapa alat sebelumnya (sed dan grep, saya kira) sedang dikembangkan. Tentu saja saya mendengar ini dari profesor kompiler saya yang tidak sepenuhnya yakin, jadi ini adalah akun pihak ketiga.
Tikhon Jelvis
5

Sebuah O(1)algoritma:

def constant_time_algorithm
  one_million = 1000 * 1000
  sleep(one_million) # seconds
end

Sebuah O(n)algoritma:

def linear_time_algorithm(n)
  sleep(n) # seconds
end

Jelas, untuk nilai di nmana pun n < one_million, O(n)algoritma yang diberikan dalam contoh akan lebih cepat daripada O(1)algoritma.

Meskipun contoh ini agak jenaka, semangat ini setara dengan contoh berikut:

def constant_time_algorithm
  do_a_truckload_of_work_that_takes_forever_and_a_day
end

def linear_time_algorithm(n)
  i = 0
  while i < n
    i += 1
    do_a_minute_amount_of_work_that_takes_nanoseconds
  end
end

Anda harus mengetahui konstanta dan koefisien dalam Oekspresi Anda , dan Anda harus mengetahui kisaran yang diharapkan n, untuk menentukan apriori algoritma mana yang akan berakhir lebih cepat.

Jika tidak, Anda harus membandingkan kedua algoritma dengan nilai ndalam kisaran yang diharapkan untuk menentukan posteriori yang akhirnya menjadi lebih cepat.

yfeldblum
sumber
4

Penyortiran:

Sortasi penyisipan adalah O (n ^ 2) tetapi mengungguli algoritma penyortiran lainnya O (n * log (n)) untuk sejumlah kecil elemen.

Ini adalah alasan mengapa sebagian besar implementasi semacam menggunakan kombinasi dari dua algoritma. Misalnya, gunakan pengurutan gabungan untuk memecah array besar sampai mereka mencapai ukuran array tertentu, kemudian gunakan pengurutan penyortiran untuk mengurutkan unit yang lebih kecil dan menggabungkan mereka lagi dengan pengurutan gabungan.

Lihat Timsort implementasi default saat ini penyortiran Python dan Java 7 yang menggunakan teknik ini.

Oliver
sumber
4

The unifikasi algoritma yang digunakan dalam praktek adalah eksponensial dalam kasus terburuk, untuk beberapa masukan patologis.

Ada algoritma penyatuan polinomial , tetapi dalam praktiknya terlalu lambat.

starblue
sumber
3

Bubblesort dalam memori dapat mengungguli quicksort ketika program sedang ditukar ke disk atau perlu membaca setiap item dari disk saat membandingkan.

Ini harus menjadi contoh yang bisa dia hubungkan.

pengguna1249
sumber
Bukankah kompleksitas yang dikutip pada quicksort dan bubblesort mengasumsikan O (1) akses memori acak? Jika ini bukan lagi masalahnya, bukankah kompleksitas quicksort perlu diperiksa ulang?
Viktor Dahl
@ ViktorDahl, waktu akses item bukan bagian dari apa yang secara tradisional diukur dalam kompleksitas algoritme sehingga "O (1)" bukan pilihan kata yang tepat di sini. Gunakan "waktu konstan" sebagai gantinya. PHK menulis sebuah artikel beberapa waktu lalu tentang mengurutkan algoritma mengetahui bahwa beberapa item lebih mahal untuk retreive daripada yang lain (memori virtual) - queue.acm.org/detail.cfm?id=1814327 - Anda mungkin menemukan itu menarik.
Saya melihat kesalahan saya sekarang. Seseorang biasanya mengukur jumlah perbandingan, dan tentu saja mereka tidak terpengaruh oleh kecepatan media penyimpanan. Juga, terima kasih atas tautannya.
Viktor Dahl
3

Seringkali algoritma yang lebih maju mengasumsikan sejumlah pengaturan (mahal). Jika Anda hanya perlu menjalankannya sekali, Anda mungkin lebih baik dengan metode brute-force.

Sebagai contoh: pencarian biner dan pencarian tabel hash keduanya jauh lebih cepat per pencarian daripada pencarian linear, tetapi mereka meminta Anda untuk mengurutkan daftar atau membangun tabel hash, masing-masing.

Pengurutan akan dikenakan biaya N log (N) dan tabel hash akan dikenakan biaya setidaknya N. Sekarang jika Anda akan melakukan ratusan atau ribuan pencarian, itu masih merupakan tabungan yang diamortisasi. Tetapi jika Anda hanya perlu melakukan satu atau dua pencarian, mungkin hanya masuk akal untuk melakukan pencarian linear dan menghemat biaya startup.

Matthew Scouten
sumber
1

Dekripsi seringkali 0 (1). Misalnya ruang utama untuk DES adalah 2 ^ 56, jadi dekripsi pesan apa pun adalah operasi waktu yang konstan. Hanya saja Anda memiliki faktor 2 ^ 56 di sana sehingga konstanta yang sangat besar.

Zachary K
sumber
Bukankah dekripsi pesan O ( n ), di mana n sebanding dengan ukuran pesan? Selama Anda memiliki kunci yang benar, ukuran kunci itu bahkan tidak masuk dalam pertimbangan; beberapa algoritma memiliki minimal atau tidak ada proses setup / ekspansi kunci (DES, RSA - perhatikan bahwa pembuatan kunci mungkin masih merupakan tugas yang rumit, tetapi itu tidak ada hubungannya dengan ekspansi kunci) sedangkan yang lain sangat kompleks (Blowfish datang ke pikiran), tetapi setelah selesai, waktu untuk melakukan pekerjaan aktual sebanding dengan ukuran pesan, maka O (n).
CVn
Anda mungkin berarti cryptananalysis daripada dekripsi?
leftaroundabout
3
Ya, ada sejumlah hal yang dapat Anda ambil untuk menjadi konstan dan mendeklarasikan algoritma sebagai O (1). [pengurutan secara implisit mengasumsikan bahwa unsur-unsur mengambil jumlah waktu yang konstan untuk membandingkan, misalnya, atau matematika apa pun dengan angka non-bignum]
Random832
1

Implementasi set yang berbeda muncul di benak saya. Salah satu yang paling naif adalah mengimplementasikannya lebih vektor, yang berarti removeserta containsdan karena itu juga addsemua take O (N).
Alternatifnya adalah mengimplementasikannya pada beberapa hash tujuan umum, yang memetakan hash input ke nilai input. Implementasi set seperti itu dilakukan dengan O (1) untuk add, containsdan remove.

Jika kita menganggap N sekitar 10 atau lebih, maka implementasi pertama mungkin lebih cepat. Yang harus dilakukan untuk menemukan elemen adalah membandingkan 10 nilai dengan satu.
Implementasi lain harus memulai segala macam transformasi pintar, yang bisa jauh lebih mahal, daripada membuat 10 perbandingan. Dengan semua overhead, Anda bahkan mungkin memiliki cache miss dan kemudian tidak masalah seberapa cepat solusi Anda secara teori.

Ini tidak berarti, bahwa implementasi terburuk yang dapat Anda pikirkan akan mengungguli yang layak, jika N cukup kecil. Ini hanya berarti untuk N yang cukup kecil, bahwa implementasi yang naif, dengan tapak rendah dan overhead sebenarnya dapat membutuhkan lebih sedikit instruksi dan menyebabkan lebih sedikit cache yang hilang daripada implementasi yang mengutamakan skala, dan karenanya akan lebih cepat.

Anda tidak dapat benar-benar tahu seberapa cepat sesuatu dalam skenario dunia nyata, sampai Anda memasukkannya ke dalam satu dan hanya mengukurnya. Seringkali hasilnya mengejutkan (setidaknya bagi saya).

back2dos
sumber
1

Ya, untuk N. kecil yang sesuai Akan selalu ada N, di atasnya Anda akan selalu memiliki urutan O (1) <O (lg N) <O (N) <O (N log N) <O (N ^ c ) <O (c ^ N) (di mana O (1) <O (lg N) berarti bahwa pada O (1) algoritma akan mengambil lebih sedikit operasi ketika N cukup besar dan c adalah konstanta tetap yang lebih besar dari 1 ).

Katakanlah algoritma O (1) tertentu membutuhkan operasi f (N) = 10 ^ 100 (a googol) dan sebuah algoritma O (N) membutuhkan operasi g (N) = 2 N + 5. Algoritma O (N) akan memberikan kinerja yang lebih besar sampai Anda N kira-kira googol (sebenarnya ketika N> (10 ^ 100 - 5) / 2), jadi jika Anda hanya berharap N berada di kisaran 1000 hingga satu miliar Anda akan menderita penalti besar menggunakan algoritma O (1).

Atau untuk perbandingan yang realistis, misalkan Anda mengalikan angka n-digit bersama-sama. The Karatsuba algoritma yang paling banyak 3 n ^ (lg 3) operasi (yang kira-kira O (n ^ 1,585)) sedangkan algoritma Schönhage-Strassen adalah O (N log N log log N) yang merupakan urutan lebih cepat , tetapi untuk kutipan wikipedia:

Dalam praktiknya, algoritma Schönhage-Strassen mulai mengungguli metode yang lebih tua seperti Karatsuba dan perkalian Toom-Cook untuk angka di luar 2 ^ 2 ^ 15 hingga 2 ^ 2 ^ 17 (10.000 hingga 40.000 angka desimal). [4] [5] [6 ]

Jadi, jika Anda mengalikan 500 angka angka bersama, tidak masuk akal untuk menggunakan algoritma yang "lebih cepat" oleh argumen O besar.

EDIT: Anda dapat menemukan menentukan f (N) dibandingkan g (N), dengan mengambil batas N-> tak terhingga dari f (N) / g (N). Jika batasnya adalah 0 maka f (N) <g (N), jika batasnya tidak terbatas maka f (N)> g (N), dan jika batasnya adalah konstanta lain maka f (N) ~ g (N) dalam hal notasi O besar.

dr jimbob
sumber
1

Metode simpleks untuk pemrograman linier dapat bersifat eksponensial dalam kasus terburuk, sementara algoritma titik interior yang relatif baru dapat bersifat polinomial.

Namun, dalam praktiknya, kasus terburuk eksponensial untuk metode simpleks tidak muncul - metode simpleks cepat dan andal, sementara algoritma titik interior awal terlalu lambat untuk bersaing. (Ada algoritma titik interior sekarang lebih modern yang berada kompetitif - tapi metode simpleks adalah, terlalu ...)

datang badai
sumber
0

Algoritma Ukkonen untuk membangun percobaan sufiks adalah O (n log n). Ini memiliki keuntungan menjadi "online" - yaitu, Anda dapat menambahkan teks secara bertahap.

Baru-baru ini, algoritma lain yang lebih kompleks diklaim lebih cepat dalam praktiknya, sebagian besar karena akses memori mereka memiliki lokalitas yang lebih tinggi, sehingga meningkatkan pemanfaatan cache prosesor dan menghindari warung pipa CPU. Lihat, misalnya, survei ini , yang mengklaim bahwa 70-80% waktu pemrosesan dihabiskan untuk menunggu memori, dan makalah ini menjelaskan algoritma "wotd".

Upaya sufiks penting dalam genetika (untuk mencocokkan urutan gen) dan, yang agak kurang penting, dalam penerapan kamus Scrabble.

Ed Staub
sumber
0

Selalu ada algoritma tercepat dan terpendek untuk masalah yang terdefinisi dengan baik . Ini hanya murni secara teoritis algoritma tercepat (asimptotik).

Diberi deskripsi masalah P dan sebuah contoh untuk itu masalah saya , itu menyebutkan semua algoritma mungkin A dan bukti Pr , memeriksa setiap pasangan seperti apakah Pr merupakan bukti valid yang A adalah algoritma asimtotik tercepat untuk P . Jika menemukan bukti seperti itu, kemudian mengeksekusi A di saya .

Mencari pasangan masalah-bukti ini memiliki kompleksitas O (1) (untuk masalah tetap P ), jadi Anda selalu menggunakan algoritma tercepat asimptotik untuk masalah tersebut. Namun, karena konstanta ini sangat luar biasa dalam hampir semua kasus, metode ini sama sekali tidak berguna dalam praktiknya.

Alex ten Brink
sumber
0

Banyak bahasa / kerangka kerja menggunakan pencocokan pola naif untuk mencocokkan string, bukan KMP . Kami mencari string seperti Tom, New York daripada ababaabababababaababababababab.

Lukasz Madon
sumber