Apakah ada algoritma O (1 / n)?
Atau apa pun yang kurang dari O (1)?
theory
complexity-theory
big-o
Peter Mortensen
sumber
sumber
Jawaban:
Pertanyaan ini tidak sebodoh kelihatannya. Setidaknya secara teoritis, sesuatu seperti O (1 / n ) sepenuhnya masuk akal ketika kita mengambil definisi matematika dari notasi O Besar :
Sekarang Anda dapat dengan mudah mengganti g ( x ) dengan 1 / x ... sudah jelas bahwa definisi di atas masih berlaku untuk beberapa f .
Untuk tujuan memperkirakan pertumbuhan run-time asimptotik, ini kurang layak ... algoritma yang bermakna tidak bisa lebih cepat ketika input tumbuh. Tentu, Anda dapat membuat algoritma arbitrer untuk memenuhi hal ini, misalnya yang berikut:
Jelas, fungsi ini menghabiskan lebih sedikit waktu karena ukuran input tumbuh ... setidaknya sampai batas tertentu, ditegakkan oleh perangkat keras (ketepatan angka, waktu minimum yang
sleep
bisa menunggu, waktu untuk memproses argumen dll.): Batas ini kemudian akan menjadi batas bawah konstan sehingga sebenarnya fungsi di atas masih memiliki runtime O (1).Tapi ada yang sebenarnya algoritma dunia nyata di mana runtime dapat menurunkan (setidaknya sebagian) ketika ukuran masukan meningkat. Perhatikan bahwa algoritma ini tidak akan menampilkan perilaku runtime di bawah O (1). Meski begitu, mereka menarik. Misalnya, ambil algoritma pencarian teks yang sangat sederhana oleh Horspool . Di sini, runtime yang diharapkan akan berkurang karena panjang pola pencarian meningkat (tetapi meningkatnya panjang tumpukan jerami akan sekali lagi meningkatkan runtime).
sumber
Iya.
Tepatnya ada satu algoritma dengan runtime O (1 / n), algoritma "kosong".
Untuk suatu algoritma menjadi O (1 / n) berarti bahwa ia dijalankan secara asimptotik dalam langkah-langkah yang lebih sedikit daripada algoritma yang terdiri dari satu instruksi. Jika dijalankan dalam langkah kurang dari satu langkah untuk semua n> n0, itu harus terdiri dari tepat tidak ada instruksi sama sekali untuk mereka n. Karena memeriksa 'jika n> n0' memerlukan biaya setidaknya 1 instruksi, itu harus terdiri dari tidak ada instruksi untuk semua n.
Kesimpulannya: Satu-satunya algoritma yang O (1 / n) adalah algoritma kosong, yang terdiri dari tanpa instruksi.
sumber
sharptooth benar, O (1) adalah kinerja terbaik. Namun, itu tidak menyiratkan solusi cepat, hanya solusi waktu tetap.
Varian yang menarik, dan mungkin apa yang sebenarnya disarankan, adalah masalah mana yang lebih mudah seiring pertambahan populasi. Saya dapat memikirkan 1, meskipun dibuat-buat dan jawaban yang tidak jelas:
Apakah ada dua orang dalam satu set yang berulang tahun yang sama? Ketika n melebihi 365, kembalikan benar. Meskipun kurang dari 365, ini adalah O (n ln n). Mungkin bukan jawaban yang bagus karena masalahnya tidak perlahan menjadi lebih mudah tetapi hanya menjadi O (1) untuk n> 365.
sumber
Itu tidak mungkin. Definisi Big-O adalah yang tidak lebih besar dari ketimpangan:
Jadi B (n) sebenarnya adalah nilai maksimum, oleh karena itu jika menurun ketika n meningkatkan estimasi tidak akan berubah.
sumber
Dari pembelajaran saya sebelumnya tentang notasi O besar, bahkan jika Anda memerlukan 1 langkah (seperti memeriksa variabel, melakukan tugas), yaitu O (1).
Perhatikan bahwa O (1) sama dengan O (6), karena "konstan" tidak masalah. Itu sebabnya kami mengatakan O (n) sama dengan O (3n).
Jadi, jika Anda memerlukan 1 langkah saja, itu O (1) ... dan karena program Anda setidaknya membutuhkan 1 langkah, algoritma minimum yang bisa digunakan adalah O (1). Kecuali jika kita tidak melakukannya, maka itu adalah O (0), saya pikir? Jika kita melakukan apa saja, maka itu adalah O (1), dan itu adalah minimum yang bisa dilakukan.
(Jika kita memilih untuk tidak melakukannya, maka itu bisa menjadi pertanyaan Zen atau Tao ... dalam bidang pemrograman, O (1) masih minimum).
Atau bagaimana dengan ini:
programmer : boss, saya menemukan cara untuk melakukannya dalam waktu O (1)!
Bos : tidak perlu melakukannya, kami bangkrut pagi ini.
programmer : oh lalu, itu menjadi O (0).
sumber
Tidak, ini tidak mungkin:
Karena n cenderung tak terhingga dalam 1 / n kita akhirnya mencapai 1 / (inf), yang secara efektif 0.
Dengan demikian, kelas big-oh dari masalahnya adalah O (0) dengan n besar, tetapi lebih dekat ke waktu konstan dengan n rendah. Ini tidak masuk akal, karena satu-satunya hal yang dapat dilakukan lebih cepat daripada waktu konstan adalah:
void nothing() {};
Dan bahkan ini bisa diperdebatkan!
Segera setelah Anda menjalankan perintah, Anda berada di setidaknya O (1), jadi tidak, kami tidak dapat memiliki kelas besar oh (1 / n)!
sumber
Bagaimana dengan tidak menjalankan fungsi sama sekali (NOOP)? atau menggunakan nilai tetap. Apakah itu penting?
sumber
Saya sering menggunakan O (1 / n) untuk menggambarkan probabilitas yang semakin kecil ketika input semakin besar - misalnya, probabilitas bahwa koin yang adil muncul di log2 (n) membalik adalah O (1 / n).
sumber
O (1) berarti "waktu konstan".
Saat Anda menambahkan jalan keluar awal ke loop [1] Anda (dalam notasi O besar) mengubah algoritma O (1) menjadi O (n), tetapi membuatnya lebih cepat.
Caranya secara umum algoritma waktu konstan adalah yang terbaik, dan linear lebih baik daripada eksponensial, tetapi untuk sejumlah kecil n, algoritma eksponensial sebenarnya mungkin lebih cepat.
1: Dengan asumsi panjang daftar statis untuk contoh ini
sumber
Bagi siapa pun yang membaca pertanyaan ini dan ingin memahami tentang apa pembicaraan itu, ini mungkin membantu:
sumber
Saya percaya algoritma kuantum dapat melakukan banyak komputasi "sekaligus" melalui superposisi ...
Saya ragu ini adalah jawaban yang berguna.
sumber
banyak orang memiliki jawaban yang benar (Tidak) Berikut cara lain untuk membuktikannya: Untuk memiliki fungsi, Anda harus memanggil fungsi tersebut, dan Anda harus mengembalikan jawaban. Ini membutuhkan jumlah waktu tertentu yang konstan. BAHKAN JIKA sisa pemrosesan memakan waktu lebih sedikit untuk input yang lebih besar, mencetak jawabannya (yang dapat kita asumsikan sebagai bit tunggal) membutuhkan setidaknya waktu yang konstan.
sumber
Jika solusi ada, itu dapat disiapkan dan diakses dalam waktu konstan = segera. Misalnya menggunakan struktur data LIFO jika Anda tahu permintaan penyortiran adalah untuk urutan terbalik. Kemudian data sudah disortir, mengingat bahwa model yang sesuai (LIFO) dipilih.
sumber
Masalah mana yang lebih mudah seiring pertambahan populasi? Satu jawaban adalah hal seperti bittorrent di mana kecepatan unduhan adalah fungsi terbalik dari jumlah node. Berlawanan dengan mobil, yang semakin melambat saat Anda memuatnya, jaringan berbagi file seperti bittorrent mempercepat semakin banyak node yang terhubung.
sumber
Anda tidak bisa pergi di bawah O (1), namun O (k) di mana k kurang dari N adalah mungkin. Kami menyebutnya algoritma waktu sublinear . Dalam beberapa masalah, algoritma waktu Sublinear hanya dapat memberikan solusi perkiraan untuk masalah tertentu. Namun, kadang-kadang, solusi perkiraan baik-baik saja, mungkin karena dataset terlalu besar, atau itu terlalu mahal secara komputasi untuk menghitung semua.
sumber
Bagaimana dengan ini:
saat ukuran daftar bertambah, runtime yang diharapkan dari program berkurang.
sumber
constains
O (1)O (1 / n) tidak kurang dari O (1), itu pada dasarnya berarti bahwa semakin banyak data yang Anda miliki, semakin cepat algoritma berjalan. Katakanlah Anda mendapatkan array dan selalu mengisinya hingga 10 100 elemen jika memiliki kurang dari itu dan tidak melakukan apa pun jika ada lagi. Yang ini bukan O (1 / n) tentu saja tetapi sesuatu seperti O (-n) :) Notasi O-besar yang terlalu buruk tidak memungkinkan nilai negatif.
sumber
Seperti yang telah ditunjukkan, terlepas dari kemungkinan pengecualian dari fungsi null, tidak ada
O(1/n)
fungsi, karena waktu yang dibutuhkan harus mendekati 0.Tentu saja, ada beberapa algoritma, seperti yang didefinisikan oleh Konrad, yang sepertinya harus kurang dari
O(1)
setidaknya dalam beberapa hal.Jika Anda ingin menyelidiki algoritma ini, Anda harus menentukan pengukuran asimptotik Anda sendiri, atau gagasan waktu Anda sendiri. Misalnya, dalam algoritme di atas, saya dapat mengizinkan penggunaan sejumlah operasi "bebas" dalam jumlah tertentu. Dalam algoritma di atas, jika saya mendefinisikan t 'dengan mengecualikan waktu untuk semuanya kecuali tidur, maka t' = 1 / n, yaitu O (1 / n). Mungkin ada contoh yang lebih baik, karena perilaku asimptotiknya sepele. Bahkan, saya yakin bahwa seseorang di luar sana dapat datang dengan indera yang memberikan hasil yang tidak sepele.
sumber
Sebagian besar sisa jawaban menafsirkan big-O secara eksklusif tentang waktu berjalan suatu algoritma. Tetapi karena pertanyaannya tidak menyebutkannya, saya pikir layak menyebutkan aplikasi big-O lainnya dalam analisis numerik, yaitu tentang kesalahan.
Banyak algoritma dapat berupa O (h ^ p) atau O (n ^ {- p}) tergantung pada apakah Anda berbicara tentang ukuran langkah (h) atau jumlah divisi (n). Misalnya, dalam metode Euler , Anda mencari perkiraan y (h) mengingat Anda tahu y (0) dan dy / dx (turunan dari y). Perkiraan Anda dari y (h) lebih akurat, semakin dekat h ke 0. Jadi untuk menemukan y (x) untuk beberapa x sewenang-wenang, seseorang mengambil interval 0 hingga x, membaginya hingga n buah, dan menjalankan metode Euler di setiap titik, untuk beralih dari y (0) ke y (x / n) ke y (2x / n), dan seterusnya.
Jadi metode Euler kemudian merupakan algoritma O (h) atau O (1 / n), di mana h biasanya ditafsirkan sebagai ukuran langkah dan n ditafsirkan sebagai berapa kali Anda membagi interval.
Anda juga dapat memiliki O (1 / jam) dalam aplikasi analisis numerik nyata, karena kesalahan pembulatan titik mengambang . Semakin kecil interval yang Anda buat, semakin banyak pembatalan yang terjadi untuk penerapan algoritma tertentu, lebih banyak kehilangan digit signifikan, dan karenanya lebih banyak kesalahan, yang akan disebarkan melalui algoritma.
Untuk metode Euler, jika Anda menggunakan floating point, gunakan langkah dan pembatalan yang cukup kecil dan Anda menambahkan angka kecil ke angka besar, meninggalkan angka besar tidak berubah. Untuk algoritma yang menghitung turunan melalui pengurangan satu sama lain dua angka dari fungsi yang dievaluasi pada dua posisi yang sangat dekat, kira-kira y '(x) dengan (y (x + h) - y (x) / h), dalam fungsi yang halus y (x + h) mendekati y (x) yang menghasilkan pembatalan besar dan estimasi untuk turunan dengan angka signifikan yang lebih sedikit. Ini pada gilirannya akan merambat ke algoritma apa pun yang Anda perlukan untuk turunannya (misalnya, masalah nilai batas).
sumber
OK, saya sedikit memikirkannya, dan mungkin ada algoritma yang bisa mengikuti bentuk umum ini:
Anda perlu menghitung masalah salesman keliling untuk grafik 1000 simpul, namun, Anda juga diberikan daftar node yang tidak dapat Anda kunjungi. Ketika daftar node yang tidak dapat dibalik semakin besar, masalahnya menjadi lebih mudah untuk dipecahkan.
sumber
Saya melihat algoritma yang O (1 / n) diakui untuk batas atas:
Anda memiliki serangkaian input besar yang berubah karena sesuatu di luar rutinitas (mungkin merefleksikan perangkat keras atau bahkan mungkin beberapa inti lain dalam prosesor yang melakukannya.) Dan Anda harus memilih yang acak tetapi valid.
Sekarang, jika itu tidak berubah Anda hanya akan membuat daftar item, pilih satu secara acak dan dapatkan O (1) waktu. Namun, sifat dinamis dari data menghalangi pembuatan daftar, Anda hanya perlu menyelidiki secara acak dan menguji validitas penyelidikan. (Dan perhatikan bahwa secara inheren tidak ada jaminan jawabannya masih valid ketika dikembalikan. Ini masih bisa menggunakan - katakanlah, AI untuk unit dalam permainan. Bisa menembak pada target yang keluar dari pandangan saat itu menarik pelatuknya.)
Ini memiliki kinerja kasus tak terbatas terburuk tetapi kinerja kasus rata-rata yang turun saat ruang data terisi.
sumber
Dalam analisis numerik, algoritma aproksimasi harus memiliki kompleksitas asimtotik sub-konstan dalam toleransi aproksimasi.
sumber
Saya kira kurang dari O (1) tidak mungkin. Setiap waktu yang diambil oleh algo disebut sebagai O (1). Tetapi untuk O (1 / n) bagaimana dengan fungsi di bawah ini. (Saya tahu ada banyak varian yang telah disajikan dalam solusi ini, tapi saya kira mereka semua memiliki beberapa kekurangan (tidak utama, mereka menjelaskan konsep dengan baik). Jadi di sini ada satu, hanya demi argumen:
Jadi dengan bertambahnya fungsi akan memakan waktu lebih sedikit dan lebih sedikit. Juga dipastikan bahwa jika input benar-benar 0, maka fungsi akan membutuhkan waktu lama untuk kembali.
Orang mungkin berpendapat bahwa itu akan dibatasi oleh presisi mesin. Jadi, sinc memiliki batas atas yaitu O (1). Tapi kita juga bisa memotongnya, dengan mengambil input n dan C dalam string. Dan penambahan dan perbandingan dilakukan pada string. Gagasannya adalah, dengan ini kita dapat mengurangi n sembarang kecil. Jadi batas atas fungsi tidak dibatasi, bahkan ketika kita abaikan n = 0.
Saya juga percaya bahwa kita tidak bisa hanya mengatakan bahwa run time adalah O (1 / n). Tetapi kita harus mengatakan sesuatu seperti O (1 + 1 / n)
sumber
Dimungkinkan untuk membuat algoritma yang O (1 / n). Salah satu contoh akan menjadi loop yang mengulang beberapa kelipatan dari f (n) -n kali di mana f (n) adalah beberapa fungsi yang nilainya dijamin lebih besar dari n dan batas f (n) -n saat n mendekati tak terhingga adalah nol. Perhitungan f (n) juga harus konstan untuk semua n. Saya tidak tahu secara langsung seperti apa f (n) akan terlihat atau aplikasi apa yang akan dimiliki algoritma seperti itu, menurut pendapat saya, namun fungsi seperti itu bisa ada tetapi algoritma yang dihasilkan tidak memiliki tujuan selain untuk membuktikan kemungkinan algoritma dengan O (1 / n).
sumber
Saya tidak tahu tentang algoritma tetapi kompleksitas kurang dari O (1) muncul dalam algoritma acak. Sebenarnya, o (1) (sedikit o) kurang dari O (1). Kompleksitas semacam ini biasanya muncul dalam algoritma acak. Sebagai contoh, seperti yang Anda katakan, ketika probabilitas beberapa peristiwa adalah urutan 1 / n mereka menyatakannya dengan o (1). Atau ketika mereka ingin mengatakan bahwa sesuatu terjadi dengan probabilitas tinggi (misalnya 1 - 1 / n) mereka menyatakannya dengan 1 - o (1).
sumber
Jika jawabannya sama terlepas dari input data maka Anda memiliki algoritma O (0).
atau dengan kata lain - jawabannya diketahui sebelum input data dikirimkan - fungsinya dapat dioptimalkan - jadi O (0)
sumber
Notasi O besar mewakili skenario kasus terburuk untuk suatu algoritma yang tidak sama dengan run time tipikal. Mudah untuk membuktikan bahwa algoritma O (1 / n) adalah algoritma O (1). Menurut definisi,
O (1 / n) -> T (n) <= 1 / n, untuk semua n> = C> 0
O (1 / n) -> T (n) <= 1 / C, Karena 1 / n <= 1 / C untuk semua n> = C
O (1 / n) -> O (1), karena notasi Big-O mengabaikan konstanta (yaitu nilai C tidak masalah)
sumber
hashtable-contains
algoritma yang dapat dilambangkan sebagai O (1) - dan kasus terburuk dapat diberikan dengan tepat seperti Theta (n)! Omega dan Theta mungkin hanya digunakan untuk menunjukkan batas lain tetapi untuk mengatakannya lagi : mereka tidak ada hubungannya dengan kasus rata-rata atau terbaik.Tidak ada yang lebih kecil dari O (1) Notasi O-besar menyiratkan urutan kompleksitas terbesar untuk suatu algoritma
Jika suatu algoritma memiliki runtime n ^ 3 + n ^ 2 + n + 5 maka itu adalah O (n ^ 3) Kekuatan yang lebih rendah tidak penting di sini sama sekali karena sebagai n -> Inf, n ^ 2 akan tidak relevan dibandingkan dengan n ^ 3
Demikian juga dengan n -> Inf, O (1 / n) akan tidak relevan dibandingkan dengan O (1) maka 3 + O (1 / n) akan sama dengan O (1) sehingga menjadikan O (1) komputasi sekecil mungkin. kompleksitas
sumber
sumber
Berikut adalah algoritma O (1 / n) sederhana. Dan itu bahkan melakukan sesuatu yang menarik!
O (1 / n) dimungkinkan karena menggambarkan bagaimana output suatu fungsi berubah mengingat ukuran input yang meningkat. Jika kita menggunakan fungsi 1 / n untuk menggambarkan jumlah instruksi yang dieksekusi fungsi maka tidak ada persyaratan bahwa fungsi mengambil instruksi nol untuk ukuran input apa pun. Sebaliknya, untuk setiap ukuran input, n di atas beberapa ambang batas, jumlah instruksi yang diperlukan dibatasi di atas oleh konstanta positif dikalikan dengan 1 / n. Karena tidak ada angka aktual yang 1 / n adalah 0, dan konstanta adalah positif, maka tidak ada alasan mengapa fungsi akan dibatasi untuk mengambil instruksi 0 atau lebih sedikit.
sumber