Terjemahan Bahasa Indonesia dari Buku Foundation of Algorithms by Richard Neapolitan
Diterjemahkan oleh : Eva Rahma Indriyani
NIM : 18102011
Institut Teknologi Telkom Purwokerto
Dokumen tersebut membahas struktur kondisi IF, IF-ELSE, dan Nested-IF beserta contoh penerapannya dalam algoritma dan flowchart. Dibahas pula cara kerja dan penulisan masing-masing struktur kondisi tersebut.
Dokumen tersebut membahas konsep dasar pemrograman seperti bahasa pemrograman, tipe data, variabel, konstanta, operator, dan komentar program. Beberapa bahasa pemrograman populer dijelaskan seperti Java, C, PHP, dan Python. Aturan penamaan variabel dan memilih tipe data pun diuraikan.
Struktur dasar algoritma terdiri atas struktur sekuensial (runtunan instruksi), struktur seleksi (pemilihan salah satu aksi), dan struktur repetisi (pengulangan instruksi). Ketiga struktur tersebut merupakan komponen penting dalam membangun logika penyelesaian masalah dalam algoritma.
Teks tersebut membahas tentang algoritma dan pemograman pseudo pascal untuk deret aritmatika. Teks tersebut menjelaskan pengertian algoritma, struktur perulangan dalam pascal seperti while-do, repeat-until, dan for-do. Teks tersebut juga memberikan contoh soal dan pembahasan mengenai penerapan struktur perulangan untuk menyelesaikan masalah deret aritmatika dan geometri.
Octave adalah perangkat lunak gratis yang bermanfaat untuk memecahkan masalah komputasi numerik yang berkaitan dengan vektor dan matriks. Panduan ini menjelaskan cara menginstalasi dan menjalankan Octave serta mengenalkan perintah dasar seperti operator aritmetika, variabel, tipe data, dan bantuan online.
Dokumen ini memberikan ringkasan tentang algoritma dan pemrograman, termasuk pengertian algoritma dan program, langkah-langkah membangun program, bentuk-bentuk algoritma seperti pseudo-code dan flowchart, serta contoh algoritma pertukaran nilai variabel.
Dokumen tersebut membahas struktur kondisi IF, IF-ELSE, dan Nested-IF beserta contoh penerapannya dalam algoritma dan flowchart. Dibahas pula cara kerja dan penulisan masing-masing struktur kondisi tersebut.
Dokumen tersebut membahas konsep dasar pemrograman seperti bahasa pemrograman, tipe data, variabel, konstanta, operator, dan komentar program. Beberapa bahasa pemrograman populer dijelaskan seperti Java, C, PHP, dan Python. Aturan penamaan variabel dan memilih tipe data pun diuraikan.
Struktur dasar algoritma terdiri atas struktur sekuensial (runtunan instruksi), struktur seleksi (pemilihan salah satu aksi), dan struktur repetisi (pengulangan instruksi). Ketiga struktur tersebut merupakan komponen penting dalam membangun logika penyelesaian masalah dalam algoritma.
Teks tersebut membahas tentang algoritma dan pemograman pseudo pascal untuk deret aritmatika. Teks tersebut menjelaskan pengertian algoritma, struktur perulangan dalam pascal seperti while-do, repeat-until, dan for-do. Teks tersebut juga memberikan contoh soal dan pembahasan mengenai penerapan struktur perulangan untuk menyelesaikan masalah deret aritmatika dan geometri.
Octave adalah perangkat lunak gratis yang bermanfaat untuk memecahkan masalah komputasi numerik yang berkaitan dengan vektor dan matriks. Panduan ini menjelaskan cara menginstalasi dan menjalankan Octave serta mengenalkan perintah dasar seperti operator aritmetika, variabel, tipe data, dan bantuan online.
Dokumen ini memberikan ringkasan tentang algoritma dan pemrograman, termasuk pengertian algoritma dan program, langkah-langkah membangun program, bentuk-bentuk algoritma seperti pseudo-code dan flowchart, serta contoh algoritma pertukaran nilai variabel.
1. Bab tujuh membahas operasi simbolik MATLAB yang digunakan untuk memanipulasi ekspresi matematika tanpa bilangan numerik.
2. Alat Symbolic Math Toolbox MATLAB digunakan untuk mengolah ekspresi simbolik seperti integrasi, diferensiasi, dan penyelesaian persamaan.
3. Objek dan ekspresi simbolik direpresentasikan dalam MATLAB untuk memungkinkan operasi matematika simbolik.
Dokumen tersebut membahas tentang algoritma dan pemrograman Matlab. Secara singkat, dokumen tersebut menjelaskan tentang konsep algoritma dan flowchart serta penggunaan kontrol program seperti if-else, for, dan while dalam pemrograman Matlab.
Tutorial ini membahas struktur pemilihan (if-then) dalam algoritma dan bahasa pemrograman Java. Terdapat penjelasan mengenai konsep dasar pemilihan, bentuk umum struktur if-then, contoh kasus pemilihan satu kondisi, dan implementasi pemilihan dalam bahasa Java.
Dokumen tersebut memberikan penjelasan singkat tentang struktur program Pascal dan tipe data yang digunakan dalam bahasa pemrograman Pascal. Terdapat penjelasan mengenai bagian-bagian struktur program, simbol-simbol diagram alur, dan berbagai tipe data standar dan terdefinisikan seperti integer, real, string, array, dan record.
Algoritma Pemrograman (Flowchart) - Logika dan AlgoritmaAri Septiawan
Program menghitung tarif taksi berdasarkan jarak tempuh dengan menentukan tarif km pertama sebesar Rp. 2500 dan tarif km selanjutnya sebesar Rp. 1800. Jika jarak kurang dari 1 km, tarif tetap Rp. 2500.
Dokumen tersebut membahas tentang variabel, tipe data, dan ekspresi dalam bahasa C++. Terdapat penjelasan mengenai berbagai tipe data seperti char, int, float, array, string, dan pointer serta penggunaannya. Juga dibahas mengenai operator aritmatika, relasional, logika, dan ekspresi conditional beserta contoh kodenya.
Fungsi dalam SQL memiliki berbagai kegunaan untuk memanipulasi dan menganalisis data. Terdapat tiga jenis fungsi utama yaitu fungsi perbandingan, fungsi aliran kontrol, dan fungsi pengubahan tipe data. Fungsi-fungsi tersebut dapat digunakan untuk membandingkan nilai, mengeksekusi logika kondisi, serta mengkonversi tipe data.
Dokumen ini membahas tentang Dev-C++ sebagai translator bahasa pemrograman C++ yang dapat berjalan di berbagai platform. Dijelaskan cara penulisan kode program menggunakan Dev-C++ dan proses kompilasi. Diberikan contoh kasus dan penyelesaian menggunakan algoritma dan pemrograman C++. Terdapat pula penjelasan mengenai operator increment, decrement, dan tabel ASCII.
Materi algoritma dan pemrograman insan unggul newasdammantap
Dokumen tersebut berisi informasi kontak dan penjelasan tentang mata kuliah Algoritma dan Pemrograman. Terdapat penjelasan tentang penilaian, pokok bahasan, referensi, tahapan pemrograman, penulisan algoritma, contoh soal, dan penjelasan tentang struktur pemrograman seperti input output, variabel, operator, pemilihan, dan perulangan.
1. Tes pendahuluan membahas tentang pseudecode, flowchart, dan algoritma untuk menyelesaikan masalah perhitungan nilai total dan pertukaran nilai variabel. 2. Materi membahas pengertian dasar logika dan algoritma serta unsur-unsurnya seperti variabel, pertukaran nilai, dan struktur algoritma seperti urut, cabang, dan pengulangan. 3. Diberikan contoh-contoh penggunaan struktur algoritma.
Dokumen ini membahas tentang algoritma dan flowchart. Terdapat penjelasan tentang definisi algoritma, contoh algoritma dalam kehidupan sehari-hari dan komputer, jenis proses algoritma, kriteria algoritma, serta penjelasan tentang flowchart dan pseudo code. Mahasiswa diberikan tugas kelompok untuk membuat algoritma dan flowchart dari beberapa permasalahan yang diberikan dan akan dipresentasikan hasilnya.
1. Dokumen ini membahas tentang dasar-dasar algoritma dan konsep-konsep pemrograman dasar seperti tipe data, variabel, operator, algoritma, pseudocode, dan flowchart.
2. Terdapat penjelasan mengenai definisi algoritma, konsep algoritma, struktur algoritma, berbagai tipe data yang digunakan dalam pemrograman, variabel, operator aritmatika dan perbandingan, serta penggunaan pseudocode dan flowchart dalam menyajikan algoritma.
3. Dokumen ini bertujuan
Modul 2 Variabel dan operasi dasar (1).pptxssuser4e88af1
Variabel dan operasi dasar dalam MATLAB digunakan untuk melakukan perhitungan matematika sederhana, menciptakan dan mengelola variabel, serta menggunakan fungsi matematika dasar seperti eksponensial, logaritma, dan trigonometri.
1. Bab tujuh membahas operasi simbolik MATLAB yang digunakan untuk memanipulasi ekspresi matematika tanpa bilangan numerik.
2. Alat Symbolic Math Toolbox MATLAB digunakan untuk mengolah ekspresi simbolik seperti integrasi, diferensiasi, dan penyelesaian persamaan.
3. Objek dan ekspresi simbolik direpresentasikan dalam MATLAB untuk memungkinkan operasi matematika simbolik.
Dokumen tersebut membahas tentang algoritma dan pemrograman Matlab. Secara singkat, dokumen tersebut menjelaskan tentang konsep algoritma dan flowchart serta penggunaan kontrol program seperti if-else, for, dan while dalam pemrograman Matlab.
Tutorial ini membahas struktur pemilihan (if-then) dalam algoritma dan bahasa pemrograman Java. Terdapat penjelasan mengenai konsep dasar pemilihan, bentuk umum struktur if-then, contoh kasus pemilihan satu kondisi, dan implementasi pemilihan dalam bahasa Java.
Dokumen tersebut memberikan penjelasan singkat tentang struktur program Pascal dan tipe data yang digunakan dalam bahasa pemrograman Pascal. Terdapat penjelasan mengenai bagian-bagian struktur program, simbol-simbol diagram alur, dan berbagai tipe data standar dan terdefinisikan seperti integer, real, string, array, dan record.
Algoritma Pemrograman (Flowchart) - Logika dan AlgoritmaAri Septiawan
Program menghitung tarif taksi berdasarkan jarak tempuh dengan menentukan tarif km pertama sebesar Rp. 2500 dan tarif km selanjutnya sebesar Rp. 1800. Jika jarak kurang dari 1 km, tarif tetap Rp. 2500.
Dokumen tersebut membahas tentang variabel, tipe data, dan ekspresi dalam bahasa C++. Terdapat penjelasan mengenai berbagai tipe data seperti char, int, float, array, string, dan pointer serta penggunaannya. Juga dibahas mengenai operator aritmatika, relasional, logika, dan ekspresi conditional beserta contoh kodenya.
Fungsi dalam SQL memiliki berbagai kegunaan untuk memanipulasi dan menganalisis data. Terdapat tiga jenis fungsi utama yaitu fungsi perbandingan, fungsi aliran kontrol, dan fungsi pengubahan tipe data. Fungsi-fungsi tersebut dapat digunakan untuk membandingkan nilai, mengeksekusi logika kondisi, serta mengkonversi tipe data.
Dokumen ini membahas tentang Dev-C++ sebagai translator bahasa pemrograman C++ yang dapat berjalan di berbagai platform. Dijelaskan cara penulisan kode program menggunakan Dev-C++ dan proses kompilasi. Diberikan contoh kasus dan penyelesaian menggunakan algoritma dan pemrograman C++. Terdapat pula penjelasan mengenai operator increment, decrement, dan tabel ASCII.
Materi algoritma dan pemrograman insan unggul newasdammantap
Dokumen tersebut berisi informasi kontak dan penjelasan tentang mata kuliah Algoritma dan Pemrograman. Terdapat penjelasan tentang penilaian, pokok bahasan, referensi, tahapan pemrograman, penulisan algoritma, contoh soal, dan penjelasan tentang struktur pemrograman seperti input output, variabel, operator, pemilihan, dan perulangan.
1. Tes pendahuluan membahas tentang pseudecode, flowchart, dan algoritma untuk menyelesaikan masalah perhitungan nilai total dan pertukaran nilai variabel. 2. Materi membahas pengertian dasar logika dan algoritma serta unsur-unsurnya seperti variabel, pertukaran nilai, dan struktur algoritma seperti urut, cabang, dan pengulangan. 3. Diberikan contoh-contoh penggunaan struktur algoritma.
Dokumen ini membahas tentang algoritma dan flowchart. Terdapat penjelasan tentang definisi algoritma, contoh algoritma dalam kehidupan sehari-hari dan komputer, jenis proses algoritma, kriteria algoritma, serta penjelasan tentang flowchart dan pseudo code. Mahasiswa diberikan tugas kelompok untuk membuat algoritma dan flowchart dari beberapa permasalahan yang diberikan dan akan dipresentasikan hasilnya.
1. Dokumen ini membahas tentang dasar-dasar algoritma dan konsep-konsep pemrograman dasar seperti tipe data, variabel, operator, algoritma, pseudocode, dan flowchart.
2. Terdapat penjelasan mengenai definisi algoritma, konsep algoritma, struktur algoritma, berbagai tipe data yang digunakan dalam pemrograman, variabel, operator aritmatika dan perbandingan, serta penggunaan pseudocode dan flowchart dalam menyajikan algoritma.
3. Dokumen ini bertujuan
Modul 2 Variabel dan operasi dasar (1).pptxssuser4e88af1
Variabel dan operasi dasar dalam MATLAB digunakan untuk melakukan perhitungan matematika sederhana, menciptakan dan mengelola variabel, serta menggunakan fungsi matematika dasar seperti eksponensial, logaritma, dan trigonometri.
Dokumen tersebut membahas tentang lisensi dokumen IlmuKomputer.com yang memungkinkan penggunaan, modifikasi, dan penyebaran dokumen tersebut untuk tujuan non-komersial dengan syarat tidak menghapus atau merubah atribut penulis dan pernyataan hak cipta. Dokumen tersebut juga berisi contoh-contoh algoritma pemrograman menggunakan C++ seperti mencari nilai terbesar dari 3 bilangan, jumlah deret
Mata kuliah Logika dan Pemrograman membahas konsep dasar pemrograman seperti algoritma, struktur data, tipe data, operator, pemilihan, dan pengulangan. Mahasiswa diajak membuat algoritma penyelesaian masalah dan mengimplementasikannya dalam bahasa pemrograman tertentu. Program komputer adalah rangkaian perintah yang dimengerti komputer untuk menyelesaikan masalah secara logis berdasarkan bahasa pemrograman. Algoritma dan pseudocode
Dokumen tersebut membahas tentang metode numerik sebagai algoritma komputasi untuk menyelesaikan masalah matematika yang sulit diselesaikan secara analitis. Metode numerik menggunakan pendekatan iteratif untuk memperoleh hasil yang mendekati nilai sebenarnya. Dokumen ini juga membahas bilangan bulat, pecahan, akurasi, presisi, dan jenis kesalahan dalam metode numerik."
Dokumen tersebut membahas tentang penggunaan array untuk menyimpan data di memori. Array adalah variabel yang dapat menyimpan kumpulan data dengan tipe yang sama menggunakan indeks. Dokumen menjelaskan tentang deklarasi, akses, dan alokasi memori untuk array baik secara statis maupun dinamis.
Dokumen ini membahas tentang tipe data array dalam bahasa pemrograman Pascal. Terdiri dari pengertian tipe data array, cara penggunaannya untuk array satu dimensi dan dua dimensi beserta contoh kode programnya. Tipe data array digunakan untuk menyimpan kumpulan data yang sama tipe dalam satu variabel secara efisien. Array dapat diakses menggunakan indeks dan dapat berisi satu atau dua dimensi tergantung kebutuhan
Dokumen tersebut membahas tentang pengertian algoritma dan contoh-contohnya, serta simbol-simbol yang digunakan dalam membuat flowchart program. Juga dibahas tentang struktur bahasa pemrograman Pascal seperti deklarasi variabel, input output, operator, dan contoh-contoh soal algoritma sederhana.
Dokumen tersebut merupakan rencana perkuliahan mata kuliah Algoritma dan Pemrograman yang mencakup pengertian algoritma, bahasa pemrograman, struktur dasar algoritma, notasi algoritma, dan elemen-elemen dasar bahasa C++ seperti tipe data, variabel, dan operator."
Dokumen ini membahas tentang variabel dan tipe data dasar dalam bahasa pemrograman Pascal. Terdapat penjelasan mengenai konsep variabel, deklarasi variabel, assignment nilai ke variabel, representasi tipe data di dalam komputer, konstanta, input dan output variabel bertipe dasar seperti integer, serta operasi yang dapat dilakukan terhadap tipe data integer.
Makalah Pengaruh ponsel terhadap kesehatan dan psikologisevarahma70
Teks tersebut membahas tentang pengaruh penggunaan ponsel yang berkepanjangan terhadap kesehatan fisik dan psikologis. Secara garis besar dijelaskan bahwa penggunaan berlebihan ponsel dapat menyebabkan gangguan pada mata, postur tubuh, kesuburan, gangguan tidur, dan bahkan berpotensi meningkatkan risiko terkena kanker. Sementara itu, dampak psikologisnya meliputi menurunnya konsentrasi,
Gagasan ini mengusulkan digitalisasi karangan ilmiah mahasiswa dengan cara mengunggahnya ke website resmi institusi. Hal ini dimaksudkan untuk mengurangi penggunaan kertas secara besar-besaran yang tidak ramah lingkungan serta mempermudah proses revisi tanpa harus bertemu langsung dengan dosen pembimbing.
Disusun oleh :
Eva Rahma Indriyani
Faradhila Firdhausi
Iqbal Rafi' Atallah
Natasya Dewiyanti
Naufal FAiruz Iqbal
Rafly Taufiqa Fikri
Tahun : 2017
SMA 2 KUDUS
Kimia Unsur "ALKALI" (Kegunaan,Kelimpahan,dan proses pembuatan)evarahma70
Dokumen ini membahas sifat-sifat dan kegunaan logam golongan alkali seperti litium, natrium, dan kalium. Logam-logam ini bereaksi dengan air dan oksigen untuk membentuk basa dan oksida. Natrium digunakan dalam industri sabun dan kaca, sementara kalium digunakan sebagai pupuk dan bahan peledak. Litium, natrium, dan kalium diproduksi melalui proses elektrolisis garam-garam mereka.
Penyimpangan fenotipe yang tidak sesuai dengan hukum Mendel dapat terjadi karena interaksi antar alel dan interaksi genetik seperti kodominan, dominansi tidak sempurna, alel ganda, alel letal, atavisme, epistasis, polimeri, kriptomeri dan komplementer.
Usus terdiri dari usus besar dan usus halus. Usus besar menyerap air dan vitamin, melindungi dari infeksi, dan mengeluarkan kotoran. Usus halus terdiri dari duodenum, jejunum, dan ileum, yang mencerna makanan secara kimiawi dan menyerap hasil pencernaan ke darah.
Sistem dan struktur politik ekonomi indonesia masa reformasievarahma70
Dokumen tersebut membahas sistem dan struktur politik-ekonomi Indonesia masa reformasi, mulai dari tuntutan reformasi pada masa Orde Baru hingga pemerintahan Presiden Susilo Bambang Yudhoyono. Mencakup perjalanan reformasi ekonomi, politik, hukum, dan berbagai upaya penyelesaian konflik di tanah air.
Dokumen tersebut membahas tentang kepedulian umat Islam terhadap jenazah, mulai dari perawatan jenazah (memandikan, mengafani, menyalati), sampai dengan menguburkan jenazah. Dokumen juga membahas tentang ta'ziyyah (melayat) dan ziarah kubur.
Laporan Pembina Pramuka SD dalam format doc dapat anda jadikan sebagai rujukan dalam membuat laporan. silakan download di sini https://unduhperangkatku.com/contoh-laporan-kegiatan-pramuka-format-word/
Materi ini membahas tentang defenisi dan Usia Anak di Indonesia serta hubungannya dengan risiko terpapar kekerasan. Dalam modul ini, akan diuraikan berbagai bentuk kekerasan yang dapat dialami anak-anak, seperti kekerasan fisik, emosional, seksual, dan penelantaran.
Modul Ajar Matematika Kelas 11 Fase F Kurikulum MerdekaFathan Emran
Modul Ajar Matematika Kelas 11 SMA/MA Fase F Kurikulum Merdeka - abdiera.com. Modul Ajar Matematika Kelas 11 SMA/MA Fase F Kurikulum Merdeka. Modul Ajar Matematika Kelas 11 SMA/MA Fase F Kurikulum Merdeka. Modul Ajar Matematika Kelas 11 SMA/MA Fase F Kurikulum Merdeka. Modul Ajar Matematika Kelas 11 SMA/MA Fase F Kurikulum Merdeka.
Modul Ajar Bahasa Indonesia Kelas 7 Fase D Kurikulum Merdeka - [abdiera.com]Fathan Emran
Modul Ajar Bahasa Indonesia Kelas 7 SMP/MTs Fase D Kurikulum Merdeka - abdiera.com. Modul Ajar Bahasa Indonesia Kelas 7 SMP/MTs Fase D Kurikulum Merdeka. Modul Ajar Bahasa Indonesia Kelas 7 SMP/MTs Fase D Kurikulum Merdeka. Modul Ajar Bahasa Indonesia Kelas 7 SMP/MTs Fase D Kurikulum Merdeka. Modul Ajar Bahasa Indonesia Kelas 7 SMP/MTs Fase D Kurikulum Merdeka. Modul Ajar Bahasa Indonesia Kelas 7 SMP/MTs Fase D Kurikulum Merdeka.
Ppt landasan pendidikan Pai 9 _20240604_231000_0000.pdffadlurrahman260903
Ppt landasan pendidikan tentang pendidikan seumur hidup.
Prodi pendidikan agama Islam
Fakultas tarbiyah dan ilmu keguruan
Universitas Islam negeri syekh Ali Hasan Ahmad addary Padangsidimpuan
Pendidikan sepanjang hayat atau pendidikan seumur hidup adalah sebuah system konsepkonsep pendidikan yang menerangkan keseluruhan peristiwa-peristiwa kegiatan belajarmengajar yang berlangsung dalam keseluruhan kehidupan manusia. Pendidikan sepanjang
hayat memandang jauh ke depan, berusaha untuk menghasilkan manusia dan masyarakat yang
baru, merupakan suatu proyek masyarakat yang sangat besar. Pendidikan sepanjang hayat
merupakan asas pendidikan yang cocok bagi orang-orang yang hidup dalam dunia
transformasi dan informasi, yaitu masyarakat modern. Manusia harus lebih bisa menyesuaikan
dirinya secara terus menerus dengan situasi yang baru.
Modul Ajar Bahasa Inggris Kelas 10 Fase E Kurikulum MerdekaFathan Emran
Modul Ajar Bahasa Inggris Kelas 10 SMA/MA Fase E Kurikulum Merdeka - abdiera.com. Modul Ajar Bahasa Inggris Kelas 10 SMA/MA Fase E Kurikulum Merdeka. Modul Ajar Bahasa Inggris Kelas 10 SMA/MA Fase E Kurikulum Merdeka.
Terjemahan bahasa indonesia (foundation of algorithm by richard neapolitan)
1. Bab 1
Efisiensi, Analisis, dan Urutan Algoritma
Teks ini mengenai teknik untuk memecahkan masalah menggunakan
komputer. Dengan "teknik" kita tidak bermaksud gaya pemrograman atau bahasa
pemrograman melainkan pendekatan atau metodologi yang digunakan untuk
memecahkan masalah. Intinya di sini adalah kita memiliki dua pendekatan
berbeda untuk memecahkan masalah,dan pendekatan tidak ada hubungannya
dengan bahasa atau gaya pemrograman. Program komputer hanyalah satu cara
untuk menerapkan pendekatan ini.
Bab 2 hingga 6 membahas berbagai teknik pemecahan masalah dan
menerapkan teknik-teknik tersebut ke berbagai permasalahan. Menerapkan teknik
ke masalah menghasilkan prosedur selangkah demi selangkah untuk
menyelesaikan masalah. Prosedur Langkah demi langkah ini disebut algoritma
untuk masalah. Tujuan mempelajari teknik-teknik ini dan pengaplikasianya adalah
,agar ketika dihadapkan dengan masalah baru, Kita memiliki teknik pengulangan
untuk dipertimbangkan sebagai cara yang mungkin untuk memecahkan
masalah.Karena itu,tidak hanya fokus dengan menentukan apakah suatu masalah
dapat diselesaikan dengan menggunakan teknik yang diberikan tetapi juga dengan
menganalisis seberapa efisien algoritma yang dihasilkan dalam hal waktu dan
penyimpanan. Ketika algoritma diimplementasikan pada komputer, waktu berarti
siklus CPU dan penyimpanan berarti memori.Dalam bab ini, kita membahas
beberapa konsep dasar yang diperlukan untuk materi di seluruh teks. Kami
menunjukkan mengapa efisiensi selalu menjadi pertimbangan, terlepas dari
seberapa cepat komputer dan seberapa murahnya memori.
1.1 Algoritma
Program komputer terdiri dari modul yang dapat dimengerti oleh
komputer dan memecahkan tugas-tugas tertentu. Maksud teks ini bukanlah desain
seluruh program, melainkan desain individu modul yang menyelesaikan tugas-
tugas tertentu. Tugas-tugas khusus ini disebut masalah. Masalah adalah
pertanyaan yang kita cari jawabannya. Contoh masalah dibawah ini.
Contoh 1.1
Berikut ini adalah contoh masalah:
Urutkan daftar S dari n angka dalam urutan yang tidak lagi diminimalkan.
Jawabannya adalah angka-angka dalam urutan yang diurutkan.
Daftar yang di maksud adalah kumpulan item yang diatur dalam urutan tertentu.
contoh,
S = [10,7,11,13,8]
Daftar ini untuk disortir dalam "order nondecreasing" bukannya meningkatkan
pesanan untuk memungkinkan kemungkinan bahwa nomor yang sama dapat
muncul lebih dari satu kali dalam daftar.
2. Contoh 1.2
Berikut ini adalah contoh masalah:
Tentukan apakah angka x ada dalam daftar S dari n angka. Jawabannya
adalah ya jika x dalam S dan tidak jika tidak.
Masalah mungkin berisi variabel yang tidak diberi nilai spesifik dalam
pernyataan masalah. Ini variabel disebut parameter untuk masalah.
Dalam Contoh 1.1 ada dua parameter: S (daftar) dan n (jumlah item dalam S).
Dalam Contoh 1.2 ada tiga parameter: S, n, dan nomor x. Itu tidak perlu di sini
dua contoh untuk membuat n salah satu parameter karena nilainya ditentukan
secara unik oleh S. Namun, membuat parameter n memfasilitasi deskripsi
masalah .
Karena masalah mengandung parameter, yang mewakili kelas masalah, satu
untuk setiap penugasan nilai ke parameter. Setiap penugasan spesifik nilai ke
parameter disebut turunan dari masalah.
Contoh 1.3
Contoh masalah dalam Contoh 1.1 adalah
S = [10,7,11,5,13,8] dan n = 6
Solusi untuk hal ini adalah [5, 7, 8, 10, 11, 13]
Contoh 1.4
Contoh masalah dalam Contoh 1.2 adalah
S = [10,7,11,13,8], n = 6 dan x = 5
Solusi untuk contoh ini adalah, "ya, x ada di S."
Kita dapat menemukan solusi untuk contoh di Contoh 1.3 dengan
memeriksa S dan memungkinkan untuk menghasilkan urutan yang diurutkan
berdasarkan langkah-langkah kognitif yang tidak dapat dijelaskan secara spesifik.
Namun, jika contoh diatas memiliki nilai 1.000 untuk n, seseorang tidak akan
bisa menggunakan metode ini. Untuk menghasilkan program komputer yang
dapat menyelesaikan semua contoh masalah, kita harus menentukan prosedur
langkah-demi-langkah umum untuk menghasilkan solusi untuk setiap contoh.
Langkah demi langkah ini prosedur disebut algoritma.
Contoh 1.5
Suatu algoritma untuk masalah dalam Contoh 1.2 adalah sebagai berikut. Dimulai
dengan item pertama di S, bandingkan x dengan masing-masing item dalam S
secara berurutan hingga x ditemukan atau sampai S habis. Jika x ditemukan,
jawab ya; jika x tidak ditemukan, jawab tidak.
Kita dapat mengkomunikasikan algoritma dalam bahasa Inggris, Namun,
ada dua kelemahan untuk menulis algoritma dengan cara ini. Pertama, sulit untuk
menulis algoritma yang rumit dengan cara ini, jika kita melakukannya, seseorang
akan kesulitan memahami algoritmanya. Kedua, tidak jelas bagaimana cara
3. membuat deskripsi bahasa komputer dari suatu algoritma kedalam deskripsi
bahasa Inggris itu.
Algoritma berikut mewakili daftar S dengan sebuah array, dan bukan
hanya mengembalikan ya atau tidak,namun juga mengembalikan lokasi x dalam
larik jika x dalam S dan mengembalikan 0 sebaliknya. Algoritma pencarian
khusus ini tidak mengharuskan itu
item berasal dari kumpulan yang telah ditentukan, tetapi kami masih
menggunakan jenis kunci tipe data standar .
Algoritma 1.1
Pencarian Berurutan
Masalah: Apakah kunci x dalam susunan S tombol n?
Input (parameter): bilangan bulat positif n, susunan kunci S yang diindeks dari 1
menjadi n, dan kunci x.
Output: lokasi, lokasi x dalam S (0 jika x tidak dalam S).
4. void seqsearch ( int n,
const keytype S [ ]) ‘
keytype x,
index& location )
{
location = 1;
while ( location <= n && [location ] != x)
location++
if ( location > n)
location = 0;
}
Pseudocode nya serupa, tetapi tidak sama dengan C ++. Pengecualian
penting adalah penggunaan array. C ++ memungkinkan array untuk di indeks
hanya dengan bilangan bulat mulai dari 0. Seringkali kita dapat menjelaskan
algoritma nya dengan lebih jelas menggunakan array yang diindeks oleh rentang
bilangan bulat lainnya, dan terkadang kita dapat menjelaskannya dengan baik
menggunakan indeks yang bukan bilangan bulat sama sekali. Jadi dalam
pseudocode kami mengizinkan set acak untuk mengindeks array. Algoritma
khusus ini dapat diimplementasikan secara langsung di C + + dengan
mendeklarasikan
keytype S[ n + 1 ];
dan tidak menggunakan slot S [0]. Pada akhirnya,kita tidak akan membahas
penerapan algoritme pada khususnya bahasa pemrograman. Tujuan kami
hanyalah menyajikan algoritme dengan jelas sehingga mereka dapat dipahami
dengan mudah dan dianalisis.
Ada dua penyimpangan signifikan lainnya dari C ++ mengenai array
dalam pseudocode. Pertama, panjang variabel dengan array dua dimensi sebagai
parameter untuk rutinitas. Kedua, kami mendeklarasikan array variabel-panjang
lokal. Sebagai contoh, jika n adalah parameter untuk contoh prosedur, dan kita
memerlukan lokal array diindeks dari 2 ke n, kami menyatakan
void contoh (int n)
{
keytype S [2.....n];
.
.
}
Notasi S [2...n ] berarti larik array yang diindeks dari 2 ke n secara ketat
pseudocode; artinya, itu bukan bagian dari bahasa C ++ .
Setiap kali kita dapat menunjukkan langkah-langkah lebih ringkas dan
jelas menggunakan ekspresi matematika atau deskripsi menyerupai bahasa
Inggris yang kita bisa gunakan instruksi C ++ yang sebenarnya. Misalnya, anggap
beberapa instruksi dieksekusi hanya jika variabel x adalah antara nilai-nilai
rendah dan tinggi. Kami menulis
5. if (low ≤ x ≤ high ) { if (low <= x && x <=
high ) {
: :
: daripada :
} }
Misalkan kita menginginkan variabel x untuk mengambil nilai dari variabel y dan
y untuk mengambil nilai x. Kami menulis
Exchange x and y temp = x;
daripada x = y;
y = temp ;
Selain tipe keytype,kami sering menggunakan yang berikut ini, yang juga bukan
tipe data C++ yang ditentukan sebelumnya:
Tipe data Arti
Index Variabel integer digunakan sebagai indeks
Nomor variable yang dapat didefinisikan sebagai integral (int) atau rill
(float)
Boolean variabel yang dapat mengambil nilai "true" atau "false"
Kami menggunakan nomor tipe data ketika tidak penting bagi algoritme apakah
bilangan dapat mengambil nyata nilai atau terbatas pada bilangan bulat.
Terkadang kami menggunakan struktur kontrol tidak standar berikut:
repeat (n times) {
.
.
.
}
Ini berarti mengulangi kode n kali. Dalam C ++ perlu untuk memperkenalkan
variabel kontrol yang asing dan menulis untuk loop. Kami hanya menggunakan
for loop ketika kami benar-benar perlu merujuk ke variabel kontrol dalam loop.
Secara umum, kami menghindari fitur khusus untuk C ++ sehingga
pseudocode dapat diakses oleh seseorang yang hanya tahu bahasa tingkat tinggi
lainnya. Namun, kami menulis instruksi seperti i ++, yang berarti kenaikan i
sebesar 1.
Jika Anda tidak tahu C ++, Anda dapat menemukan notasi yang digunakan
untuk operator logika dan operator relasional tertentu tidak dikenal. Notasi ini
adalah sebagai berikut:
Operator Simbol C++
And &&
Or ||
Not !
6. Algoritma 1.2
Tambahkan Anggota Array
Masalah: Tambahkan semua angka dalam larik S dari n angka.
Input: bilangan bulat positif n, larik angka S yang diindeks dari 1 menjadi n.
Output: jumlah, jumlah angka dalam S.
Kami membahas banyak algoritma penyortiran dalam teks ini. Yang sederhana
mengikuti
Algoritma 1.3
Sortir Exchange
Masalah: Urutkan n kunci dalam urutan yang tidak menentu.
Masukan: bilangan bulat positif n, susunan kunci S yang diindeks dari 1 menjadi
n.
Keluaran: larik S yang berisi kunci dalam urutan yang nondecreasing
Intruksi
tukarkan S [i] dan S [j];
berarti bahwa S [i] mengambil nilai S [j], dan S [j] adalah mengambil nilai S [i].
Perintah ini tidak terlihat seperti instruksi C++; kapanpun kita bisa menyatakan
sesuatu lebih sederhana dengan tidak menggunakan rincian instruksi C ++ yang
kita lakukan begitu. Exchange Sort bekerja dengan membandingkan nomor di
slot i dengan nomor dalam (i + 1) melalui slot n.
Setiap kali nomor di slot yang diberikan ditemukan lebih keci lslot i ke-n, dua
angka tersebut ditukar. Dengan cara ini, angka terkecil berakhir di slot pertama
setelah yang pertama melewati loop for-i, the angka terkecil kedua berakhir di
slot kedua setelah lulus kedua, dan seterusnya. Algoritma selanjutnya melakukan
perkalian matriks. Ingat bahwa jika kita memiliki dua matriks 2 × 2,
Perbandingan Kode C++
x=y (x==y)
x≠y (x!=y)
(x ≤ y) (x<=y)
(x ≥ y) (x >= y)
7. dan
produk mereka C = A X B diberikan oleh
Sebagai contoh ;
Secara umum, jika kita memiliki dua n x n matriks A dan B, produk C mereka
diberikan oleh
Langsung dari definisi ini, kita memperoleh algoritma berikut untuk perkalian
matriks.
Algoritma 1.4
Multiplikasi Matriks
Masalah: Tentukan produk dari dua matriks n x n.
Input : bilangan bulat positif n, array dua dimensi bilangan A dan B, yang
masing-masing memiliki baris dan kolom diindeks dari 1 menjadi n.
Output: array dua dimensi dari angka C, yang memiliki baris dan kolom diindeks
dari 1 menjadi n, mengandung produk A dan B.
1.2 Pentingnya Mengembangkan Algoritma Yang Efisien
Sebelumnya kami menyebutkan bahwa, terlepas dari seberapa cepat komputer
menjadi atau seberapa murah memori, efisiensi akan selalu tetap menjadi
pertimbangan penting. Selanjutnya kami menunjukkan mengapa demikian
dengan membandingkan dua algoritma untuk masalah yang sama.
1.2.1 Pencarian Sequence (Berurutan) Versus Pencarian Biner
Membandingkan algoritma untuk dua pendekatan untuk menunjukkan caranya
jauh lebih cepat pencarian biner.
8. Kami telah menulis algoritma yang melakukan pencarian sekuensial -
yaitu, Algoritma 1.1.
Artinya, mengingat bahwa kita mencari x, algoritma pertama membandingkan x
dengan item tengah larik. Jika mereka sama, algoritma ini dilakukan. Jika x lebih
kecil dari item tengah, maka x harus di paruh pertama array (jika ada), dan
algoritma mengulangi prosedur pencarian pada paruh pertama dari array. Jika x
lebih besar dari item tengah dari array, pencarian diulang pada paruh kedua dari
array.
Algoritma 1.5
Pencarian Biner
Masalah: Tentukan apakah x dalam susunan S terurut dari kunci n.
Input: bilangan bulat positif n, susunan urutan yang diurutkan (nondecreasing
order) S diindeks dari 1 menjadi n, sebuah kunci x.
Output: lokasi, lokasi x dalam S (0 jika x tidak dalam S).
Mari kita bandingkan pekerjaan yang dilakukan oleh Pencarian Berurutan
dan Pencarian Biner. Untuk fokus, kami akan menentukan jumlah perbandingan
dilakukan oleh masing-masing algoritma. Jika array S berisi 32 item,dan x tidak
dalam array, Algoritma 1.1
(Pencarian Berurutan) membandingkan x dengan semua 32 item sebelum
menentukan bahwa x tidak dalam larik. Secara umum, Berurutan Pencarian
melakukan perbandingan n untuk menentukan bahwa x tidak dalam larik dengan
ukuran n.
Misalkan kita menggandakan ukuran array sehingga mengandung 64 item.
Pencarian Biner hanya melakukan satu perbandingan lebih banyak karena
perbandingan pertama memotong array menjadi setengah, menghasilkan
subrangkaian ukuran 32 yang dicari. Oleh karena itu, ketika x lebih besar dari
semua item dalam larik ukuran 64, Binary Search melakukan tujuh perbandingan.
Melihat bahwa 7 = lg 64 + 1. Secara umum, setiap kali kita menggandakan
ukuran array, kita hanya menambahkan satu perbandingan. Karena itu, jika n
adalah kekuatan 2 dan x lebih besar dari semua item dalam array ukuran n,
jumlah perbandingan yang dilakukan oleh Pencarian Biner adalah lg n +1.
9. Tabel 1.1 Membandingkan jumlah perbandingan yang dilakukan oleh
Pencarian Berurutan dan Pencarian Biner untuk berbagai nilai dari n, ketika x
lebih besar dari semua item dalam array. Ketika array berisi sekitar 4 milyar item
(sekitar jumlah orang di dunia), Binary Search hanya melakukan 33
perbandingan, sedangkan Sequential Search membandingkan x dengan semua 4
milyar item. Bahkan jika komputer itu mampu menyelesaikan satu melewati loop
sementara dalam nanosecond (satu per satu milyar detik), Pencarian Berurutan
akan memakan waktu 4 detik untuk menentukan bahwa x tidak ada dalam array,
sedangkan Pencarian Biner akan membuat tekad itu hampir secara instan.
Gambar 1.1 Item array yang Cari Binary membandingkan dengan x ketika x lebih besar dari
semua item dalam array ukuran 32. Item diberi nomor sesuai ke urutan di mana mereka
dibandingkan.
Tabel 1.1 Jumlah perbandingan yang dilakukan oleh Pencarian Berurutan dan Pencarian
Biner ketika x lebih besar dari semua item array
Ukuran Array Jumlah Perbandingan oleh Jumlah
Perbandingan oleh
Pencarian Berurutan Pencarian
Binary
Pencarian Berurutan masih mendapatkan pekerjaan yang dilakukan dalam
jumlah waktu dapat ditoleransi untuk rentang kehidupan manusia. Selanjutnya
kita akan melihat algoritma inferior yang tidak menyelesaikan pekerjaan dalam
jumlah waktu yang lumayan.
1.2.2 Urutan Fibonacci
Algoritma yang dibahas di sini menghitung istilah nth dari deret Fibonacci, yang
didefinisikan secara rekursif sebagai mengikuti
Menghitung beberapa istilah pertama, kami punya
10. Ada berbagai aplikasi dari deret Fibonacci dalam ilmu komputer dan matematika.
Karena
Urutan fibonacci didefinisikan secara rekursif, kami memperoleh algoritma
rekursif berikut dari definisi.
Algoritma 1.6
nth Fibonacci Term (Rekursif)
Masalah: Tentukan istilah ke-n dalam urutan Fibonacci.
Input: bilangan bulat nonnegatif n.
Output: fib, istilah n dari deret Fibonacci
"Bilangan bulat non-negatif" yang dimaksud yaitu integer yang lebih besar dari
atau sama dengan 0, sedangkan dengan "bilangan bulat positif" berarti integer
yang lebih besar dari 0. Kami menetapkan input ke algoritma dengan cara ini
untuk membuatnya jelas nilai-nilai apa yang bisa diambil oleh masukan.
Enam nilai pertama dapat diperoleh dengan menghitung simpul dalam sub pohon
yang berakar pada fib (n) untuk 1 ≤ n ≤ 5, sedangkan jumlah istilah untuk fib (6)
adalah jumlah dari simpul di pohon yang berakar pada fib (5) dan fib (4)
ditambah satu node pada akar. Angka-angka ini tidak menunjukkan ekspresi
sederhana seperti yang diperoleh untuk Pencarian Biner. Perhatikan,
bagaimanapun,dalam kasus tujuh nilai pertama, jumlah istilah dalam pohon lebih
dari dua kali lipat setiap kali n meningkat 2. Misalnya, ada sembilan istilah dalam
pohon ketika n = 4 dan 25 istilah ketika n = 6. Kita panggil T (n) jumlah istilah
dalam pohon rekursi untuk n. Jika jumlah suku lebih dari dua kali lipat setiap kali
n meningkat 2, kita akan memiliki yang berikut untuk n genap:
Gambar 1.2 Pohon rekursi yang sesuai dengan Algoritma 1.6 saat menghitung suku Fibonacci
kelima.
11. Jika T (n) adalah jumlah istilah dalam pohon rekursi yang sesuai dengan
Algoritma 1.6, maka, untuk n ≥ 2,
Buktinya: Buktinya dengan induksi pada n.
Induksi basis: Kami membutuhkan dua kasus dasar karena langkah induksi
mengasumsikan hasil dari dua kasus sebelumnya. Untuk n = 2 dan n = 3, rekursi
pada Gambar 1.2 menunjukkan bahwa
Hipotesis induksi: Salah satu cara untuk membuat hipotesis induksi adalah
dengan berasumsi bahwa pernyataan itu benar untuk semua m < n.
Kemudian, dalam langkah induksi, tunjukkan bahwa ini menyiratkan bahwa
pernyataan harus benar untuk n. Teknik tersebut digunakan dalam bukti ini.
Misalkan untuk semua m seperti 2 ≤ m <n
Langkah induksi: Kami harus menunjukkan bahwa T (n)> 2n/2. Nilai T (n) adalah
jumlah
T (n - 1) dan T (n - 2) ditambah satu simpul pada akarnya. Karena itu,
Kami menetapkan bahwa jumlah istilah yang dihitung oleh Algoritma 1.6 untuk
menentukan istilah Fibonacci n adalah lebih besar dari 2n / 2. Kami akan kembali
ke hasil ini untuk menunjukkan betapa tidak efisiennya algoritma ini. Tapi
pertama-tama mari kita mengembangkan algoritma yang efisien untuk
menghitung istilah Fibonacci n. Ingat bahwa masalah dengan algoritma rekursif
12. adalah itu nilai yang sama dihitung berulang kali. Algoritma iteratif berikut
menggunakan strategi ini.
Algoritma 1.7
nth Fibonacci Term (Iterative)
Masalah: Tentukan istilah ke-n dalam urutan Fibonacci.
Input : bilangan bulat nonnegatif n.
Output: fib2, istilah ke-n dalam deret Fibonacci.
Algoritma 1.7 dapat ditulis tanpa menggunakan array f karena hanya dua
istilah paling baru yang diperlukan di masing-masing iterasi dari loop. Namun,
lebih jelas diilustrasikan menggunakan array.
Tabel 1.2 Perbandingan Algoritma 1.6 dan 1.7
Algoritma 1.6 adalah algoritma divide-and-conquer. Kami menunjukkan bahwa
Algoritma 1.6 menghitung setidaknya sejumlah besar istilah, tetapi apakah bisa
juga lebih buruk? Jawabannya adalah tidak. Dengan menggunakan teknik dalam
Lampiran B, memungkinkan untuk mendapatkan formula yang tepat untuk
jumlah istilah, dan rumusnya eksponensial dalam n. Lihat Contoh B.5 dan B.9
dalam Lampiran B untuk lebih lanjut diskusi tentang deret Fibonacci.
1.3 Analisis Algoritma
Untuk menentukan seberapa efisien suatu algoritma menyelesaikan masalah, kita
perlu menganalisis algoritma. Kami memperkenalkan analisis efisiensi algoritma
ketika kami membandingkan algoritma di bagian sebelumnya.
1.3.1 Analisis Kompleksitas
13. Terkadang kita harus berhati-hati untuk memanggil parameter sebagai ukuran
masukan. Misalnya, dalam Algoritma 1.6 (nth Istilah Fibonacci, Rekursif) dan
1.7 (nth Fibonacci Term, Iterative), Anda mungkin berpikir bahwa n harus
disebut input ukuran. Namun, n adalah inputnya; bukan ukuran inputnya. Untuk
algoritma ini, ukuran yang wajar dari ukuran input adalah jumlah simbol yang
digunakan untuk mengkodekan n. Jika kita menggunakan representasi biner,
ukuran input akan menjadi nomor bit yang dibutuhkan untuk mengkodekan n,
yang merupakan lg n + 1. Sebagai contoh:
Oleh karena itu, ukuran input n = 13 adalah 4. Kami memperoleh wawasan ke
dalam efisiensi relatif dari dua algoritma dengan menentukan jumlah istilah yang
dihitung masing-masing sebagai fungsi dari n, tetapi masih n tidak mengukur
ukuran input.Pertimbangan ini akan menjadi penting dalam Bab 9, di mana kita
akan membahas ukuran input lebih rinci. Sampai saat itu,biasanya akan cukup
menggunakan ukuran sederhana, seperti jumlah item dalam larik/array, sebagai
ukuran masukan.
Secara umum, analisis kompleksitas waktu dari suatu algoritma adalah
penentuan berapa kali operasi dasar dilakukan untuk setiap nilai ukuran input.
Meskipun kami tidak ingin mempertimbangkan rincian tentang bagaimana suatu
algoritma diimplementasikan, kami biasanya akan menganggap bahwa operasi
dasar diimplementasikan seefisien mungkin.
. Dengan cara ini, kami menganalisis implementasi operasi dasar yang paling
efisien.
Analisis Algoritma 1.2
Kompleksitas Every-Case Time (Tambah Anggota Array)
Selain instruksi kontrol, satu-satunya instruksi dalam loop adalah yang
menambahkan item dalam array untuk dijumlahkan. Oleh karena itu, kita akan
memanggil instruksi itu sebagai operasi dasar.
Operasi dasar: penambahan item dalam array untuk dijumlahkan. Ukuran
masukan: n, jumlah item dalam larik.
Terlepas dari nilai-nilai angka dalam array, ada n melewati loop for. Karena itu,
dasar
operasi selalu dilakukan n kali
Analisis Algoritma 1.3
Every-Case Time CompIexity (Exchange Sort)
Seperti yang disebutkan sebelumnya, dalam kasus algoritma yang mengurutkan
dengan membandingkan kunci, kita dapat mempertimbangkan perbandingannya
instruksi atau instruksi penugasan sebagai operasi dasar. Kami akan menganalisis
jumlah perbandingan di sini.
Operasi dasar: perbandingan S [j] dengan S [i].
Ukuran masukan: n, jumlah item yang akan disortir.
14. Kita harus menentukan berapa banyak melewati loop untuk-j. Untuk n
yang diberikan selalu ada n - 1 lewatan melalui loop-i. Dalam melewati pertama
melalui loop for-i, ada n - 1 melewati loop for-j, di pass kedua ada n - 2 melewati
loop for-j, pada lewatan ketiga ada n − 3 melewati loop j, «, dan pada lewatan
terakhir ada satu pass melalui for-j loop. Oleh karena itu, jumlah total melewati
loop for-j diberikan oleh
Kesetaraan terakhir diturunkan dalam Contoh A.1 di Lampiran A.
Analisis Algoritma 1.4
Every-Case Time CompIexity (Matrix Multiplication)
Satu-satunya instruksi dalam lingkaran terdalam adalah yang melakukan
penggandaan dan penambahan. Tidak sulit untuk melakukannya melihat bahwa
algoritma dapat diimplementasikan sedemikian rupa sehingga penambahan lebih
sedikit dilakukan daripada perkalian.
Oleh karena itu, kami hanya akan mempertimbangkan instruksi penggandaan
sebagai operasi dasar.
Operasi dasar: instruksi perkalian di bagian paling dalam untuk loop.
Ukuran masukan: n, jumlah baris dan kolom.
Selalu ada n melewati loop-i, di setiap lewatan selalu ada n melewati loop-j, dan
di setiap pass melalui j-loop selalu ada n melewati loop for-k. Karena operasi
dasarnya
di dalam loop for-k,
ada tiga teknik analisis lainnya yang bisa dicoba. Yang pertama adalah
mempertimbangkan jumlah maksimum kali operasi dasar dilakukan. Untuk
sebuah algoritma yang diberikan,: (n) didefinisikan sebagai jumlah maksimum
kali algoritma akan melakukan operasi dasarnya untuk ukuran input dari n. Jadi:
(n) disebut kompleksitas waktu terburuk dari algoritma, dan penentuan: (n)
disebut analisis kompleksitas waktu kasus terburuk. Jika T (n) ada, maka jelas:
(n) = T (n). Berikut ini adalah analisis
dari: (n) dalam kasus di mana T (n) tidak ada.
Analisis Algoritma 1.1
Kompleksitas Kasus Terburuk (Pencarian Berurutan)
Operasi dasar: perbandingan item dalam larik dengan x.
Ukuran masukan: n, jumlah item dalam larik.
Operasi dasar dilakukan paling banyak n kali, yang merupakan kasus jika x
adalah item terakhir dalam array atau jika x tidak dalam larik. Karena itu,
W(n) = n.
Meskipun analisis kasus terburuk memberi tahu kita tentang jumlah waktu
maksimum yang dikonsumsi, dalam beberapa kasus kita mungkin lebih tertarik
15. untuk mengetahui bagaimana kinerja algoritma rata-rata. Untuk algoritma yang
diberikan, A(n) adalah didefinisikan sebagai rata-rata (nilai yang diharapkan) dari
berapa kali algoritma melakukan operasi dasar untuk input ukuran n (lihat Bagian
A.8.2 di Lampiran A untuk diskusi rata-rata). A (n) disebut waktu rata-rata
kompleksitas algoritma, dan penentuan A (n) disebut analisis kompleksitas waktu
kasus rata-rata. Sebagai adalah kasus untuk: (n), jika T (n) ada, maka A (n) = T
(n).
Analisis Algoritma 1.1
Kompleksitas Waktu-Kasus-Waktu (Pencarian Berurutan)
Operasi dasar: perbandingan item dalam larik dengan x.
Ukuran masukan: n, jumlah item dalam larik.
Kami pertama menganalisis kasus di mana diketahui bahwa x dalam S, di mana
item dalam S semuanya berbeda, dan di mana kita miliki tidak ada alasan untuk
percaya bahwa x lebih mungkin berada dalam satu slot array daripada berada di
slot yang lain. Berdasarkan informasi ini, untuk 1 ≤ k ≤ n, probabilitas bahwa x
dalam slot array kth adalah 1 / n. Jika x dalam slot array k ke-n, berapa kali
operasi dasar dilakukan untuk menemukan x (dan, karenanya, untuk keluar dari
loop) adalah k. Ini berarti kompleksitas waktu rata-rata diberikan oleh
Langkah terakhir dalam kesetaraan tiga ini berasal dari manipulasi aljabar. Jika p
= 1, A(n) = (n + 1)/2, seperti sebelumnya, sedangkan jika p = 1/2, A (n) = 3n / 4 +
1/4. Ini berarti sekitar 3/4 dari array dicari rata-rata.
Analisis Algoritma 1.1
Komplikasi Waktu Kasus Terbaik (Pencarian Berurutan)
Operasi dasar: perbandingan item dalam larik dengan x.
Ukuran masukan: n, jumlah item dalam larik.
Karena n ≥ 1, harus ada setidaknya satu laluan melalui loop, Jika x = S [1], akan
ada satu laluan yang melewati loop terlepas dari ukuran n. Karena itu,
B(n) = 1
Untuk algoritma yang tidak memiliki kompleksitas waktu setiap kasus, kami
melakukan analisis kasus terburuk dan rata-rata banyak lebih sering terjadi
daripada analisis kasus terbaik. Analisis kasus rata-rata sangat berguna karena
memberitahu kita berapa banyak waktu yang dibutuhkan.
Secara umum, fungsi kompleksitas dapat berupa fungsi apa pun yang
memetakan bilangan bulat positif ke reval non-negatif. Ketika tidak mengacu
pada kompleksitas waktu atau kompleksitas memori untuk beberapa algoritma
tertentu, biasanya kita akan menggunakan notasi fungsi standar, seperti f (n) dan
g (n), untuk mewakili fungsi kompleksitas.
Contoh 1.6
16. Fungsi-fungsi
semua contoh fungsi kompleksitas karena mereka semua memetakan bilangan
bulat positif ke reval non-negatif.
1.3.2 Menerapkan Teori
Misalkan kita memiliki dua algoritma untuk masalah yang sama dengan
kompleksitas waktu setiap kasus berikut: n untuk algoritma pertama dan n2 untuk
algoritme kedua. Algoritma pertama tampak lebih efisien. Misalkan,
bagaimanapun, komputer yang diberikan membutuhkan 1.000 kali lebih lama
untuk memproses operasi dasar sekali dalam algoritma pertama yang
diperlukanmemproses operasi dasar sekali dalam algoritma kedua. Dengan
"memproses" kami berarti bahwa kami termasuk waktu itu dibutuhkan untuk
mengeksekusi instruksi kontrol. Oleh karena itu, jika t adalah waktu yang
diperlukan untuk memproses operasi dasar sekali dalam Algoritma kedua, 1.000t
adalah waktu yang diperlukan untuk memproses operasi dasar sekali dalam
algoritma pertama. Untuk penyederhanaan, mari kita berasumsi bahwa waktu
yang diperlukan untuk mengeksekusi instruksi overhead dapat diabaikan dalam
kedua algoritma. Ini berarti waktu yang dibutuhkan komputer untuk memproses
suatu instance dari ukuran n adalah n1 1,000t untuk algoritma pertama dan n2× t
untuk algoritma kedua. Kita harus memecahkan ketidaksamaan berikut untuk
menentukan kapan algoritma pertama
lebih efisien:
n2 x t > n x 1,000t
Membagi kedua sisi dengan hasil nt
n > 1,000
Jika aplikasi tidak pernah memiliki ukuran input lebih besar dari 1.000, algoritma
kedua harus diterapkan. Sebelum melanjutkan, kita harus menunjukkan bahwa
tidak selalu begitu mudah untuk menentukan secara tepat kapan satu algoritma
lebih cepat daripada lain. Terkadang kita harus menggunakan teknik pendekatan
untuk menganalisa ketidaksamaan yang diperoleh dengan membandingkan dua
algoritma.
1.3.3 Analisis Ketelitian
Dalam teks ini, "analisis suatu algoritma" berarti analisis efisiensi baik dari segi
waktu atau memori. Ada jenis analisis lainnya. Sebagai contoh, kita dapat
menganalisis kebenaran suatu algoritma dengan mengembangkan bukti bahwa
algoritma sebenarnya melakukan apa yang seharusnya dilakukan.
1.4 Pesanan
17. Kami hanya menggambarkan bahwa algoritma dengan kompleksitas waktu n
lebih efisien daripada yang memiliki kompleksitas waktu n2 untuk nilai n yang
cukup besar, terlepas dari berapa lama waktu yang dibutuhkan untuk memproses
operasi dasar dalam keduanya algoritma. Misalkan sekarang kita memiliki dua
algoritma untuk masalah yang sama dan waktu setiap kasusnya kerumitan adalah
100n untuk algoritma pertama dan 0.01n2 untuk algoritme kedua. Menggunakan
argumen seperti itu hanya diberikan, kita dapat menunjukkan bahwa algoritma
pertama pada akhirnya akan lebih efisien daripada yang kedua. Sebagai
contoh,jika dibutuhkan jumlah waktu yang sama untuk memproses operasi dasar
di kedua algoritma dan overhead adalah tentang sama, algoritma pertama akan
lebih efisien jika
0,01n2 > 100n
Membagi kedua sisi dengan hasil 0,01n
n > 10,000.
Jika diperlukan waktu lebih lama untuk memproses operasi dasar dalam
algoritma pertama daripada yang kedua, maka ada beberapa nilai yang lebih besar
dari n di mana algoritma pertama menjadi lebih efisien. Algoritma dengan
kompleksitas waktu seperti n dan 100n disebut algoritma linear-time karena
waktu mereka kompleksitas linear dalam ukuran input n, sedangkan algoritma
dengan kompleksitas waktu seperti n2 dan 0.01n2 adalah disebut algoritma
kuadrat-waktu karena kompleksitas waktu mereka adalah kuadratik dalam
ukuran input n. Ada sebuah prinsip mendasar di sini. Artinya, setiap algoritma
waktu linear akhirnya lebih efisien daripada waktu kuadrat algoritma. Dalam
analisis teoritis dari suatu algoritma, kami tertarik pada perilaku akhirnya.
Selanjutnya kita akan menunjukkan caranya algoritma dapat dikelompokkan
berdasarkan perilaku akhirnya. Dengan cara ini kita dapat dengan mudah
menentukan apakah salah satunya algoritma perilaku akhirnya lebih baik dari
yang lain.
1.4.1 Pengantar Intuitif untuk Memesan
Fungsi seperti 5n2 dan 5n2 + 100 disebut fungsi kuadrat murni karena tidak
mengandung istilah linear,sedangkan fungsi seperti 0,1n2 + n + 100 disebut
fungsi kuadrat lengkap karena mengandung istilah linier.
Himpunan semua fungsi kompleksitas yang dapat diklasifikasikan dengan
fungsi kuadratik murni disebut Θ(n2), di mana Θ berada huruf Yunani "theta."
Jika suatu fungsi adalah anggota dari set Θ(n2), kami mengatakan bahwa fungsi
adalah urutan n2. UntukMisalnya, karena kita dapat membuang istilah rendah-
pesanan
g(n) = 5n2 + 100n + 20 ϵ Θ(n2)
yang berarti bahwa g (n) adalah urutan n2. Sebagai contoh yang lebih konkret,
ingat dari Bagian 1.3.1 bahwa kompleksitas waktu untuk Algorithm 1.3
(Exchange Sort) diberikan oleh T(n) = n(n - 1)/2. Karena
membuang istilah lower-order n / 2 menunjukkan bahwa T(n) ϵ Θ(n2).
18. Tabel 1.3 Istilah kuadrat akhirnya mendominasi
Ketika kompleksitas waktu suatu algoritma dalam Θ(n2), algoritma ini
disebut algoritma kuadrat-waktu atau Θ(n2) algoritma. Kami juga
mengatakan bahwa algoritma tersebut adalah Θ(n2). Exchange Sort
adalah algoritma waktu kuadratik.Demikian pula, himpunan fungsi
kompleksitas yang dapat diklasifikasikan dengan fungsi kubik murni
disebut Θ (n3), dan fungsi dalam set dikatakan urutan n3 , dan seterusnya.
Kami akan menyebut ini menetapkan kategori kompleksitas. Berikut
adalah beberapa kategori kompleksitas yang paling umum:
Θ(lgn) Θ(n) Θ(n lg n) Θ(n2) Θ(n3) Θ(2n)
Dalam pemesanan ini, jika f (n) berada dalam kategori di sebelah kiri
kategori yang mengandung g (n), maka f (n) akhirnya terletak di bawah g
(n) pada grafik. Asumsi yang menyederhanakan adalah bahwa
dibutuhkan 1 nanodetik (10-9 kedua) untuk memproses operasi dasar
untuk setiap algoritma. Tabel menunjukkan a hasil yang mungkin
mengejutkan. Orang mungkin berharap bahwa selama algoritma bukan
merupakan algoritma eksponensial-waktu, itu akan memadai. Namun,
bahkan algoritma kuadrat-waktu membutuhkan 31,7 tahun untuk
memproses sebuah instance dengan ukuran input 1 milyar. Di sisi lain,
algoritma Θ(n ln n) hanya membutuhkan 29,9 detik untuk memproses
instance semacam itu.Biasanya algoritma harus Θ(n ln n) atau lebih baik
bagi kita untuk mengasumsikan bahwa ia dapat memproses contoh yang
sangat besar dalam jumlah waktu yang dapat ditoleransi. Ini bukan untuk
mengatakan bahwa algoritma yang kompleksitas waktunya berada di
urutan yang lebih tinggi kategori tidak berguna. Algoritma dengan
kompleksitas waktu kuadratik, kubik, dan bahkan lebih tinggi sering bisa
menangani contoh aktual yang muncul di banyak aplikasi.
1.4.2 Pengantar Pesanan
Diskusi sebelumnya menanamkan perasaan intuitif untuk pesanan (Ĭ). Di
sini kita mengembangkan teori yang memungkinkan kita untuk
mendefinisikan
memesan dengan ketat. Kami mencapai ini dengan menghadirkan dua
konsep dasar lainnya. Yang pertama adalah "O besar."
Gambar 1.3 Tingkat pertumbuhan dari beberapa fungsi kerumitan yang umum.
19. Definisi
Untuk fungsi kompleksitas yang diberikan f(n), O(f(n)) adalah himpunan
fungsi kompleksitas g(n) yang ada beberapa
konstanta nyata positif c dan beberapa bilangan bulat non-negatif N
sehingga untuk semua
n ≥ N ,
g(n) ≤ c x f(n) .
Jika g(n) ϵ O (f(n)), kita mengatakan bahwa g (n) adalah O besar f(n).
Gambar 1.4(a) mengilustrasikan "big O." Meskipun g(n) dimulai di atas
cf (n) dalam gambar itu, akhirnya jatuh di bawah cf (n) dan tetap di sana.
Gambar 1.5 menunjukkan contoh konkret.
Meskipun n2 + 10n awalnya di atas 2n2 dalam angka itu, untuk n • 10
Tabel 1.4 Waktu eksekusi untuk algoritma dengan kompleksitas waktu yang diberikan
N f(n) = lg
n
f(n) = n f(n) =n
lg n
f(n) = n2 f(n) = n3 f(n) =
2n
10
0.003 μs 0.01 μs 0.033 μs 0.10 μs 1.0 μs 1 μs
20
0.004 μs 0.02 μs 0.086 μs 0.40μs 8.0 μs 1 ms
30
0.005μs 0.03 μs 0,147 μs 0.90 μs 27.0 μs 1 s
40
0.005 μs 0.04 μs 0.213 μs 1.60 μs 64.0 μs 18.3
min
50
0.006 μs 0.05 μs 0.282 μs 2.50 μs 125.0 μs 13 hari
10
0.007 μs 0.10 μs 0.664 μs 10.00
μs
1.0 ms 4 x
1013
20. tahun
10
0.010 μs 1.00 μs 9.966μs 1.00 ms 1.0 s
10
0.013 μs 10.00
μs
130.000
μs
100.00
ms
16.7 min
10
0.017 μs 0.10 ms 1.670 ms 10.00 s 11.6 hari
10
0.020 μs 1.00 ms 19.930
ms
16.70
min
31.7tahun
10
0.023 μs 0.01 s 2.660 s 1.16
hari
31,709
tahun
10
0.027 μs 0.10 s 2.660 s 115.70
hari
3.17 x
107 tahun
10
0.030μs 1.00 s 29.900 s 31.70
tahun
*1 μs = 10-6
* 1 ms = 10-3
Gambar 1.4 Mengilustrasikan “O besar,” Ω, and Θ.
Oleh karena itu kita dapat mengambil c = 2 dan N = 10 dalam definisi "O besar"
untuk menyimpulkan bahwa
N2 + 10n ϵ O (n2)
21. Jika, misalnya, g (n) ada di O (n2), maka akhirnya g (n) terletak di bawah
beberapa fungsi kuadrat murni cn2 pada grafik.
Ini berarti bahwa jika g (n) adalah kompleksitas waktu untuk beberapa algoritma,
akhirnya waktu berjalan dari algoritma akan setidaknya secepat kuadrat. Untuk
keperluan analisis, kita dapat mengatakan bahwa akhirnya g (n) setidaknya sama
baiknya dengan a
fungsi kuadrat murni. "O besar" (dan konsep lain yang akan diperkenalkan
segera) dikatakan untuk mendeskripsikan perilaku asimtotik dari suatu fungsi.
Kami mengatakan bahwa "O besar" menempatkan batas atas asimtotik pada
fungsi.
Gambar 1.5 Fungsi n2 + 10n akhirnya tetap di bawah fungsi 2n2
.
Contoh berikut mengilustrasikan cara menampilkan "O besar”
Contoh 1.7
Kami menunjukkan bahwa 5n2 ϵ O (n2)
Karena, untuk n ≥ 0,
5n2 ≤ 5n2 ,
kita dapat mengambil c = 5 dan N = 0 untuk mendapatkan hasil yang diinginkan.
Contoh 1.8
Ingat bahwa kompleksitas waktu Algoritma 1.3 (Sortir Exchange) diberikan oleh
Karena untuk n ≥ 0 ,
kita dapat mengambil c = 1/2 dan N = 0 untuk menyimpulkan bahwa T (n) ϵ O
(n2)
Kesulitan yang sering dimiliki siswa dengan "O besar" adalah bahwa
mereka secara keliru berpikir ada beberapa C unik dan unik yang harus ditemukan
22. untuk menunjukkan bahwa satu fungsi adalah "O besar" dari yang lain. Ini bukan
kasusnya sama sekali.
Ingat bahwa Gambar 1.5 menggambarkan bahwa n2
+ 10n ϵ O (n2) menggunakan c = 2 dan N = 10. Atau, kita bisa menunjukkannya
sebagai berikut.
Contoh 1.9
Kami menunjukkan bahwa n2 + 10n ϵ O (n2). Karena, untuk n ≥ 1,
n2 + 10n ≤ n2 + 10n = 11n2
kita dapat mengambil c = 11 dan N = 1 untuk mendapatkan hasil kami.
Secara umum, seseorang dapat menunjukkan "O besar" menggunakan manipulasi
apa pun yang tampaknya paling mudah.
Contoh 1.10
Kami menunjukkan bahwa n2 ϵ O (n2 + 10n). Karena, untuk n ≥ 0,
n2 ≤ 1 x (n2 + 10n)
kita dapat mengambil c = 1 dan N = 0 untuk mendapatkan hasil kami.
Tujuan dari contoh terakhir ini adalah untuk menunjukkan bahwa fungsi di dalam
"O besar" tidak harus menjadi salah satu yang sederhana
fungsi diplot pada Gambar 1.3. Ini bisa menjadi fungsi yang rumit. Biasanya,
bagaimanapun, kami menganggapnya sederhana berfungsi seperti yang diplot
pada Gambar 1.3.
Contoh 1.11
Kami menunjukkan bahwa n ϵ O (n2). Karena, untuk n ≥ 1,
n ≤ 1 x n2
kita dapat mengambil c = 1 dan N = 1 untuk mendapatkan hasil kami.
Contoh terakhir ini membuat titik penting tentang "O besar." Fungsi
kompleksitas tidak perlu memiliki istilah kuadrat berada di O (n2). Oleh karena
itu, setiap logaritma atau fungsi kompleksitas linier dalam O (n2). Demikian pula,
setiap fungsi kompleksitas logaritma, linear, atau kuadratik masuk di O(n3) dan
seterusnya. Gambar 1.6 (a) menunjukkan beberapa anggota O (n2). Sama seperti
"O besar" menempatkan batas atas asimtotik pada fungsi kompleksitas, konsep
berikut menempatkan sebuah batas bawah asimtotik pada fungsi kompleksitas.
Gambar 1.6 Set O (n2), Ω (n2), Θ(n2). Beberapa anggota ditampilkan.
23. Definisi
Untuk fungsi kompleksitas tertentu f(n),Ω(f (n)) adalah himpunan fungsi
kompleksitas g (n) yang ada beberapa konstanta nyata positif c dan beberapa
bilangan bulat non-negatif N sehingga, untuk semua n ≥ N ,
G(n) ≥ c x f(n)
Simbol Ω adalah huruf kapital Yunani "omega." Jika g(n) ϵ Ω(f(n)), kita
mengatakan bahwa g (n) adalah omega dari f (n). Gambar
1.4 (b) mengilustrasikan Ω. Beberapa contoh mengikuti.
Contoh 1.12
Kami menunjukkan bahwa 5n2 ϵ Ω(n2). Karena, untuk n ≥ 0,
5n2 ≥ 1 x n
kita dapat mengambil c = 1 dan N = 0 untuk mendapatkan hasil kami.
Contoh 1.13
Kami menunjukkan bahwa n2 + 10n ϵ Ω (n2). Karena, untuk n ≥ 0, n2 + 10n ≥ n2,
n2 + 10n ≥ n2
kita dapat mengambil c = 1 dan N = 0 untuk mendapatkan hasil kami.
Contoh 1.14
Pertimbangkan lagi kompleksitas waktu Algoritma 1.3 (Sortir Exchange). Kami
menunjukkan itu
Untuk n ≥ 2,
Karena itu, untuk n ≥ 2,
yang berarti kita dapat mengambil c = 1/4 dan N = 2 untuk mendapatkan hasil
kami.
24. Seperti halnya untuk "O besar," tidak ada konstanta unik c dan N yang
kondisi dalam definisi Ω memegang. Kita dapat memilih mana yang membuat
manipulasi kita menjadi termudah.
Contoh 1.15
Kami menunjukkan bahwa n3 Ω (n2). Karena, jika n ≥ 1,
n3 ≥ 1 x n2
kita dapat mengambil c = 1 dan N = 1 untuk mendapatkan hasil kami.
Gambar 1.6 (b) menunjukkan beberapa anggota Ω(n2)
Jika suatu fungsi ada di O(n2) dan Ω(n2) kita dapat menyimpulkan bahwa pada
akhirnya fungsi terletak di bawah beberapa murni fungsi kuadrat pada grafik dan
akhirnya terletak di atas beberapa fungsi kuadrat murni pada grafik.
Oleh karena itu kita dapat menyimpulkan bahwa pertumbuhannya mirip dengan
fungsi kuadratik murni. Ini adalah tepatnya hasil yang kita inginkan untuk
gagasan pesanan kita yang ketat. Kami memiliki definisi berikut.
Definisi
Untuk fungsi kompleksitas tertentu f (n),
Θ(f(n)) = O(f(n)) ∩ Ω(f(n))
Ini berarti bahwa Θ(f(n)) adalah himpunan fungsi kompleksitas g (n) yang
ada beberapa real positif konstanta c dan d dan beberapa bilangan bulat
non-negatif N sehingga, untuk semua
n ≥ N,
c x f(n) ≤ g(n) ≤ d x f (n)
Jika g(n) ϵ Θ(f(n)), kita mengatakan bahwa g (n) adalah urutan f (n).
Contoh 1.16
Pertimbangkan sekali lagi kompleksitas waktu Algoritma 1.3. Contoh 1.8 dan
1.14 bersama-sama menetapkan bahwa
Ini berarti bahwa T(n) ϵ O(n2) ∩ Ω(n2) = Θ(n2)
Gambar 1.6 (c) menggambarkan bahwa Θ(n2) adalah perpotongan O (n2) dan Ω
(n2), sedangkan Gambar 1.4 (c) mengilustrasikan Θ. Melihat pada Gambar 1.6 (c)
bahwa fungsi 5n + 7 tidak dalam Ω(n2), dan fungsi 4n3 + 3n2 tidak dalam O (n2).
Oleh karena itu, keduanya fungsi-fungsi ini dalam Θ(n2). Meskipun secara intuitif
ini tampaknya benar, kami belum membuktikannya. contoh menunjukkan
bagaimana bukti tersebut berlangsung.
Contoh 1.17
Kami menunjukkan bahwa n tidak dalam Ω(n2) dengan menggunakan bukti
dengan kontradiksi. Dalam jenis bukti ini, kita asumsikan ada sesuatu yang
benar dalam hal ini, bahwa n ϵ Ω(n2) Dan kemudian kita melakukan manipulasi
yang mengarah pada hasil yang tidak benar. Yaitu, hasilnya bertentangan dengan
sesuatu yang diketahui benar. Kami kemudian menyimpulkan bahwa apa yang
kami anggap di tempat pertama tidak mungkin benar.
25. Dengan asumsi bahwa n ϵ Ω (n2) Berarti kita mengasumsikan bahwa ada
beberapa konstanta positif c dan beberapa nonnegatif bilangan bulat N sehingga,
untuk n ≥ N,
n ≥ cn2
Jika kita membagi kedua sisi ketidaksetaraan ini dengan cn, kita memiliki, untuk
n ≥ N,
1/c ≥ n
Namun, untuk setiap n> 1/c, ketidaksetaraan ini tidak dapat dipertahankan, yang
berarti tidak dapat berlaku untuk semua n N. Ini kontradiksi membuktikan bahwa
n tidak dalam Ω(n2).
Kami memiliki satu definisi lagi tentang urutan yang menyatakan hubungan
seperti yang ada di antara fungsi n dan fungsi Ω (n2).
Definisi
Untuk fungsi kompleksitas tertentu f (n), o(f (n)) adalah himpunan semua
fungsi kompleksitas g (n) yang memuaskan hal-hal berikut:
Untuk setiap konstanta nyata positif, terdapat bilangan bulat N negatif
nonnegatif sehingga, untuk semua n ≥ N,
g(n) ≤ c x f(n)
Jika g (n) ϵ o(f (n)), kita mengatakan bahwa g (n) adalah o kecil dari f (n).
Ingat bahwa "O besar" berarti harus ada yang positif konstanta c yang
terikat memegang. Definisi ini mengatakan bahwa batasan harus berlaku
untuk setiap konstanta positif yang nyata c.
Karena terikat memegang untuk setiap c positif, itu berlaku untuk
sewenang-wenang kecil c. Misalnya, jika g(n) ϵ o(f(n)), di sana adalah N
seperti itu, untuk n> N,
g(n) ≤ 0,00001 x f(n)
Kita melihat bahwa g (n) menjadi tidak signifikan relatif terhadap f (n) karena n
menjadi besar. Untuk keperluan analisis, jika g (n) masuk o(f (n)), maka g (n)
pada akhirnya jauh lebih baik daripada fungsi seperti f (n). Contoh-contoh berikut
mengilustrasikan ini.
Contoh 1.18
Kami menunjukkan bahwa
n ϵ o(n2)
Biarkan c> 0 diberikan. Kita perlu menemukan N seperti itu, untuk n ≥ N,
n ≤ cn2
Jika kita membagi kedua sisi ketidaksetaraan ini dengan cn, kita dapatkan
1/c ≤ n
Oleh karena itu, sudah cukup untuk memilih N ≥ 1 / c.
Perhatikan bahwa nilai N tergantung pada konstanta c. Sebagai contoh, jika c =
0,00001, kita harus mengambil N sama dengan setidaknya 100.000. Yaitu, untuk
n ≤ 0,00001n2
Contoh 1.19
26. Kami menunjukkan bahwa n tidak dalam o(5n). Kami akan menggunakan bukti
dengan kontradiksi untuk menunjukkan ini. Biarkan c = 1/6 . Jika n ϵ o(5n), maka
di sana harus ada beberapa N sehingga, untuk n ≥ N,
Kontradiksi ini membuktikan bahwa n tidak dalam o(5n).
Teorema berikut menghubungkan "o kecil" dengan notasi asymptotic kami yang
lain.
Teorema 1.2
Jika g(n) ϵ o(f (n)), lalu
g(n) ϵ O(f(n)) – Ω(f(n))
Yaitu, g(n) dalam O(f (n)) tetapi tidak dalam Ω(f (n)).
Bukti: Karena g (n) ϵ o(f (n)), untuk setiap konstanta nyata positif c ada N
sehingga, untuk semua n ≥N,
g(n) ≤ c x f(n)
yang berarti bahwa batasan pasti berlaku untuk beberapa c. Karena itu,
g(n) ϵ O (f(n))
Kami akan menunjukkan bahwa g (n) tidak dalam ȍ (f (n)) menggunakan bukti
dengan kontradiksi. Jika g (n) ϵ Ω(f (n)), maka ada beberapa yang nyata konstanta
c> 0 dan beberapa N1 seperti itu, untuk semua n ≥ N1
g(n) ≥ c x f(n)
Tapi, karena g (n) ϵ o(f (n)), ada beberapa N2 seperti itu, untuk semua n ≥ N2,
Kedua ketidaksetaraan harus berlaku untuk semua yang lebih besar dari N1 dan
N2. Kontradiksi ini membuktikan bahwa g (n) tidak bisa
berada di Ω(f (n)).
Anda mungkin berpikir bahwa o(f (n)) dan O(f(n)) - Ω(f (n)) harus merupakan
himpunan yang sama. Ini tidak benar. Ada fungsi yang tidak biasa yang berada di
O(f (n)) - Ω(f (n)) tetapi itu tidak dalam
o(f (n)). Contoh berikut mengilustrasikan ini.
Contoh 1.20
Pertimbangkan fungsinya
N jika n adalah bulat
g(n)
1 jika n adalah ganjil
Itu dibiarkan sebagai latihan untuk menunjukkan itu
G(n) ϵ O(n) - Ω(n) tetapi bahwa g(n) tidak ada di o(n)
Contoh 1.20, tentu saja, cukup dibuat-buat. Ketika fungsi kompleksitas mewakili
kompleksitas waktu aktual algoritma, biasanya fungsi dalam O(f (n)) - Ω(f (n))
adalah yang sama yang berada di
o(f (n)).
Mari kita bahas Θ lebih lanjut. Dalam latihan kami menetapkan bahwa
g(n) ϵ Θ(f(n)) jika dan hanya jika f(n) ϵ Θ(g(n))
27. sebagai contoh,
n2 + 10n ϵ Θ(n2) dan n2 ϵ Θ (n2 + 10n)
Ini berarti bahwa Θ memisahkan fungsi kompleksitas menjadi set disjoint. Kami
akan menyebut ini menetapkan kategori kompleksitas.
Setiap fungsi dari kategori tertentu dapat mewakili kategori. Untuk kenyamanan,
kami biasanya mewakili kategori oleh anggota yang paling sederhana. Kategori
kompleksitas sebelumnya ditunjukkan oleh Θ(n2).
Berikut ini adalah beberapa sifat penting dari pesanan yang memudahkan
untuk menentukan pesanan banyak orang fungsi kompleksitas.
Properties of Order
1. g(n) ϵ O(f (n)) jika dan hanya jika f(n) ϵ Ω(g(n)).
2. g (n) ϵ Θ(f(n)) jika dan hanya jika f (n) ϵ Θ(g(n)).
3. Jika b> 1 dan a> 1, maka loga n ϵ Θ (logb n).
Ini menyiratkan bahwa semua fungsi kompleksitas logaritmik berada
dalam kategori kompleksitas yang sama. Kami akan mewakili kategori ini
dengan Θ(lg n).
4. Jika b> a> 0, maka
an ϵ o(bn)
Ini menyiratkan bahwa semua fungsi kompleksitas eksponensial tidak
dalam kategori kompleksitas yang sama.
5. Untuk semua> 0
an ϵ o(n!)
Ini menyiratkan bahwa n lebih buruk daripada fungsi kompleksitas
eksponensial apa pun.
6. Pertimbangkan urutan kategori kompleksitas berikut ini:
Θ(lg n) Θ(n) Θ(n lg n) Θ(n2) Θ(n3) Θ(nk) Θ(an) Θ(bn) Θ(n!) ,
di mana k> j> 2 dan b> a> 1. Jika fungsi kompleksitas g (n) berada dalam
kategori yang berada di sebelah kiri kategori yang mengandung f (n), lalu
g(n) ϵ o(f(n))
7. Jika c ≥ 0, d> 0, g (n) ϵ O (f (n)), dan h(n) ϵ Θ(f (n)), maka
C x g(n) + d x h(n) ϵ Θ(f(n))
Contoh 1.21
Properti 3 menyatakan bahwa semua fungsi kompleksitas logaritmik berada dalam
kategori kompleksitas yang sama. Sebagai contoh,
Θ(log4 n) = Θ(lg n)
Ini berarti bahwa hubungan antara log4 n dan lg n adalah sama dengan yang ada
di antara 7n2 + 5n dan n2
.
Contoh 1.22
Properti 6 menyatakan bahwa setiap fungsi logaritma pada akhirnya lebih baik
daripada polinomial apa pun, setiap polinomial adalah akhirnya lebih baik
daripada fungsi eksponensial apa pun, dan fungsi eksponensial apa pun akhirnya
lebih baik daripada faktoria fungsi. Sebagai contoh,
lg n ϵ o(n) n10 ϵ o(2n) dan 2n ϵ o(n!)
28. Contoh 1.23
Properti 6 dan 7 dapat digunakan berulang kali. Sebagai contoh, kita dapat
menunjukkan bahwa 5n + 3 lg n + 10n lg n + 7n2 ϵ Θ(n2), sebagai mengikuti.
Berulang kali menerapkan Properti 6 dan 7, kami punya
7n2 ϵ Θ(n2)
Yang berarti
10n lg n + 7n2 ϵ Θ(n2)
Yang berarti
3 lg n +10n lg n + 7n2 ϵ Θ(n2)
Yang berarti
5n + 3 lg n +10n lg n + 7n2 ϵ Θ(n2)
Dalam prakteknya, kita tidak berulang kali menarik properti, tetapi kita
hanya menyadari bahwa kita dapat membuang loworder istilah.
Jika kita dapat memperoleh kompleksitas waktu yang tepat dari suatu
algoritma, kita dapat menentukan urutannya hanya dengan membuang persyaratan
tingkat rendah. Ketika ini tidak mungkin, kita dapat mengajukan banding kembali
ke definisi " O besar" dan Ω untuk menentukan urutan. Misalnya, untuk beberapa
algoritma kami tidak dapat menentukan T (n) [atauW (n), A (n), atau B (n)]
dengan tepat. Jika kita bisa menunjukkan itu
T(n) ϵ O(f(n)) dan T(n) ϵ Ω(f(n))
dengan menarik langsung ke definisi, kita dapat menyimpulkan bahwa T(n) ϵ Θ(f
(n)).
Sebelum ditutup, kami menyebutkan bahwa banyak penulis berkata
f(n) = Θ(n2) dari pada f(n) ϵ Θ(n2)
Keduanya berarti hal yang sama — yaitu, bahwa f (n) adalah anggota dari set
Θ(n2). Demikian pula, adalah hal biasa untuk ditulis
f(n) = O(n2) dari pada f(n) ϵ O(n2)
1.4.3 Menggunakan Batas untuk Menentukan Urutan
Kami sekarang menunjukkan bagaimana urutan terkadang dapat ditentukan
dengan menggunakan batas. Bahan ini termasuk bagi mereka yang akrabdengan
batasan dan turunan. Pengetahuan tentang materi ini tidak diperlukan di tempat
lain dalam teks.
Teorema 1.3
Kami memiliki yang berikut:
Buktinya: Buktinya dibiarkan sebagai latihan.
Contoh 1.24
Teorema 1.3 mengimplikasikan hal itu
Karena
29. Menggunakan Teorema 1.3 dalam Contoh 1.24 tidak terlalu menarik
karena hasilnya dapat dengan mudah ditetapkan langsung. Contoh-contoh berikut
lebih menarik.
Contoh 1.25
Teorema 1.3 menyiratkan bahwa, untuk b> a> 0,
an ϵ o(bn)
karena
Batasnya adalah 0 karena 0 <a / b <1.
Ini adalah Properti 4 di Properties of Order (dekat akhir Bagian 1.4.2).
Contoh 1.26
Teorema 1.3 menyiratkan bahwa, untuk> 0,
an ϵ o(n!)
Jika ≤ 1, hasilnya sepele. Misalkan a> 1. Jika n begitu besar itu
Kemudian
Karena a> 1, ini menyiratkan itu
Ini adalah Properti 5 di Properties of Order.
Teorema berikut, yang buktinya dapat ditemukan di sebagian besar teks
kalkulus, meningkatkan kegunaan Teorema 1.3.
Teorema 1.4
Aaturan L’Hopital’s Jika f (x) dan g (x) keduanya terdiferensiasi dengan turunan
f ′(x) dan g '(x), masing-masing, dan jika
Kemudian
setiap kali batas di sebelah kanan ada.
Teorema 1.4 menampung fungsi-fungsi bernilai nyata, sedangkan fungsi
kompleksitas kami adalah fungsi integer variabel. Namun, sebagian besar fungsi
kompleksitas kami (misalnya, lg n, n, dll.) Juga fungsi dari variabel nyata.
Selanjutnya, jika fungsi f (x) adalah fungsi dari variabel x riil, maka
30. di mana n adalah bilangan bulat, kapan pun batas di sebelah kanan ada. Oleh
karena itu, kita dapat menerapkan Teorema 1.4 pada kompleksitas analisis,
seperti yang diilustrasikan contoh-contoh berikut.
Contoh 1.27
Teorema 1.3 dan 1.4 menyiratkan itu
lg n ϵ o(n)
karena
Contoh 1.28
Teorema 1.3 dan 1.4 menyiratkan bahwa, untuk b> 1 dan a> 1,
loga n ϵ Θ (logb n)
karena
Ini adalah properti 3 di Properties of Order
1.5 Garis Besar Buku Ini
Kami sekarang siap mengembangkan dan menganalisis algoritma canggih. Untuk
sebagian besar, organisasi kami adalah oleh teknik bukan berdasarkan area
aplikasi. Sebagaimana dicatat sebelumnya, tujuan dari organisasi ini adalah untuk
mendirikan sebuah pengulangan teknik yang dapat diselidiki sebagai
kemungkinan cara untuk mendekati masalah baru. Bab 2 membahas teknik yang
disebut "Divide and Conquer." Bab 3 mencakup pemrograman dinamis. Bab 4
membahas “orang yang tamakpendekatan. "Dalam Bab 5, teknik backtracking
disajikan. Bab 6 membahas teknik yang berkaitan dengan backtracking disebut
"cabang-dan-terikat." Dalam Bab 7 dan 8, kita beralih dari mengembangkan dan
menganalisis algoritma untuk menganalisis masalah itu sendiri. Analisis
semacam itu, yang disebut analisis komputasional kompleksitas, melibatkan
menentukan batas bawah untuk kompleksitas waktu dari semua algoritma untuk
masalah yang diberikan. Bab 7 menganalisa
Menyortir Masalah, dan Bab 8 menganalisis Masalah Pencarian. Bab 9
dikhususkan untuk kelas khusus masalah.Kelas itu mengandung masalah yang
belum pernah ada yang mengembangkan algoritme yang kompleksitas waktunya
lebih baik daripada eksponensial dalam kasus terburuk.
Dalam Bab 10 kita kembali untuk berkembang algoritma. Namun, tidak seperti
metode yang disajikan dalam Bab 2–6, kami membahas algoritma untuk
memecahkan jenis tertentu masalah. Artinya, kita membahas algoritma angka-
teoritis, yang merupakan algoritma yang memecahkan masalah yang melibatkan
bilangan bulat.
Latihan
31. Bagian 1.1
1. Tulis algoritma yang menemukan angka terbesar dalam daftar (array) dari n
angka.
2. Tulis algoritma yang menemukan angka terkecil dalam daftar n nomor.
3. Tulis algoritma yang mencetak semua himpunan bagian dari tiga elemen dari
satu set elemen n. Unsur-unsur
set ini disimpan dalam daftar yang merupakan input ke algoritma.
4. Tulis algoritme Penyisipan Urutan (Urutan Penyisipan dibahas di Bagian 7.2)
yang menggunakan Pencarian Biner untuk menemukan
posisi di mana penyisipan berikutnya harus dilakukan.
5. Tulis algoritma yang menemukan pembagi umum terbesar dari dua bilangan
bulat.
6. Tuliskan algoritma yang menemukan angka terkecil dan terbesar dalam daftar
n angka. Coba cari a
metode yang paling banyak melakukan 1.5n perbandingan item larik.
7. Tulis algoritma yang menentukan apakah pohon biner hampir lengkap adalah
heap.
Bagian 1.2
8. Dalam keadaan apa, ketika operasi pencarian diperlukan, apakah Sequential
Search (Algorithm 1.1)
tidak pantas?
9. Berikan contoh praktis di mana Anda tidak akan menggunakan Exchange Sort
(Algoritma 1.3) untuk melakukan tugas pengurutan.
Bagian 1.3
10. Tentukan operasi dasar untuk algoritme Anda dalam Latihan 1–7, dan pelajari
kinerja algoritme ini. Jika sebuah
algoritma yang diberikan memiliki kompleksitas waktu setiap kasus, tentukan itu.
Jika tidak, tentukan waktu terburuk
kompleksitas.
11. Tentukan kasus terburuk, rata-rata, dan kerumitan waktu terbaik untuk
Penyisipan Dasar dan untuk
versi yang diberikan dalam Latihan 4, yang menggunakan Pencarian Biner.
12. Tulis a Ĭ (n) algoritma yang mengurutkan n bilangan bulat berbeda, mulai
dalam ukuran antara 1 dan kn inklusif, di mana k adalah a
bilangan bulat positif konstan. (Petunjuk: Gunakan array knelement.)
13. Algoritma A melakukan 10n2 operasi dasar, dan algoritma B melakukan 300
operasi dasar ln n. Untuk apa nilai n apakah algoritma B mulai menunjukkan
kinerjanya yang lebih baik?
14. Ada dua algoritma yang disebut Alg1 dan Alg2 untuk masalah ukuran n. Alg1
berjalan di n2
mikrodetik dan Alg2 berjalan di 100n log dan mikrodetik. Alg1 dapat
diimplementasikan menggunakan 4 jam waktu dan kebutuhan programmer 2
menit waktu CPU. Di sisi lain, Alg2 membutuhkan 15 jam waktu programmer
dan 6 menit waktu CPU.
32. Jika programmer dibayar 20 dolar per jam dan waktu CPU biaya 50 dolar per
menit, berapa kali harus contoh masalah ukuran 500 dipecahkan menggunakan
Alg2 untuk membenarkan biaya pengembangannya?
Bagian 1.4
15 Tunjukkan langsung bahwa f (n) = n2 + 3n3 ϵ Θ(n3). Yaitu, gunakan definisi O
dan Ω untuk menunjukkan bahwa f (n) ada di keduanya
Di O(n3) dan Ω(n3).
16. Menggunakan definisi O dan ȍ, tunjukkan itu
17. Menggunakan Properties of Order dalam Bagian 1.4.2, tunjukkan bahwa
5n5 + 4n4 + 6n3 + 2n2 + n + 7 ϵ Θ(n3)
18. Biarkan p (n) = aknk + ak-1nk-1 + ....+ a1n + a0 , dimana ak > 0. Menggunakan
Properties of Order dalam Bagian 1.4.2, tunjukkan itu p(n) ϵ Θ(nk).
19. Fungsi f (x) = 3n2 + 10n log n + 1000n + 4 log n + 9999 termasuk dalam
kompleksitas berikut
kategori:
(a) θ(lg n)
(b) θ(n2 log n)
(c) θ(n)
(d) θ(n lg n)
(e) θ(n2)
(f) Tidak satu pun dari ini
20. Fungsi f (x) = (log n)2 + 2n + 4n + log n + 50 termasuk dalam kategori
kompleksitas berikut:
(a) θ(lg n)
(b) θ((log n)2)
(c) θ(n)
(d) θ(n lg n)
(e) θ(n (lg n)2)
(f) Tidak satu pun dari ini
21. Fungsi f (x) = n + n2 + 2n + n4 termasuk dalam kategori kerumitan berikut:
(a) θ(n)
(b) θ(n2)
(c) θ(n3)
(d) θ(n lg n)
(e) θ(n4)
(f) Tidak satu pun dari ini
22. Kelompokkan fungsi-fungsi berikut dengan kategori kompleksitas.
33. 23. Menetapkan Properti 1, 2, 6, dan 7 dari Properti Ketertiban dalam Bagian
1.4.2.
25. Misalkan Anda memiliki komputer yang membutuhkan 1 menit untuk
menyelesaikan masalah contoh ukuran n = 1.000. Misalkan Anda beli komputer
baru yang berjalan 1.000 kali lebih cepat dari yang lama. Apa ukuran instance
dapat dijalankan dalam 1 menit, dengan asumsi kompleksitas waktu berikut T (n)
untuk algoritma kami?
(a) T (n) = n
(b) T (n) = n3
(c) T (n) = 10n
26. Turunkan bukti Teorema 1.3
27. Tunjukkan kebenaran dari pernyataan berikut.
(a) lg n ϵ O(n)
(b) n ϵ O(n lg n)
(c) n lg n ϵ O (n2)
(d) 2n ϵ Ω 5ln n
(e) lg3 n ϵ (n 0,5)
Latihan Tambahan
28. Saat ini kita dapat memecahkan masalah contoh ukuran 30 dalam 1 menit
menggunakan algoritma A, yang merupakan Θ(2n) algoritma. Di sisi lain, kita
akan segera menyelesaikan masalah contoh dua kali ini besar dalam 1 menit.
Apakah kamu pikir itu akan membantu membeli komputer yang lebih cepat (dan
lebih mahal)?
29. Pertimbangkan algoritme berikut:
For ( i = 1; i <= 1.5n; i++)
Cout << i ;
For ( i = n ; i >= 1; i--)
Cout << i;
(a) Berapakah output ketika n = 2, n = 4, dan n = 6?
(b) Apa kompleksitas waktu T (n)? Anda dapat mengasumsikan bahwa input n
habis dibagi 2.
30. Pertimbangkan algoritme berikut:
J = 1;
While ( j <= n/2) {
i = 1;
while ( i <= j) {
cout << j << i;
i++;
}
j++
}
(a) Berapakah output ketika n = 6, n = 8, dan n = 10?
(b) Apa kompleksitas waktu T (n)? Anda dapat mengasumsikan bahwa input n
habis dibagi 2.
34. 31. Pertimbangkan algoritme berikut:
For ( i = 2; i <= n; i++) {
For ( j = 0; j <= n ) {
Cout << i << j;
j = j + [n/4];
}
}
(a) Berapakah output ketika n = 4, n = 16, n = 32?
(b) Berapakah kompleksitas waktu T (n). Anda dapat berasumsi bahwa n dapat
dibagi 4.
32. Apa kompleksitas waktu T(n) dari loop bersarang di bawah ini? Untuk
kesederhanaan, Anda dapat mengasumsikan bahwa n adalah kekuatan 2. Artinya,
n = 2k untuk beberapa bilangan bulat positif k.
for ( i = 1; i <= n; i++) {
j = n ;
while ( j >= 1 ) {
< body of the while loop> //Butuh Θ(1).
J = [j/2];
}
}
33. Berikan algoritme untuk masalah berikut dan tentukan kompleksitas
waktunya. Diberikan daftar n yang berbeda bilangan bulat positif, partisi daftar
menjadi dua subliter, masing-masing ukuran n / 2, sehingga perbedaan antara
jumlah dari bilangan bulat dalam dua sublist dimaksimalkan. Anda dapat
berasumsi bahwa n adalah kelipatan dari 2.
34. Apa kompleksitas waktu T (n) dari loop bersarang di bawah ini? Untuk
kesederhanaan, Anda dapat mengasumsikan bahwa n adalah kekuatan 2. Artinya,
n = 2k untuk beberapa bilangan bulat positif k.
i = n
while ( i >= 1) {
j = i;
while ( j <= n ) {
<body of the while loop> // butuh Θ(1)
j = 2 + j ;
}
i = [i/2];
}
35. Pertimbangkan algoritme berikut:
int add_them (int n , int A [ ] )
{
index i,j,k;
j = 0;
for ( i = 1; i <= n; i++)
j = j + A[1];
35. k=1
for ( i = 1 ; i <= n ; i++)
k = k+k;
return j + k;
(a) Jika n = 5 dan array A berisi 2, 5, 3, 7, dan 8, berapakah outputnya?
(B) Apa kompleksitas waktu T (n) dari algoritma?
(C) Cobalah untuk meningkatkan efisiensi algoritma.
36. Pertimbangkan algoritme berikut:
int any_equal (int n , int A [ ] [ ] )
{
index i,j,k,m ;
for ( i = 1; i <= n; i++)
for (j = 1; j <= n ; j++)
for (k =1 ; k<= n ; k++)
for (m = 1,m <= n ; m++)
if (A [i] [j] ==A [k] [m] && ! (i==k
&& j==m))
return 1;
return 0;
}
(A) Apa kompleksitas waktu kasus terbaik dari algoritma (dengan asumsi n> 1)?
(b) Apa kompleksitas waktu kasus terburuk dari algoritma?
(C) Cobalah untuk meningkatkan efisiensi algoritma.
(D) Properti apa yang berlaku untuk array A jika algoritma mengembalikan 0?
(E) Properti apa yang berlaku untuk array A jika algoritma mengembalikan 1?
37. Berikan sebuah algoritma Θ(lg n) yang menghitung sisa ketika xn dibagi
dengan p. Untuk kesederhanaan, Anda mungkin berasumsi n itu adalah kekuatan
2. Artinya, n = 2k untuk beberapa bilangan bulat positif k.
38. Jelaskan dalam bahasa Inggris fungsi apa saja yang ada dalam set berikut
(a) no(1)
(b) O (n o(1))
(c) O (O(no(1)))
39. Tunjukkan bahwa fungsi f (n) = | n2 = sin n | tidak ada O (n) atau Ω(n).
40. Membenarkan kebenaran pernyataan berikut dengan asumsi bahwa f(n) dan
g(n) adalah asimtotik positif fungsi.
(a) f(n) + g(n) ϵ O (max(f (n)), g(n))
(b) f2(n) ϵ Ω(f (n))
(c) f(n) + o(f(n)) ϵ Θ(f(n)), di mana o(f(n)) berarti fungsi apa pun g(n) ϵ o(f(n))
41. Berikan algoritme untuk masalah berikut. Diberikan daftar n bilangan bulat
positif yang berbeda, partisi daftar menjadi dua sublists, masing-masing ukuran n
/ 2, sehingga perbedaan antara jumlah bilangan bulat dalam dua sublist adalah
diminimalkan. Tentukan kompleksitas waktu dari algoritma Anda. Anda dapat
berasumsi bahwa n adalah kelipatan dari 2.
36. 42. Algoritma 1.7 (nth Fibonacci Term, Iterative) jelas linear dalam n, tetapi
apakah itu algoritma linear-time? Di bagian 1.3.1 kami mendefinisikan ukuran
input sebagai ukuran input. Dalam kasus istilah Fibonacci n, n adalah input, dan
jumlah bit yang diperlukan untuk menyandikan n dapat digunakan sebagai ukuran
masukan. Dengan menggunakan ukuran ini, ukuran 64 adalah lg 64= 6, dan
ukuran 1,024 adalah lg 1,024 = 10. Tunjukkan bahwa Algoritma 1.7 adalah
waktu eksponensial dalam hal ukuran inputnya.Tunjukkan lebih lanjut bahwa
setiap algoritma untuk menghitung istilah Fibonacci n harus merupakan algoritma
eksponensial-waktu karena ukuran outputnya eksponensial dalam ukuran input.
(Lihat Bagian 9.2 untuk diskusi terkait tentang ukuran masukan.)
43. Tentukan kompleksitas waktu Algoritma 1.6 (nth Fibonacci Term, Recursive)
dalam hal ukuran inputnya (lihat Latihan 34).
44. Dapatkah Anda memverifikasi kebenaran algoritme Anda untuk Latihan 1
hingga 7?
37. Bab 2
Membagi dan mengatasi pendekatan pertama kami untuk merancang
algoritma, Divide dan Conquer,
Pendekatan divide-and-conquer menggunakan strategi yang sama ini pada
sebuah contoh masalah. Artinya, ia membagi suatu contoh masalah menjadi dua
atau lebih kecil .
Kami sekarang memperkenalkan pendekatan membagi-dan-menaklukkan dengan
contoh, dimulai dengan Pencarian Biner.
2.1 Pencarian Biner
Kami menunjukkan versi berulang dari Pencarian Biner (Algoritma 1.5) di
Bagian 1.2. Di sini kami menyajikan versi rekursif karena rekursi
menggambarkan pendekatan top-down yang digunakan oleh divide-and-conquer.
Dinyatakan dalam membagi-dan-menaklukkan terminologi, Pencarian Biner
menempatkan kunci x dalam susunan yang diurutkan (nondecreasing order)
dengan terlebih dahulu membandingkan x dengan item tengah dari array. Jika
mereka sama, algoritma ini dilakukan. Jika tidak, array dibagi menjadi dua sub-
bagian, satu berisi semua item di sebelah kiri item tengah dan yang lainnya berisi
semua item ke kanan. Jika x lebih kecil daripada item tengah, prosedur ini
kemudian diterapkan pada sub-tugas kiri. Jika tidak, itu diterapkan pada sub-
tugas yang benar.
Artinya, x dibandingkan dengan item tengah dari sub-kontrak yang sesuai. Jika
mereka sama, algoritma ini dilakukan. Jika tidak, sub-pembagian dibagi menjadi
dua. Prosedur ini diulangi sampai x ditemukan atau ditentukan bahwa x tidak
dalam larik.
Langkah-langkah Pencarian Biner dapat diringkas sebagai berikut.
Jika x sama dengan item tengah, keluar. Jika tidak:
1. Bagilah array menjadi dua sub-bagian sekitar separuh besar. Jika x lebih kecil
dari item tengah, pilih yang kiri subarray. Jika x lebih besar dari item tengah,
pilih sub yang tepat.
2. Menaklukkan (memecahkan) sub-tugas dengan menentukan apakah x dalam
sub-tugas itu. Kecuali subarray sudah cukup kecil, gunakan rekursi untuk
melakukan ini.
3. Dapatkan solusi ke array dari solusi ke sub-tujuan. Pencarian Biner adalah
jenis algoritma divide-and-conquer yang paling sederhana karena instance
dipecah menjadi hanya satu contoh yang lebih kecil, sehingga tidak ada
kombinasi output. Solusi untuk contoh asli hanyalah solusi untuk contoh yang
lebih kecil. Contoh berikut mengilustrasikan Pencarian Biner.
Contoh 2.1
Misalkan x = 18 dan kami memiliki larik berikut:
10 12 13 14 18 20 25 27 30 35 40 45 47
Nomor tengah
1. Bagilah array: Karena x <25, kita perlu mencari
10 12 13 14 18 20
38. 2. Taklukkan subarray dengan menentukan apakah x dalam sub-rangkai. Ini
dilakukan dengan membagi secara rekursif subarray. Solusinya adalah:
Ya, x ada di bawah.
3. Dapatkan solusi ke array dari solusi ke subarray:
Ya, x ada dalam array.
Pada Langkah 2 kami hanya berasumsi bahwa solusi untuk sub-kontrak
tersedia. Kami tidak membahas semua detailnya terlibat dalam mendapatkan
solusi karena kami ingin menunjukkan solusi pada tingkat penyelesaian masalah.
Kapan mengembangkan algoritma rekursif untuk masalah, kita perlu
Kembangkan sebuah cara untuk mendapatkan solusi dari sebuah contoh
dari solusi ke satu atau beberapa contoh yang lebih kecil.
Tentukan kondisi terminal (s) yang lebih kecil (s) mendekati ().
Tentukan solusi dalam kasus kondisi terminal (s).
Gambar 2.1 menunjukkan langkah-langkah yang dilakukan oleh manusia ketika
mencari dengan Pencarian Biner.
Versi rekursif dari Pencarian Biner sekarang mengikuti
Algoritma 2.1
Pencarian Biner (Rekursif)
Masalah: Tentukan apakah x dalam susunan S terurut dari ukuran n.
Input: bilangan bulat positif n, susunan urutan yang diurutkan (nondecreasing
order) S diindeks dari 1 menjadi n, sebuah kunci x.
Output: lokasi, lokasi x dalam S (0 jika x tidak dalam S).
index location (index low , index high )
{
index mid;
if ( low > high )
return 0;
else {
mid = [(low + high ) / 2] ;
if ( x == S [mid] )
return mid
else if ( x < S[mid])
return location (low , mid - 1);
else
return location (mid + 1,high);
}
}
Perhatikan bahwa n, S, dan x bukan parameter untuk lokasi fungsi. Karena
mereka tetap tidak berubah di setiap rekursif panggilan, tidak perlu membuat
mereka parameter. Dalam teks ini hanya variabel, yang nilainya dapat berubah di
panggilan rekursif, dibuat parameter untuk rutinitas rekursif. Ada dua alasan
untuk melakukan ini. Pertama, itu membuat ekspresi rutinitas rekursif kurang
berantakan. Kedua, dalam implementasi aktual dari rutin rekursif, yang baru
salinan variabel yang dilewatkan ke rutinitas dibuat di setiap panggilan rekursif.
Jika nilai variabel tidak berubah, maka salinan tidak diperlukan. Limbah ini bisa
mahal jika variabelnya adalah array. Salah satu cara untuk menghindari masalah
ini akan melewati variabel berdasarkan alamat.
39. Gambar 2.1 Langkah-langkah yang dilakukan oleh manusia ketika mencari dengan Pencarian
Biner. (Catatan: x = 18.)
Masing-masing algoritma rekursif dapat diimplementasikan dalam beberapa cara,
tergantung pada bahasa yang digunakan untuk pelaksanaan.. Jika kami
mendefinisikan S dan x secara global dan n adalah jumlah item dalam S,
panggilan tingkat atas kami ke lokasi fungsi dalam Algoritma 2.1 adalah sebagai
berikut:locationout = lokasi (1, n);
Karena versi rekursif dari Pencarian Biner menggunakan rekursi ekor
(yaitu, tidak ada operasi yang dilakukan setelah panggilan rekursif), sangat mudah
untuk menghasilkan versi iteratif, seperti yang dilakukan dalam Bagian 1.2.
Seperti sebelumnya dibahas, kami telah menulis versi rekursif karena rekursi jelas
menggambarkan proses membagi-dan-menaklukkan membagi sebuah instance
menjadi instance yang lebih kecil.
Alasan lain untuk mengganti ekor-rekursi dengan iterasi adalah bahwa
algoritma iteratif akan mengeksekusi lebih cepat (tetapi hanya oleh faktor
pengganda konstan) daripada versi rekursif karena tidak ada tumpukan perlu
dipertahankan. Karena kebanyakan dialek LISP modern mengkompilasi rekursi
ekor ke kode berulang, tidak ada alasan untuk mengganti rekursi ekor oleh iterasi
dalam dialek-dialek ini.Pencarian Biner tidak memiliki kompleksitas waktu setiap
kasus. Jika Anda tidak terbiasa dengan teknik untuk memecahkan persamaan
perulangan, Anda harus mempelajari Lampiran B sebelum melanjutkan.
Analisis Algoritma 2.1
Kompleksitas Kasus Terburuk (Pencarian Biner, Rekursif)
Dalam suatu algoritma yang mencari suatu array, operasi yang paling mahal
biasanya adalah perbandingan item pencarian dengan suatu item array. Jadi, kita
memiliki yang berikut:
Operasi dasar: perbandingan x dengan S [mid ].
Ukuran masukan: n, jumlah item dalam larik.
Kami pertama menganalisis kasus di mana n adalah kekuatan 2. Ada dua
perbandingan x dengan S [mid ] dalam panggilan apa pun ke lokasi fungsi di
mana x tidak sama dengan S [mid]. Namun, seperti yang dibahas dalam analisis
40. informal kami tentang Biner Cari di Bagian 1.2, kita dapat mengasumsikan bahwa
hanya ada satu perbandingan, karena ini akan menjadi kasus di
implementasi bahasa assembler yang efisien. Ingat dari Bagian 1.3 bahwa kita
biasanya berasumsi bahwa dasar operasi dilaksanakan seefisien
mungkin.Sebagaimana dibahas dalam Bagian 1.2, salah satu cara kasus terburuk
dapat terjadi adalah ketika x lebih besar dari semua item array. Jika n adalah
kekuatan dari 2 dan x lebih besar dari semua item array, setiap panggilan rekursif
mengurangi instance menjadi satu tepat setengah besar. Untuk contoh, jika n = 16,
lalu mid = (1 + 16) / 2 = 8. Karena x lebih besar dari semua item array, delapan
item teratas adalah input ke panggilan rekursif pertama. Demikian pula, empat
item teratas adalah input ke panggilan rekursif kedua, dan seterusnya.
Kami memiliki kekambuhan berikut:
Jika n = 1 dan x lebih besar dari item array tunggal, ada perbandingan x dengan
item yang diikuti oleh rekursif panggil dengan rendah> tinggi. Pada titik ini
kondisi terminal benar, yang berarti tidak ada lagi perbandingan.
Oleh karena itu,: (1) adalah 1. Kami telah menetapkan kekambuhan
Kekambuhan ini dipecahkan dalam Contoh B.1 di Appendix B. Solusinya adalah
W(n) = lg n +1
Jika n tidak terbatas menjadi kekuatan 2, maka
W(n) = [lg n] + 1 ϵ Θ(lg n)
di mana y berarti bilangan bulat terbesar kurang dari atau sama dengan y. Kami
menunjukkan cara menetapkan hasil ini dalam latihan.
2.2 Mergesort
Proses yang terkait dengan penyortiran adalah penggabungan. Dengan
penggabungan dua arah, kami mengombinasikan dua susunan yang diurutkan
menjadi satu yang disortir larik. Dengan berulang kali menerapkan prosedur
penggabungan, kita dapat mengurutkan suatu array.
Mergesort melibatkan langkah-langkah berikut:
1. Bagilah array menjadi dua sub-sub bagian masing-masing dengan n / 2 item.
2. Menaklukkan (memecahkan) setiap sub-tugas dengan menyortirnya. Kecuali
array cukup kecil, gunakan rekursi untuk melakukan ini.
3. Gabungkan solusi ke sub-rays dengan menggabungkannya ke dalam susunan
tunggal yan diurutkan.
Contoh berikut mengilustrasikan langkah-langkah ini.
Contoh 2.2
Misalkan array berisi angka-angka ini secara berurutan:
27 10 12 20 25 13 15 22
1. Bagilah larik:
27 10 12 20 dan 25 13 15 22
2. Urutkan masing-masing sub-tugas:
41. 10 12 20 27 dan 13 15 22 25
3. Gabungkan subarray:
10 12 13 15 20 22 25 27
Gambar 2.2 Langkah-langkah yang dilakukan oleh manusia saat menyortir dengan
Mergesort.
Pada Langkah 2, kami berpikir pada tingkat penyelesaian masalah dan
menganggap bahwa solusi untuk subarray tersedia. Untuk membuat hal-hal
menjadi lebih konkret, Gambar 2.2 mengilustrasikan langkah-langkah yang
dilakukan oleh seorang manusia ketika menyortir dengan Mergesort. Itu
kondisi terminal terjadi ketika array ukuran 1 tercapai; pada saat itu,
penggabungan dimulai.
Algoritma 2.2
Mergesort
Masalah: Urutkan n kunci dalam urutan yang tidak menentu.
Masukan: bilangan bulat positif n, susunan kunci S yang diindeks dari 1 menjadi
n.
Keluaran: larik S yang berisi kunci dalam urutan yang nondecreasing.
void mergesort (int n, keytype S [])
{
if ( n > 1) {
const int h = [n/2] , m = n – h;
keytype U [1....h] , V [1...m];
42. copy S [1] through S[h] to U[1] through U[h];
copy S [h + 1] through S[n] to V[1] through V[m];
mergesort (h , U);
mergesort (m, V) ;
merge (h , m ,, U , V ,S);
}
}
Sebelum kita dapat menganalisis Mergesort, kita harus menulis dan menganalisis
suatu algoritma yang menggabungkan dua susunan yang diurutkan.
Algoritma 2.3
Menggabungkan
Masalah: Menggabungkan dua susunan yang diurutkan menjadi satu susunan
yang diurutkan.
Input: bilangan bulat positif h dan m, larik kunci yang diurutkan U yang diindeks
dari 1 hingga h, larik kunci yang diurutkan V yang diindeks dari 1untuk m.
Output: array S yang diindeks dari 1 hingga h + m berisi kunci dalam U dan V
dalam satu array yang diurutkan
Tabel 2.1 Contoh penggabungan dua array U dan V ke dalam satu array S
Nomor yang dibandingkan bercetak tebal
43. Tabel 2.1 mengilustrasikan bagaimana prosedur penggabungan bekerja ketika
menggabungkan dua larik dengan ukuran 4.
44. Analisis Algoritma 2.3
Worse-Case Time Complexity (Merge)
Instruksi perbandingan dan instruksi penugasan masing-masing dapat dianggap
sebagai operasi dasar. Di sini kita akan mempertimbangkan perbandingannya
petunjuk. Ketika kita membahas Mergesort lebih lanjut di Bab 7, kita akan
mempertimbangkan jumlah tugas. Di dalam algoritma, jumlah perbandingan
tergantung pada h dan m. Karena itu kami memiliki yang berikut:
Operasi dasar: perbandingan U [i] dengan V [j].
Ukuran input: h dan m, jumlah item di masing-masing dari dua array input.
Kasus terburuk terjadi ketika loop keluar, karena salah satu indeks - katakanlah,
saya - telah mencapai titik keluarnya h + 1 sedangkan indeks lainnya j telah
mencapai m, 1 kurang dari titik keluarnya. Misalnya, ini dapat terjadi ketika m
pertama – 1 item dalam V ditempatkan pertama di S, diikuti oleh semua item h
dalam U, pada saat mana loop keluar karena saya sama dengan h + 1.
Karena itu,
W (h,m) = h + m -1
Kami sekarang dapat menganalisa Mergesort
Analisis Algoritma 2.2
Kompleksitas Kasus Terburuk (Mergesort)
Operasi dasar adalah perbandingan yang terjadi dalam penggabungan. Karena
jumlah perbandingan meningkat dengan h dan m, dan h dan m meningkat dengan
n, kita memiliki yang berikut:
Operasi dasar: perbandingan yang terjadi dalam gabungan.
Ukuran masukan: n, jumlah item dalam larik S.
Jumlah total perbandingan adalah jumlah dari jumlah perbandingan dalam
panggilan rekursif untuk mergesort dengan U sebagai input, jumlah perbandingan
dalam panggilan rekursif untuk mergesort dengan V sebagai input, dan jumlah
perbandingan di panggilan tingkat atas untuk bergabung. Karena itu,
Kami pertama menganalisis kasus di mana n adalah kekuatan 2. Dalam hal ini,
Ekspresi kami untuk: (n) menjadi
Ketika ukuran input adalah 1, kondisi terminal terpenuhi dan tidak ada
penggabungan yang dilakukan. Oleh karena itu,: (1) adalah 0. Kami punya
menetapkan kekambuhan
45. Perulangan ini dipecahkan dalam Contoh B.19 dalam Lampiran B. Solusinya
adalah
W(n) = n lg n – ( n- 1) ϵ Θ (n lg n )
Untuk n bukan kekuatan 2, kami akan menetapkan dalam latihan itu
di mana [y] dan [y] adalah bilangan bulat terkecil ≥ y dan bilangan bulat terbesar
≤ y, masing-masing. Contoh B.25 dalam Lampiran B, dapat ditunjukkan bahwa:
(n) tidak meningkat. Oleh karena itu, Teorema B.4 dalam lampiran itu
mengimplikasikanbahwa
W(n) = ϵ Θ (n lg n )
Jenis in-place adalah algoritma penyortiran yang tidak menggunakan ruang
tambahan di luar yang diperlukan untuk menyimpan input.
Algoritma 2.2 bukan jenis di tempat karena menggunakan array U dan V selain
array input S. Jika U dan V adalah parameter variabel (dilewatkan oleh alamat)
dalam gabungan, salinan kedua dari array ini tidak akan dibuat saat
penggabungan bernama. Namun, array baru U dan V akan tetap dibuat setiap kali
mergesort dipanggil. Di tingkat atas, jumlah dari jumlah item dalam dua larik ini
adalah n. Dalam panggilan rekursif tingkat atas, jumlah jumlah item dalam dua
larik adalah sekitar n / 2; dalam panggilan rekursif di tingkat berikutnya, jumlah
jumlah item dalam dua larik adalah sekitar n / 4; dan, secara umum, jumlah
jumlah item dalam dua larik pada setiap tingkat rekursi adalah sekitar
setengahnya dari jumlah pada tingkat sebelumnya. Oleh karena itu, jumlah total
item array tambahan yang dibuat adalah sekitar n (1 + 1/2 + 1/4 + .....) = 2n.
Algoritma 2,2 jelas menggambarkan proses membagi contoh masalah
menjadi contoh yang lebih kecil karena dua array baru (instance kecil)
sebenarnya dibuat dari array input (contoh asli). Karena itu, ini adalah a cara
yang baik untuk memperkenalkan Mergesort dan mengilustrasikan pendekatan
divide-and-conquer. Namun, itu mungkin untuk dikurangi jumlah ruang ekstra
hanya satu larik yang berisi n item. Ini dilakukan dengan melakukan banyak hal
manipulasi pada array input S. Metode berikut untuk melakukan ini mirip dengan
metode yang digunakan dalam Algoritma2.1 (Pencarian Biner, Rekursif).
void mergesort2 ( index low , index high )
{
index mid;
if ( low < high ) {
mid = [(low + high )/2];
mergesort2 (low,mid);
mergesort2 ( mid + 1 ,high);
merge2 (low , mid , high);
}
}
Mengikuti konvensi kami membuat hanya variabel, yang nilainya dapat berubah
dalam panggilan rekursif, parameter ke rutinitas rekursif, n dan S bukan
46. parameter untuk prosedur mergesort2. Jika algoritma tersebut diimplementasikan
oleh mendefinisikan S secara global dan n adalah jumlah item dalam S, panggilan
tingkat atas untuk mergesort2 adalah sebagai berikut:
mergesort2 (1, n);
Prosedur penggabungan yang berfungsi dengan mergesort2 mengikuti.
Algoritma 2.5
Gabungkan 2
Masalah: Gabungkan dua sub-bagian yang diurutkan dari S yang dibuat di
Mergesort 2.
Input: indeks rendah, sedang, dan tinggi, dan sub-kontrak S diindeks dari rendah
ke tinggi. Tombol-tombol di slot array dari rendah
hingga pertengahan sudah diurutkan dalam urutan yang tidak menentu, seperti
halnya kunci dalam slot array dari pertengahan + 1 hingga tinggi.
Output: sub-sub dari S yang diindeks dari rendah ke tinggi yang mengandung
kunci dalam urutan yang tidak ditingkatkan.
47. void merge2 (index low , index mid ,index high)
{
index i, j ,k;
keytype U [low.....high]; // Array lokal yang diperlukan untuk
merging
iI = low ; j = mid + 1; k= low ;
while (i ≤ mid && j ≤ high) {
if (S [i] < S[j] ) {
U[k] = S[i] ;
I++;
}
else {
U[k] = S[j];
J++;
}
K++;
}
if ( i > mid)
move S[j] through S [high] to U[k] through U[high];
else
move S[i] through S [high] to U[k] through U[high];
move U [low] through U [high] to S[low] through S[high];
}
2.3 Pendekatan Divide-dan-Conquer
Strategi desain Divide -dan-Conquer melibatkan langkah-langkah berikut:
1. Membagi contoh masalah menjadi satu atau beberapa kejadian yang lebih
kecil.
2. Menaklukkan (memecahkan) masing-masing contoh yang lebih kecil. Kecuali
contoh yang lebih kecil cukup kecil, gunakan rekursi
untuk melakukan ini.
3. Jika perlu, gabungkan solusi ke instance yang lebih kecil untuk mendapatkan
solusi ke instance asli.
Alasan kita mengatakan "jika perlu" di Langkah 3 adalah bahwa dalam
algoritma seperti Binary Search Recursive (Algorithm 2.1) instance dikurangi
menjadi hanya satu instance yang lebih kecil, jadi tidak perlu menggabungkan
solusi.
Lebih banyak contoh pendekatan divide-and-conquer. Dalam contoh ini
kami tidak akan menyebutkan secara eksplisit langkah-langkah sebelumnya
diuraikan. Harus jelas bahwa kita mengikuti mereka
2.4 Quicksort (Partition Exchange Sort)
Selanjutnya kita melihat algoritma penyortiran, yang disebut "Quicksort,"
Quicksort mirip dengan Mergesort dalam hal semacam itu dilakukan dengan
membagi array menjadi dua partisi dan kemudian menyortir setiap partisi secara
48. rekursif. Di Quicksort, bagaimanapun, array dipartisi dengan menempatkan
semua item lebih kecil dari beberapa item pivot sebelumnya item itu dan semua
item yang lebih besar dari item pivot setelahnya. Item pivot bisa berupa item apa
saja, dan untuk kenyamanan kita hanya akan membuatnya menjadi yang pertama.
Contoh berikut mengilustrasikan cara kerja Quicksort.
Contoh 2.3
Misalkan array berisi angka-angka ini secara berurutan:
Sumbu tengah (item pivot)
15 22 13 27 12 10 20 25
1. Partisi larik sehingga semua item yang lebih kecil dari pivot berada di sebelah
kiri dan semua item lebih besar
hak:
Sumbu tengah
10 13 12 15 22 27 20 25
2. Urutkan subarray:
Sumbu tengah
10 12 13 15 20 22 25 27
Telah diurutkan telah diurutkan
Setelah partisi, urutan item dalam subarray tidak ditentukan dan
merupakan hasil dari bagaimana partisidiimplementasikan. Kami telah
memerintahkan mereka sesuai dengan bagaimana rutin partisi, yang akan
disajikan segera, akan menempatkan mereka. Yang penting adalah semua item
yang lebih kecil dari item pivot berada di sebelah kiri, dan semua item lebih besar
berada di sebelah kanannya. Quicksort kemudian disebut secara rekursif untuk
mengurutkan masing-masing dari dua sub-bagian. Merekadipartisi, dan prosedur
ini dilanjutkan hingga array dengan satu item tercapai.
Algoritma 2.6
Quicksort
Masalah: Urutkan n kunci dalam urutan yang tidak menentu.
Masukan: bilangan bulat positif n, susunan kunci S yang diindeks dari 1 menjadi
n.
Keluaran: larik S yang berisi kunci dalam urutan yang nondecreasing.
void quicksort (index low , index high)
{
index pivotpoint;
if (high > low) {
Partition (low , high , pivotpoint) ;
quicksort (low ,pivotpoint - 1);
Quicksort (pivotpoint + 1 , high) ;
}
49. }
Mengikuti konvensi kami yang biasa, n dan S bukanlah parameter untuk prosedur
quicksort. Jika algoritma itu diimplementasikan dengan mendefinisikan S global
dan n adalah jumlah item dalam S, panggilan tingkat atas untuk quicksort akan
menjadi seperti
berikut:
quicksort (1, n);
Gambar 2.3 Langkah-langkah yang dilakukan oleh manusia saat menyortir dengan Quicksort.
Subarray diapit dalam persegi panjang sedangkan pivot point bebas.
Partisi dari array dilakukan oleh partisi prosedur. Selanjutnya kami menunjukkan
algoritma untuk prosedur ini.
Algoritma 2.7
Partisi
Masalah: Mempartisi array S untuk Quicksort.
Input: dua indeks, rendah dan tinggi, dan sub-kontrak S diindeks dari rendah ke
tinggi.
Output: pivotpoint, pivot point untuk subarray diindeks dari rendah ke tinggi.
void partition (index low , index high,
Index pivotpoint )
{
index i ,j ;
Keytype pivotitem ;
pivotitem = S[low]; //Pilih item pertama untuk
j = low ; // pivotitem
for ( i = low + 1 ; i <= high; i++)
if (S [i] < pivotitem ) {
j++
exchange S[i] and S[j] ;
}
pivotpoint = j;
exchange S[low] and S [pivotpoint]; // Letakkan pivotitem
di pivotpoint
50. }
Tabel 2.2 Contoh partisi prosedur *
* Item yang dibandingkan dalam huruf tebal. Item yang baru saja
dipertukarkan muncul dalam kotak
Partisi prosedur bekerja dengan memeriksa setiap item dalam array secara
berurutan. Setiap kali item ditemukan kurang dari item pivot, dipindahkan
ke sisi kiri larik. Tabel 2.2 menunjukkan bagaimana partisi akan diproses
pada larik dalam Contoh 2.3.
Selanjutnya kita menganalisis Partisi dan Quicksort.
Analisis Algoritma 2.7
Kompleksitas Waktu Setiap Kasus (Partisi)
Operasi dasar: perbandingan S [i] dengan pivotitem.
Ukuran masukan: n = tinggi - rendah + 1, jumlah item dalam sub-cabang.
Karena setiap item kecuali yang pertama dibandingkan,
T(n = n - 1)
Kami menggunakan n di sini untuk mewakili ukuran subarray, bukan
ukuran array S. Ini mewakili ukuran S saja ketika partisi dipanggil di
tingkat atas.
Quicksort tidak memiliki kompleksitas setiap kasus. Kami akan
melakukan analisis kasus terburuk dan rata-rata
Analisis Algoritma 2.6
Kompleksitas Kasus Terburuk (Quicksort)
Operasi dasar: perbandingan S [i] dengan pivotitem di partisi.
Ukuran masukan: n, jumlah item dalam larik S.
Anehnya, ternyata bahwa kasus terburuk terjadi jika array sudah disortir
dalam urutan yang tidak menentu. Itu alasan untuk ini harus menjadi jelas.
Jika array sudah disortir dalam urutan yang tidak dikehendaki, tidak ada
item yang kurang dari item pertama dalam larik, yang merupakan item
pivot. Oleh karena itu, ketika partisi dipanggil di tingkat atas, tidak ada
item ditempatkan di sebelah kiri item pivot, dan nilai pivotpoint yang
diberikan oleh partisi adalah 1. Demikian pula, di setiap rekursif
panggil, pivotpoint menerima nilai rendah. Oleh karena itu, array berulang
kali dipartisi menjadi sebuah sub-tugas kosong pada kiri dan subarray
dengan satu item kurang di sebelah kanan. Untuk kelas instance yang
sudah diurutkan dalam nondecreasing pesanan, kami punya
51. Kami menggunakan notasi T (n) karena kami saat ini menentukan
kompleksitas setiap kasus untuk kelas
contoh yang sudah diurutkan dalam urutan yang tidak ditingkatkan.
Karena T (0) = 0, kita memiliki kekambuhan
Kekambuhan ini dipecahkan dalam Contoh B.16 di Appendix B.
Solusinya adalah
Kami telah menetapkan bahwa kasus terburuk setidaknya n (n - 1) / 2.
Meskipun secara intuitif sekarang mungkin tampak bahwa ini adalah
sebagai buruk seperti yang bisa terjadi, kita masih perlu menunjukkan ini.
Kami akan mencapai ini dengan menggunakan induksi untuk
menunjukkan bahwa, untuk semua n,
Induksi basis: Untuk n = 0
Hipotesis induksi: Asumsikan bahwa, untuk 0 ≤ k <n,
Langkah induksi: Kita perlu menunjukkan itu
Untuk n yang diberikan, ada beberapa contoh dengan ukuran n yang
waktu pemrosesannya adalah: (n). Biarkan p menjadi nilai pivotpoint
dikembalikan oleh partisi di tingkat atas saat instance ini diproses. Karena
waktu untuk memproses
contoh ukuran p - 1 dan n - p tidak boleh lebih dari: (p - 1) dan: (n - p),
masing - masing, kita punya
Ketidaksamaan terakhir adalah dengan hipotesis induksi. Manipulasi
aljabar dapat menunjukkan bahwa untuk 1 ≤ p ≤ n ini terakhir ekspresi
adalah
Ini melengkapi bukti induksi.
Kami telah menunjukkan bahwa kompleksitas waktu terburuk diberikan
oleh
52. Kasus terburuk terjadi ketika array sudah diurutkan karena kami
selalu memilih item pertama untuk item pivot. Oleh karena itu, jika kita
memiliki alasan untuk percaya bahwa array tersebut hampir disortir, ini
bukan pilihan yang baik untuk pivot barang. Saat kami membahas
Quicksort lebih lanjut di Bab 7, kami akan menyelidiki metode lain untuk
memilih pivot barang. Jika kita menggunakan metode ini, kasus terburuk
tidak terjadi ketika array sudah disortir. Tapi yang terburuk
kompleksitas waktu masih n (n - 1) / 2.
Dalam kasus terburuk, Algoritma 2.6 tidak lebih cepat dari
Exchange Sort (Algorithm 1.3). Lalu mengapa ini disebut Quicksort?
Seperti yang akan kita lihat, itu dalam perilaku kasus rata-rata bahwa
Quicksort mendapatkan namanya.
Analisis Algoritma 2.6
Kompleksitas Waktu-Kasus-Waktu (Quicksort)
Operasi dasar: perbandingan S [i @ dengan pivotitem di partisi
Ukuran masukan: n, jumlah item dalam larik S.
Kami akan menganggap bahwa kami tidak memiliki alasan untuk percaya
bahwa angka dalam array dalam urutan tertentu, dan oleh karena itu nilai
pivotpoint yang dikembalikan oleh partisi sama-sama mungkin menjadi
salah satu angka dari 1 sampai n. Jika ada alasan untuk mempercayai
distribusi yang berbeda, analisis ini tidak akan berlaku. Rata-rata yang
diperoleh
Oleh karena itu, waktu pengurutan rata-rata ketika setiap pemesanan yang
mungkin diurutkan dalam jumlah yang sama. Pada kasus ini, kompleksitas
waktu rata-rata kasus diberikan oleh kekambuhan berikut:
Memasukkan kesetaraan ini ke dalam hasil Equality 2.1
Mengalikan dengan n yang kita miliki
Mengalikan dengan n yang kita miliki
Menerapkan Kesetaraan 2.2 ke n - 1 memberi
Mengurangi Kesetaraan 2.3 dari hasil Kesetaraan 2,2
53. yang menyederhanakannya
Jika kita membiarkan
Kita punya perulangan
Seperti perulangan dalam Contoh B.22 dalam Lampiran B, solusi
perkiraan untuk perulangan ini diberikan oleh
yang menyiratkan bahwa
Kompleksitas waktu rata-rata Quicksort adalah dari urutan yang sama
dengan kompleksitas waktu Mergesort.
2.5 Algoritma Multiplikasi Matrik Strassen
Ingat bahwa Algoritma 1.4 (Matriks Multiplication) dikalikan dua matriks
secara ketat sesuai dengan definisi perkalian matriks. Kami menunjukkan
bahwa kompleksitas waktu dari jumlah perkaliannya diberikan oleh T (n)
= n3, dimana n adalah jumlah baris dan kolom dalam matriks.. Seperti
kamu akan ditampilkan dalam latihan, setelah algoritma dimodifikasi
sedikit, kompleksitas waktu dari jumlah penambahan diberikan oleh T (n)
= n3 – n2. Karena kedua kompleksitas waktu ini berada di Θ (n3), algoritme
bisa menjadi tidak praktis
cukup cepat. Pada tahun 1969, Strassen menerbitkan suatu algoritma yang
kompleksitas waktunya lebih baik daripada kubik baik dari segi
keduanyperkalian dan penambahan / pengurangan. Contoh berikut
mengilustrasikan metodenya.
Contoh 2.4
Misalkan kita ingin produk C dari dua 2 × 2 matriks, A dan B. Artinya,
Strassen memutuskan bahwa jika kita membiarkannya
Strassen memutuskan bahwa jika kita membiarkannya
54. produk C diberikan oleh
Dalam latihan, Anda akan menunjukkan bahwa ini benar.
Untuk mengalikan dua 2 × 2 matriks, metode Strassen membutuhkan tujuh
perkalian dan 18 penambahan / pengurangan, sedangkan metode langsung
membutuhkan delapan perkalian dan empat penambahan / pengurangan.
Kami telah menyelamatkan diri kita satu perkalian dengan mengorbankan
melakukan 14 penambahan atau pengurangan tambahan. Ini tidak terlalu
mengesankan, dan memang tidak dalam kasus 2 × 2 matriks yang metode
Strassen bernilai. Karena komutatif perkalian tidak digunakan dalam
formula Strassen, formula tersebut berhubungan dengan matriks yang
lebih besar masing-masing dibagi menjadi empat submatrices. Pertama
kita membagi matriks A dan B, seperti yang diilustrasikan pada Gambar
2.4. Berasumsi bahwa n adalah kekuatan 2, matriks A11, misalnya,
dimaksudkan untuk mewakili submatrix A berikut ini:
Dengan menggunakan metode Strassen, pertama kita hitung
M1 = M1 + M4 – M5 + M7
dan C12, C21, dan C22. Akhirnya, produk C dari A dan B diperoleh
dengan menggabungkan empat Cij submatrices. Itu
contoh berikut mengilustrasikan langkah-langkah ini.
Gambar 2.4 Partisi ke dalam submatrices dalam algoritma Strassen.
Contoh 2.5
Seandainya
55. Gambar 2.5 menggambarkan partisi dalam metode Strassen. Perhitungan
berlangsung sebagai berikut:
Gambar 2.5 Partisi dalam algoritma Strassen dengan n = 4 dan nilai-nilai
yang diberikan kepada matriks.
Ketika matriks cukup kecil, kita berkembang biak dengan cara standar.
Dalam contoh ini, kita melakukan ini ketika n = 2.
Karena itu,
Setelah ini, M2
melalui M7 dihitung dengan cara yang sama, dan kemudian nilai-nilai
C11, C12, C21, dan C22 dihitung. Mereka dikombinasikan untuk
menghasilkan C.
Selanjutnya kami menyajikan algoritma untuk metode Strassen ketika n
adalah kekuatan 2.
Algoritma 2.8
Strassen
Masalah: Tentukan produk dari dua nin matriks di mana n adalah kekuatan
2.
Input: sebuah integer n yang merupakan kekuatan 2, dan dua nin matriks A
dan B.
Keluaran: produk C dari A dan B.
void strassen (int n
N x n_matrix A,
N x n_matrix B,
N x n_matrix C )
56. {
if ( n <= threshold)
Compute C = A x B using standard algorithm ;
else {
Partition A into four submatrices A11 , A12 , A21 ,
A22 ;
Partition B into four submatrices B11 , B12 , B21 ,
B22 ;
Compute C = A x B using strassen method ;
//contoh pemanggilan rekursif
//strassen (n / 2 , A11 + A22 , B11 + B22 , M1)
}
}
Nilai ambang adalah titik di mana kita merasa lebih efisien untuk
menggunakan algoritma standar daripada itu akan memanggil prosedur
strassen secara rekursif. Di Bagian 2.7 kami membahas metode untuk
menentukan ambang batas.
Analisis Algoritma 2.8
Analisis Kerumitan Kasus Setiap Kasus Jumlah Perkalian (Strassen)
Operasi dasar: satu perkalian dasar.
Ukuran masukan: n, jumlah baris dan kolom dalam matriks.
Untuk mempermudah, kami menganalisis kasus di mana kita terus
membagi sampai kita memiliki dua 1 × 1 matriks, pada titik mana kita
cukup kalikan angka dalam setiap matriks. Nilai ambang sebenarnya yang
digunakan tidak memengaruhi pesanan. Ketika n = 1,tepat satu perkalian
dilakukan. Ketika kita memiliki dua nin matriks dengan n> 1, algoritma ini
disebut persis tujuh kali dengan matriks (n / 2) × (n / 2) dilewatkan setiap
kali, dan tidak ada perkalian dilakukan di tingkat atas. Kita punya
menetapkan perulangan
Perulangan ini dipecahkan dalam Contoh B.2 dalam Lampiran B.
Solusinya adalah
T(n) = nlg 7 ≈ n2.81 ϵ Θ (n2.81)
Analisis Algoritma 2.8
Analisis Kerumitan Kasus Setiap Jumlah Jumlah Penambahan /
Pengurangan (Strassen)
Operasi dasar: satu penambahan atau pengurangan elementer.
Ukuran masukan: n, jumlah baris dan kolom dalam matriks.
Sekali lagi kami berasumsi bahwa kami terus membagi sampai kami
memiliki dua 1 × 1 matriks. Ketika n = 1, tidak ada penambahan /
pengurangan
57. selesai. Ketika kita memiliki dua nin matriks dengan n> 1, algoritma ini
disebut tepat tujuh kali dengan (n / 2) × (n / 2) matriks dilewatkan pada
setiap waktu, dan 18 penambahan matriks / pengurangan dilakukan pada
matriks (n / 2) × (n / 2). Ketika dua (n / 2) × (n / 2) matriks ditambahkan
atau dikurangkan, (n/2)2 tambahan atau pengurangan dilakukan pada item
dalam matriks. Kita
telah menetapkan kekambuhan
Kekambuhan ini dipecahkan dalam Contoh B.20 dalam Lampiran B.
Solusinya adalah
T(n) = 6nlg 7 – 6n2 ≈ 6n2.81 – 6n2 ϵ Θ (n2.81)
Kami menanamkan matriks di yang lebih besar dengan 2km baris
dan kolom, di mana k = lg n - 4 dan m = n / 2k + 1. Kami menggunakan
metode Strassen hingga a nilai ambang m dan menggunakan algoritma
standar setelah mencapai ambang batas. Dapat ditunjukkan bahwa total
jumlah operasi aritmatika (perkalian, penambahan, dan pengurangan)
kurang dari 4.7n2.81
.
Tabel 2.3 membandingkan kompleksitas waktu dari algoritma standar dan
algoritma Strassen untuk n kekuatan 2. Jika kita mengabaikan untuk saat
overhead yang terlibat dalam panggilan rekursif, algoritma Strassen selalu
lebih efisien dalam hal perkalian, dan untuk nilai besar n, algoritma
Strassen lebih efisien dalam hal penambahan / pengurangan. Dalam
Bagian 2.7 kita akan membahas teknik analisis yang memperhitungkan
waktu yang diambil oleh panggilan rekursif.
Tabel 2.3A perbandingan dua algoritma yang mengalikan matriks n x n
Shmuel Winograd mengembangkan varian dari algoritma Strassen
yang hanya membutuhkan 15 penambahan / pengurangan.Untuk algoritma
ini, kompleksitas waktu penambahan / pengurangan adalah
T(n) ≈ 5n2.81 – 5n2
diberikan oleh Coppersmith dan Winograd (1987) mengembangkan
algoritma perkalian matriks yang kompleksitas waktunya untuk jumlah
perkalian ada di O (n2.38). Namun, konstanta begitu besar sehingga
algoritma Strassen biasanya lebih banyak
efisien.
mungkin untuk membuktikan bahwa perkalian matriks
membutuhkan suatu algoritma yang kompleksitas waktunya paling tidak
kuadratik. Apakah perkalian matriks dapat dilakukan dalam waktu kuadrat
tetap merupakan pertanyaan terbuka; tidak ada yang pernah menciptakan
algoritma kuadrat-waktu untuk perkalian matriks, dan tidak ada yang telah
membuktikan bahwa tidak mungkin untuk membuat seperti itu algoritma.
58. Satu titik terakhir adalah operasi matriks lainnya seperti
membalikkan matriks dan menemukan determinan matriks secara
langsung berkaitan dengan perkalian matriks. Oleh karena itu, kita dapat
dengan mudah membuat algoritma untuk operasi-operasi ini seefisien
algoritma Strassen untuk perkalian matriks.
2.6 Aritmatika dengan Bilangan Besar Besar
Misalkan kita perlu melakukan operasi aritmatika pada bilangan bulat
yang ukurannya melebihi kapabilitas perangkat keras komputer mewakili
bilangan bulat. Jika kita perlu mempertahankan semua angka signifikan
dalam hasil kami, beralih ke floating-point representasi tidak akan bernilai.
Dalam kasus seperti itu, satu-satunya alternatif kami adalah menggunakan
perangkat lunak untuk mewakili dan memanipulasi bilangan bulat. Kita
dapat mencapai hal ini dengan bantuan pendekatan pembagian-dan-
penaklukan. Diskusi kami berfokus pada bilangan bulat yang diwakili
dalam basis 10. Namun, metode yang dikembangkan dapat dengan mudah
dimodifikasi untuk digunakan di lain
basa.
2.6.1 Representasi Penambahan Bilangan Besar dan Waktu Linear
Lainnya Operasi
Cara langsung untuk merepresentasikan bilangan bulat besar adalah
dengan menggunakan larik bilangan bulat, di mana setiap larik larik
menyimpan salah satunya angka. Misalnya, bilangan bulat 543.127 dapat
diwakili dalam larik S sebagai berikut:
Algoritma linear-time dapat dengan mudah ditulis yang melakukan operasi
u x10m u divide 10m u rem 10m
dimana u mewakili integer yang lebih besar, m adalah bilangan bulat non-
negatif, membagi mengembalikan hasil bagi dalam pembagian bilangan
bulat, dan rem mengembalikan sisanya. Ini juga dilakukan dalam latihan.
2.6.2 Penggandaan Bilangan Bulat Besar
Algoritma waktu kuadratik sederhana untuk mengalikan bilangan bulat
besar adalah salah satu yang meniru cara standar yang dipelajari sekolah
tata bahasa. Kami akan mengembangkan yang lebih baik dari waktu
kuadratik. Algoritme kami didasarkan pada penggunaan divide-
andconquer
untuk membagi bilangan bulat n-digit menjadi dua bilangan bulat kira-kira
n / 2 digit. Berikut ini dua contohnya perpecahan.
567,382 = 567 x 103 + 832
6 digit 3 digit 3 digit
59. 9,423,723 = 9432 x 103 + 723
7 digit 4 digit 3 digit
Secara umum, jika n adalah jumlah digit dalam bilangan bulat u, kita akan
membagi bilangan bulat menjadi dua bilangan bulat, satu dengan n / 2 dan
yang lainnya dengan n / 2, sebagai berikut:
U = x x 10m + y
n digit [n/2] digit [n/2] digit
Dengan representasi ini, eksponen m dari 10 diberikan oleh
Jika kita memiliki dua bilangan bulat n-digit
U = x x 10m + y
v = w x 10m + z,
produk mereka diberikan oleh
uv = (x x 10m + y) (w x 10m + z)
= xw x 102m + (xz + wy) x 10m + yz
Kita dapat mengalikan u dan v dengan melakukan empat perkalian pada
bilangan bulat dengan sekitar setengah dari banyak digit dan performanya
operasi linear-waktu. Contoh berikut mengilustrasikan metode ini.
Contoh 2.6
Pertimbangkan yang berikut ini
567,832 x 9,423,723 = (567 x 103 + 832) (9423 x 103 + 732)
= 567 x 9423 x 106 + ( 567 x 723 + 9423 x 832 )
x 103+ 832 x 723
Secara rekursif, bilangan bulat yang lebih kecil ini kemudian dapat
dikalikan dengan membaginya menjadi bilangan bulat yang lebih kecil.
Divisi ini
proses dilanjutkan sampai nilai ambang tercapai, pada saat itu perkalian
dapat dilakukan dalam cara standar
Meskipun kami mengilustrasikan metode menggunakan bilangan
bulat dengan jumlah digit yang hampir sama, itu masih berlaku saat itu
jumlah digit berbeda. Kami hanya menggunakan m = n / 2 untuk
memisahkan keduanya, di mana n adalah jumlah digit dalam integer yang
lebih besar. Algoritme sekarang mengikuti. Kami terus membagi hingga
salah satu bulat adalah 0 atau kami mencapai beberapa nilai ambang
untuk bilangan bulat yang lebih besar, pada saat itu perkalian dilakukan
dengan menggunakan perangkat keras komputer (Yaitu, dengan cara
biasa).
Algoritma 2.9
Penggandaan Bilangan Besar Besar
Masalah: Kalikan dua bilangan bulat besar, u dan v.
Masukan: bilangan bulat besar u dan v.
60. Output: prod, produk dari u dan v.
large_integer prod (large_integer u , large_integer v)
{
large integer x, y ,w , z;
int n,m;
n = maximum (number of digits in u , number of digits in v)
if (u == 0 || v == 0 )
return 0;
else if (n <= threshold )
return u x v obtained in the usual way;
else {
m = [n/2]
x = u divide 10m ; y = u rem 10m ;
w = v divide 10m ; z = v rem 10m ;
return prod (x,w) x 102m + (prod (x,z) + prod (w, y) ) x 10m
+ prod(y,z) ;
}
}
Perhatikan bahwa n adalah input implisit ke algoritma karena itu adalah
jumlah digit yang lebih besar dari keduanya bilangan bulat. Ingat bahwa
membagi, rem, dan × mewakili fungsi linear-waktu yang perlu kita tulis.
Nilai aktual di mana kita tidak lagi membagi instance kurang dari atau
sama dengan ambang dan merupakan kekuatan 2, karena semua input
dalam hal ini adalah kekuatan 2.
Untuk tidak terbatas pada kekuatan 2, adalah mungkin untuk
membangun kekambuhan seperti yang sebelumnya tetapi melibatkan
lantai dan langit-langit. Menggunakan argumen induksi seperti yang ada
dalam Contoh B.25 di Appendix B, kita dapat menunjukkan itu : (n)
akhirnya nondecreasing. Oleh karena itu, Teorema B.6 dalam Lampiran B
menyiratkan bahwa
W(n) ϵ Θ (nlg 4) = Θ(n2)
Algoritma kami untuk mengalikan bilangan bulat besar masih kuadrat.
Masalahnya adalah algoritma itu melakukan empat perkalian pada
bilangan bulat dengan setengah digit sebanyak bilangan bulat asli. Jika kita
bisa mengurangi jumlah ini perkalian, kita bisa mendapatkan algoritma
yang lebih baik daripada kuadrat. Kami melakukan ini dengan cara
berikut. Ingat itu fungsi prod harus menentukan
xw, xz + yw , dan yz , (2.4)
dan kami mencapai ini dengan memanggil fungsi prod secara rekursif
empat kali untuk menghitung
xw , xz , yw dan yz
Jika bukan kita mengatur
r = ( x + y ) ( w + z) = xw + (xz + yw ) + yz;
Kemudian