Big O: batas atas
"Big O" ( ) sejauh ini adalah yang paling umum. Ketika Anda menganalisis kompleksitas suatu algoritma, sebagian besar waktu, yang penting adalah memiliki batas atas seberapa cepat waktu berjalan¹ tumbuh ketika ukuran input tumbuh. Pada dasarnya kita ingin tahu bahwa menjalankan algoritma tidak akan memakan waktu “terlalu lama”. Kami tidak dapat mengungkapkan ini dalam satuan waktu aktual (detik), karena itu akan tergantung pada implementasi yang tepat (cara program ditulis, seberapa baik kompiler, seberapa cepat prosesor mesin, ...). Jadi kami mengevaluasi apa yang tidak bergantung pada detail seperti itu, yaitu berapa lama waktu yang diperlukan untuk menjalankan algoritme saat kami memberinya input yang lebih besar. Dan kami sangat peduli ketika kami bisa memastikan bahwa program ini selesai, jadi kami biasanya ingin tahu bahwa ini akan memakan waktu yang begitu lama.O
Untuk mengatakan bahwa suatu algoritma memiliki run time untuk ukuran input berarti bahwa ada beberapa konstanta sehingga algoritma menyelesaikan paling banyak langkah , yaitu waktu berjalan algoritma paling banyak tumbuh secepat (hingga faktor penskalaan). Memperhatikan waktu proses algoritma untuk ukuran input , secara informal berarti bahwa hingga beberapa faktor penskalaan.n K KO(f(n))nKf T ( n ) n O ( n ) T ( n ) ≤ f ( n )Kf(n)fT(n)nO(n)T(n)≤f(n)
Batas bawah
Terkadang, berguna untuk memiliki lebih banyak informasi daripada batas atas. adalah kebalikan dari : itu menyatakan bahwa suatu fungsi tumbuh setidaknya secepat yang lain. berarti bahwa untuk beberapa konstanta , atau secara informal, naik untuk beberapa faktor penskalaan.O T ( n ) = Ω ( g ( n ) ) T ( N ) ≥ K ′ g ( n ) K ′ T ( n ) ≥ g ( n )ΩOT(n)=Ω(g(n))T(N)≥K′g(n)K′T(n)≥g(n)
Ketika waktu berjalan dari algoritma dapat ditentukan secara tepat, menggabungkan dan : itu menyatakan bahwa laju pertumbuhan suatu fungsi diketahui, hingga faktor penskalaan. berarti bahwa untuk beberapa konstanta dan . Secara informal, hingga beberapa faktor penskalaan.O Ω T ( n ) = Θ ( h ( n ) ) K h ( n ) ≥ T ( n ) ≥ K ′ h ( n ) K K ′ T ( n ) ≈ h ( n )ΘOΩT(n)=Θ(h(n))Kh(n)≥T(n)≥K′h(n)KK′T(n)≈h(n)
Pertimbangan lebih lanjut
"Little" dan lebih jarang digunakan dalam analisis kompleksitas. Sedikit lebih kuat dari besar ; di mana menunjukkan pertumbuhan yang tidak lebih cepat, menunjukkan bahwa pertumbuhan itu lebih lambat. Sebaliknya, menunjukkan pertumbuhan yang lebih cepat.ω o O O o ωoωoOOoω
Saya sedikit informal dalam diskusi di atas. Wikipedia memiliki definisi formall dan pendekatan yang lebih matematis.
Perlu diingat bahwa penggunaan tanda sama dengan dan sejenisnya adalah keliru. Sebenarnya, adalah seperangkat fungsi dari variabel , dan kita harus menulis .O ( f ( n ) ) n T ∈ O ( f )T(n)=O(f(n))O(f(n))nT∈O(f)
Contoh: beberapa algoritma penyortiran
Karena ini agak kering, izinkan saya memberi contoh. Sebagian besar algoritma pengurutan memiliki kuadrat waktu run case terburuk, yaitu untuk input ukuran , run time algoritma adalah . Misalnya, pemilihan sort memiliki waktu berjalan , karena memilih elemen membutuhkan perbandingan , untuk total perbandingan . Bahkan, jumlah perbandingan selalu tepat , yang tumbuh sebagai . Jadi kita bisa lebih tepat tentang kompleksitas waktu dari jenis seleksi: itu adalah .O ( n 2 )nO(n2)O(n2)kn−kn(n−1)/2n(n−1)/2n2Θ(n2)
Sekarang ambil semacam penggabungan . Sortir gabungan juga kuadratik ( ). Ini benar, tetapi tidak terlalu tepat. Penggabungan jenis sebenarnya memiliki waktu berjalan dalam kasus terburuk. Seperti pemilihan, aliran pekerjaan gabungan pada dasarnya tidak tergantung pada bentuk input, dan waktu berjalannya selalu hingga faktor multiplikasi konstan, yaitu .O(n2)O(nlg(n))nlg(n)Θ(nlg(n))
Selanjutnya, pertimbangkan quicksort . Quicksort lebih kompleks. Ini tentu saja . Selain itu, kasus terburuk quicksort adalah kuadrat: kasus terburuk adalah . Namun, kasus quicksort terbaik (ketika input sudah diurutkan) adalah linear: yang terbaik yang bisa kita katakan untuk batas bawah untuk quicksort secara umum adalah . Saya tidak akan mengulangi buktinya di sini, tetapi kompleksitas rata - rata quicksort (rata-rata diambil alih semua kemungkinan permutasi input) adalah .O(n2)Θ(n2)Ω(n)Θ(nlg(n))
Ada hasil umum tentang kompleksitas pengurutan algoritma dalam pengaturan umum. Asumsikan bahwa algoritma pengurutan hanya dapat membandingkan dua elemen sekaligus, dengan hasil ya-atau-tidak (baik atau ). Maka jelas bahwa waktu berjalan algoritma pengurutan selalu (di mana adalah jumlah elemen untuk disortir), karena algoritma harus membandingkan setiap elemen setidaknya sekali untuk mengetahui di mana ia akan cocok. Batas bawah ini dapat dipenuhi, misalnya, jika input sudah diurutkan dan algoritme hanya membandingkan setiap elemen dengan yang berikutnya dan menyimpannya secara berurutan (yaitu perbandingan ). Apa yang kurang jelas adalah bahwa waktu berjalan maksimum itu perlux≤yx>yΩ(n)nn−1Ω(nlg(n)) . Ada kemungkinan bahwa algoritma kadang-kadang akan membuat perbandingan lebih sedikit, tetapi harus ada beberapa konstan sehingga untuk setiap ukuran input , setidaknya ada satu input yang algoritma membuat lebih dari perbandingan. Gagasan buktinya adalah untuk membangun pohon keputusan dari algoritma, yaitu untuk mengikuti keputusan yang diambil algoritma dari hasil setiap perbandingan. Karena setiap perbandingan mengembalikan hasil ya-atau-tidak, pohon keputusan adalah pohon biner. Adakemungkinan permutasi input, dan algoritme perlu membedakan antara semuanya, sehingga ukuran pohon keputusan adalahKnKnlg(n)n!n!. Karena pohon itu adalah pohon biner, dibutuhkan kedalaman agar sesuai dengan semua node ini. Kedalaman adalah jumlah maksimum keputusan yang diambil algoritma, sehingga menjalankan algoritme setidaknya melibatkan banyak perbandingan ini: waktu lari maksimum adalah .Θ(lg(n!))=Θ(nlg(n))Ω(nlg(n))
¹ Atau konsumsi sumber daya lainnya seperti ruang memori. Dalam jawaban ini, saya hanya mempertimbangkan waktu berjalan.