Apa arti O (log n) sebenarnya?

2139

Saya belajar tentang waktu O Notasi Besar berjalan dan waktu diamortisasi. Saya memahami gagasan O (n) waktu linear, yang berarti bahwa ukuran input mempengaruhi pertumbuhan algoritma secara proporsional ... dan hal yang sama berlaku untuk, misalnya, waktu kuadrat O (n 2 ) dll. Bahkan algoritma , seperti generator permutasi, dengan O (n!) kali, yang tumbuh secara faktorial.

Sebagai contoh, fungsi berikut adalah O (n) karena algoritma tumbuh sebanding dengan inputnya n :

f(int n) {
  int i;
  for (i = 0; i < n; ++i)
    printf("%d", i);
}

Demikian pula, jika ada loop bersarang, waktu akan menjadi O (n 2 ).

Tapi apa sebenarnya O (log n) ? Sebagai contoh, apa artinya mengatakan bahwa ketinggian pohon biner lengkap adalah O (log n) ?

Saya tahu (mungkin tidak dengan sangat terperinci) apa itu Logaritma, dalam arti bahwa: log 10 100 = 2, tetapi saya tidak dapat memahami bagaimana mengidentifikasi suatu fungsi dengan waktu logaritma.

Andreas Grech
sumber
60
Pohon biner 1-simpul memiliki tinggi log2 (1) +1 = 1, pohon 2-simpul memiliki tinggi log2 (2) +1 = 2, pohon 4-simpul memiliki tinggi log2 (4) +1 = 3, dan begitu seterusnya. Pohon n-simpul memiliki tinggi log2 (n) +1, jadi menambahkan simpul ke pohon menyebabkan tinggi rata-rata tumbuh secara logaritmik.
David R Tribble
36
Satu hal yang saya lihat di sebagian besar jawaban adalah bahwa mereka pada dasarnya menggambarkan "O (sesuatu)" berarti waktu berjalan algoritma tumbuh sebanding dengan "sesuatu". Mengingat Anda meminta "arti sebenarnya" dari "O (log n)", itu tidak benar. Itulah deskripsi intuitif notasi Big-Theta, bukan Big-O. O (log n) secara intuitif berarti waktu berjalan tumbuh paling proporsional dengan "log n": stackoverflow.com/questions/471199/…
Mehrdad Afshari
31
Saya selalu ingat membagi dan menaklukkan sebagai contoh untuk O (log n)
RichardOD
14
Sangat penting untuk menyadari bahwa itu adalah basis log 2 (bukan basis 10). Ini karena pada setiap langkah dalam suatu algoritma, Anda menghapus setengah dari sisa pilihan Anda. Dalam ilmu komputer kita hampir selalu berurusan dengan basis log 2 karena kita dapat mengabaikan konstanta. Namun ada beberapa pengecualian (yaitu waktu menjalankan Quad Tree adalah basis log 4)
Ethan
13
@ Ethan: Tidak masalah Anda berada di basis mana, karena konversi basis hanyalah perkalian konstan, rumusnya adalah log_b (x) = log_d (x) / log_d (b). Log_d (b) hanya berupa konstanta.
mindvirus

Jawaban:

2711

Saya tidak mengerti bagaimana mengidentifikasi suatu fungsi dengan waktu log.

Atribut paling umum dari fungsi waktu berjalan logaritmik adalah:

  • pilihan elemen berikutnya untuk melakukan beberapa tindakan adalah salah satu dari beberapa kemungkinan, dan
  • hanya satu yang perlu dipilih.

atau

  • elemen di mana tindakan dilakukan adalah digit n

Inilah sebabnya, misalnya, mencari orang di buku telepon adalah O (log n). Anda tidak perlu memeriksa setiap orang di buku telepon untuk menemukan yang tepat; alih-alih, Anda bisa membagi dan menaklukkannya dengan melihat berdasarkan di mana nama mereka berdasarkan abjad, dan di setiap bagian Anda hanya perlu menjelajahi subset dari setiap bagian sebelum akhirnya menemukan nomor telepon seseorang.

Tentu saja, buku telepon yang lebih besar masih akan membawa Anda lebih lama, tetapi itu tidak akan tumbuh secepat peningkatan proporsional dalam ukuran tambahan.


Kami dapat memperluas buku contoh telepon untuk membandingkan jenis lain dari operasi dan mereka waktu berjalan. Kami akan menganggap buku telepon kami memiliki bisnis ("Halaman Kuning") yang memiliki nama dan orang unik ("Halaman Putih") yang mungkin tidak memiliki nama unik. Nomor telepon ditetapkan paling banyak untuk satu orang atau bisnis. Kami juga akan menganggap bahwa perlu waktu konstan untuk beralih ke halaman tertentu.

Berikut adalah waktu berjalan dari beberapa operasi yang mungkin kami lakukan di buku telepon, dari yang tercepat hingga yang paling lambat:

  • O (1) (dalam kasus terburuk): Mengingat halaman tempat nama bisnis itu aktif dan nama bisnisnya, temukan nomor teleponnya.

  • O (1) (dalam kasus rata-rata): Diberikan halaman tempat seseorang menggunakan nama mereka, temukan nomor teleponnya.

  • O (log n): Diberi nama seseorang, cari nomor telepon dengan memilih titik acak sekitar setengah bagian dari buku yang belum Anda cari, kemudian periksa untuk melihat apakah nama orang itu pada titik itu. Kemudian ulangi proses sekitar setengah bagian dari buku di mana nama orang itu berada. (Ini adalah pencarian biner untuk nama seseorang.)

  • O (n): Temukan semua orang yang nomor teleponnya berisi digit "5".

  • O (n): Diberi nomor telepon, cari orang atau bisnis dengan nomor itu.

  • O (n log n): Ada kekacauan di kantor printer, dan buku telepon kami memasukkan semua halamannya dalam urutan acak. Perbaiki pemesanan sehingga benar dengan melihat nama depan pada setiap halaman dan kemudian menempatkan halaman itu di tempat yang tepat di buku telepon baru yang kosong.

Untuk contoh di bawah ini, kami sekarang berada di kantor printer. Buku-buku telepon sedang menunggu untuk dikirimkan ke setiap penghuni atau bisnis, dan ada stiker di setiap buku telepon yang mengidentifikasi ke mana harus dikirim. Setiap orang atau bisnis mendapat satu buku telepon.

  • O (n log n): Kami ingin mempersonalisasi buku telepon, jadi kami akan menemukan masing-masing orang atau nama bisnis dalam salinan yang ditunjuk, kemudian lingkari nama mereka di buku itu dan tulis catatan singkat terima kasih atas dukungan mereka. .

  • O (n 2 ): Terjadi kesalahan di kantor, dan setiap entri di masing-masing buku telepon memiliki "0" tambahan di akhir nomor telepon. Ambil beberapa white-out dan hapus setiap nol.

  • O (n · n!): Kami siap memuat buku telepon ke dok pengiriman. Sayangnya, robot yang seharusnya memuat buku-buku itu menjadi berantakan: menempatkan buku-buku itu ke truk dalam urutan acak! Lebih buruk lagi, memuat semua buku ke truk, lalu memeriksa untuk melihat apakah mereka berada dalam urutan yang benar, dan jika tidak, itu membongkar mereka dan mulai lagi. (Ini adalah jenis bogo yang ditakuti .)

  • O (n n ): Anda memperbaiki robot sehingga memuat semuanya dengan benar. Hari berikutnya, salah satu rekan kerja Anda mengerjai Anda dan mengirimkan robot dock loading ke sistem pencetakan otomatis. Setiap kali robot memuat buku asli, printer pabrik membuat duplikat semua buku telepon! Untungnya, sistem deteksi bug robot cukup canggih sehingga robot tidak mencoba mencetak lebih banyak salinan ketika menemukan buku duplikat untuk dimuat, tetapi masih harus memuat setiap buku asli dan duplikat yang telah dicetak.

John Feminella
sumber
81
@cletus: Kebetulan, saya takut. Saya memilihnya karena buku telepon memiliki N besar, orang mengerti apa itu dan apa yang mereka lakukan, dan karena itu serbaguna sebagai contoh. Ditambah lagi, saya harus menggunakan robot dalam penjelasan saya! Kemenangan all-around. (Juga, sepertinya jawaban Anda dibuat sebelum saya bahkan menjadi anggota di StackOverflow!)
John Feminella
12
"Terjadi kesalahan di kantor, dan setiap entri di masing-masing buku telepon memiliki" 0 "tambahan di akhir nomor telepon. Ambillah white-out dan hapus setiap nol." <- ini bukan urutan N kuadrat. N didefinisikan sebagai ukuran input. Ukuran input adalah jumlah nomor telepon, yang merupakan jumlah angka per buku kali jumlah buku. Itu masih operasi waktu linier.
Billy ONeal
21
@Illy: Dalam contoh ini, Nadalah jumlah orang dalam satu buku. Karena setiap orang di buku telepon juga mendapatkan salinan buku itu sendiri, ada buku telepon yang N identik , masing-masing dengan Norang - orang di dalamnya, yaitu O (N ^ 2).
John Feminella
48
Bukankah O (1) kasus terbaik, bukan kasus terburuk seperti yang disorot aneh?
Svip
54
Butuh waktu O (lama! N-55/2) untuk menemukan definisi O (log n) yang akhirnya masuk akal. +1
iAteABug_And_iLiked_it
611

O(log N)pada dasarnya berarti waktu naik secara linear sedangkan nnaik secara eksponensial. Jadi, jika diperlukan 1detik untuk menghitung 10elemen, dibutuhkan 2detik untuk menghitung 100elemen, 3detik untuk menghitung 1000elemen, dan sebagainya.

Itu adalah O(log n)ketika kita membagi dan menaklukkan jenis algoritma misalnya pencarian biner. Contoh lain adalah penyortiran cepat di mana setiap kali kita membagi array menjadi dua bagian dan setiap kali dibutuhkan O(N)waktu untuk menemukan elemen pivot. Karena itu N O(log N)

fastcodejava
sumber
108
Tiga baris kebijaksanaan yang mengalahkan semua jawaban esai lainnya ... :) Kalau-kalau ada orang yang melewatkannya, dalam konteks pemrograman, basis log adalah 2 (bukan 10), jadi O (log n) skala seperti 1 detik selama 10 elemen, 2 detik untuk 20, 3 untuk 40 dll.
nawfal
3
Setuju, ringkas dan jelas, meskipun pertanyaan terakhir dari OP adalah bagaimana mengidentifikasi fungsi logaritmik, tidak cukup "apa itu"
Adam
4
ya, fungsi logaritmik itu terbalik dengan fungsi eksponensial. ((log x) basis a) kebalikan dari (kekuatan x). Analisis kualitatif fungsi-fungsi ini dengan grafik akan memberikan lebih banyak intuisi.
overexchange
7
Ini membuat saya sekitar 3 kali membaca untuk menyadari itu tidak salah. Waktu naik secara linear, sementara jumlah elemen bersifat eksponensial. Ini berarti lebih banyak elemen dalam waktu yang lebih singkat . Ini membebani secara mental bagi mereka yang memvisualisasikan logsebagai kurva log akrab pada grafik.
Qix - MONICA DISALAHKAN
1
Saya pikir ini adalah jawaban yang sangat bagus, kecuali untuk bagian di mana ia mengklaim bahwa pencarian biner adalah algoritma divide and conquer. Bukan itu.
code_dredd
579

Banyak jawaban yang baik telah diposting untuk pertanyaan ini, tetapi saya percaya kita benar-benar kehilangan yang penting - yaitu, jawaban yang diilustrasikan.

Apa artinya mengatakan bahwa ketinggian pohon biner lengkap adalah O (log n)?

Gambar berikut menggambarkan pohon biner. Perhatikan bagaimana setiap level berisi dua kali lipat jumlah node dibandingkan dengan level di atas (maka biner ):

Pohon biner

Pencarian biner adalah contoh dengan kompleksitas O(log n). Katakanlah bahwa simpul di tingkat bawah pohon pada gambar 1 mewakili item dalam beberapa koleksi yang diurutkan. Pencarian biner adalah algoritma divide-and-conquer, dan gambar menunjukkan bagaimana kita akan membutuhkan (paling banyak) 4 perbandingan untuk menemukan catatan yang kita cari dalam dataset 16 item ini.

Anggap saja kita memiliki dataset dengan 32 elemen. Lanjutkan gambar di atas untuk menemukan bahwa kita sekarang membutuhkan 5 perbandingan untuk menemukan apa yang kita cari, karena pohon hanya tumbuh satu tingkat lebih dalam ketika kita mengalikan jumlah data. Akibatnya, kompleksitas algoritma dapat digambarkan sebagai urutan logaritmik.

Memplot log(n)pada selembar kertas biasa, akan menghasilkan grafik di mana kenaikan kurva melambat dengan nmeningkatnya:

O (log n)

Jørn Schou-Rode
sumber
60
"Perhatikan bagaimana setiap level berisi jumlah ganda node dibandingkan dengan level di atas (karenanya biner)" Ini tidak benar. Apa yang Anda gambarkan adalah pohon biner seimbang . Pohon biner berarti setiap simpul memiliki paling banyak dua anak.
Oenotria
8
Sebenarnya, ini adalah pohon biner seimbang yang sangat istimewa, yang disebut pohon biner lengkap. Saya sudah mengedit jawabannya tetapi butuh seseorang untuk menyetujuinya.
user21820
5
Pohon biner lengkap tidak perlu memiliki level terakhir untuk diisi sepenuhnya. Saya akan mengatakan, 'pohon biner penuh' lebih tepat.
Tn. AJ
Jawaban Anda mencoba merespons lebih konkret masalah asli OP, jadi itu lebih baik daripada jawaban yang diterima saat ini (IMO), tetapi masih sangat tidak lengkap: Anda hanya memberikan setengah contoh dan 2 gambar ...
nbro
2
Pohon ini memiliki 31 item di dalamnya, bukan 16. Mengapa disebut set data 16 item? Setiap node di atasnya mewakili angka, jika tidak maka akan menjadi pohon biner yang tidak efisien: P
Perry Monschau
245

Penjelasan di bawah ini menggunakan kasus pohon biner seimbang untuk membantu Anda memahami bagaimana kami mendapatkan kompleksitas waktu logaritmik.

Pohon biner adalah kasus di mana masalah ukuran n dibagi menjadi sub-masalah ukuran n / 2 sampai kita mencapai masalah ukuran 1:

ketinggian pohon biner

Dan itulah cara Anda mendapatkan O (log n) yang merupakan jumlah pekerjaan yang perlu dilakukan pada pohon di atas untuk mencapai solusi.

Algoritma umum dengan kompleksitas waktu O (log n) adalah Binary Search yang hubungan rekursifnya adalah T (n / 2) + O (1) yaitu pada setiap tingkat pohon berikutnya Anda membagi masalah menjadi setengah dan melakukan jumlah pekerjaan tambahan yang konstan.

2cupsOfTech
sumber
2
pemula di sini. Jadi dapatkah Anda mengatakan tinggi pohon adalah tingkat pembagian secara rekursi untuk mencapai ukuran n = 1?
Cody
@Cody, ya sebagian besar pengamatan Anda akurat. Contoh ini menggambarkan / memanfaatkan log_2. Pengamatan Anda akan melebihi log_2dan akurat untuk di log_xmana saja x > 1. Melakukan pembagian lurus mungkin tidak mengarah ke 1, jadi Anda mungkin ingin mengatakan pembagian rekursif sampai Ceiling()divisi terakhir sama dengan 1, atau yang serupa.
James Oravec
198

Gambaran

Yang lain telah memberikan contoh diagram yang baik, seperti diagram pohon. Saya tidak melihat contoh kode sederhana. Jadi selain penjelasan saya, saya akan memberikan beberapa algoritma dengan pernyataan cetak sederhana untuk menggambarkan kompleksitas berbagai kategori algoritma.

Pertama, Anda ingin memiliki gagasan umum tentang Logaritma, yang dapat Anda peroleh dari https://en.wikipedia.org/wiki/Logarithm . Penggunaan ilmu alam edan log alami. Murid teknik akan menggunakan log_10 (log base 10) dan ilmuwan komputer akan menggunakan log_2 (log base 2) banyak, karena komputer berbasis biner. Kadang-kadang Anda akan melihat singkatan log natural sebagai ln(), insinyur biasanya meninggalkan _10 off dan hanya menggunakan log()dan log_2 disingkat lg(). Semua jenis logaritma tumbuh dengan cara yang sama, itulah sebabnya mereka berbagi kategori yang sama log(n).

Ketika Anda melihat contoh kode di bawah ini, saya sarankan melihat O (1), lalu O (n), lalu O (n ^ 2). Setelah Anda baik dengan itu, kemudian lihat yang lain. Saya telah menyertakan contoh bersih serta variasi untuk menunjukkan bagaimana perubahan halus masih dapat menghasilkan kategorisasi yang sama.

Anda dapat menganggap O (1), O (n), O (logn), dll sebagai kelas atau kategori pertumbuhan. Beberapa kategori akan membutuhkan waktu lebih lama daripada yang lain. Kategori-kategori ini membantu memberi kami cara memesan kinerja algoritma. Beberapa tumbuh lebih cepat seiring input n tumbuh. Tabel berikut menunjukkan pertumbuhan kata secara numerik. Dalam tabel di bawah ini anggap log (n) sebagai langit-langit log_2.

masukkan deskripsi gambar di sini

Contoh Kode Sederhana Dari Berbagai Kategori O Besar:

O (1) - Contoh Waktu Konstan:

  • Algoritma 1:

Algoritma 1 mencetak halo sekali dan itu tidak bergantung pada n, jadi itu akan selalu berjalan dalam waktu yang konstan, begitu juga O(1).

print "hello";
  • Algoritma 2:

Algoritma 2 mencetak halo 3 kali, namun tidak tergantung pada ukuran input. Bahkan ketika n tumbuh, algoritma ini hanya akan selalu mencetak halo 3 kali. Yang sedang dikatakan 3, adalah konstan, jadi algoritma ini juga O(1).

print "hello";
print "hello";
print "hello";

O (log (n)) - Contoh Logaritmik:

  • Algoritma 3 - Ini bertindak seperti "log_2"

Algoritma 3 menunjukkan algoritma yang berjalan di log_2 (n). Perhatikan operasi posting dari for loop mengalikan nilai i saat ini dengan 2, jadi ilanjutkan dari 1 menjadi 2 menjadi 4 hingga 8 hingga 16 hingga 32 ...

for(int i = 1; i <= n; i = i * 2)
  print "hello";
  • Algoritma 4 - Ini bertindak seperti "log_3"

Algoritma 4 menunjukkan log_3. Pemberitahuan iberlaku dari 1 hingga 3 menjadi 9 hingga 27 ...

for(int i = 1; i <= n; i = i * 3)
  print "hello";
  • Algoritma 5 - Ini bertindak seperti "log_1.02"

Algoritma 5 penting, karena membantu menunjukkan bahwa selama angkanya lebih besar dari 1 dan hasilnya berulang kali dikalikan dengan dirinya sendiri, bahwa Anda melihat algoritma logaritmik.

for(double i = 1; i < n; i = i * 1.02)
  print "hello";

O (n) - Contoh Waktu Linear:

  • Algoritma 6

Algoritma ini sederhana, yang mencetak halo n kali.

for(int i = 0; i < n; i++)
  print "hello";
  • Algoritma 7

Algoritma ini menunjukkan variasi, di mana ia akan mencetak halo n / 2 kali. n / 2 = 1/2 * n. Kami mengabaikan konstanta 1/2 dan melihat bahwa algoritma ini adalah O (n).

for(int i = 0; i < n; i = i + 2)
  print "hello";

O (n * log (n)) - nlog (n) Contoh:

  • Algoritma 8

Pikirkan ini sebagai kombinasi dari O(log(n))dan O(n). Bersarang loop for membantu kami mendapatkanO(n*log(n))

for(int i = 0; i < n; i++)
  for(int j = 1; j < n; j = j * 2)
    print "hello";
  • Algoritma 9

Algoritma 9 seperti algoritma 8, tetapi masing-masing loop memungkinkan variasi, yang masih menghasilkan hasil akhir O(n*log(n))

for(int i = 0; i < n; i = i + 2)
  for(int j = 1; j < n; j = j * 3)
    print "hello";

O (n ^ 2) - n kuadrat Contoh:

  • Algoritma 10

O(n^2) diperoleh dengan mudah dengan standar bersarang untuk loop.

for(int i = 0; i < n; i++)
  for(int j = 0; j < n; j++)
    print "hello";
  • Algoritma 11

Seperti algoritma 10, tetapi dengan beberapa variasi.

for(int i = 0; i < n; i++)
  for(int j = 0; j < n; j = j + 2)
    print "hello";

O (n ^ 3) - n potong dadu Contoh:

  • Algoritma 12

Ini seperti algoritma 10, tetapi dengan 3 loop, bukan 2.

for(int i = 0; i < n; i++)
  for(int j = 0; j < n; j++)
    for(int k = 0; k < n; k++)
      print "hello";
  • Algoritma 13

Seperti algoritma 12, tetapi dengan beberapa variasi yang masih menghasilkan O(n^3).

for(int i = 0; i < n; i++)
  for(int j = 0; j < n + 5; j = j + 2)
    for(int k = 0; k < n; k = k + 3)
      print "hello";

Ringkasan

Di atas memberikan beberapa contoh langsung, dan variasi untuk membantu menunjukkan perubahan halus apa yang dapat diperkenalkan yang benar-benar tidak mengubah analisis. Semoga ini memberi Anda wawasan yang cukup.

James Oravec
sumber
17
Luar biasa. Penjelasan terbaik untuk saya yang pernah saya lihat. Akan lebih baik jika O(n^2)dicatat sebagai kombinasi dari O(n)dan O(n), jadi O(n) * O(n) = O(n * n) = O(n^2). Rasanya seperti sedikit melompat tanpa persamaan ini. Ini adalah pengulangan dari penjelasan sebelumnya, tetapi saya pikir pengulangan ini dapat memberikan lebih banyak kepercayaan kepada pembaca untuk memahami.
Eonil
2
Ini hanyalah penjelasan terbaik yang pernah ada.
Edgar Kiljak
2
@IceTea, untuk memberi Anda wawasan / intuisi terhadap pertanyaan Anda. Jika Anda memetakan nversus n/2Anda akan melihat bahwa mereka berdua membuat garis lurus. Ini menempatkan mereka di kelas yang sama karena mereka memiliki tingkat pertumbuhan yang sama (anggap saja sebagai bentuk grafik). Demikian pula, jika Anda memetakan log_2versus log_3Anda akan melihat bahwa keduanya mengambil "bentuk yang sama" atau "tingkat pertumbuhan yang sama".
James Oravec
1
@IceTea, Penjelasan yang diberikan oleh @Shai dan @James lebih akurat, n/2 or 2n or n+2 or nakan memiliki garis yang berbeda-beda dalam grafik tetapi mereka akan memiliki tingkat pertumbuhan yang sama yang berarti mereka semua akan mengikuti pertumbuhan linier.
Naresh Joshi
2
Bagaimana dengan kasus di mana kita memiliki dua loop bersarang, tetapi iterator kedua tergantung pada yang pertama, apakah ketergantungan ini mempengaruhi kompleksitas waktu?
Bionix1441
131

Jika Anda memiliki fungsi yang dibutuhkan:

1 millisecond to complete if you have 2 elements.
2 milliseconds to complete if you have 4 elements.
3 milliseconds to complete if you have 8 elements.
4 milliseconds to complete if you have 16 elements.
...
n milliseconds to complete if you have 2^n elements.

Kemudian dibutuhkan log 2 (n) waktu. The Big O notasi , longgar berbicara, berarti bahwa hubungan hanya perlu benar untuk n besar, dan bahwa faktor konstan dan istilah yang lebih kecil dapat diabaikan.

Mark Byers
sumber
Apakah log2 (n) sama dengan o (log n)?
Sven van den Boogaart
Ya, lihat komentar oleh nawfal untuk jawaban lain di sini: (copy-paste) - dalam konteks pemrograman, basis log adalah 2 (bukan 10), jadi O (log n) skala seperti 1 detik untuk 10 elemen, 2 detik untuk 20 , 3 untuk 40 dll
Andrejs
@SvenvandenBoogaart, contoh dalam solusi ini menggambarkan log_2, yang ada di kelas O(log(n)). Ada banyak yang lain di kelas yang sama O(log(n))yaitu di log_xmanax > 1
James Oravec
@Andrejs, komentar Anda so O(log n) scales like 1 sec for 10 elements, 2 sec for 20, 3 for 40 etctidak akurat. Pola / kelas itu akan cocok / sejajar dengan O(n)tidak O(log(n)). Jika seseorang tertarik log_10maka contoh yang setara akan menjadi 1 detik untuk 10 elemen, 2 detik untuk 100, 3 untuk 1000, dll.
James Oravec
99

Logarithmic running time ( O(log n)) pada dasarnya berarti bahwa waktu berjalan tumbuh sebanding dengan logaritma ukuran input - sebagai contoh, jika 10 item paling banyak memakan waktu x, dan 100 item paling banyak, katakanlah 2x, dan 10.000 item membutuhkan paling banyak 4x, maka itu tampak seperti O(log n)kompleksitas waktu.

Segera.
sumber
1
+1, tetapi Anda benar-benar harus menunjukkan bahwa itu log2, bukan log10.
Adriano Varoli Piazza
62
log2 atau log10 tidak relevan. Mereka hanya berbeda oleh faktor skala, yang membuat mereka dari urutan yang sama, yaitu mereka masih tumbuh pada tingkat yang sama.
Noldorin
17
Hal yang menyenangkan tentang logaritma adalah ketika membandingkan ketinggian relatif, basis tepat yang Anda gunakan tidak masalah. log 10,000 / log 100adalah 2 terlepas dari basis apa yang Anda gunakan.
Anon.
12
Agar nitpicky, O (lg n) berarti runtime paling proporsional dengan lg n. Apa yang Anda gambarkan adalah Theta (lg n).
1
@ rgrig: Itu benar. Saya telah mengedit dalam beberapa "paling banyak" untuk menunjukkan sifat batas atas dari big-O.
Anon.
95

Logaritma

Ok, mari kita coba dan memahami sepenuhnya apa sebenarnya logaritma itu.

Bayangkan kita memiliki tali dan kita mengikatnya pada seekor kuda. Jika tali langsung diikat ke kuda, kekuatan yang kuda perlu tarik (katakanlah, dari seorang pria) secara langsung 1.

Sekarang bayangkan talinya melingkari sebuah tiang. Kuda untuk melarikan diri sekarang harus menarik berkali-kali lebih keras. Jumlah kali akan tergantung pada kekasaran tali dan ukuran tiang, tetapi mari kita asumsikan itu akan melipatgandakan kekuatan seseorang dengan 10 (ketika tali membuat putaran penuh).

Sekarang jika talinya dililitkan sekali, kuda harus menarik 10 kali lebih keras. Jika manusia memutuskan untuk membuat kuda itu sangat sulit, ia dapat mengikat tali lagi di sekeliling tiang, menambah kekuatannya dengan tambahan 10 kali. Loop ketiga akan kembali meningkatkan kekuatan dengan 10 kali lebih jauh.

masukkan deskripsi gambar di sini

Kita dapat melihat bahwa untuk setiap loop, nilainya meningkat sebesar 10. Jumlah putaran yang diperlukan untuk mendapatkan angka apa pun disebut logaritma angka yaitu kita perlu 3 posting untuk menggandakan kekuatan Anda dengan 1000 kali, 6 posting untuk menggandakan kekuatan Anda dengan 1.000.000.

3 adalah logaritma 1.000, dan 6 adalah logaritma 1.000.000 (basis 10).

Jadi, apa sebenarnya yang dimaksud dengan O (log n)?

Dalam contoh kami di atas, 'tingkat pertumbuhan' kami adalah O (log n) . Untuk setiap loop tambahan, gaya yang dapat ditanggung tali kami adalah 10 kali lebih besar:

Turns | Max Force
  0   |   1
  1   |   10
  2   |   100
  3   |   1000
  4   |   10000
  n   |   10^n

Sekarang contoh di atas memang menggunakan basis 10, tetapi untungnya basis log tidak signifikan ketika kita berbicara tentang notasi besar.

Sekarang mari kita bayangkan Anda mencoba menebak angka antara 1-100.

Your Friend: Guess my number between 1-100! 
Your Guess: 50
Your Friend: Lower!
Your Guess: 25
Your Friend: Lower!
Your Guess: 13
Your Friend: Higher!
Your Guess: 19
Your Friend: Higher!
Your Friend: 22
Your Guess: Lower!
Your Guess: 20
Your Friend: Higher!
Your Guess: 21
Your Friend: YOU GOT IT!  

Sekarang Anda butuh 7 tebakan untuk memperbaiki ini. Tapi apa hubungannya di sini? Berapakah jumlah item terbanyak yang dapat Anda tebak dari setiap tebakan tambahan?

Guesses | Items
  1     |   2
  2     |   4
  3     |   8
  4     |   16
  5     |   32
  6     |   64
  7     |   128
  10    |   1024

Dengan menggunakan grafik, kita dapat melihat bahwa jika kita menggunakan pencarian biner untuk menebak angka antara 1-100 itu akan membawa kita paling banyak 7 upaya. Jika kita memiliki 128 angka, kita juga bisa menebak angka dalam 7 percobaan tetapi 129 angka akan membawa kita paling banyak 8 upaya (dalam kaitannya dengan logaritma, di sini kita akan membutuhkan 7 tebakan untuk rentang nilai 128, 10 tebakan untuk kisaran nilai 1024 7 adalah logaritma 128, 10 adalah logaritma 1024 (basis 2)).

Perhatikan bahwa saya paling berani '. Notasi O besar selalu mengacu pada kasus yang lebih buruk. Jika Anda beruntung, Anda bisa menebak jumlahnya dalam satu upaya dan kasus terbaiknya adalah O (1), tapi itu cerita lain.

Kita dapat melihat bahwa untuk setiap tebakan, kumpulan data kita menyusut. Aturan praktis yang baik untuk mengidentifikasi apakah suatu algoritma memiliki waktu logaritmik adalah untuk melihat apakah kumpulan data menyusut dengan urutan tertentu setelah setiap iterasi

Bagaimana dengan O (n log n)?

Anda pada akhirnya akan menemukan algoritma waktu O (n log (n)) linearitmik . Aturan praktis di atas berlaku lagi, tetapi kali ini fungsi logaritmik harus dijalankan n kali mis mengurangi ukuran daftar n kali , yang terjadi dalam algoritma seperti mergesort.

Anda dapat dengan mudah mengidentifikasi apakah waktu algoritmik adalah n log n. Carilah loop luar yang berulang melalui daftar (O (n)). Kemudian lihat apakah ada lingkaran dalam. Jika loop dalam memotong / mengurangi set data pada setiap iterasi, loop itu adalah (O (log n)), dan algoritma keseluruhan adalah = O (n log n) .

Penafian: Contoh tali-logaritma diambil dari buku Delight karya matematikawan karya W.Sawyer .

benscabbia
sumber
Tidak In our example above, our 'growth rate' is O(log n). For every additional loop, the force our rope can handle is 10 times more, didukung oleh bagan yang menunjukkan n == jumlah loop dan our 'growth rate'=> 10 ^ n, yang TIDAK dicatat n. Contoh dapat dibuat benar dengan membuat n=# horses, yang membutuhkan log n loop untuk menahan. Contoh pedogogis yang buruk menghasilkan siswa yang hanya percaya bahwa mereka mengerti.
psimpson
56

Anda dapat memikirkan O (log N) secara intuitif dengan mengatakan waktu sebanding dengan jumlah digit dalam N.

Jika suatu operasi melakukan pekerjaan waktu konstan pada setiap digit atau bit input, seluruh operasi akan memakan waktu sebanding dengan jumlah digit atau bit dalam input, bukan besarnya input; dengan demikian, O (log N) daripada O (N).

Jika suatu operasi membuat serangkaian keputusan waktu konstan yang masing-masing dibagi dua (dikurangi dengan faktor 3, 4, 5 ..) ukuran input yang akan dipertimbangkan, keseluruhan akan memakan waktu sebanding dengan basis log 2 (basis 3 , basis 4, basis 5 ...) dengan ukuran N dari input, bukannya O (N).

Dan seterusnya.

bayangan bulan
sumber
7
Cukup akurat dan lebih mudah dipahami daripada kebanyakan penjelasan, saya rasa.
T.
ini penjelasan log<sub>10</sub> N, kan?
LiuYan 刘 研
1
@LiuYan 刘 研 mereka tidak mengatakan basis apa jumlah digit itu masuk. Bagaimanapun, log₂ (n) = log₁₀ (n) / log₁₀ (2) dan 1 / log₁₀ (2) karenanya merupakan pengganda konstan, dengan prinsip yang sama berlaku untuk semua pangkalan lainnya. Ini menunjukkan dua hal. Pertama prinsip moonshadow menerapkan basis apa pun (meskipun semakin rendah basis, semakin sedikit "jags" dalam perkiraan) dan juga bahwa O (log n) adalah O (log n) tidak peduli apa dasar perhitungan yang membawa Anda ke kesimpulan itu .
Jon Hanna
"proporsional" ... "yang masing-masing membagi dua ukuran input" ??????
csguy
52

Cara terbaik yang selalu saya miliki untuk memvisualisasikan secara mental suatu algoritma yang berjalan di O (log n) adalah sebagai berikut:

Jika Anda menambah ukuran masalah dengan jumlah multiplikatif (yaitu, gandakan ukurannya dengan 10), pekerjaan hanya bertambah dengan jumlah aditif.

Menerapkan ini ke pohon pertanyaan biner Anda sehingga Anda memiliki aplikasi yang baik: jika Anda menggandakan jumlah node dalam pohon biner, tingginya hanya meningkat sebesar 1 (jumlah aditif). Jika Anda menggandakannya lagi, itu hanya meningkat sebesar 1. (Jelas saya berasumsi itu tetap seimbang dan semacamnya). Dengan begitu, alih-alih menggandakan pekerjaan Anda ketika ukuran masalahnya dikalikan, Anda hanya melakukan pekerjaan yang sedikit lebih banyak. Itu sebabnya algoritma O (log n) mengagumkan.

DivineWolfwood
sumber
52

Pertama, saya sarankan Anda membaca buku berikut;

Algoritma (Edisi ke-4)

Berikut adalah beberapa fungsi dan kerumitan yang diharapkan. Angka menunjukkan frekuensi eksekusi pernyataan .

Berikut adalah beberapa fungsi dan kerumitan yang diharapkan

Mengikuti Big-O Complexity Chart juga diambil dari bigocheatsheet Grafik Kompleksitas Big-O

Terakhir showcase sangat sederhana ada menunjukkan bagaimana itu dihitung;

Anatomi dari frekuensi eksekusi pernyataan program.

Menganalisis waktu berjalan suatu program (contoh).

Menganalisis waktu berjalan suatu program

Teoman shipahi
sumber
5
Saya tidak akan memasukkan O (n log n) ke keranjang yang buruk . Itu milik yang adil .
André Werlang
Saat melihat grafik kompleksitas big-O (di atas) Anda harus ingat O (n) adalah titik linear aktual, bukan pink / oranye asrama. @Andre Itu sebabnya O (n log n) ditandai dengan benar dalam braket kinerja 'buruk', itu adalah kinerja yang lebih buruk daripada linear.
JavaBeast
@JavaBeast benar, sementara kinerja O (n log n) secara teknis lebih buruk daripada O (n), lihat tabel di atas, yang menyajikan perbandingan yang baik dari keduanya (lihat pertumbuhan keduanya). otoh bagan, dari sumber yang berbeda, bertentangan karena menempatkan O (1) dan O (log n) dalam barang yang sama / sangat baik. urutan pertumbuhan relatif mereka sebanding dengan O (n) dan O (n log n). tl; dr; O (n log n) tidak bagus, tetapi jauh dari buruk.
André Werlang
1
Jawaban ini salah! Diasumsikan bahwa N = N * N. Sebenarnya N = N! Contoh Anda sebenarnya adalah N potong dadu. Anda melakukan hal yang sama dalam grafik Anda. O Anda (n) sebenarnya harus menjadi kesenjangan antara mengerikan dan buruk. Bukti matematika: Anda mengatakan bahwa untuk loop konstan dengan O (1). Itulah yang sebenarnya berarti 1, tidak bergantung pada N. Itu hanya berarti tidak variabel. Tapi itu variabel karena tergantung pada N. Dua kali N dan separuh waktu. Karena itu tidak valid. Jika itu dari buku itu, jangan membelinya! Grafik kode yang Anda tunjukkan tidak nyata, ini lelucon, lihat, "Theesome", artinya tiga orang berhubungan seks sekaligus! OMG
jgmjgm
1
Bukankah seharusnya O (n) berada di diagonal?
gyosifov
46

Apa log b (n)?

Ini adalah berapa kali Anda dapat memotong log dengan panjang n berulang kali menjadi b bagian yang sama sebelum mencapai bagian ukuran 1.

Chad Brewbaker
sumber
Komentar Luar Biasa! Ini singkat dan tepat jawaban yang saya cari.
DennisL
18

Algoritma Divide and Conquer biasanya memiliki lognkomponen untuk waktu yang berjalan. Ini berasal dari separuh berulang input.

Dalam kasus pencarian biner, setiap iterasi Anda membuang setengah dari input. Perlu dicatat bahwa dalam notasi Big-O, log adalah log basis 2.

Sunting: Seperti dicatat, basis log tidak masalah, tetapi ketika menurunkan kinerja Big-O suatu algoritma, faktor log akan datang dari separuh, maka mengapa saya menganggapnya sebagai basis 2.

David Kanarek
sumber
2
Mengapa log basis 2? Dalam quicksort acak misalnya, saya tidak berpikir itu adalah basis 2. Sejauh yang saya tahu, basis tidak masalah, karena basis log a (n) = log2 (n) / log2 (a), jadi setiap logaritma berbeda dari yang lain dengan konstanta, dan konstanta diabaikan dalam notasi besar. Sebenarnya, menulis basis log dalam notasi besar adalah kesalahan menurut pendapat saya, karena Anda menulis konstanta.
IVlad
Sangat benar bahwa itu dapat dikonversi ke basis apa pun dan itu tidak masalah, tetapi jika Anda mencoba untuk mendapatkan kinerja Big-O dan Anda melihat separuh terus-menerus, itu membantu untuk memahami bahwa Anda tidak akan melihat log basis 10 tercermin dalam kode.
David Kanarek
Selain: Dalam hal-hal seperti B-pohon, di mana node memiliki fan-out lebih dari 2 (yaitu "lebih luas" dari pohon biner), Anda masih akan melihat pertumbuhan O (logn), karena masih membelah-dan -conquer, tetapi dasar log akan terkait dengan fan-out.
Roger Lipscombe
Penyimpangan pada log 2 sebenarnya cukup membantu.
Dan Rosenstark
15

Tapi apa sebenarnya O (log n)? Sebagai contoh, apa artinya mengatakan bahwa ketinggian pohon biner> lengkap adalah O (log n)?

Saya akan mengulangi ini sebagai 'tinggi pohon biner lengkap adalah log n'. Menggambarkan ketinggian pohon biner lengkap akan menjadi O (log n), jika Anda melintasi langkah demi langkah.

Saya tidak mengerti bagaimana mengidentifikasi suatu fungsi dengan waktu logaritmik.

Logaritma pada dasarnya adalah kebalikan dari eksponensial. Jadi, jika setiap 'langkah' dari fungsi Anda menghilangkan faktor elemen dari set item asli, itu adalah algoritma waktu logaritmik.

Sebagai contoh pohon, Anda dapat dengan mudah melihat bahwa mengecilkan tingkat node mengurangi jumlah elemen eksponensial saat Anda terus melintasi. Contoh populer dari melihat-lihat buku telepon yang diurutkan pada dasarnya setara dengan menelusuri pohon pencarian biner (halaman tengah adalah elemen root, dan Anda dapat menyimpulkan pada setiap langkah apakah ke kiri atau kanan).

pengguna2421873
sumber
3
+1 untuk menyebutkan "Logaritma pada dasarnya adalah kebalikan dari eksponensial".
talonx
12

2 kasus ini akan memakan waktu O (log n)

case 1: f(int n) {
      int i;
      for (i = 1; i < n; i=i*2)
        printf("%d", i);
    }


 case 2  : f(int n) {
      int i;
      for (i = n; i>=1 ; i=i/2)
        printf("%d", i);
    }
Ravi Bisla
sumber
Saya yakin saya kehilangan sesuatu, tetapi bukankah saya selalu nol dan loop berjalan selamanya dalam kedua kasus tersebut, karena 0 * 2 = 0 dan 0/2 = 0?
dj_segfault
2
@dj_segfault, itu adalah kesalahan saya. Saya pikir sekarang ini masuk akal .. :)
Ravi Bisla
@RaviBisla Jawaban lain menyatakan bahwa input 10 akan mengambil 1 kali sebanyak 10 loop, dan input 100 akan mengambil 3 kali waktu input 1, itu pasti tidak terjadi dengan contoh-contoh tersebut. stackoverflow.com/a/2307330/1667868
Sven van den Boogaart
12

O (log n) agak menyesatkan, lebih tepatnya itu O (log 2 n), yaitu (logaritma dengan basis 2).

Ketinggian pohon biner seimbang adalah O (log 2 n), karena setiap node memiliki dua (catat "dua" seperti dalam log 2 n) simpul anak. Jadi, pohon dengan n node memiliki tinggi log 2 n.

Contoh lain adalah pencarian biner, yang memiliki waktu berjalan O (log 2 n) karena pada setiap langkah Anda membagi ruang pencarian dengan 2.

stmax
sumber
4
O (log n) adalah urutan yang sama dengan O (ld n) atau O (LN n). Mereka proporsional. Saya mengerti bahwa untuk tujuan belajar lebih mudah untuk menggunakan ld.
helios
4
"lebih tepatnya itu O (ld n)" - Tidak, tidak: semua log adalah urutan yang sama (masing-masing berbeda dari yang lain hanya oleh beberapa faktor penskalaan konstan, yang diabaikan / diabaikan).
ChrisW
1
Anda benar chris, kata-kata yang sangat buruk. seharusnya mengatakan itu seperti helios lakukan. itu membantu untuk belajar / memahami tetapi akhirnya semua log adalah urutan yang sama.
stmax
10

O(log n) mengacu pada fungsi (atau algoritma, atau langkah dalam algoritma) yang bekerja dalam jumlah waktu yang sebanding dengan logaritma (biasanya basis 2 dalam kebanyakan kasus, tetapi tidak selalu, dan dalam hal apa pun ini tidak signifikan dengan notasi O-besar *) dari ukuran input.

Fungsi logaritmik adalah kebalikan dari fungsi eksponensial. Dengan kata lain, jika input Anda tumbuh secara eksponensial (bukan linear, seperti yang biasanya Anda pertimbangkan), fungsi Anda tumbuh secara linear.

O(log n)waktu berlari sangat umum dalam segala jenis aplikasi divide-and-menaklukkan, karena Anda (idealnya) memotong pekerjaan menjadi dua setiap kali. Jika dalam setiap langkah divisi atau taklukkan, Anda melakukan pekerjaan waktu konstan (atau pekerjaan yang bukan waktu konstan, tetapi dengan waktu tumbuh lebih lambat daripada O(log n)), maka seluruh fungsi Anda O(log n). Ini cukup umum untuk setiap langkah membutuhkan waktu linier pada input sebagai gantinya; ini akan berjumlah total kompleksitas waktu O(n log n).

Kompleksitas waktu berjalan dari pencarian biner adalah contoh dari O(log n). Ini karena dalam pencarian biner, Anda selalu mengabaikan setengah dari input Anda di setiap langkah selanjutnya dengan membagi array menjadi setengah dan hanya fokus pada setengahnya dengan setiap langkah. Setiap langkah adalah waktu yang konstan, karena dalam pencarian biner Anda hanya perlu membandingkan satu elemen dengan kunci Anda untuk mengetahui apa yang harus dilakukan selanjutnya terlepas dari seberapa besar array yang Anda pertimbangkan ada di titik mana pun. Jadi Anda melakukan kira-kira langkah (n) / log (2) langkah.

Kompleksitas waktu berjalan dari semacam gabungan adalah contoh dari O(n log n). Ini karena Anda membagi array menjadi dua dengan setiap langkah, menghasilkan total kira-kira langkah-langkah log (n) / log (2). Namun, dalam setiap langkah Anda perlu melakukan operasi penggabungan pada semua elemen (apakah itu satu operasi penggabungan pada dua sublists dari elemen n / 2, atau dua operasi penggabungan pada empat sublist dari elemen n / 4, tidak relevan karena menambah keharusan untuk lakukan ini untuk n elemen di setiap langkah). Dengan demikian, kompleksitas totalnya adalah O(n log n).

* Ingat bahwa notasi O besar, menurut definisi , konstanta tidak masalah. Juga oleh perubahan aturan dasar untuk logaritma, satu-satunya perbedaan antara logaritma dari basis yang berbeda adalah faktor konstan.

Platinum Azure
sumber
Catatan akhir * menyelesaikan kebingungan saya tentang logaritma berdasarkan 2 atau 10 :) Terima kasih banyak.
yahya
9

Ini berarti bahwa waktu yang dibutuhkan untuk tugas ini bertambah dengan log (n) (contoh: 2s untuk n = 10, 4s untuk n = 100, ...). Baca artikel Wikipedia tentang Algoritma Binary Search dan Notasi O Besar untuk lebih banyak precision

Valentin Rocher
sumber
9

Sederhananya: Pada setiap langkah algoritma Anda, Anda dapat memotong pekerjaan menjadi dua. (Asimptotik setara dengan ketiga, keempat, ...)

Brian R. Bondy
sumber
2
Jawaban ini sangat tidak tepat. Pertama-tama, Anda bisa memikirkan memotong pekerjaan menjadi dua hanya dalam kasus logaritma di basis 2. Sangat luar biasa bagaimana jawaban ini (dan sebagian besar jawaban untuk pertanyaan asli) menerima begitu banyak suara. "(Asimptotik setara dengan ketiga, keempat, ...)"? Mengapa menjawab pertanyaan jika Anda tidak punya waktu?
nbro
8

Jika Anda memplot fungsi logaritmik pada kalkulator grafis atau yang serupa, Anda akan melihatnya naik sangat lambat - bahkan lebih lambat dari fungsi linear.

Inilah sebabnya mengapa algoritma dengan kompleksitas waktu logaritmik sangat dicari: bahkan untuk n yang sangat besar (misalkan n = 10 ^ 8, misalnya), mereka melakukan lebih dari yang dapat diterima.

Hadewijch Debaillie
sumber
7

Tapi apa sebenarnya O (log n)

Apa artinya tepatnya adalah "sebagai nkecenderungan ke arah infinity, timekecenderungan ke arah a*log(n)mana aadalah faktor penskalaan konstan".

Atau sebenarnya, itu tidak berarti bahwa; lebih mungkin itu berarti sesuatu seperti " timedibagi oleh a*log(n)kecenderungan ke arah 1".

"Cenderung ke arah" memiliki arti matematika biasa dari 'analisis': "jika Anda memilih misalnya, bahwa setiap sewenang-wenang kecil non-nol konstan k, maka saya dapat menemukan yang sesuai nilai Xsehingga ((time/(a*log(n))) - 1)kurang dari kuntuk semua nilai nlebih besar dari X."


Dalam istilah awam, ini berarti bahwa persamaan untuk waktu mungkin memiliki beberapa komponen lain: misalnya, ia mungkin memiliki waktu startup yang konstan; tetapi komponen-komponen lain ini pucat menuju tidak penting untuk nilai besar n, dan a * log (n) adalah istilah yang mendominasi untuk n besar.

Perhatikan bahwa jika persamaannya adalah, misalnya ...

waktu (n) = a + b log (n) + c n + d n n

... maka ini akan menjadi O (n kuadrat) karena, tidak peduli apa nilai konstanta a, b, c, dan non-nol d, d*n*nistilah tersebut akan selalu mendominasi yang lain untuk nilai n yang cukup besar.

Itulah yang dimaksud dengan sedikit notasi O: artinya "apa urutan istilah dominan untuk n yang cukup besar".

ChrisW
sumber
Itu salah. en.wikipedia.org/wiki/…
Michael Graczyk
7

Saya dapat menambahkan sesuatu yang menarik, yang saya baca di buku oleh Kormen dan lain-lain sejak lama. Sekarang, bayangkan sebuah masalah, di mana kita harus menemukan solusi di ruang masalah. Ruang masalah ini harus terbatas.

Sekarang, jika Anda dapat membuktikan, bahwa pada setiap iterasi dari algoritma Anda Anda memotong sebagian kecil dari ruang ini, yang tidak kurang dari batas tertentu, ini berarti bahwa algoritma Anda berjalan dalam waktu O (logN).

Saya harus menunjukkan, bahwa kita berbicara di sini tentang batas fraksi relatif, bukan batas absolut. Pencarian biner adalah contoh klasik. Pada setiap langkah kita membuang 1/2 dari ruang masalah. Tetapi pencarian biner bukan satu-satunya contoh. Misalkan, Anda membuktikan entah bagaimana, bahwa pada setiap langkah Anda membuang setidaknya 1/128 ruang masalah. Itu berarti, program Anda masih berjalan pada waktu O (logN), meskipun secara signifikan lebih lambat daripada pencarian biner. Ini adalah petunjuk yang sangat baik dalam menganalisis algoritma rekursif. Seringkali dapat dibuktikan bahwa pada setiap langkah rekursi tidak akan menggunakan beberapa varian, dan ini mengarah pada pemutusan sebagian fraksi dalam ruang masalah.

SPIRiT_1984
sumber
6

Saya dapat memberikan contoh untuk for for dan mungkin sekali memahami konsep mungkin akan lebih mudah untuk dipahami dalam konteks yang berbeda.

Itu berarti bahwa dalam loop langkahnya tumbuh secara eksponensial. Misalnya

for (i=1; i<=n; i=i*2) {;}

Kompleksitas dalam notasi-O dari program ini adalah O (log (n)). Mari kita coba memutarnya dengan tangan (ada di antara 512 dan 1023 (tidak termasuk 1024):

step: 1   2   3   4   5    6    7    8     9     10
   i: 1   2   4   8   16   32   64   128   256   512

Meskipun n berada di suatu tempat antara 512 dan 1023, hanya 10 iterasi yang terjadi. Ini karena langkah dalam loop tumbuh secara eksponensial dan dengan demikian hanya membutuhkan 10 iterasi untuk mencapai terminasi.

Logaritma x (ke dasar a) adalah fungsi kebalikan dari a ^ x.

Itu seperti mengatakan bahwa logaritma adalah kebalikan dari eksponensial.

Sekarang coba lihat seperti itu, jika eksponensial tumbuh sangat cepat maka logaritma tumbuh (berbanding terbalik) sangat lambat.

Perbedaan antara O (n) dan O (log (n)) sangat besar, mirip dengan perbedaan antara O (n) dan O (a ^ n) (menjadi konstan).

Ely
sumber
6

Sebenarnya, jika Anda memiliki daftar elemen n, dan membuat pohon biner dari daftar itu (seperti dalam algoritma divide and conquer), Anda akan terus membaginya dengan 2 hingga Anda mencapai daftar ukuran 1 (daun).

Pada langkah pertama, Anda membagi 2. Anda kemudian memiliki 2 daftar (2 ^ 1), Anda membagi masing-masing dengan 2, sehingga Anda memiliki 4 daftar (2 ^ 2), Anda membagi lagi, Anda memiliki 8 daftar (2 ^ 3 ) dan seterusnya hingga ukuran daftar Anda adalah 1

Itu memberi Anda persamaan:

n/(2^steps)=1 <=> n=2^steps <=> lg(n)=steps

(Anda mengambil lg dari setiap sisi, lg menjadi basis log 2)

Dinaiz
sumber
2
Sampai beberapa malware mulai memasukkan daftar baru dengan panjang x di dua tingkat sebelum meninggalkan node. Maka itu kelihatannya akan menjadi loop tanpa batas ...
Francis Cugler
1
Saya tidak mendapatkan komentar Anda. Apakah penjelasan saya salah?
Dinaiz
1
Saya hanya membuat lelucon hipotetis. Saya tidak benar-benar berarti apa-apa dengan itu.
Francis Cugler
6

Setiap kali kami menulis algoritma atau kode, kami mencoba menganalisis kompleksitas asimptotiknya. Ini berbeda dari kompleksitas waktunya .

Kompleksitas asimptotik adalah perilaku waktu eksekusi suatu algoritma sedangkan kompleksitas waktu adalah waktu eksekusi aktual. Tetapi beberapa orang menggunakan istilah ini secara bergantian.

Karena kompleksitas waktu tergantung pada berbagai parameter yaitu.
1. Sistem Fisik
2. Bahasa Pemrograman
3. Gaya pengkodean
4. Dan banyak lagi ......

Waktu eksekusi aktual bukan ukuran yang baik untuk analisis.


Sebagai gantinya kami mengambil ukuran input sebagai parameter karena apa pun kodenya, inputnya sama. Jadi waktu eksekusi adalah fungsi dari ukuran input.

Berikut ini adalah contoh Algoritma Linear Waktu


Pencarian Linear
Diberi n elemen input, untuk mencari elemen dalam array yang paling Anda butuhkan perbandingan 'n' . Dengan kata lain, tidak peduli apa bahasa pemrograman yang Anda gunakan, gaya pengkodean apa yang Anda sukai, pada sistem apa Anda menjalankannya. Dalam skenario terburuk, ini hanya membutuhkan perbandingan n. Waktu eksekusi berbanding lurus dengan ukuran input.

Dan itu bukan hanya pencarian, apa pun pekerjaan (kenaikan, perbandingan, atau operasi apa pun) yang merupakan fungsi dari ukuran input.

Jadi ketika Anda mengatakan algoritma apa pun adalah O (log n) itu berarti waktu eksekusi adalah log kali ukuran input n.

Ketika ukuran input meningkatkan pekerjaan yang dilakukan (di sini waktu eksekusi) meningkat. (Oleh karena itu proporsionalitas)

      n      Work
      2     1 units of work
      4     2 units of work
      8     3 units of work

Lihat sebagai ukuran input meningkat pekerjaan yang dilakukan meningkat dan tidak tergantung pada mesin apa pun. Dan jika Anda mencoba mencari tahu nilai unit kerja itu sebenarnya tergantung pada parameter yang ditentukan di atas. Ini akan berubah sesuai dengan sistem dan semua.

Sanjay Kumar
sumber
5

Pohon

log x to base b = y adalah kebalikan dari b^y = x

Jika Anda memiliki pohon M-ary dengan kedalaman d dan ukuran n, maka:

  • melintasi seluruh pohon ~ O (M ^ d) = O (n)

  • Berjalan satu jalur di pohon ~ O (d) = O (log n ke basis M)

Khaled.K
sumber
5

Dalam teknologi informasi itu berarti:

  f(n)=O(g(n)) If there is suitable constant C and N0 independent on N, 
  such that
  for all N>N0  "C*g(n) > f(n) > 0" is true.

Semut tampaknya notasi ini sebagian besar diambil dari matematika.

Dalam artikel ini ada kutipan: DE Knuth, "OMICRON BESAR DAN OMEGA BESAR DAN THETA BESAR", 1976 :

Atas dasar masalah yang dibahas di sini, saya mengusulkan agar anggota SIGACT, dan editor jurnal ilmu komputer dan matematika, mengadopsi notasi sebagaimana didefinisikan di atas, kecuali jika alternatif yang lebih baik dapat ditemukan dengan segera .

Hari ini adalah 2016, tetapi kami masih menggunakannya sampai sekarang.


Dalam analisis matematika itu berarti:

  lim (f(n)/g(n))=Constant; where n goes to +infinity

Tetapi bahkan dalam analisis matematika kadang-kadang simbol ini digunakan dalam arti "C * g (n)> f (n)> 0".

Seperti yang saya tahu dari universitas, simbol diperkenalkan oleh ahli matematika Jerman Landau (1877-1938)

bruziuz
sumber
4

Contoh biner lengkap adalah O (ln n) karena pencarian terlihat seperti ini:

1 2 3 4 5 6 7 8 9 10 11 12

Mencari 4 menghasilkan 3 hit: 6, 3 lalu 4. Dan log2 12 = 3, yang merupakan apporximate bagus untuk berapa banyak hit di mana diperlukan.

Amirshk
sumber
terima kasih untuk contohnya. Itu dengan jelas mengatakan bagaimana algoritma kami dapat menggunakan waktu logaritmik dalam metode membagi dan menaklukkan.
Abc
Jadi jika ini adalah loop n / 2 selalu log (n)?
Gil Beyruth
3

Jika Anda mencari jawaban berdasarkan intuisi, saya ingin memberikan dua interpretasi untuk Anda.

  1. Bayangkan sebuah bukit yang sangat tinggi dengan basis yang sangat luas pula. Untuk mencapai puncak bukit ada dua cara: satu adalah jalur khusus yang berputar secara spiral di sekitar bukit mencapai di atas, yang lain: teras kecil seperti ukiran dipotong untuk menyediakan tangga. Sekarang jika cara pertama mencapai waktu linear O (n), yang kedua adalah O (log n).

  2. Bayangkan sebuah algoritma, yang menerima integer, nsebagai input dan melengkapi dalam waktu yang proporsional untuk nkemudian itu adalah O (n) atau theta (n) tetapi jika itu berjalan dalam proporsi waktu ke number of digits or the number of bits in the binary representation on numbermaka algoritma berjalan di O (log n) atau theta (log n) waktu.

mickeymoon
sumber
tolong edit. memiliki "O (n) atau theta (n)" di kedua skenario ...? Juga, saya sudah sering mendengar ini, ukuran vs # digit. Apakah kita mengatakan ukuran === 128 untuk n = 10.000000 dan digit === 8 untuk n = 10000000? Tolong jelaskan.
Cody
2

Algoritma dalam paradigma Divide and Conquer adalah kompleksitas O (logn). Satu contoh di sini, hitung fungsi daya Anda sendiri,

int power(int x, unsigned int y)
{
    int temp;
    if( y == 0)
        return 1;
    temp = power(x, y/2);
    if (y%2 == 0)
        return temp*temp;
    else
        return x*temp*temp;
}

dari http://www.geeksforgeeks.org/write-ac-program-to-calculate-powxn/

Kiriloff
sumber