Notasi Oh besar tidak menyebutkan nilai konstan

13

Saya seorang programmer dan baru saja mulai membaca Algoritma. Saya tidak sepenuhnya yakin dengan notasi yaitu Bog Oh, Big Omega dan Big Theta. Alasannya adalah dengan definisi Big Oh, ia menyatakan bahwa harus ada fungsi g (x) sehingga selalu lebih besar atau sama dengan f (x). Atau f (x) <= cn untuk semua nilai n> n0.

Mengapa kita tidak menyebutkan nilai konstan dalam definisi? Misalnya, katakanlah fungsi 6n + 4, kami menyatakannya sebagai O (n). Tapi itu tidak benar bahwa definisi itu berlaku untuk semua nilai konstan. Ini berlaku hanya ketika c> = 10 dan n> = 1. Untuk nilai yang lebih rendah dari c dari 6, nilai n0 meningkat. Jadi mengapa kita tidak menyebutkan nilai konstan sebagai bagian dari definisi?

Pradeep
sumber
4
Bagaimana Anda mengusulkan untuk mewakili nilai konstan, tepatnya?
Daniel B
1
Mengambil langkah Anda selangkah lebih maju, fungsi terminating adalah O (1) jika Anda terikat n.
Brian

Jawaban:

23

Ada beberapa alasan, tetapi mungkin yang paling penting adalah bahwa konstanta adalah fungsi dari implementasi algoritma, bukan algoritma itu sendiri. Urutan suatu algoritma berguna untuk membandingkan algoritme terlepas dari implementasinya.

Runtime aktual quicksort biasanya akan berubah jika diterapkan dalam C atau Python atau Scala atau Postscript. Hal yang sama berlaku untuk bubble sort - runtime akan sangat bervariasi berdasarkan implementasi.

Namun, apa yang tidak akan berubah adalah kenyataan bahwa, semua yang lain sama, karena set data semakin besar waktu yang diperlukan untuk menjalankan semacam gelembung akan meningkat lebih cepat daripada waktu yang diperlukan untuk menjalankan quicksort dalam kasus umum, tidak peduli apa bahasa atau mesin mereka diimplementasikan dengan, dengan asumsi implementasi yang cukup benar. Fakta sederhana ini memungkinkan Anda membuat kesimpulan cerdas tentang algoritme itu sendiri ketika detail konkret tidak tersedia.

The agar suatu algoritma filter keluar faktor yang, sementara penting dalam pengukuran dunia nyata yang sebenarnya, cenderung hanya menjadi kebisingan ketika membandingkan algoritma secara abstrak.

tylerl
sumber
22

O (n) dan notasi urutan lainnya (biasanya) tidak berkaitan dengan perilaku fungsi untuk nilai-nilai kecil. Ini berkaitan dengan perilaku fungsi untuk nilai-nilai yang sangat besar, yaitu batas ketika n bergerak menuju tak terhingga.

Konstanta secara teknis penting tetapi mereka biasanya diabstraksi ketika n menjadi cukup besar, nilai c sama sekali tidak relevan. Jika nilai c adalah penting, kita dapat memasukkannya dalam analisis tetapi kecuali jika fungsi yang dibandingkan memiliki faktor konstan yang sangat besar atau jika efisiensi merupakan masalah yang sangat penting, mereka biasanya tidak.

Insinyur Dunia
sumber
3
Misalnya, membangun piramida adalah O (n), menyortir gambarnya adalah O (n log n) - pada titik tertentu Anda bisa memiliki cukup piramida yang akan membutuhkan waktu lebih lama untuk mengurutkan gambar daripada membangun yang baru! Tetapi hanya untuk sejumlah besar piramida!
Martin Beckett
Jawaban yang baik, tetapi untuk N yang diberikan, dan dua algoritma yang biasanya jatuh ke dalam "keluarga" kompleksitas yang sama, mungkin ada manfaat dalam melakukan persis apa yang disarankan OP dan termasuk setidaknya koefisien relatif. Algoritma linier dengan menggandakan jumlah instruksi per elemen sebagai elemen yang lain dapat disebut * O * (2N) ke alg kedua * O * (N) untuk menunjukkan perbedaan relatif, karena untuk setiap N, algoritma pertama akan selalu berlipat ganda waktu eksekusi yang kedua; Namun, ketika membandingkan dengan fungsi keluarga kompleksitas yang berbeda, seperti * O * (NlogN), koefisien tidak masalah.
KeithS
10

Notasi O Besar sesuai definisi menyatakan bahwa: Notasi O besar dibangun di atas intuisi bahwa untuk semua nilai n pada dan di sebelah kanan n ', nilai f (n) berada pada atau di bawah cg (n). Konstanta juga tidak masalah ketika Anda pergi ke faktor (variabel) bernilai tinggi (seperti n-square atau n-cube) karena mereka hanya konstanta dan bukan jumlah yang bervariasi yang dapat menjadi sebesar faktor-faktor tersebut. Diberikan di bawah ini adalah grafik notasi Big-O.
For a given function g(n), we denote by O(g(n)) the set of functions:
O(g(n)) = {f(n): there exist positive constants c and n' such that 0<=f(n)<=c.g(n) for all n > n'}




masukkan deskripsi gambar di sini

Inti dari notasi ini adalah pada kenyataan " how lower is f(n) from c.g(n) and not when it starts becoming lower".

Vaibhav Agarwal
sumber
Dalam hal ini untuk setiap O (n) juga merupakan theta Besar dari n karena sesuai definisi untuk beberapa konstanta akan menjadi batas bawah dan untuk beberapa konstanta adalah batas atas. misalnya 6n + 4 juga merupakan theta besar (n) karena ketika c kurang dari 10 itu selalu merupakan batas bawah. dan ketika c lebih dari 10 itu adalah batas atas. Jadi dapatkah kita mengatakan bahwa untuk notasi Besar Oh yang diberikan juga merupakan theta Besar?
Pradeep
1
Anda mengatakan sebaliknya: "Big Theta berarti Big Oh". Dan Big-Oh bisa diganti dengan Big-Theta untuk batas ketat asimptotik.
Vaibhav Agarwal
9

Dalam analisis algoritma, Urutan Pertumbuhan adalah abstraksi kunci dan memberikan tingkat perubahan waktu berjalan seiring perubahan ukuran input. Katakanlah suatu algoritma memiliki waktu berjalan f(n) = 2n + 3. Sekarang kita pasang beberapa ukuran input,

n = 10: 2 * 10 + 3 = 23

n = 100: 2 * 100 + 3 = 203

n = 10000: 2 * 10000 + 3 = 20003

n = 1000000: 2 * 1000000 + 3 = 2000003

n = 100000000 : 2 * 100000000 + 3 = 200000003

Seperti dapat dilihat, urutan pertumbuhan terutama ditentukan oleh variabel n; konstanta 2 dan 3 kurang signifikan dan ketika ukuran input bertambah, mereka menjadi semakin tidak signifikan dalam menentukannya. Inilah sebabnya mengapa dalam analisis algoritma, konstanta mereda mendukung variabel menentukan urutan pertumbuhan suatu fungsi.

theD
sumber
1

Seluruh gagasan notasi Big-Oh adalah khusus untuk mengabaikan konstanta dan menyajikan bagian terpenting dari fungsi yang menggambarkan run-time dari suatu algoritma.

Lupakan definisi formal sejenak. Fungsi manakah yang lebih buruk (lebih cepat tumbuh), n^2 - 5000atau 5000 n + 60000? Untuk nkurang dari sekitar 5000, fungsi linear lebih besar (dan dengan demikian lebih buruk). Di luar itu (nilai tepat 5013?), Persamaan kuadrat lebih besar.

Karena ada lebih banyak (lebih sedikit) angka positif lebih besar dari 5000 daripada kurang, kita menganggap kuadrat menjadi fungsi 'lebih besar' (lebih buruk) secara umum. Notasi pesanan (Big-Oh, dll) memberlakukan itu (Anda selalu dapat menghilangkan konstanta tambahan dan multiplikatif menggunakan definisi tersebut).

Tentu saja, semuanya tidak selalu sederhana. Kadang-kadang Anda tidak ingin tahu konstanta tersebut. Manakah yang lebih baik jenis Penyisipan atau semacam Bubble? Keduanya O(n^2). Tapi yang satu benar-benar lebih baik dari yang lain. Dengan analisis yang lebih rumit, Anda bisa mendapatkan konstanta seperti yang Anda tanyakan. Biasanya lebih mudah untuk menghitung fungsi Big-Oh daripada fungsi yang lebih tepat.

Big-Oh mengabaikan konstanta ini untuk menyederhanakan dan membuat perbandingan yang paling penting menjadi lebih mudah. Kami menyukai notasi karena biasanya kami tidak ingin tahu tentang konstanta (kebanyakan tidak relevan).

Mitch
sumber
1

(karena ini adalah jawaban yang lebih panjang, bacalah tebal untuk ringkasan )

Mari kita ambil contoh Anda dan berjalan melalui langkah demi langkah, memahami tujuan di balik apa yang kami lakukan. Kami mulai dengan fungsi Anda dan tujuan menemukan notasi Oh Besarnya:

f(n) = 6n+4

Pertama, biarkan O(g(n))notasi Big Oh yang kita cari f(n). Dari definisi Big Oh, kita perlu menemukan yang disederhanakan di g(n) mana ada beberapa konstanta cdan di n0mana c*g(n) >= f(n)berlaku untuk semua nlebih besar dari n0.

Pertama, mari kita pilih g(n) = 6n + 4(yang akan menghasilkan O(6n+4)Big Oh). Dalam hal ini kita melihat bahwa c = 1dan nilai apa pun n0akan memenuhi persyaratan matematika dari definisi Big Oh, karena g(n)selalu sama dengan f(n):

c*g(n)      >=  f(n)    
1*(6n + 4)  >=  6n + 4    //True for all n's, so we don't need to pick an n0

Pada titik ini kami telah memenuhi persyaratan matematika. Jika kita berhenti diO(6n+4) , jelas bahwa ini tidak lebih membantu daripada menulis f(n), sehingga akan kehilangan tujuan sebenarnya dari notasi Oh Besar: untuk memahami kompleksitas waktu umum dari suatu algoritma! Jadi, mari kita beralih ke langkah selanjutnya: penyederhanaan.

Pertama, bisakah kita menyederhanakan dari 6nBig Oh O(4)? Tidak! (Latihan untuk pembaca jika mereka tidak mengerti mengapa)

Kedua, dapatkah kita menyederhanakan 4the Big Oh O(6n)? Iya! Dalam hal itu g(n) = 6n,, jadi:

c*g(n)    >=  f(n)
c*6n      >=  6n + 4     

Pada titik ini, mari kita pilih c = 2sejak saat itu sisi kiri akan meningkat lebih cepat (sebesar 12) daripada sisi kanan (sebesar 6) untuk setiap kenaikan n.

2*6n      >=  6n + 4

Sekarang kita perlu menemukan yang positif di n0mana persamaan di atas benar untuk semua nlebih besar dari nilai itu. Karena kita sudah tahu bahwa sisi kiri meningkat lebih cepat daripada yang kanan, yang harus kita lakukan adalah menemukan satu solusi positif. Dengan demikian, karena n0 = 2membuat hal di atas benar, kita tahu itu g(n)=6n, atau O(6n)berpotensi notasi Oh Besar f(n).

Sekarang, bisakah kita menyederhanakan 6the Big Oh O(n)? Iya! Dalam hal itu g(n) = n,, jadi:

c*g(n)      >=  f(n)    
c*n         >=  6n + 4    

Mari kita pilih c = 7karena yang kiri akan meningkat lebih cepat daripada yang kanan.

7*n         >=  6n + 4

Kami melihat bahwa di atas akan berlaku untuk semua yang nlebih besar atau sama dengan n0 = 4. Dengan demikian, O(n)notasi Big Oh potensial untuk f(n). Bisakah kita menyederhanakan g(n)lagi? Nggak!

Akhirnya, kami menemukan bahwa notasi Big Oh yang paling sederhana f(n)adalah O(n). Kenapa kita harus melalui semua ini? Karena sekarang kita tahu bahwa f(n)itu linier , karena notasi Big Oh adalah kompleksitas linier O(n). Yang menyenangkan adalah bahwa sekarang kita dapat membandingkan kompleksitas waktu f(n)dengan algoritma lainnya! Sebagai contoh, kita sekarang tahu bahwa f(n)adalah sebanding waktu-kompleksitas fungsi h(n) = 123n + 72, i(n) = n, j(n) = .0002n + 1234, dll; karena menggunakan proses penyederhanaan yang sama yang diuraikan di atas mereka semua memiliki kompleksitas waktu linear O(n).

Manis!!!

Briguy37
sumber
Hai, penjelasan yang bagus. Saya masih memiliki beberapa keraguan. 1. Kita tidak dapat menjadikan 6n + 4 sebagai O (4) karena ada nilai variabel 'n'. Apakah ini jawabannya? 2. sementara penyederhanaan Anda memilih c = 7 dan sesuai dihitung n0 sampai 4. Apa yang membuat memutuskan c = 7 dan tidak kurang dari 7? karena berdasarkan pada nilai c maka n0 akan berubah.
Pradeep
@Pradeep: Untuk 1, Anda benar. Untuk penjelasan yang lebih dalam: Jika kita mencoba O(4), itu akan membuat persamaan ketimpangan kita c*4 >= 6n+4, dan untuk apa pun yang ckita pilih, kita selalu bisa menemukan nilai di mana semua nilai di natas yang akan membuat ketidaksetaraan salah.
Briguy37
@Pradeep: Untuk 2, nilai aktual cdan n0tidak penting. Yang penting adalah yang n0ada untuk ckita pilih. Agar hal ini benar, sisi kiri ketidaksetaraan harus meningkat lebih cepat daripada sisi kanan untuk nilai besar n. c=6tidak baik untuk ini ( 6n >= 6n+4tidak pernah benar), jadi saya memilih c=7. Saya bisa saja dengan mudah memilih c=10,, c=734atau c=6.0000001dan masih akan dapat melihat bahwa ada beberapa n0yang ada untuk membuat ketidaksetaraan menjadi benar n >= n0, yang berarti Oh Besar yang kami uji valid.
Briguy37
Terima kasih atas penjelasan yang jelas. Inilah yang sebenarnya saya cari. Sekali lagi terima kasih.
Pradeep
@Pradeep: Senang saya bisa membantu :)
Briguy37
1

Jika Anda memiliki fungsi kinerja 6n + 4, pertanyaan yang relevan adalah, "6 apa?". Sebagai satu komentar bertanya: apa yang diwakili konstanta Anda? Dalam istilah fisika, apa unit faktor konstan Anda?

Alasan mengapa notasi O () begitu banyak digunakan untuk menggambarkan kinerja algoritma adalah bahwa tidak ada cara portabel untuk menjawab pertanyaan itu. Prosesor yang berbeda akan mengambil jumlah siklus clock yang berbeda dan jumlah waktu yang berbeda untuk melakukan perhitungan elementer yang sama, atau mereka mungkin menyamakan perhitungan elementer yang relevan secara berbeda. Bahasa komputer yang berbeda, atau deskripsi formal dan informal yang berbeda seperti kodesemu, akan mewakili algoritma dengan cara yang sulit untuk dibandingkan secara langsung. Bahkan implementasi dalam bahasa yang sama dapat mewakili algoritma yang sama dengan cara yang berbeda - detail format sepele seperti jumlah baris di samping, Anda umumnya akan memiliki berbagai pilihan struktural yang sewenang-wenang untuk mengimplementasikan algoritma yang diberikan.

Lihatlah dengan cara lain: kami menggunakan "algoritma" tidak untuk menggambarkan implementasi tertentu, tetapi untuk menggambarkan seluruh kelas dari implementasi potensial dari prosedur umum yang sama. Abstraksi ini mengabaikan detail implementasi demi mendokumentasikan sesuatu yang bernilai umum, dan faktor kinerja konstan adalah salah satu dari detail ini.

Yang mengatakan, deskripsi algoritma sering disertai dengan cerita rakyat, catatan, atau bahkan tolok ukur aktual yang menggambarkan kinerja implementasi aktual pada perangkat keras yang sebenarnya. Ini memberi Anda gambaran kasar faktor konstan apa yang diharapkan, tetapi juga harus diambil dengan sebutir garam karena kinerja aktual tergantung pada hal-hal seperti berapa banyak pekerjaan yang dilakukan untuk mengoptimalkan implementasi yang diberikan. Juga, dalam jangka panjang, kinerja relatif dari algoritma yang sebanding cenderung melayang ketika arsitektur prosesor terbaru dan terhebat berubah ...

datang badai
sumber