Saya telah mendengar beberapa kali bahwa untuk nilai n yang cukup kecil, O (n) dapat dipikirkan / diperlakukan seolah-olah itu O (1).
Contoh :
Motivasi untuk melakukannya didasarkan pada gagasan yang salah bahwa O (1) selalu lebih baik daripada O (lg n), selalu lebih baik daripada O (n). Urutan asimptotik dari operasi hanya relevan jika dalam kondisi realistis ukuran masalah sebenarnya menjadi besar. Jika n tetap kecil maka setiap masalah adalah O (1)!
Apa yang cukup kecil? 10? 100? 1.000? Pada titik apa Anda berkata "kita tidak bisa memperlakukan ini seperti operasi gratis lagi"? Apakah ada aturan praktis?
Sepertinya ini bisa spesifik untuk domain atau kasus, tetapi apakah ada aturan umum tentang cara berpikir tentang ini?
asymptotics
rianjs
sumber
sumber
O(1)
untuk bebas . Alasan di balik beberapa kalimat pertama adalah bahwaO(1)
adalah konstan , yang kadang-kadang bisa gila-gilaan lambat. Suatu perhitungan yang membutuhkan waktu seribu miliar tahun terlepas dari input adalah suatuO(1)
perhitungan.Jawaban:
Semua urutan besarnya melibatkan konstanta , beberapa di antaranya sebenarnya. Ketika jumlah item cukup besar konstanta tidak relevan. Pertanyaannya adalah apakah jumlah barang cukup kecil sehingga konstan untuk mendominasi.C
Inilah cara visual untuk memikirkannya.
Semua memiliki konstanta startup yang menentukan titik awal mereka pada sumbu Y. Masing-masing juga memiliki konstanta kritis mendominasi seberapa cepat mereka akan meningkat.C
Untuk menentukan algoritma mana yang harus Anda gunakan, Anda perlu memperkirakan tempat di mana runtimes berpotongan. Misalnya, solusi dengan waktu startup tinggi atau tinggi akan kalah dari solusi dengan waktu startup rendah dan rendah pada jumlah item yang cukup besar.C O ( n ) CO(1) C O(n) C
Inilah contoh dunia nyata. Anda harus memindahkan banyak batu bata ke halaman. Anda dapat memindahkannya sedikit demi sedikit dengan tangan Anda, atau mengambil backhoe yang besar dan lambat untuk mengangkat dan mengarahkannya dalam satu perjalanan. Apa jawaban Anda jika ada tiga batu bata? Apa jawaban Anda jika ada tiga ribu?
Inilah contoh CS. Katakanlah Anda memerlukan daftar yang selalu diurutkan. Anda bisa menggunakan pohon yang akan menjaga dirinya agar . Atau Anda bisa menggunakan daftar yang tidak disortir dan mengurutkan ulang setelah setiap penyisipan atau penghapusan di . Karena operasi pohon rumit (mereka memiliki konstanta tinggi), dan pengurutan sangat sederhana (konstanta rendah), daftar kemungkinan akan menang hingga ratusan atau ribuan item.O ( n log n )O(logn) O(nlogn)
Anda dapat melihat hal semacam ini, tetapi pada akhirnya pembandingan adalah yang akan melakukannya. Anda juga harus melihat berapa banyak barang yang biasanya Anda miliki, dan mengurangi risiko diserahkan lebih banyak. Anda juga akan ingin mendokumentasikan asumsi Anda seperti "kinerja akan menurun dengan cepat di atas item " atau "kami menganggap ukuran set maksimum ".XX X
Karena persyaratan ini dapat berubah, penting untuk menempatkan keputusan semacam ini di belakang sebuah antarmuka. Dalam contoh pohon / daftar di atas, jangan memaparkan pohon atau daftar. Dengan begitu, jika asumsi Anda ternyata salah, atau Anda menemukan algoritma yang lebih baik, Anda bisa berubah pikiran. Anda bahkan dapat melakukan hibrida dan secara dinamis beralih algoritma saat jumlah item bertambah.
sumber
Ini sebagian besar dukungan piggy pada jawaban yang sudah diposting, tetapi dapat menawarkan perspektif yang berbeda.
Ini mengungkapkan bahwa pertanyaan ini membahas "nilai n cukup kecil ". Inti dari Big-O adalah untuk menggambarkan bagaimana pemrosesan tumbuh sebagai fungsi dari apa yang sedang diproses. Jika data yang sedang diproses tetap kecil, tidak relevan untuk membahas Big-O, karena Anda tidak tertarik dengan pertumbuhan (yang tidak terjadi).
Dengan kata lain, jika Anda menempuh jarak yang sangat dekat, mungkin sama cepatnya untuk berjalan, menggunakan sepeda, atau berkendara. Bahkan mungkin lebih cepat untuk berjalan jika perlu waktu untuk menemukan kunci mobil Anda, atau jika mobil Anda membutuhkan bensin, dll.
Untuk n kecil , gunakan apa pun yang nyaman.
Jika Anda melakukan perjalanan lintas negara, maka Anda perlu mencari cara untuk mengoptimalkan mengemudi, jarak tempuh bahan bakar, dll.
sumber
n < infinity
.Kutipannya agak kabur dan tidak tepat. Setidaknya ada tiga cara terkait yang bisa ditafsirkan.
sumber
Di sisi lain, jika Anda hanya menemukan nilai n = 1, 2 dan 3, maka dalam praktiknya tidak ada bedanya apa yang dilakukan f (n) untuk n ≥ 4, jadi sebaiknya Anda juga mempertimbangkan bahwa f ( n) = O (1), dengan c = maks (f (1), f (2), f (3)). Dan itu artinya cukup kecil: Jika klaim bahwa f (n) = O (1) tidak menyesatkan Anda jika satu-satunya nilai f (n) yang Anda temui adalah "cukup kecil".
sumber
Jika tidak tumbuh, itu O (1)
Pernyataan penulis agak aksiomatis.
Susunan pertumbuhan menggambarkan apa yang terjadi pada jumlah pekerjaan yang harus Anda lakukan sebagai
N
peningkatan. Jika Anda tahu ituN
tidak meningkat, masalah Anda efektifO(1)
.Ingat itu
O(1)
tidak berarti "cepat". Algoritma yang selalu membutuhkan 1 triliun langkah untuk diselesaikan adalahO(1)
. Algoritma yang mengambil dari 1-200 langkah, tetapi tidak pernah lebih, adalahO(1)
. [1]Jika algoritma Anda mengambil
N ^ 3
langkah tepat , dan Anda tahu ituN
tidak boleh lebih dari 5, itu tidak akan pernah bisa lebih dari 125 langkah, jadi itu efektifO(1)
.Tetapi sekali lagi,
O(1)
tidak harus berarti "cukup cepat". Itu pertanyaan terpisah yang tergantung pada konteks Anda. Jika butuh satu minggu untuk menyelesaikan sesuatu, Anda mungkin tidak peduli apakah itu secara teknisO(1)
.[1] Misalnya, pencarian dalam hash adalah
O(1)
, meskipun tabrakan hash berarti bahwa Anda mungkin harus melihat beberapa item dalam satu ember, asalkan ada batasan keras tentang berapa banyak item yang bisa berada di ember itu.sumber
g(n) = min(f(2^15), f(n))
- yang ada di O (1). Yang mengatakan dalam prakteknya konstanta sangat penting dan jelas n dapat menjadi cukup besar sehingga analisis asimptotik berguna.Praktis, itu adalah titik di mana membangun tabel hash mengambil lebih dari manfaat yang Anda peroleh dari pencarian yang ditingkatkan. Ini akan sangat bervariasi berdasarkan seberapa sering Anda melakukan pencarian, versus seberapa sering Anda melakukan hal-hal lain. O (1) vs O (10) bukan masalah besar jika Anda melakukannya sekali. Jika Anda melakukannya ribuan kali per detik, bahkan itu penting (meskipun setidaknya itu penting pada tingkat yang meningkat secara linear).
sumber
Sementara kutipan itu benar (tetapi tidak jelas) ada juga bahaya untuk itu. Saya juga harus melihat kompleksitas dalam setiap tahap aplikasi Anda.
Terlalu mudah untuk mengatakan: hei saya hanya memiliki daftar kecil, jika saya ingin memeriksa apakah item A ada dalam daftar, saya hanya akan menulis loop mudah untuk melintasi daftar dan membandingkan item.
Kemudian buddyprogrammer Anda datang perlu menggunakan daftar, melihat fungsi Anda dan seperti: hei saya tidak ingin ada duplikat dalam daftar sehingga ia menggunakan fungsi untuk setiap item yang ditambahkan ke daftar.
(Pikiran Anda, ini masih skenario daftar kecil.)
3 tahun kemudian saya datang dan bos saya baru saja melakukan penjualan besar: perangkat lunak kami akan digunakan oleh pengecer nasional besar. Sebelumnya kami hanya melayani toko-toko kecil. Dan sekarang bos saya datang kepada saya bersumpah dan berteriak, mengapa perangkat lunak, yang selalu "bekerja dengan baik" sekarang sangat lambat.
Ternyata, daftar itu adalah daftar klien, dan pelanggan kami hanya memiliki sekitar 100 klien, jadi tidak ada yang memperhatikan. Operasi mengisi daftar pada dasarnya adalah operasi O (1), karena butuh kurang dari satu milidetik. Ya, tidak banyak ketika ada 10.000 klien yang ditambahkan.
Dan bertahun-tahun setelah keputusan O (1) buruk yang asli, perusahaan hampir kehilangan klien besar. Semua karena satu kesalahan desain / asumsi kecil tahun sebelumnya.
sumber
Jika saya memiliki dua algoritma dengan waktu ini:
Lalu ada beberapa titik di mana mereka menyeberang. Untuk
n
lebih kecil dari itu, algoritma "linear" lebih cepat, dan untukn
lebih besar dari itu, algoritma "logaritmik" lebih cepat. Banyak orang membuat kesalahan dengan mengasumsikan algoritma logaritmik lebih cepat, tetapi untuk yang keciln
tidak.Saya berspekulasi apa yang dimaksudkan di sini adalah bahwa jika
n
terbatas, maka setiap masalah adalah O (1). Misalnya, jika kami mengurutkan bilangan bulat, kami dapat memilih untuk menggunakan quicksort.O(n*log(n))
jelas. Tetapi jika kita memutuskan bahwa tidak mungkin ada lebih dari2^64=1.8446744e+19
bilangan bulat, maka kita tahu bahwan*log(n)
<=1.8446744e+19*log(1.8446744e+19)
<=1.1805916e+21
. Oleh karena itu, algoritme akan selalu memakan waktu kurang dari1.1805916e+21
"satuan waktu". Karena itu adalah waktu yang konstan, kita dapat mengatakan algoritme selalu dapat dilakukan dalam waktu yang konstan itu ->O(1)
. (Perhatikan bahwa meskipun satuan waktu itu adalah nanodetik, itu adalah total keseluruhan lebih dari 37411 tahun). Tapi tetap sajaO(1)
.sumber
Saya menduga banyak dari jawaban ini yang kehilangan konsep mendasar. O (1): O (n) tidak sama dengan f (1): f (n) di mana f adalah fungsi yang sama, karena O tidak mewakili fungsi tunggal. Bahkan grafik bagus Schwern tidak valid karena memiliki sumbu Y yang sama untuk semua garis. Untuk semua menggunakan sumbu yang sama, garis harus fn1, fn2 dan fn3, di mana masing-masing adalah fungsi yang kinerjanya dapat langsung dibandingkan dengan yang lain.
Nah, jika n = 1 mereka persis sama? Tidak. Fungsi yang memungkinkan sejumlah variabel iterasi tidak memiliki kesamaan dengan yang tidak, notasi O besar tidak peduli, dan kita juga tidak.
Notasi O besar hanya ada untuk mengekspresikan apa yang terjadi ketika kita memiliki proses berulang, dan bagaimana kinerja (waktu atau sumber daya) akan menurun ketika 'n' meningkat.
Jadi untuk menjawab pertanyaan yang sebenarnya ... Saya akan mengatakan bahwa mereka yang membuat klaim itu tidak memahami notasi Big-O dengan benar, karena ini adalah perbandingan yang tidak masuk akal.
Inilah pertanyaan yang serupa: Jika saya mengulang-ulang serangkaian karakter, dan saya tahu bahwa secara umum string saya akan kurang dari 10 karakter, dapatkah saya mengatakan bahwa itu setara dengan O (1), tetapi jika string saya lebih panjang maka saya akan mengatakan itu O (n)?
Tidak, karena string 10 karakter membutuhkan 10 kali lebih lama dari string 1 karakter, tetapi 100 kali lebih kecil dari string 1000 karakter! Ini O (n).
sumber
Saya percaya teks yang Anda kutip cukup tidak akurat (menggunakan kata "lebih baik" biasanya tidak ada artinya kecuali Anda memberikan konteksnya: dalam hal waktu, ruang, dll.) Bagaimanapun, saya percaya penjelasan paling sederhana adalah:
Jika waktu eksekusi tumbuh dengan ukuran input maka sudah pasti bukan dan itu harus jelas. tidak berarti cepat . Ini hanya berarti (dalam hal kompleksitas waktu) bahwa waktu eksekusi memiliki batas atas yang konstan .O(1) O(1)
Sekarang, mari kita ambil 10 elemen yang relatif kecil dan memiliki beberapa algoritma untuk mengurutkannya (hanya sebuah contoh). Mari kita asumsikan bahwa kita menyimpan elemen dalam struktur yang juga menyediakan kita dengan algoritma yang mampu mengurutkan elemen dalam waktu yang konstan. Katakanlah algoritma sorting kami dapat memiliki kompleksitas berikut (dengan notasi O-besar):
Algoritme apa yang akan Anda pilih? Jawaban pertama yang terlintas dalam pikiran mungkin "tentu saja saya akan menggunakan satu!", Tetapi ini belum tentu benar. Apa yang Anda lupa ketika berpikir seperti itu adalah bahwa notasi-O besar menyembunyikan faktor konstan . Dan jika Anda tahu perangkat Anda cukup kecil, maka faktor konstan ini mungkin jauh lebih penting daripada kompleksitas asimptotik.O(1)
Sekarang mari kita "mengungkapkan" kompleksitas sebenarnya dari algoritma pengurutan yang disebutkan di atas (di mana "benar" berarti tidak menyembunyikan konstanta), diwakili oleh sejumlah langkah yang diperlukan untuk menyelesaikan (dan menganggap semua langkah mengambil jumlah waktu yang sama):
Jika input kami berukuran 10, maka ini adalah jumlah langkah yang tepat untuk setiap algoritma yang disebutkan di atas:
Seperti yang Anda lihat, dalam hal ini algoritma yang tampaknya paling buruk dengan kompleksitas asimptotik adalah yang tercepat, mengalahkan algoritma dengan kompleksitas asimptotik dan . Faktor konstan yang disembunyikan oleh notasi O besar penting di sini. Menurut pendapat saya itu tidak berarti bahwa kita dapat memperlakukan lebih baik daripada (apa artinya itu?) Itu berarti bahwa untuk input yang cukup kecil (seperti yang Anda lihat dalam contoh) mungkin masih lebih cepat daripada karena konstanta tersembunyi. Dan jika konstanta relatif besar dibandingkan dengan ukuran input, itu mungkin lebih penting daripada kompleksitas asimptotik.O(n2) O(1),O(n) O(nlog(n)) O(n2) O(1) O(n2) O(1)
sumber