Apakah ada algoritma O (1 / n)?


335

Apakah ada algoritma O (1 / n)?

Atau apa pun yang kurang dari O (1)?


Sebagian besar pertanyaan mengasumsikan maksud Anda "Apakah ada algoritma dengan kompleksitas waktu O (1 / n)?" Haruskah kita menganggap ini masalahnya? Big-O (dan Big-Theta, dll.) Menjelaskan fungsi, bukan algoritma. (Saya tahu tidak ada kesetaraan antara fungsi dan algoritma.)
jyoungdev

4
Itulah definisi yang umum dipahami dari "O (X) algoritma" dalam ilmu komputer: suatu algoritma yang kompleksitas waktu adalah O (X) (untuk beberapa ekspresi X).
David Z

2
Saya telah mendengar seperti itu dalam kasus algoritma prioritas antrian efisien I / O menggunakan Buffer Tree. Dalam Pohon Buffer, setiap operasi membutuhkan O (1 / B) I / Os; di mana B adalah ukuran blok. Dan total I / O untuk operasi n adalah O (n / B.log (basis M / B) (n / B)), di mana bagian log adalah ketinggian pohon penyangga.
CODError

Ada banyak algoritma dengan probabilitas kesalahan O (1 / n). Misalnya filter bloom dengan O (n log n) bucket.
Thomas Ahle

Anda tidak dapat bertelur lebih cepat dengan menambahkan ayam.
Wyck

Jawaban:


310

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:

def get_faster(list):
    how_long = (1 / len(list)) * 100000
    sleep(how_long)

Jelas, fungsi ini menghabiskan lebih sedikit waktu karena ukuran input tumbuh ... setidaknya sampai batas tertentu, ditegakkan oleh perangkat keras (ketepatan angka, waktu minimum yang sleepbisa 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).


22
'Dipaksakan oleh perangkat keras' juga berlaku untuk Mesin Turing. Dalam kasus O (1 / n) akan selalu ada ukuran input yang algoritma tidak seharusnya menjalankan operasi apa pun. Dan karena itu saya akan berpikir bahwa O (1 / n) kompleksitas waktu memang mustahil untuk dicapai.
Roland Ewald

28
Mehrdad, kamu tidak mengerti. Notasi O adalah sesuatu tentang batas (secara teknis lim sup) sebagai n -> ∞. Waktu berjalan dari suatu algoritma / program adalah jumlah langkah pada beberapa mesin, dan karena itu diskrit - ada batas bawah yang bukan nol pada waktu yang dapat diambil oleh algoritma ("satu langkah"). Hal ini kemungkinan bahwa upto beberapa terbatas N program mengambil sejumlah langkah menurun dengan n, tetapi satu-satunya cara algoritma dapat O (1 / n), atau memang o (1), adalah jika dibutuhkan waktu 0 untuk semua cukup besar n - yang tidak mungkin.
ShreevatsaR

28
Kami tidak setuju bahwa fungsi O (1 / n) (dalam pengertian matematika) ada. Jelas mereka melakukannya. Tetapi perhitungan pada dasarnya terpisah. Sesuatu yang memiliki batas bawah, seperti waktu berjalan suatu program - baik pada arsitektur von Neumann atau mesin Turing yang murni abstrak - tidak boleh O (1 / n). Secara ekuivalen, sesuatu yang O (1 / n) tidak dapat memiliki batas bawah. (Fungsi "tidur" Anda harus dipanggil, atau "daftar" variabel harus diperiksa - atau pita input harus diperiksa pada mesin Turing. Jadi waktu yang diambil akan berubah dengan n karena beberapa ε + 1 / n, yang bukan O (1 / n))
ShreevatsaR

16
Jika T (0) = ∞, itu tidak berhenti. Tidak ada yang namanya "T (0) = ∞, tetapi masih terhenti". Lebih lanjut, bahkan jika Anda bekerja di R∪ {∞} dan mendefinisikan T (0) = ∞, dan T (n + 1) = T (n) / 2, maka T (n) = ∞ untuk semua n. Saya ulangi: jika fungsi bernilai diskrit adalah O (1 / n), maka untuk semua yang cukup besar n itu adalah 0. [Bukti: T (n) = O (1 / n) berarti ada c yang konstan sehingga untuk n> N0, T (n) <c (1 / n), yang berarti bahwa untuk setiap n> maks (N0,1 / c), T (n) <1, yang berarti T (n) = 0.] Tidak ada mesin, nyata atau abstrak, dapat mengambil 0 waktu: itu harus melihat input. Nah, selain mesin yang tidak pernah melakukan apa-apa, dan untuk itu T (n) = 0 untuk semua n.
ShreevatsaR

43
Anda harus menyukai jawaban yang dimulai, "Pertanyaan ini tidak sebodoh kelihatannya."
Telemachus

138

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.


2
Jadi jika seseorang bertanya apa kompleksitas waktu dari sebuah algoritma kosong, Anda akan menjawab dengan O (1 / n) ??? Entah bagaimana saya meragukannya.
phkahler

24
Ini adalah satu-satunya jawaban yang benar di utas ini, dan (terlepas dari upvote saya) itu di nol suara. Begitulah StackOverflow, di mana jawaban "berpenampilan benar" dipilih lebih tinggi daripada yang benar-benar benar.
ShreevatsaR

5
Tidak, ini diberi nilai 0 karena tidak benar. Mengekspresikan nilai big-Oh dalam kaitannya dengan N saat independen dari N adalah tidak benar. Kedua, menjalankan program apa pun, bahkan yang baru saja ada, membutuhkan setidaknya jumlah waktu yang konstan, O (1). Bahkan jika itu tidak terjadi, itu akan menjadi O (0), bukan O (1 / n).
kenj0418

32
Fungsi apa pun yang O (0) juga O (1 / n), dan juga O (n), juga O (n ^ 2), juga O (2 ^ n). Sigh, tidak ada yang mengerti definisi sederhana? O () adalah batas atas.
ShreevatsaR

16
@ kenj0418 Anda berhasil salah dalam setiap kalimat. "Mengekspresikan nilai big-Oh dalam kaitannya dengan N ketika itu independen terhadap N adalah tidak benar." Fungsi konstan adalah fungsi yang sangat salah. "Kedua, menjalankan program apa pun, bahkan yang baru saja ada, membutuhkan setidaknya jumlah waktu yang konstan, O (1)." Definisi kerumitan tidak mengatakan apa-apa tentang menjalankan program apa pun. "Itu akan menjadi O (0), bukan O (1 / n)". Lihat komentar @ ShreevatsaR.
Alexey Romanov

25

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.


7
366. Jangan lupa tentang tahun kabisat!
Nick Johnson

1
Anda benar. Seperti komputer, saya kadang-kadang mengalami kesalahan pembulatan :-)
Adrian.

10
+1. Ada sejumlah masalah NP-lengkap yang mengalami "transisi fase" karena n meningkat, yaitu mereka dengan cepat menjadi lebih mudah atau lebih sulit karena Anda melebihi nilai ambang batas n. Salah satu contoh adalah Masalah Partisi Nomor: diberi satu set n bilangan bulat negatif, partisi mereka menjadi dua bagian sehingga jumlah setiap bagian sama. Ini menjadi lebih mudah secara dramatis pada nilai ambang tertentu n.
j_random_hacker

23

Itu tidak mungkin. Definisi Big-O adalah yang tidak lebih besar dari ketimpangan:

A(n) = O(B(n))
<=>
exists constants C and n0, C > 0, n0 > 0 such that
for all n > n0, A(n) <= C * B(n)

Jadi B (n) sebenarnya adalah nilai maksimum, oleh karena itu jika menurun ketika n meningkatkan estimasi tidak akan berubah.


42
Saya menduga jawaban ini adalah "yang benar", tetapi sayangnya saya kurang memiliki kecerdasan untuk memahaminya.
freespace

12
AFAIK kondisi ini tidak harus benar untuk semua n, tetapi untuk semua n> n_0 (yaitu, hanya ketika ukuran input mencapai ambang tertentu).
Roland Ewald

30
Saya tidak melihat bagaimana definisi (bahkan dikoreksi) bertentangan dengan pertanyaan OP. Definisi ini berlaku untuk fungsi yang sepenuhnya arbitrer! 1 / n adalah fungsi yang sepenuhnya masuk akal untuk B, dan sebenarnya persamaan Anda tidak bertentangan dengan itu (lakukan saja matematika). Jadi tidak, meskipun banyak konsensus, jawaban ini sebenarnya salah . Maaf.
Konrad Rudolph

10
Salah! Saya tidak suka downvoting tetapi Anda menyatakan bahwa ini tidak mungkin ketika tidak ada konsensus yang jelas. Dalam prakteknya Anda benar, jika Anda membangun fungsi dengan runtime 1 / n (mudah) pada akhirnya akan mencapai waktu minimum, secara efektif menjadikannya algoritma O (1) ketika diimplementasikan. Tidak ada yang menghentikan algoritma dari menjadi O (1 / n) di atas kertas.
jheriko

3
@Jason: Yap, sekarang Anda mengatakannya ... :) @jheriko: Kompleksitas waktu O (1 / n) tidak berfungsi pada kertas IMHO. Kami mengkarakterisasi fungsi pertumbuhan f (ukuran input) = #ops untuk mesin Turing. Jika tidak berhenti untuk input dengan panjang n = 1 setelah x langkah, maka saya akan memilih ukuran input n >> x, yaitu cukup besar, jika algoritma memang dalam O (1 / n), tidak ada operasi yang seharusnya selesai Bagaimana seharusnya mesin Turing memperhatikan hal ini (tidak diperbolehkan membaca sekali dari kaset)?
Roland Ewald

16

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).


Lelucon Anda mengingatkan saya pada sesuatu dari Tao Pemrograman: canonical.org/~kragen/tao-of-programming.html#book8 (8.3)
kenj0418

Algoritma yang terdiri dari nol langkah adalah O (0). Itu algoritma yang sangat malas.
nalply

8

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)!


7

Bagaimana dengan tidak menjalankan fungsi sama sekali (NOOP)? atau menggunakan nilai tetap. Apakah itu penting?


16
Itu masih O (1) runtime.
Konrad Rudolph

2
Benar, itu masih O (1). Saya tidak melihat bagaimana seseorang dapat memahami ini, namun mengklaim dalam jawaban lain bahwa sesuatu yang kurang dari NO-OP adalah mungkin.
ShreevatsaR

4
ShreevatsaR: sama sekali tidak ada kontradiksi. Anda tampaknya gagal memahami bahwa notasi O besar tidak ada hubungannya dengan waktu yang dihabiskan dalam fungsi - melainkan, itu menggambarkan bagaimana waktu itu berubah dengan mengubah input (di atas nilai tertentu). Lihat utas komentar lainnya untuk lebih lanjut.
Konrad Rudolph

Saya memahami dengan baik, terima kasih. Intinya - seperti yang saya buat beberapa kali di utas lainnya - adalah bahwa jika waktu berkurang dengan input, pada tingkat O (1 / n), maka akhirnya harus menurun di bawah waktu yang diambil oleh NOOP. Ini menunjukkan bahwa tidak ada algoritma yang dapat O (1 / n) asimptotik, meskipun tentu saja runtime dapat berkurang hingga batas.
ShreevatsaR

1
Ya ... seperti yang saya katakan di tempat lain, algoritma apa pun yang O (1 / n) juga harus mengambil nol waktu untuk semua input, jadi tergantung pada apakah Anda mempertimbangkan algoritma nol untuk mengambil 0 waktu atau tidak, ada O (1) / n) algoritma. Jadi jika Anda menganggap NOOP sebagai O (1), maka tidak ada algoritma O (1 / n).
ShreevatsaR

7

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).


6
Tapi bukan itu yang besar. Anda tidak bisa mendefinisikannya kembali untuk menjawab pertanyaan.
Zifre

11
Ini bukan redefinisi, itu persis definisi big O.
ShreevatsaR

10
Saya seorang ilmuwan komputer teoretis berdasarkan perdagangan. Ini tentang urutan fungsi asimptotik.
Dave

4
Big O adalah properti dari fungsi nyata yang sewenang-wenang. Kompleksitas waktu hanyalah salah satu aplikasi yang mungkin. Kompleksitas ruang (jumlah memori kerja yang digunakan algoritma) adalah hal lain. Bahwa pertanyaannya adalah tentang O (1 / n) algoritma menyiratkan bahwa itu salah satu dari ini (kecuali ada yang lain yang berlaku untuk algoritma yang saya tidak tahu tentang). Aplikasi lain termasuk pesanan pertumbuhan populasi, misalnya dalam Conway's Life. Lihat juga en.wikipedia.org/wiki/Big_O_notation
Stewart

5
@ Dave: Pertanyaannya bukan apakah ada fungsi O (1 / n), yang jelas ada. Sebaliknya, itu adalah apakah ada O (1 / n) algoritma, yang (dengan kemungkinan pengecualian dari fungsi null) tidak ada
Casebash

6

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


6

Bagi siapa pun yang membaca pertanyaan ini dan ingin memahami tentang apa pembicaraan itu, ini mungkin membantu:

|    |constant |logarithmic |linear|  N-log-N |quadratic|  cubic  |  exponential  |
|  n |  O(1)   | O(log n)   | O(n) |O(n log n)|  O(n^2) |  O(n^3) |     O(2^n)    |
|  1 |       1 |          1 |     1|         1|        1|       1 |             2 |
|  2 |       1 |          1 |     2|         2|        4|       8 |             4 |
|  4 |       1 |          2 |     4|         8|       16|      64 |            16 |
|  8 |       1 |          3 |     8|        24|       64|     512 |           256 |
| 16 |       1 |          4 |    16|        64|      256|   4,096 |         65536 |
| 32 |       1 |          5 |    32|       160|    1,024|  32,768 | 4,294,967,296 |
| 64 |       1 |          6 |    64|       384|    4,069| 262,144 |   1.8 x 10^19 |

5

Saya percaya algoritma kuantum dapat melakukan banyak komputasi "sekaligus" melalui superposisi ...

Saya ragu ini adalah jawaban yang berguna.


Itu masih akan menjadi waktu yang konstan, yaitu O (1), yang berarti dibutuhkan jumlah waktu yang sama untuk menjalankan untuk data ukuran n seperti halnya untuk data ukuran 1. #
freespace

2
Tetapi bagaimana jika masalahnya adalah bir pucat? (ah. hah. ha.)
Jeff Meatball Yang

7
Itu akan menjadi posisi super untuk berada di.
Daniel Earwicker

1
Algoritme kuantum dapat melakukan banyak komputasi, tetapi Anda hanya dapat mengambil hasil dari satu komputasi, dan Anda tidak dapat memilih hasil mana yang akan diperoleh. Untungnya, Anda juga dapat melakukan operasi pada register kuantum secara keseluruhan (misalnya, QFT) sehingga Anda jauh lebih mungkin untuk menemukan sesuatu :)
Gracenotes

2
itu mungkin tidak berguna, tetapi memiliki keuntungan menjadi kenyataan, yang menempatkannya di atas beberapa jawaban yang lebih banyak dipilih B-)
Brian Postow

4

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.


2

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.


2

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.


Ya, tetapi jumlah node bittorrent lebih seperti jumlah prosesor di komputer paralel. "N" dalam hal ini adalah ukuran file yang ingin diunduh. Sama seperti Anda dapat menemukan elemen dalam array yang tidak disortir dengan panjang N dalam waktu konstan jika Anda memiliki komputer N, Anda dapat mengunduh file Ukuran N dalam waktu konstan jika Anda memiliki komputer N yang mencoba mengirimkan data kepada Anda.
Kibbee

2

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.


1
Tidak yakin saya mengerti. Log (N) kurang dari N. Apakah itu berarti Log (N) adalah algoritma sublinear? Dan banyak algoritma Log (N) memang ada. Salah satu contohnya adalah menemukan nilai dalam pohon biner. Namun, ini masih berbeda dari 1 / N, Karena Log (N) selalu meningkat, sedangkan 1 / n adalah fungsi yang menurun.
Kibbee

Melihat definisi, algoritma waktu sublinear adalah algoritma yang waktunya tumbuh lebih lambat dari ukuran N. Jadi itu termasuk algoritma waktu logaritmik, yaitu Log (N).
Hao Wooi Lim

2
Algoritma waktu sublinear dapat memberikan jawaban yang tepat, misalnya pencarian biner dalam array yang dipesan pada mesin RAM.
A. Rex

@SEBUAH. Rex: Hao Wooi Lim berkata "Dalam beberapa masalah".
LarsH

1

Bagaimana dengan ini:

void FindRandomInList(list l)
{
    while(1)
    {
        int rand = Random.next();
        if (l.contains(rand))
            return;
    }
}

saat ukuran daftar bertambah, runtime yang diharapkan dari program berkurang.


Saya pikir Anda tidak mengerti arti O (n)
Markus Lausberg

Tidak dengan daftar, dengan array atau hash di mana constainsO (1)
vava

ok, fungsi acak dapat dianggap sebagai array malas, jadi Anda pada dasarnya mencari setiap elemen dalam "daftar acak malas" dan memeriksa apakah itu terdapat dalam daftar input. Saya pikir ini lebih buruk daripada linear, tidak lebih baik.
hasen

Dia punya beberapa poin jika Anda memperhatikan bahwa int memiliki sejumlah nilai yang terbatas. Jadi ketika saya akan berisi 2 nilai <sup> 64 </sup> itu akan menjadi instan sepanjang jalan. Yang membuatnya lebih buruk dari O (1) tetap :)
vava

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.


1
"O (1 / n) tidak kurang dari O (1)" - jika fungsi f adalah O (1 / n), itu juga O (1). Dan big-oh terasa sangat mirip dengan hubungan "lebih rendah dari": itu refleksif, transitif, dan jika kita memiliki simetri antara f dan g keduanya sama, di mana big-theta adalah hubungan ekivalensi kita. ISTR "real" memesan relasi yang membutuhkan a <= b dan b <= a untuk menyiratkan a = b, dan netcraft ^ W wikipedia mengkonfirmasinya. Jadi dalam arti tertentu, adil untuk mengatakan bahwa memang O (1 / n) adalah "kurang dari" O (1).
Jonas Kölker

1

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.

def get_faster(list):
    how_long = 1/len(list)
    sleep(how_long)

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.


1

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).


0

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.


4
Itu berbeda n di O (n) lalu. Dengan trik ini Anda bisa mengatakan setiap algoritma memiliki O (q) di mana q adalah jumlah orang yang tinggal di China misalnya.
vava

2
Boyer-Moore adalah sejenis (O (n / m)), tetapi itu tidak benar-benar "lebih baik daripada O (1)", karena n> = m. Saya pikir hal yang sama berlaku untuk "TSP unvisitable" Anda.
Niki

Bahkan dalam kasus ini runtime dari TSP adalah NP-Complete, Anda cukup menghapus node dari grafik, dan karenanya secara efektif mengurangi n.
Ed James

0

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.


0

Dalam analisis numerik, algoritma aproksimasi harus memiliki kompleksitas asimtotik sub-konstan dalam toleransi aproksimasi.

class Function
{
    public double[] ApproximateSolution(double tolerance)
    {
        // if this isn't sub-constant on the parameter, it's rather useless
    }
}

maksud Anda benar-benar sub-konstan, atau sublinear? Mengapa algoritma aproksimasi harus sub-konstan? Dan apa artinya itu ??
LarsH

@ LarsH, kesalahan algoritma perkiraan sebanding dengan ukuran langkah (atau kekuatan positifnya), jadi semakin kecil ukuran langkah Anda, semakin kecil kesalahan. Tetapi cara umum lainnya untuk memeriksa masalah perkiraan adalah kesalahan dibandingkan dengan berapa kali interval dibagi. Jumlah partisi dari suatu interval berbanding terbalik dengan ukuran langkah, sehingga kesalahan berbanding terbalik dengan beberapa kekuatan positif dari jumlah partisi - saat Anda menambah jumlah partisi, kesalahan Anda berkurang.
Andrew Lei

@AndrewLei: Wow, jawabannya hampir 7 tahun kemudian! Saya mengerti jawaban Sam sekarang lebih baik daripada saya. Terima kasih telah merespons.
LarsH

0

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:

def 1_by_n(n, C = 10):   #n could be float. C could be any positive number
  if n <= 0.0:           #If input is actually 0, infinite loop.
    while True:
      sleep(1)           #or pass
    return               #This line is not needed and is unreachable
  delta = 0.0001
  itr = delta
  while delta < C/n:
    itr += delta

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)


-1

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).


Pengulangan Anda memerlukan pemeriksaan yang membutuhkan waktu paling tidak konstan, sehingga algoritma yang dihasilkan setidaknya memiliki kompleksitas O (1).
Stefan Reich

-1

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).


-2

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)


Betulkah? Anda masih perlu mengembalikan nilai, jadi bukankah masih O (1)?
Joachim Sauer

7
tidak, O (0) akan menyiratkan dibutuhkan nol waktu untuk semua input. O (1) adalah waktu yang konstan.
Pete Kirkham

-2

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)


Tidak: Notasi O besar juga digunakan untuk membicarakan skenario rata-rata dan waktu yang diharapkan (dan bahkan kasus terbaik). Sisanya mengikuti.
Konrad Rudolph

Notasi 'O' jelas mendefinisikan batas atas (dalam hal kompleksitas algoritmik, ini akan menjadi kasus terburuk). Omega dan Theta masing-masing digunakan untuk menunjukkan kasus terbaik dan rata-rata.
Roland Ewald

2
Roland: Itu kesalahpahaman; batas atas tidak sama dengan kasus terburuk, keduanya adalah konsep independen. Pertimbangkan runtime yang diharapkan (dan rata-rata) dari hashtable-containsalgoritma 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.
Konrad Rudolph

Konrad: Benar. Tetap saja, Omega, Theata dan O biasanya digunakan untuk mengekspresikan batasan, dan jika semua input yang mungkin dipertimbangkan, O mewakili batas atas, dll.
Roland Ewald

1
Fakta bahwa O (1 / n) adalah himpunan bagian dari O (1) adalah sepele dan mengikuti langsung dari definisi. Faktanya, jika suatu fungsi g adalah O (h), maka setiap fungsi f yang merupakan O (g) juga O (h).
Tobias

-2

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


-2
inline void O0Algorithm() {}

1
Itu akan menjadi algoritma O (1).
Lasse V. Karlsen

2
Itu juga, tetapi intinya adalah itu bukan Ω (1). Dan mengapa jawaban saya direndahkan? Jika Anda pikir saya salah, bagaimana dengan menjelaskan?
Stewart

Saya bertanya di tempat lain apakah, pada dasarnya, jawaban ini benar atau tidak, dan tampaknya diperselisihkan: stackoverflow.com/questions/3209139/…
jyoungdev

Baik itu sebaris, sehingga Anda dapat menganggapnya O (0). Namun, semua algoritma O (0) adalah sepele (tidak melakukan apa-apa), jadi ... bukan jawaban yang sangat menarik.
Stefan Reich

@StefanReich Benar, itu bukan jawaban yang sangat menarik, tapi itu sebuah jawaban.
Stewart

-2

Berikut adalah algoritma O (1 / n) sederhana. Dan itu bahkan melakukan sesuatu yang menarik!

function foo(list input) {
  int m;
  double output;

  m = (1/ input.size) * max_value;  
  output = 0;
  for (int i = 0; i < m; i++)
    output+= random(0,1);

  return output;
}

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.


1
Karena O (1 / n) akan jatuh di bawah garis horizontal = 1, dan ketika n mencapai tak terbatas, kode Anda masih akan menjalankan sejumlah langkah, algoritma ini adalah algoritma O (1). Notasi O besar adalah fungsi dari semua bagian algoritma yang berbeda, dan ia mengambil yang terbesar. Karena metode ini akan selalu menjalankan beberapa instruksi, ketika n mencapai tak terhingga, Anda memiliki instruksi yang sama yang dijalankan setiap waktu, dan dengan demikian metode tersebut akan berjalan dalam waktu yang konstan. Memang, tidak akan banyak waktu, tapi itu tidak relevan dengan notasi Big-O.
Lasse V. Karlsen
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.