Apakah ada sistem di balik keajaiban analisis algoritma?

159

Ada banyak pertanyaan tentang bagaimana menganalisis waktu berjalan algoritma (lihat, misalnya, dan ). Banyak yang serupa, misalnya yang meminta analisis biaya loop bersarang atau algoritma Divide & Conquer, tetapi sebagian besar jawaban tampaknya dibuat khusus.

Di sisi lain, jawaban untuk pertanyaan umum lainnya menjelaskan gambaran yang lebih besar (khususnya mengenai analisis asimptotik) dengan beberapa contoh, tetapi tidak bagaimana cara membuat tangan Anda kotor.

Apakah ada metode umum terstruktur untuk menganalisis biaya algoritma? Biaya mungkin waktu berjalan (kompleksitas waktu), atau ukuran biaya lainnya, seperti jumlah perbandingan yang dilakukan, kompleksitas ruang, atau sesuatu yang lain.

Ini seharusnya menjadi referensi pertanyaan yang dapat digunakan untuk mengarahkan pemula; karenanya cakupannya lebih luas dari biasanya. Harap berhati-hati untuk memberikan jawaban umum, yang disajikan secara didaktis yang diilustrasikan oleh setidaknya satu contoh tetapi tetap mencakup banyak situasi. Terima kasih!

Raphael
sumber
3
Terima kasih kepada penulis StackEdit yang telah membuatnya nyaman untuk menulis posting yang begitu panjang, dan pembaca beta saya FrankW , Juho , Gilles dan Sebastian karena membantu saya memperbaiki sejumlah kekurangan dari draft sebelumnya.
Raphael
1
Hai @Raphael, ini hal yang luar biasa. Saya pikir saya akan menyarankan menyatukannya sebagai PDF untuk diedarkan? Hal semacam ini bisa menjadi referensi yang sangat berguna.
Hadsed
1
@hadsed: Terima kasih, saya senang ini berguna bagi Anda! Untuk saat ini, saya lebih suka tautan ke pos ini diedarkan. Namun, konten pengguna SE "dilisensikan di bawah cc by-sa 3.0 dengan atribusi diperlukan" (lihat halaman footer) sehingga siapa pun dapat membuat PDF dari itu, asalkan diberikan atribusi.
Raphael
2
Saya tidak terlalu kompeten dalam hal ini, tetapi apakah itu normal bahwa tidak ada referensi ke teorema Master dalam setiap jawaban?
babou
1
@ Babou, saya tidak tahu apa artinya "normal" di sini. Dari sudut pandang saya, teorema Master tidak ada urusannya berada di sini: ini adalah tentang menganalisis algoritma, teorema Master adalah alat yang sangat spesifik untuk memecahkan (beberapa) pengulangan (dan sangat kasar pada saat itu). Karena matematika telah dibahas di tempat lain (misalnya di sini ) saya telah memilih untuk mencakup hanya bagian dari algoritma ke matematika di sini. Saya memberikan referensi ke posting yang berhubungan dengan mengerjakan matematika dalam jawaban saya.
Raphael

Jawaban:

134

Menerjemahkan Kode ke Matematika

Diberikan (kurang lebih) semantik operasional formal Anda dapat menerjemahkan kode algoritma (pseudo-) secara harfiah ke dalam ekspresi matematika yang memberi Anda hasilnya, asalkan Anda dapat memanipulasi ekspresi menjadi bentuk yang bermanfaat. Ini bekerja dengan baik untuk ukuran biaya tambahan seperti jumlah perbandingan, swap, pernyataan, akses memori, siklus beberapa kebutuhan mesin abstrak, dan sebagainya.

Contoh: Perbandingan di Bubblesort

Pertimbangkan algoritma ini yang mengurutkan array yang diberikan A:

 bubblesort(A) do                   1
  n = A.length;                     2
  for ( i = 0 to n-2 ) do           3
    for ( j = 0 to n-i-2 ) do       4
      if ( A[j] > A[j+1] ) then     5
        tmp    = A[j];              6
        A[j]   = A[j+1];            7
        A[j+1] = tmp;               8
      end                           9
    end                             10
  end                               11
end                                 12

Katakanlah kita ingin melakukan analisis algoritma penyortiran yang biasa, yaitu menghitung jumlah perbandingan elemen (baris 5). Kami segera mencatat bahwa jumlah ini tidak bergantung pada konten array A, hanya pada panjangnya . Jadi kita bisa menerjemahkan (nested) -lompatan secara harfiah ke dalam jumlah (nested); variabel loop menjadi variabel penjumlahan dan rentang membawa. Kita mendapatkan:nfor

Ccmp(n)=i=0n2j=0ni21==n(n1)2=(n2) ,

di mana adalah biaya untuk setiap eksekusi baris 5 (yang kami hitung).1

Contoh: Swap dalam Bubblesort

Saya akan menyatakan dengan subprogram yang terdiri dari baris ke dan oleh biaya untuk menjalankan subprogram ini (satu kali).Pi,jijCi,j

Sekarang katakanlah kita ingin menghitung swap , yaitu seberapa sering dieksekusi. Ini adalah "blok dasar", yaitu subprogram yang selalu dijalankan secara atom dan memiliki biaya konstan (di sini, ). Mengontrak blok semacam itu adalah salah satu penyederhanaan yang berguna yang sering kita terapkan tanpa memikirkan atau membicarakannya.P6,81

Dengan terjemahan yang sama seperti di atas, kita sampai pada rumus berikut:

Cswaps(A)=i=0n2j=0ni2C5,9(A(i,j)) .

A(i,j) menunjukkan keadaan array sebelum -terulangan ke- .(i,j)P5,9

Perhatikan bahwa saya menggunakan sebagai ganti sebagai parameter; kita akan segera melihat alasannya. Saya tidak menambahkan dan sebagai parameter karena biaya tidak tergantung pada mereka di sini (dalam model biaya seragam , yaitu); secara umum, mereka mungkin saja.AnijC5,9

Jelas, biaya tergantung pada konten (nilai-nilai dan , khususnya) jadi kami harus memperhitungkannya. Sekarang kita menghadapi tantangan: bagaimana kita "membuka" ? Nah, kita bisa membuat ketergantungan pada konten eksplisit:P5,9AA[j]A[j+1]C5,9A

C5,9(A(i,j))=C5(A(i,j))+{1,A(i,j)[j]>A(i,j)[j+1]0,else .

Untuk setiap array input yang diberikan, biaya-biaya ini didefinisikan dengan baik, tetapi kami ingin pernyataan yang lebih umum; kita perlu membuat asumsi yang lebih kuat. Mari kita selidiki tiga kasus khas.

  1. Kasus terburuk

    Hanya dari melihat jumlah dan mencatat bahwa , kita dapat menemukan batas atas sepele untuk biaya:C5,9(A(i,j)){0,1}

    Cswaps(A)i=0n2j=0ni21=n(n1)2=(n2) .

    Tetapi dapatkah ini terjadi , yaitu adakah untuk batas atas ini tercapai? Ternyata, ya: jika kita memasukkan array yang diurutkan terbalik dari elemen berbeda berpasangan, setiap iterasi harus melakukan swap¹. Oleh karena itu, kami telah mendapatkan jumlah swap terburuk yang tepat untuk Bubblesort.A

  2. Kasus terbaik

    Sebaliknya, ada batas bawah sepele:

    Cswaps(A)i=0n2j=0ni20=0 .

    Ini juga dapat terjadi: pada array yang sudah diurutkan, Bubblesort tidak menjalankan satu swap.

  3. Kasus rata-rata

    Kasus terburuk dan terbaik membuka cukup celah. Tapi apa adalah khas jumlah swap? Untuk menjawab pertanyaan ini, kita perlu mendefinisikan apa arti "khas". Secara teori, kami tidak memiliki alasan untuk lebih memilih satu input daripada input lainnya dan oleh karena itu kami biasanya mengasumsikan distribusi yang seragam atas semua input yang mungkin, yaitu setiap input memiliki kemungkinan yang sama besar. Kami membatasi diri untuk array dengan elemen berbeda berpasangan dan dengan demikian mengasumsikan model permutasi acak .

    Kemudian, kami dapat menulis ulang biaya kami seperti ini²:

    E[Cswaps]=1n!Ai=0n2j=0ni2C5,9(A(i,j))

    Sekarang kita harus melampaui manipulasi jumlah yang sederhana. Dengan melihat algoritma, kami mencatat bahwa setiap swap menghapus tepat satu inversi dalam (kami hanya pernah bertukar tetangga )³. Artinya, jumlah swap dilakukan pada adalah persis jumlah inversi dari . Dengan demikian, kita dapat mengganti dua jumlah dalam dan mendapatkanAAinv(A)A

    E[Cswaps]=1n!Ainv(A) .

    Beruntung bagi kami, jumlah rata-rata inversi telah ditentukan

    E[Cswaps]=12(n2)

    yang merupakan hasil akhir kami. Perhatikan bahwa ini persis setengah dari biaya terburuk.


  1. Perhatikan bahwa algoritma dirumuskan dengan cermat sehingga iterasi "yang terakhir" dengan i = n-1loop luar yang tidak pernah melakukan apa pun tidak dieksekusi.
  2. " " adalah notasi matematika untuk "nilai yang diharapkan", yang di sini hanya rata-rata.E
  3. Kami belajar sepanjang jalan bahwa tidak ada algoritma yang hanya menukar elemen tetangga dapat secara asimptotik lebih cepat daripada Bubblesort (bahkan rata-rata) - jumlah inversi adalah batas yang lebih rendah untuk semua algoritma tersebut. Ini berlaku untuk mis. Penyortiran dan Penyortiran Pilihan .

Metode Umum

Kita telah melihat dalam contoh bahwa kita harus menerjemahkan struktur kontrol ke dalam matematika; Saya akan menyajikan ansambel khas aturan terjemahan. Kita juga telah melihat bahwa biaya dari setiap subprogram yang diberikan mungkin tergantung pada keadaan saat ini , yaitu (kira-kira) nilai variabel saat ini. Karena algoritma (biasanya) memodifikasi keadaan, metode umum sedikit rumit untuk diketahui. Jika Anda mulai merasa bingung, saya sarankan Anda kembali ke contoh atau membuat sendiri.

Kami menyatakan dengan keadaan saat ini (bayangkan sebagai seperangkat tugas variabel). Ketika kami menjalankan program yang dimulai dengan status , kami berakhir dengan status (disediakan berakhir).ψPψψ/PP

  • Pernyataan individu

    Diberi hanya satu pernyataan S;, Anda menetapkan biaya . Ini biasanya akan menjadi fungsi konstan.CS(ψ)

  • Ekspresi

    Jika Anda memiliki ekspresi Eformulir E1 ∘ E2(misalnya, ekspresi aritmatika di mana mungkin penambahan atau penggandaan, Anda menambahkan biaya secara rekursif:

    CE(ψ)=c+CE1(ψ)+CE2(ψ) .

    Catat itu

    • biaya operasi mungkin tidak konstan tetapi tergantung pada nilai dan dancE1E2
    • evaluasi ekspresi dapat mengubah keadaan dalam banyak bahasa,

    jadi Anda mungkin harus fleksibel dengan aturan ini.

  • Urutan

    Diberikan program Psebagai urutan program Q;R, Anda menambahkan biaya

    CP(ψ)=CQ(ψ)+CR(ψ/Q) .

  • Persyaratan

    Diberikan program Pformulir if A then Q else R end, biaya tergantung pada negara:

    CP(ψ)=CA(ψ)+{CQ(ψ/A),A evaluates to true under ψCR(ψ/A),else

    Secara umum, mengevaluasi Amungkin sangat mengubah keadaan, sehingga pembaruan untuk biaya masing-masing cabang.

  • For-Loops

    Diberikan program Pformulir for x = [x1, ..., xk] do Q end, tetapkan biaya

    CP(ψ)=cinit_for+i=1kcstep_for+CQ(ψi{x:=xi})

    di mana adalah status sebelum memproses untuk nilai , yaitu setelah iterasi dengan diatur ke , ..., .ψiQxixx1xi-1

    Perhatikan konstanta tambahan untuk pemeliharaan loop; variabel loop harus dibuat ( ) dan menetapkan nilainya ( )). Ini relevan sejakcinit_forcstep_for

    • komputasi berikutnya ximungkin mahal dan
    • a for-Lingkaran dengan tubuh kosong (misalnya setelah menyederhanakan dalam kasus terbaik dengan biaya tertentu) tidak memiliki biaya nol jika melakukan iterasi.
  • Sementara-Loops

    Diberikan program Pformulir while A do Q end, tetapkan biaya

    CP(ψ) =CA(ψ)+{0,A evaluates to false under ψCQ(ψ/A)+CP(ψ/A;Q), else

    Dengan memeriksa algoritme, perulangan ini sering kali dapat direpresentasikan dengan baik sebagai jumlah yang mirip dengan perulangan for-loop.

    Contoh: Pertimbangkan algoritma singkat ini:

    while x > 0 do    1
      i += 1          2
      x = x/2         3
    end               4
    

    Dengan menerapkan aturan, kita dapatkan

    C1,4({i:=i0;x:=x0}) =c<+{0,x00c+=+c/+C1,4({i:=i0+1;x:=x0/2}), else

    dengan beberapa biaya konstan untuk masing-masing pernyataan. Kami berasumsi secara implisit bahwa ini tidak tergantung pada negara (nilai-nilai dan ); ini mungkin atau mungkin tidak benar dalam "kenyataan": pikirkan tentang luapan!cix

    Sekarang kita harus menyelesaikan pengulangan ini untuk . Kami mencatat bahwa baik jumlah iterasi bukan biaya loop body bergantung pada nilai , sehingga kami dapat menjatuhkannya. Kita dibiarkan dengan pengulangan ini:C1,4i

    C1,4(x)={c>,x0c>+c+=+c/+C1,4(x/2), else

    Ini diselesaikan dengan sarana dasar untuk

    C1,4(ψ)=log2ψ(x)(c>+c+=+c/)+c> ,

    memperkenalkan kembali kondisi penuh secara simbolis; jika , maka .ψ={,x:=5,}ψ(x)=5

  • Panggilan Prosedur

    Diberikan program Pformulir M(x)untuk beberapa parameter di xmana Mprosedur dengan parameter (bernama) p, menetapkan biaya

    CP(ψ)=ccall+CM(ψglob{p:=x}) .

    Catat lagi konstanta tambahan (yang mungkin sebenarnya bergantung pada !). Panggilan prosedur mahal karena bagaimana mereka diterapkan pada mesin nyata, dan kadang-kadang bahkan mendominasi runtime (misalnya mengevaluasi pengulangan angka Fibonacci secara naif).ccallψ

    Saya membahas beberapa masalah semantik yang mungkin Anda miliki dengan keadaan di sini. Anda akan ingin membedakan negara global dan lokal untuk panggilan prosedur. Mari kita asumsikan kita hanya melewati negara global di sini dan Mmendapat negara lokal baru, diinisialisasi dengan menetapkan nilai pto x. Lebih jauh, xmungkin ungkapan yang kita (biasanya) asumsikan dievaluasi sebelum melewatinya.

    Contoh: Pertimbangkan prosedurnya

    fac(n) do                  
      if ( n <= 1 ) do         1
        return 1               2
      else                     3
        return n * fac(n-1)    4
      end                      5
    end                        
    

    Sesuai aturan, kami mendapatkan:

    Cfac({n:=n0})=C1,5({n:=n0})=c+{C2({n:=n0}),n01C4({n:=n0}), else=c+{creturn,n01creturn+c+ccall+Cfac({n:=n01}), else

    Perhatikan bahwa kami mengabaikan negara global, karena facjelas tidak mengaksesnya. Perulangan khusus ini mudah dipecahkan

    Cfac(ψ)=ψ(n)(c+creturn)+(ψ(n)1)(c+ccall)

Kami telah membahas fitur bahasa yang akan Anda temui dalam kode pseudo yang khas. Waspadai biaya tersembunyi ketika menganalisis kode pseudo tingkat tinggi; jika ragu, buka. Notasi tersebut mungkin terlihat rumit dan tentu saja merupakan masalah selera; konsep-konsep yang tercantum tidak dapat diabaikan. Namun, dengan beberapa pengalaman Anda akan dapat melihat langsung bagian mana dari negara yang relevan untuk ukuran biaya mana, misalnya "ukuran masalah" atau "jumlah simpul". Sisanya dapat dijatuhkan - ini menyederhanakan banyak hal!

Jika Anda berpikir sekarang bahwa ini terlalu rumit, disarankan: itu adalah ! Turunkan biaya tepat dari algoritma dalam model apa pun yang begitu dekat dengan mesin nyata sehingga memungkinkan prediksi runtime (bahkan yang relatif) adalah upaya yang sulit. Dan itu bahkan tidak mempertimbangkan caching dan efek buruk lainnya pada mesin nyata.

Oleh karena itu, analisis algoritme sering disederhanakan sampai titik yang dapat ditelusur secara matematis. Misalnya, jika Anda tidak memerlukan biaya yang pasti, Anda bisa melebih-lebihkan atau meremehkan pada titik mana pun (untuk batas atas, batas bawah): kurangi set konstanta, singkirkan persyaratan, sederhanakan penjumlahan, dan sebagainya.

Catatan tentang biaya asimptotik

Apa yang biasanya Anda temukan dalam literatur dan di web adalah "Analisis Besar-Oh". Istilah yang tepat adalah analisis asimptotik yang berarti bahwa alih-alih mendapatkan biaya yang tepat seperti yang kami lakukan dalam contoh, Anda hanya memberikan biaya hingga faktor konstan dan dalam batas (secara kasar, "untuk besar ").n

Ini (sering) adil karena pernyataan abstrak memiliki beberapa (umumnya tidak diketahui) biaya dalam kenyataan, tergantung pada mesin, sistem operasi dan faktor lainnya, dan runtime pendek dapat didominasi oleh sistem operasi yang mengatur proses di tempat pertama dan yang lainnya. Jadi, Anda mendapatkan sedikit gangguan.

Inilah bagaimana analisis asimptotik berhubungan dengan pendekatan ini.

  1. Identifikasi operasi dominan (yang menyebabkan biaya), yaitu operasi yang paling sering terjadi (hingga faktor konstan). Dalam contoh Bubblesort, satu pilihan yang mungkin adalah perbandingan di baris 5.

    Sebagai alternatif, ikat semua konstanta untuk operasi elementer dengan resp maksimum (dari atas). minimum mereka (dari bawah) dan melakukan analisis biasa.

  2. Lakukan analisis menggunakan jumlah eksekusi operasi ini sebagai biaya.
  3. Saat menyederhanakan, izinkan estimasi. Berhati-hatilah untuk hanya mengizinkan estimasi dari atas jika sasaran Anda adalah resp batas atas ( ). dari bawah jika Anda ingin batas bawah ( ).OΩ

Pastikan Anda memahami arti simbol Landau . Ingatlah bahwa batasan seperti itu ada untuk ketiga kasus ; menggunakan tidak berarti analisis kasus terburuk.O

Bacaan lebih lanjut

Ada banyak tantangan dan trik dalam analisis algoritma. Berikut ini beberapa bacaan yang disarankan.

Ada banyak pertanyaan yang ditandai yang menggunakan teknik yang mirip dengan ini.

Raphael
sumber
1
mungkin beberapa referensi dan contoh untuk teorema master (dan ekstensinya ) untuk analisis asimptotik
Nikos M.
@NikosM Ini di luar ruang lingkup di sini (lihat juga komentar pada pertanyaan di atas). Perhatikan bahwa saya menautkan ke posting referensi kami tentang menyelesaikan perulangan yang memang menghadirkan teorema Master et al.
Raphael
@ Nikos M: $ 0,02 saya: sementara teorema master bekerja untuk beberapa perulangan, itu tidak berlaku untuk banyak orang lain; ada metode standar untuk menyelesaikan kekambuhan. Dan ada algoritma yang bahkan kita tidak akan memiliki perulangan memberikan waktu berjalan; mungkin diperlukan beberapa teknik penghitungan tingkat lanjut. Untuk seseorang dengan latar belakang matematika yang baik, saya sarankan buku bagus Sedgewick dan Flajolet, "Analisis Algoritma", yang memiliki bab-bab seperti "hubungan perulangan", "menghasilkan fungsi", dan "perkiraan asimptotik". Struktur data muncul sebagai contoh sesekali, dan fokusnya adalah pada metode!
Jay
@Raphael Saya tidak dapat menemukan disebutkan di web untuk metode "Menerjemahkan Kode ke Matematika" ini berdasarkan semantik operasional. Bisakah Anda memberikan referensi untuk buku, kertas atau artikel yang berhubungan dengan ini secara lebih formal? Atau dalam hal ini dikembangkan oleh Anda, apakah Anda memiliki sesuatu yang lebih mendalam?
Wyvern666
1
@ Wyvern666 Sayangnya, tidak. Saya mengarang sendiri, sejauh yang bisa diklaim orang untuk mengarang sesuatu seperti ini. Mungkin saya akan menulis karya yang dapat dikutip sendiri di beberapa titik. Yang mengatakan, seluruh kumpulan kerja di sekitar analitik kombinatorik (Flajolet, Sedgewick, dan banyak lainnya) adalah fondasi dari ini. Mereka tidak repot-repot dengan semantik formal "kode" sebagian besar waktu, tetapi mereka menyediakan matematika untuk berurusan dengan biaya tambahan "algoritma" secara umum. Sejujurnya saya pikir konsep yang diletakkan di sini tidak terlalu dalam - matematika yang bisa Anda masuki adalah, meskipun.
Raphael
29

Hitungan Pernyataan Eksekusi

Ada metode lain, yang diperjuangkan oleh Donald E. Knuth dalam seri The Art of Computer Programming . Berbeda dengan menerjemahkan seluruh algoritma ke dalam satu rumus , ia bekerja secara independen dari semantik kode pada sisi "menyatukan semuanya" dan memungkinkan untuk naik ke level yang lebih rendah hanya jika diperlukan, mulai dari tampilan "mata elang". Setiap pernyataan dapat dianalisis secara terpisah dari yang lainnya, yang mengarah pada perhitungan yang lebih jelas. Namun, teknik ini cocok untuk kode yang agak rinci, bukan kode pseudo tingkat yang lebih tinggi.

Metode

Ini pada prinsipnya cukup sederhana:

  1. Tetapkan setiap pernyataan nama / nomor.
  2. Tetapkan setiap pernyataan beberapa biaya .SiCi
  3. Tentukan untuk setiap pernyataan jumlah eksekusi .Siei
  4. Hitung total biaya

    C=ieiCi .

Anda dapat memasukkan taksiran dan / atau jumlah simbolis pada titik mana saja, melemahkan resp. generalisasi hasilnya sesuai.

Ketahuilah bahwa langkah 3 bisa sangat rumit. Biasanya ada di sana Anda harus bekerja dengan perkiraan (asimptotik) seperti " " untuk mendapatkan hasil.e77O(nlogn)

Contoh: Pencarian mendalam-pertama

Pertimbangkan algoritma grafik-traversal berikut:

dfs(G, s) do
  // assert G.nodes contains s
  visited = new Array[G.nodes.size]     1
  dfs_h(G, s, visited)                  2
end 

dfs_h(G, s, visited) do
  foo(s)                                3
  visited[s] = true                     4

  v = G.neighbours(s)                   5
  while ( v != nil ) do                 6
    if ( !visited[v] ) then             7
      dfs_h(G, v, visited)              8
    end
    v = v.next                          9
  end
end

Kami berasumsi bahwa grafik (tidak terarah) diberikan oleh daftar adjacency pada node . Biarkan menjadi jumlah tepi.{0,,n1}m

Hanya dengan melihat algoritma, kita melihat bahwa beberapa pernyataan dieksekusi sama seringnya dengan yang lain. Kami memperkenalkan beberapa placeholder , dan untuk jumlah eksekusi :ABCei

i123456789eiAABBBB+CCB1C

Secara khusus, karena setiap panggilan rekursif di jalur 8 menyebabkan panggilan di saluran 3 (dan satu disebabkan oleh panggilan asli dari ). Selanjutnya, karena kondisi harus diperiksa sekali per iterasi tetapi kemudian sekali lagi untuk meninggalkannya.e8=e31foodfse6=e5+e7while

Jelas bahwa . Sekarang, selama pembuktian kebenaran kami akan menunjukkan bahwa dijalankan tepat satu kali per node; yaitu, . Tapi kemudian, kita mengulangi setiap daftar adjacency tepat sekali dan setiap tepi menyiratkan dua entri secara total (satu untuk setiap node insiden); kita mendapatkan iterasi secara total. Menggunakan ini, kami memperoleh tabel berikut:A=1fooB=nC=2m

i123456789ei11nnn2m+n2mn12m

Ini membawa kita ke total biaya persis

C(n,m)=(C1+C2C8)+ n(C3+C4+C5+C6+C8)+ 2m(C6+C7+C9).

Dengan membuat instance nilai yang sesuai untuk kita dapat memperoleh lebih banyak biaya konkret. Misalnya, jika kita ingin menghitung akses memori (per kata), kami akan gunakanCi

i123456789Cin00110101

dan dapatkan

Cmem(n,m)=3n+4m .

Bacaan lebih lanjut

Lihat di bagian bawah jawaban saya yang lain .

Raphael
sumber
8

Analisis algoritma, seperti pembuktian teorema, sebagian besar adalah seni (misalnya ada program sederhana (seperti masalah Collatz ) yang tidak kita ketahui cara menganalisisnya). Kita dapat mengonversi masalah kompleksitas algoritme menjadi masalah matematis, seperti yang dijawab secara komprehensif oleh Raphael , tetapi kemudian untuk menyatakan batasan biaya algoritma dalam hal fungsi yang diketahui, kita harus:

  1. Gunakan teknik yang kita ketahui dari analisis yang ada, seperti menemukan batasan berdasarkan rekurensi yang kita pahami atau jumlah / integral yang dapat kita hitung.
  2. Ubah algoritme menjadi sesuatu yang kita tahu cara menganalisis.
  3. Datang dengan pendekatan yang sama sekali baru.
Ari Trachtenberg
sumber
1
Saya kira saya tidak melihat bagaimana ini menambahkan sesuatu yang berguna dan baru, melebihi dan di atas jawaban lainnya. Tekniknya sudah dijelaskan dalam jawaban lain. Bagi saya ini lebih mirip komentar daripada jawaban untuk pertanyaan.
DW
1
Saya berani menjawab bahwa jawaban lain membuktikan bahwa itu bukan seni. Anda mungkin tidak dapat melakukannya (yaitu matematika), dan beberapa kreativitas (seperti bagaimana menerapkan matematika yang diketahui) mungkin diperlukan bahkan jika Anda melakukannya, tetapi itu berlaku untuk tugas apa pun . Saya berasumsi kita tidak bercita-cita untuk membuat matematika baru di sini. (Faktanya, pertanyaan ini resp. Jawabannya dimaksudkan untuk menghilangkan seluruh proses.)
Raphael
4
@Raphael Ari berbicara tentang datang dengan fungsi yang dikenali sebagai terikat, bukan "jumlah instruksi yang dijalankan oleh program" (yang merupakan alamat jawaban Anda). Kasus umum adalah seni - tidak ada algoritma yang dapat muncul dengan batasan nontrivial untuk semua algoritma. Kasus umum, bagaimanapun, adalah seperangkat teknik yang dikenal (seperti teorema master).
Gilles
@Gilles Jika semua yang tidak ada algoritmenya adalah seni, pengrajin (khususnya programmer) akan dibayar lebih buruk.
Raphael
1
@AriTrachlenberg membuat poin penting, ada banyak cara untuk menilai kompleksitas waktu algoritma. Definisi notasi O Besar sendiri mengisyaratkan atau secara langsung menyatakan sifat teoritis mereka tergantung pada penulis. "Skenario terburuk" dengan jelas meninggalkan ruang terbuka untuk dugaan dan atau fakta baru di antara siapa pun yang memberi N orang di ruang diskusi. Belum lagi sifat perkiraan asimptotik menjadi sesuatu ... tidak eksak.
Brian Ogden