Pengenalan Desain dan Analisis
Algoritma
Sebagai
salah satu dasar dari ilmu komputer, algoritma merupakan hal yang sangat
penting untuk dikuasai oleh orang-orang yang berkecimpung di dunia ilmu
komputer, dari peneliti sampai ke praktisi. Tentunya penguasaan akan algoritma
tidak cukup hanya sampai pada tahap mengetahui dan menggunakan algoritma yang
tepat untuk menyelesaikan masalah. Seorang yang mengerti ilmu komputer harus
juga mampu merancang dan mengembangkan sebuah algoritma berdasarkan
masalah-masalah yang ditemui. Tulisan ini bertujuan untuk memberikan pengertian
mendasar mengenai perancangan (desain) dan pengembangan algoritma, agar pembaca
dapat tidak hanya menggunakan algoritma yang sudah ada, tetapi juga merancang
dan mengembangkan algoritma sesuai dengan masalah yang akan diselesaikan.
Selain
memberikan dasar perancangan, tulisan ini juga membahas jenis-jenis algoritma
yang ada, untuk kemudian melakukan analisa terhadap beberapa algoritma untuk
setiap jenisnya. Analisis algoritma dilakukan dengan tujuan utama agar pembaca
dapat mengambil keputusan yang tepat dalam memilih algoritma untuk solusi.
Apa itu Algoritma?
Sebelum
membahas mengenai perancangan ataupun analisis algoritma, tentunya kita
terlebih dahulu harus mendefinisikan arti dari “Algoritma”. Apa itu algoritma?
Algoritma merupakan langkah-langkah
(prosedur) yang harus dilakukan untuk menyelesaikan sebuah masalah.
Program komputer
umumnya dibangun dengan menggunakan beberapa algoritma untuk menyelesaikan
sebuah permasalahan. Misalnya sebuah program pencarian teks seperti grep akan memerlukan algoritma khusus untuk membaca dan menelusuri file,
algoritma lain untuk mencari teks yang tepat di dalam file, dan satu algoritma
lagi untuk menampilkan hasil pencarian ke pengguna.
Dalam
mendefinisikan algoritma, kita harus dapat mendefinisikan tiga hal utama dengan
jelas, yaitu:
- Masalah, yaitu sebuah persoalan yang ingin diselesaikan oleh sebuah algoritma.
- Masukan, yaitu contoh data atau keadaan yang menjadi permasalahan.
- Keluaran, yaitu bentuk akhir dari data atau keadaan setelah algoritma diimplementasikan ke masukan. Keluaran merupakan hasil ideal yang diinginkan dan dianggap telah menyelesaikan masalah.
Contoh (dan Solusi) Algoritma
Contoh dari
sebuah definisi algoritma yang benar adalah sebagai berikut:
Masalah
Pengurutan sekumpulan nilai yang
bernilai acak.
Masukan
Serangkaian data berukuran $n$.
Keluaran
Serangkaian data berukuran $n$,
dengan urutan \(a_1 \leq a_2 \leq a_3 \leq ... \leq a_{n-1} \leq a_{n}\), di
mana \(a_x\) adalah data pada posisi \(x\) dalam rangkaian.
Data masukan
yang diinginkan merupakan rangkaian data, tanpa memperdulikan jenis data
(angka, huruf, teks, dan lainnya). Contoh dari nilai masukan adalah [2, 5, 1, 3, 4] ataupun ["Doni", "Andi", "Budi", "Clara"]. Data keluaran yang diinginkan,
tentunya adalah data masukan yang telah terurut: [1, 2, 3, 4, 5] dan ["Andi", "Budi", "Clara", "Doni"].
Untuk
menyelesaikan masalah yang diberikan di atas, kita dapat menggunakan algoritma insertion sort. Kode di bawah menunjukkan implementasi insertion sort pada bahasa pemrograman python:
def insertion_sort(data):
for i in range(0,
len(data)):
insert_val
= data[i]
hole_pos
= i
while hole_pos
> 0 and insert_val < data[hole_pos - 1]:
data[hole_pos]
= data[hole_pos - 1]
hole_pos
= hole_pos - 1
data[hole_pos]
= insert_val
Implementasi
insertion sort yang diberikan di atas menunjukkan
bahwa pada dasarnya sebuah prosedur yang harus dijalankan untuk mengubah data
masukan menjadi data keluaran, sehingga masalah dapat terselesaikan.
Algoritma yang Baik
Kita telah
mengetahui dengan jelas makna dari algoritma, sehingga pertanyaan selanjutnya
adalah algoritma seperti apa yang dapat dikatakan sebagai algoritma yang
baik? Pada umumnya kita tidak ingin menggunakan algoritma yang salah untuk
menyelesaikan masalah karena hal ini dapat menyebabkan masalah tidak
diselesaikan dengan optimal, atau lebih buruknya, tidak diselesaikan sama
sekali.
Sebuah
algoritma yang baik memiliki sifat-sifat berikut:
- Benar, di mana algoritma menyelesaikan masalah dengan tepat, sesuai dengan definisi masukan / keluaran algoritma yang diberikan.
- Efisien, berarti algoritma menyelesaikan masalah tanpa memberatkan bagian lain dari apliikasi. Sebuah algoritma yang tidak efisien akan menggunakan sumber daya (memori, CPU) yang besar dan memberatkan aplikasi yang mengimplementasikan algoritma tersebut.
- Mudah diimplementasikan, artinya sebuah algoritma yang baik harus dapat dimengerti dengan mudah sehingga implementasi algoritma dapat dilakukan siapapun dengan pendidikan yang tepat, dalam waktu yang masuk akal.
Pada
prakteknya, tentunya ketiga hal tersebut tidak dapat selalu tercapai. Kebenaran
dari sebuah algoritma umumnya selalu dapat dicapai, setidaknya untuk
nilai-nilai masukan umum, tetapi efisiensi dan kemudahan implementasi tidak
selalu didapatkan. Begitupun, tentunya kita harus tetap berusaha mencapai
ketiga hal tersebut dalam merancang sebuah algoritma.
Pembuktian Kebenaran Algoritma
Kita telah
mengetahui bahwa sebuah algoritma yang baik adalah algoritma yang benar,
efisien, dan mudah diimplementasikan. Pertanyaan berikutnya tentunya adalah,
bagaimana kita mengetahui bahwa sebuah algoritma telah benar? Algoritma yang
efisien itu seperti apa? Bagaimana kita mengukur kemudahan implementasi sebuah
algoritma?
Bagian ini
akan membahas mengenai pertanyaan pertama, yaitu bagaimana kita dapat
mengetahui kebenaran sebuah algoritma. Tentunya efisiensi dan kemudahan
implementasi sebuah algoritma menjadi tidak penting jika algoritma tersebut
tidak dapat memberikan hasil yang benar.
Definisi
dari kebenaran algoritma yang digunakan pada tulisan ini adalah sebagai
berikut:
Sebuah algoritma dikatakan telah
benar jika algoritma tersebut dapat memberikan keluaran yang benar jika
menerima masukan sesuai dengan definisi algoritma tersebut, dan algoritma
tersebut terbukti akan selalu dapat diterminasi (berakhir).
Pembuktian
kebenaran sebuah algoritma sendiri dapat dilakukan dengan beberapa cara,
misalnya:
- Induksi Matematika,
- Pembuktian kontradiktif,
- Pembuktian kontrapositif, dan
- Metode Formal.
Masing-masing
alat pembuktian yang disebutkan memiliki kelebihan dan kekurangan
masing-masing, serta kasus pengunaan yang berbeda-beda. Perlu diingat juga
bahwa masih terdapat sangat banyak alat-alat pembuktikan lainnya yang dapat
digunakan, tetapi kita hanya membahas satu cara pembuktian (induksi
matematika) saja sebagai pengenalan cara membuktikan algoritma. Jika
dibutuhkan, metode dan alat pembuktian lain akan dijelaskan lagi pada bagian
yang relevan.
Sekarang
mari kita lihat penggunaan masing-masing alat tersebut untuk membuktikan
algoritma!
Induksi Matematika
Induksi
matematika merupakan alat pembuktian matematis yang digunakan untuk membuktikan
pernyataan atau proses yang melibatkan perhitungan bilangan asli yang berulang.
Contoh dari rumus matematis yang dapat dibuktikan dengan menggunakan induksi
matematika yaitu perhitungan deret aritmatika, deret geometris, ataupun sigma
bilangan.
Pembuktian
menggunakan induksi matematika dilakukan dengan dua langkah, yaitu:
- Melakukan pembuktian kasus dasar (base case), yaitu membuktikan bahwa sebuah pernyataan (fungsi) matematika atau algoritma bernilai benar jika diaplikasikan pada bilangan pertama yang sah sesuai dengan spesifikasi fungsi atau algoritma tersebut.
- Melakukan induksi, yaitu membuktikan bahwa kebenaran dari fungsi \(P(k+1)\) jika kebenaran fungsi \(P(k)\) diketahui.
Dengan
membuktikan kedua hal tersebut, kita dapat mengambil kesimpulan bahwa sebuah
fungsi matematika atau algoritma bernilai benar untuk semua bilangan asli. Jika
diimplementasikan dengan tepat, induksi matematika dapat juga digunakan untuk
membuktikan kebenaran algoritma rekursif seperti penelusuran pohon (tree).
Untuk lebih
jelasnya, mari kita lihat beberapa contoh cara pembuktian yang dilakukan dengan
menggunakan induksi matematika.
Contoh 1: Deret Aritmatika
Misalkan
kita diminta untuk membuktikan bahwa pernyataan matematika untuk perhitungan
deret aritmatika berikut:
\[1 + 2 + 3
+ ... + n = \frac{n(n + 1)}{2}\]
adalah benar
untuk semua bilangan bulat \(n \geq 1\).
Untuk
membuktikan pernyataan matematika di atas, terlebih dahulu kita harus mengubah
pernyataan matematika tersebut menjadi sebuah fungsi matematika:
\[P(k) = 1 +
2 + 3 + ... + n = \frac{k(k + 1)}{2}\]
dan kemudian
membuktikan kebenarannya menggunakan induksi matematika. Seperti yang telah
dijelaskan sebelumnya, kita harus menjalankan dua langkah untuk melakukan
pembuktian dengan induksi:
- Pembuktian Kasus Dasar
Karena pernyataan matematika pada soal menyatakan
bahwa pernyataan benar untuk semua bilangan bulat \(k \geq 1\), maka untuk
pembuktian kasus dasar kita harus membuktikan bahwa \(P(1)\) adalah benar untuk
ruas kiri maupun ruas kanan dari \(P(k)\).
\[\begin{split}P(1)= 1 & = \frac{1(1+1)}{2} \\ 1
& = \frac{1(2)}{2} \\ 1 & = \frac{2}{2} \\ 1 & = 1\end{split}\]
karena hasil akhir dari ruas kanan dan ruas kiri
adalah sama (\(1\)), maka dapat dikatakan bahwa kasus dasar telah terbukti.
- Induksi
Untuk pembuktian induksi, kita harus membuktikan bahwa
\(P(k) \rightarrow P(k + 1)\) bernilai benar.
Langkah pertama yang dapat kita lakukan yaitu
menuliskan fungsi matematis dari \(P(k + 1)\) terlebih dahulu:
\[P(k + 1) = 1 + 2 + ... + k + (k + 1) = \frac{(k +
1)((k + 1) + 1)}{2}\]
dan kemudian kita harus membuktikan bahwa ruas kiri
dan ruas kanan dari \(P(k + 1)\) adalah sama. Pembuktian akan kita lakukan
dengan melakukan penurunan pada ruas kiri agar menjadi sama dengan ruas kanan:
\[\begin{split}1 + 2 + ... + k + (k + 1) & = (1 +
2 + ... + k) + (k + 1) \\ & = \frac{k(k + 1)}{2} + (k + 1) \\ & =
\frac{k(k + 1) + 2(k + 1)}{2} \\ & = \frac{k^2 + 3k + 2}{2} \\ & =
\frac{(k + 1)(k + 2)}{2} \\ & = \frac{(k + 1)((k + 1) + 2)}{2}\end{split}\]
dan seperti yang dapat dilihat, ruas kiri dari \(P(k +
1)\) telah menjadi sama dengan ruas kanannya, sehingga dapat dikatakan bahwa
tahap induksi telah berhasil dibuktikan benar.
Dengan
pembuktian kasus dasar dan induksi yang bernilai benar, kita dapat menyimpulkan
bahwa \(P(n)\) bernilai benar untuk \(n \geq 1\).
Contoh 2: Pembuktian Hipotesa
Anda diminta
untuk membuktikan hipotesa bahwa fungsi matematika \(n^3-n\) habis dibagi 6
untuk semua bilangan bulat \(n \geq 2\).
Langkah
untuk membuktikan pernyataan tersebut sama dengan sebelumnya. Mulai dari
definisi ulang fungsi matematikanya:
\[P(k) = k^3
- k\]
Dan kemudian
lakukan induksi matematika, langkah demi langkah:
- Pembuktian Kasus Dasar
Lakukan perhitungan \(P(2)\) (karena nilai \(k\)
minimal 2) dan pastikan hasilnya habis dibagi 6:
\[\begin{split}P(1) & = 2^3 - 2 \\ & = 8 - 2
\\ & = 6\end{split}\]
karena \(6 \bmod 6 = 0\) maka telah dapat dibuktikan
bahwa kasus dasar bernilai benar.
- Induksi
Jika \(P(k)\) benar habis dibagi 6, maka \(P(k + 1)\),
atau \((k + 1)^3 - (k + 1)\) harus juga habis dibagi 6. Mari kita lakukan
pembuktiannya:
\[\begin{split}P(k + 1) & = (k + 1)^3 - (k + 1) \\
& = (k^3 + 3k^2 + 3k + 1) - k - 1 \\ & = k^3 - 3k^2 + 2k \\ & = k^3
- 3k^2 + 2k + k - k \\ & = k^3 - 3k^2 + 3k - k \\ & = k^3 - k + 3k^2 +
3k \\ & = (k^3 - k) + 3k(k + 1)\end{split}\]
dan dapat dilihat bagaimana \(P(k + 1)\) telah
terbukti habis dibagi 6 karena:
- \(k^3 - k\) habis dibagi 6, sesuai dengan hipotesa \(P(k)\), dan
- \(3k(k + 1)\) habis dibagi 6 karena salah satu nikai dari \(k\) atau \(k + 1\) pasti merupakan bilangan genap, yang jika dikalikan dengan 3 akan habis dibagi 6.
Setelah berhasil menyelesaikan dua langkah induksi,
kita dapat menyimpulkan bahwa \(P(k) = k^3 - k\) habis dibagi 6 untuk \(k \geq
2\).
Induksi Matematika untuk Pembuktian Algoritma
Seperti yang
dapat dilihat dari apa yang telah kita pelajari pada bagian sebelumnya, induksi
matematika jelas sangat berguna untuk membuktikan kebenaran sebuah teorema atau
fungsi yang melibatkan perhitungan bilangan bulat yang berulang. Tetapi apa
guna induksi matematika untuk membuktikan kebenaran sebuah algoritma?
Sebuah
algoritma kerap kali akan memiliki bagian yang melakukan perhitungan bilangan
atau data secara berulang. Kita dapat menggunakan konsep perulangan pada
pemrograman untuk menerapkan perhitungan bilangan ataupun data secara berulang.
Misalnya, algoritma berikut menghitung hasil kali dari dua buah bilangan bulat:
def kali(m, n):
if m < 0:
return -1
# error
else:
i = 0
result =
0
while(m !=
i):
result
= result + n
i = i
+ 1
return result
yang secara
matematis dapat dituliskan sebagai fungsi berikut:
\[f(m, n) =
\sum_{i=1}^{n} m; n \geq 0\]
atau lebih
sederhananya:
\[m \times n
= \underbrace{m + m + m + ... + m}_{\text{n kali}}\]
dan secara
otomatis tentunya pernyataan matematis tersebut dapat kita buktikan dengan
menggunakan induksi matematika. Pembuktian perulangan yang lebih kompleks
sendiri dapat dilakukan dengan teknik yang dikenal dengan nama loop
invariant, yang tidak akan dijelaskan pada tulisan ini.
Pemodelan Masalah
Pada bagian
sebelumnya kita telah melihat bagaimana sebuah algoritma dituliskan menjadi
fungsi matematika. Baik algoritma maupun fungsi matematika adalah sebuah model,
yang digunakan untuk menggambarkan masalah yang ditemui pada dunia nyata, dan
ingin diselesaikan, baik dengan menggunakan matematika ataupun program
komputer. Dengan memiliki model masalah kita dapat lebih mudah mengerti masalah
yang akan diselesaikan, yang akan menyebabkan solusi yang ditawarkan menjadi
lebih baik.
Tetapi
pertanyaannya tentunya adalah, bagaimana kita membuat model yang benar dari
masalah-masalah yang ada? Bagian ini akan menjelaskan mengenai cara pembangunan
model, baik secara matematis maupun algoritmik, yang benar.
Jenis-Jenis Model
Sebelum
mulai membangun model permasalahan, tentunya kita terlebih dahulu harus
mengetahui jenis-jenis model yang ada. Terdapat enam jenis model yang umum
digunakan untuk menggambarkan masalah dalam dunia algoritma / pemrograman,
yaitu:
- Model Numerik
Model numerik merupakan model matematis yang paling
sederhana, yang dibuat untuk mendeskripsikan jumlah atau ukuran dari sesuatu.
Model numerik menggunakan angka (1, 2, 3, dst) untuk mendeskripsikan suatu hal.
Misalkan gambar di bawah:
Model Numerik Sapi
memberikan informasi sejumlah sapi yang ada di dalam
kotak. Model numerik paling sederhana dan informatif yang dapat kita ambil dari
gambar tersebut adalah ‘Lima ekor Sapi’ atau ‘Lima Sapi’.
- Model Simbolik
Jika kita mengembangkan model numerik lebih jauh, kita
kemudian dapat menambahkan simbol-simbol baru untuk melakukan pemrosesan
terhadap angka-angka yang ada pada model numerik. Terdapat empat buah simbol
dasar untuk pemrosesan angka, yaitu \(+, -, \times, \text{dan} \div\). Simbol \(=\)
juga digunakan untuk menandakan kesamaan nilai antara ruas kiri dan ruas kanan
dari \(=\).
Note
Simbol \(\times \text{dan} \div\) akan dituliskan
sebagai \(*\) dan \(/\) pada tulisan ini, karena kedua simbol tersebut lebih
umum digunakan pada lingkungan ilmu komputer.
Jadi, sebuah ekspresi matematika seperti ini:
\[10 = 5 * 2\]
dapat dikatakan adalah sebuah model simbolik. Tentunya
operator-operator numerik yang disebutkan sebelumnya memiliki aturan tertentu
untuk beropearsi. Aturan-aturan umum yang kita temui untuk operator numerik
yaitu:
- Hukum Kumulatif, di mana \(a + b = b + a\) dan \(a * b = b * a\).
- Hukum Asosiatif, di mana \(a + (b + c) = (a + b) + c\) dan \(a * (b * c) = (a * b) * c\).
- Hukum Distribusi, di mana \(a * (b + c) = (a * b) + (a * c)\).
- Hukum Invers, yaitu \(a + (-a) = 0\) dan a * frac{1}{a} = 1.
- Hukum Identitas, yaitu \(a + 0 = a$ dan $a * 1 = a\).
- Perkalian dengan 0, yaitu \(a * 0 = 0\).
Penjelasan mengenai kegunaan dan cara kerja dari
hukum-hukum tersebut tidak akan dibahas lagi, karena dianggap telah diketahui
oleh pembaca. Yang perlu diperhatikan adalah bagaimana kita menuliskan
simbol-simbol seperti $a$ dan $b$, untuk melambangkan semua bilangan-bilangan
yang mengikuti hukum-hukum di atas. Simbol-simbol yang dapat melambangkan
bilangan atau nilai lain secara generik seperti ini dikenal dengan nama variabel.
Sebuah variabel merupakan simbol yang digunakan untuk
merepresentasikan nilai yang dapat berubah kapanpun, tergantung dari nilai yang
kita berikan kepada variabel tersebut. Variabel digunakan dalam model simbolik
untuk mewakili nilai-nilai yang dapat berubah sewaktu-waktu, misalnya nilai
yang harus dibaca dari masukan pengguna atau nilai yang diambil secara acak.
Sebuah model bahkan dapat terdiri dari hanya variabel saja, misalnya model
matematika untuk menghitung luas sebuah persegi panjang dapat dituliskan
seperti berikut:
\[L = p * l\]
di mana \(p\) dan \(l\) mewakili panjang dan lebar
persegi panjang, yang nilainya selalu berbeda-beda, tergantung dengan persegi
panjang yang akan dihitung luasnya. Nilai \(L\), yang merepersentasikan luas
persegi panjang, sendiri bergantung kepada nilai \(p\) dan \(l\), sehingga kita
tidak akan mendapatkan nilai \(L\) yang konstan.
Deklarasi variabel sendiri dilakukan dengan
menggunakan perintah $let$, seperti berikut:
\[\text{let }L = \text{Luas Persegi}\]
Selain model-model dengan variabel, tentunya kita juga
memiliki model-model yang memiliki bilangan konstan yang tidak berubah,
misalnya untuk menghitung luas segitiga:
\[L = \frac{1}{2} * a * t\]
atau model untuk menghitung keliling lingkaran:
\[K = 2 * \pi * r\]
Nilai-nilai yang tidak pernah berubah pada kedua model
di atas (seperti \(2\), \(\frac{1}{2}\), dan \(\pi\)) dikenal dengan nama konstanta.
Perhatikan bahwa konstanta dapat mencakup angka “mentah” seperti \(2\) ataupun
simbol yang dikenal secara luas seperti \(\pi\). Konstanta biasanya
dideklarasikan pada awal model atau kamus data program, dan tidak pernah berubah
nilainya selama model tersebut digunakan.
Dari berbagai komponen dan contoh model simbolik yang
telah kita lihat, dapat disimpulkan bahwa model simbolik merupakan model yang
menggambarkan interaksi dan operasi antar komponen numerik secara abstrak. Abstraksi
dari komponen numerik (angka) pada model simbolik dilakukan dengan menggunakan
variabel dan konstanta.
- Model Spasial
Tidak semua permasalahan yang diselesaikan oleh
matematika atau komputer selalu berhubungan langsung dengan angka. Terkadang
kita menjumpai juga masalah-masalah yang berhubungan dengan representasi dunia
nyata seperti perhitungan jarak dua objek atau pencarian jalur terdekat untuk
kendaraan. Secara tradisional, model untuk penyelesaian masalah seperti ini
digambarkan dengan peta, graph, dan gambar-gambar teknis lainnya.
Untuk dunia komputer, model-model dunia nyata biasanya
digambarkan dengan menggunakan koordinat. Sistem koordinat yang paling populer
digunakan dalam hal ini adalah koordinat kartesius. Koordinat kartesius merupakan
sistem koordinat yang menggambarkan sebuah nilai riil di dalam kumpulan nilai
yang direpresentasikan dengan sebuah garis. Sistem kartesius dapat digambarkan
dalam banyak dimensi, sesuai dengan jumlah kumpulan nilai yang digambarkan.
Untuk memudahkan pengertian, gambar di bawah memperlihatkan contoh sistem
koordinat kartesius dua dimensi:
Sistem Koordinat Kartesius
Untuk menyederhanakan masalah, mayoritas algoritma dan
solusi yang dikembangkan dalam kuliah ini akan dilakukan dengan menggunakan
sistem kartesius dua dimensi. Sistem tiga dimensi dan satu dimensi dianggap
dapat diimplementasikan menggunakan konsep yang sama dengan sistem dua dimensi.
Data pada sistem kartesius dua dimensi dapat
direpresentasikan dalam bentuk sebuah titik, yaitu kombinasi antara sumbu x dan
sumbu y:
Titik pada Kartesius
atau sebuah garis, yang direpresentasikan dengan
sebuah fungsi matematika:
Garis pada Kartesius
Dalam prakteknya, kita juga akan sering memerlukan
informasi arah pergerakan dari sebuah garis. Untuk merepresentasikan hal
tersebut, kita dapat menambahkan sebuah tanda panah pada garis:
Garis Berarah pada Kartesius
dan yang terakhir, kita dapat juga merepresentasikan
sebuah bentuk atau bidang, menggunakan kombinasi beberapa garis:
Bidang pada Kartesius
Untuk melakukan pemrosesan data-data yang ada di dalam
sistem kartesius, kita dapat melakukan operasi terhadap titik-titik yang
merepresentasikan data tersebut. Titik-titik direpresentasikan dalam bentuk
matriks atau array. Misalnya, segitiga yang ada pada gambar di atas dapat
direperesentasikan sebagai matriks berikut:
\[\begin{split}\begin{bmatrix} -3 & 4 & 1 \\ 1
& 3 & -2 \end{bmatrix}\end{split}\]
Dan kemudian tentunya kita dapat melakukan operasi-operasi
matriks untuk melakukan berbagai hal terhadap segitiga tersebut.
- Model Logis
Model logis merupakan cara memodelkan masalah
berdasarkan logika matematika. Terdapat empat cabang utama dari logika
matematika, yaitu teori himpunan, teori model, teori rekursif, dan teori
pembuktian. Masing-masing teori memiliki cara pemodelan yang berbeda-beda,
untuk merepresentasikan masalah yang berbeda. Tulisan ini hanya akan membahas
pemodelan logis pada bidang himpunan, dan relevansinya dengan salah satu sistem
yang paling populer di dunia komputer: basis data.
Himpunan, seperti namanya, memodelkan sekumpulan
entitas yang memiliki atribut (ciri khas) tertentu. Dalam menentukan atribut tujuan
dari pengunaan himpunan lebih penting daripada kesamaan ciri khas dari entitas,
sehingga terkadang atribut dari elemen-elemen dalam himpunan tidak selalu dapat
dilihat dengan mudah. Misalnya, kita dapat mendeklarasikan sebuah himpunan
dengan nama “Himpunan Barang dalam Handbag” dengan isi berupa “handphone,
gunting kuku, alat make-up, tissue, dompet, alat tulis, dan karet gelang”.
Secara sekilas semua entitas yang ada di dalam himpunan tidak terlihat memiliki
atribut yang jelas, meskipun himpunan ini adalah himpunan yang valid.
Terdapat dua aturan khusus yang harus dipenuhi oleh sebuah
himpunan, yaitu:
- Himpunan harus didefinisikan dengan tepat. Sebuah entitas yang ada di dunia hanya dapat memiliki dua status berkaitan dengan himpunan yang didefinisikan: TERMASUK dalam himpunan atau TIDAK TERMASUK. Tidak boleh ada elemen yang bersifat ambigu, dalam arti tidak jelas masuk ke dalam himpunan atau tidak. Misalnya, kita tidak dapat mendefinisikan sebuah himpunan yang berisi “Orang Tinggi” karena tidak terdapat definisi dari “tinggi” yang jelas. Apakah 170 cm termasuk tinggi? 180?
Yang dapat kita definisikan ialah himpunan yang berisi
“Orang dengan tinggi badan di atas 175 cm”, sehingga tidak terdapat perdebatan
mengenai apakah 170 cm termasuk tinggi atau tidak.
- Setiap elemen dalam himpunan harus unik. Sebuah himpunan tidak boleh memiliki nilai ganda. Aturan ini menyebabkan banyak himpunan yang ada di dunia nyata tidak dapat direpresentasikan dengan himpunan matematika. Misalnya, kita dapat saja memiliki himpunan sendok yang terdiri dari banyak sendok identik. Dalam himpunan matematis, hal ini tidak diperbolehkan. Aturan ini juga menyebabkan penggabungan himpunan menjadi sedikit berbeda. Himpunan berisi angka 1, 2, 3, 4 jika digabungkan dengan himpunan 3, 4, 5, 6 akan menghasilkan himpunan 1, 2, 3, 4, 5, 6. Ide “nilai unik” untuk setiap elemen dalam himpunan ini lah yang menjadi dasar dari pengindeksan dan primary key dari basis data relasional.
Pemodelan himpunan sendiri biasanya dilakukan dengan
menggunakan diagram Venn. Gambar di bawah memberikan contoh sebuah diagram
Venn, yang menggambarkan himpunan dari segi empat:
Contoh Diagram Venn
Dari gambar diagram Venn di atas, kita dapat melihat
bagaimana seluruh persegi adalah juga persegi panjang, dan baik persegi maupun
persegi panjang adalah merupakan segi empat. Jika kita menambahkan jenis segi
empat lainnya, misalnya trapesium, dapatkah anda menggambarkan diagram
Venn-nya?
- Model Statistik
Terdapat banyak permasalahan di dunia nyata yang tidak
dapat dimodelkan dengan mudah menggunakan keempat model matematis yang telah
kita bahas sebelumnya. Terkadang kita dihadapkan dengan permasalahan yang
sangat kompleks, sampai-sampai memodelkan dan menganalisa setiap situasi yang
mempengaruhi masalah tersebut akan menjadi sangat mahal, memerlukan banyak
orang, dan banyak waktu.
Sebagai contoh, bayangkan jika kita diminta untuk
melakukan prakiraan cuaca. Dengan menggunakan model matematis yang ada, kita
akan memerlukan sangat banyak kalkulasi, yang saling mempengaruhi satu
sama lainnya. Praktisnya, kita harus mampu melakukan simulasi terhadap
seluruh elemen yang ada di bumi untuk melakukan prakiraan cuaca dengan
tepat. Hal ini tentunya sangat tidak efektif untuk dilakukan. Lalu bagaimana
para ahli sekarang melakukan prakiraan cuaca?
Jawabannya adalah model statistik.
Dengan mengumpulkan sampel data cuaca pada masa lalu, kita dapat melihat kecenderungan
atau tren cuaca yang akan terjadi sesuai dengan keadaan cuaca kita
sekarang. Pada dasarnya, sebuah model statistik melakukan analisa tren terhadap
sampel data yang relevan untuk meniadakan ketidak pastian atau keadaan khusus.
Dengan mengambil keadaan rata-rata dari sekumpulan data, kita akan mendapatkan kecenderungan
dari sebuah keadaan jika dihadapkan dengan keadaan umumnya.
Contoh Model Statistik
Gambar di atas menunjukkan contoh dari model
statistik. Ingat, bahwa kesimpulan yang dapat diambil dari sebuah model
statistik hanyalah berupa kecenderungan atau tren. Kita tidak
bisa membuktikan sesuatu atau memberikan hasil yang pasti menggunakan
statistik. Dapat dikatakan bahwa kalimat seperti “statistik membuktikan ...”
pada tulisan ilmiah populer kurang tepat.
- Pseudocode
Semua model matematis yang telah dijelaskan sebelumnya
merupakan model matematika yang digunakan dan dimengerti oleh manusia. Jika
ingin menggunakan model matematis tersebut di komputer, terlebih dahulu kita
harus melakukan konversi menjadi kode program yang dapat dibaca dan dimengerti
oleh komputer. Kode program sendiri dimodelkan dengan banyak cara, dan yang
paling relevan dengan algoritma ialah pseudocode.
Pseudocode memberikan langkah-langkah penyelesaian
masalah dengan menggunakan bahasa manusia, dengan sedikit batasan sesuai dengan
konstruk logika komputer. Pseudocode tidak memiliki konstruk untuk bahasa
pemrograman tertentu, sehingga pseudocode harus bisa diimplementasikan dengan
bahasa pemrograman apapun. Berikut adalah contoh pseudocode sederhana:
for i = 1 to 5 do
print i
end for
Untuk penjelasan lebih mendetail tentang pseudocode,
silahkan baca kembali bahan kuliah untuk Pemrograman Dasar.
Kita telah
melihat model matematis yang umum digunakan untuk menyelesaikan masalah.
Pertanyaan selanjutnya tentunya adalah: kapan kita menggunakan model A dan
kapan menggunakan model B? Bagaimana membuat model A menjadi kode program yang
dapat dijalankan oleh komputer?
Pengembangan Model
Proses
pengembangan model dapat dilakukan dengan beberapa langkah yang telah dibangun
oleh para ahli matematika. Jika proses pengembangan model dilakukan mengikuti
langkah-langkah yang ada, idealnya kita akan mendapatkan model yang tepat untuk
permasalahan yang akan diselesaikan. Adapun langkah-langkah yang harus diambil
untuk membangun sebuah model yaitu:
- Apakah masalah yang dihadapi merupakan masalah yang memerlukan solusi matematis? Jika masalahnya merupakan masalah numerik (perhitungan angka) atau logis, maka jawabannya sudah pasti “ya”. Jika solusi dari masalah berupa pendapat, maka kemungkinan jawabannya adalah “tidak”.
- Fakta-fakta relevan apa saja yang diketahui? Masalah umum yang dihadapi saat akan membangun solusi adalah informasi yang terlalu banyak, yang terkadang mencuri fokus kita dari akar masalah. Pisahkan antara fakta (informasi) yang relevan dari keseluruhan informasi yang didapatkan.
- Fakta atau informasi tambahan apa yang kita perlukan untuk menyelesaikan masalah? Di mana atau bagaimana cara agar kita mendapatkan fakta-fakta tersebut?
- Adakah langkah atau metode alami untuk menyelesaikan masalahnya? Metode alami artinya metode yang umumnya digunakan oleh manusia. Misalnya, untuk menghitung total dari sekumpulan nilai kita dapat menambahkan seluruh bilangan yang ada di dalam kumpulan nilai tersebut.
- Apakah fakta-fakta yang ada dapat direpresentasikan oleh simbol matematis dan dikategorikan menjadi fakta yang “diketahui” dan “tidak diketahui”?
- Apakah terdapat model lama yang dapat digunakan atau disesuaikan untuk menyelesaikan masalah kita?
- Jika terdapat model yang telah dikembangkan sebelumnya untuk masalah kita, apakah model tersebut dapat diaplikasikan pada komputer?
- Bagaimana kita dapat mengaplikasikan model dari solusi kita sehingga model tersebut dapat dibuat menjadi program komputer dengan mudah?
Dengan
menjalankan langkah-langkah di atas, idealnya kita akan mendapatkan sebuah
model solusi yang tepat untuk permasalahan kita. Untuk lebih jelasnya, mari
kita aplikasikan model masalah yang ada ke contoh sebuah kasus!
Contoh: Perhitungan Bunga Pinjaman
Kita diminta
untuk mengembangkan sebuah program komputer untuk sebuah perusahaan kredit
ACME. Program yang akan kita kembangkan merupakan sistem untuk menghitung total
jumlah yang harus dibayar oleh peminjam uang per tahunnya. Bunga pinjaman yang
diberikan ACME adalah sebesar 15% per tahunnya.
Untuk
membangun sistem perhitungan yang diminta, tentunya terlebih dahulu kita harus
membangun modal solusi untuk perhitungan bunganya. Mari kita ikuti
langkah-langkah untuk membangun model yang telah dijelaskan sebelumnya:
- Apakah masalah yang dihadapi merupakan masalah yang memerlukan solusi matematis?
Ya. Perhitungan total bunga bunga jelas akan melibatkan
matematika.
- Fakta-fakta relevan apa saja yang diketahui?
Bunga pinjaman sebesar 15% per tahun.
- Fakta atau informasi tambahan apa yang kita perlukan untuk menyelesaikan masalah?
Beberapa fakta tambahan yang harus ada tetapi
tidak disebutkan secara eksplisit pada deskripsi masalah:
- Jumlah pinjaman awal. Untuk menghitung total pinjaman dengan bunganya jelas kita harus mengetahui jumlah pinjaman awal terlebih dahulu.
- Lama pinjaman. Tanpa adanya lama pinjaman, kita tidak dapat mengetahui dengan pasti total bunga yang harus ditambahkan.
- Adakah langkah atau metode alami untuk menyelesaikan masalahnya?
Ya, lakukan perhitungan bunga tiap tahunnya, dan
tambahkan hasil kalkulasi tersebut sampai tahun pinjaman terakhir.
- Apakah fakta-fakta yang ada dapat direpresentasikan oleh simbol matematis?
Dari fakta-fakta yang kita dapatkan pada langkah kedua
dan ketiga, kita dapat mendefinisikan simbol matematis seperti berikut:
\[\begin{split}\text{let }b & = \text{bunga} \\
\text{let }p & = \text{jumlah pinjaman} \\ \text{let }t & = \text{waktu
pinjaman (per tahun)} \\ \text{let }T & = \text{total
pinjaman}\end{split}\]
- Apakah terdapat model lama yang dapat digunakan untuk menyelesaikan masalah kita?
Ya, perhitungan bunga majemuk yang dimodelkan dengan
rumus: \(T = p(1 + b)^t\).
- Apakah model yang ada sebelumnya pada langkah 6 dapat diaplikasikan pada komputer?
Kemungkinan tidak, karena perhitungan bunga majemuk
merupakan perhitungan yang tidak banyak diketahui orang (terutama pada bidang pemrograman),
dan juga memiliki banyak aturan kompleks yang harus dimengerti terlebih dahulu.
Karena kasus yang sederhana, kita akan lebih mudah
mengimplementasikan algoritma kita sendiri, yang cukup melakukan iterasi dan
menambahkan total pinjaman setiap tahunnya. Mari kita coba kembangkan model
iterasi yang dapat digunakan.
Untuk tahun pertama, peminjam akan berhutang sebanyak:
\[T = p + (15\% * p)\]
selanjutnya, untuk tahun kedua hutangnya akan
bertambah menjadi:
\[T' = T + (15\% * T)\]
di mana \(T'\) adalah nilai baru dari \(T\). Kita
cukup melakukan perhitungan yang sama terus menerus, sebanyak $t$ kali untuk
mendapatkan hasil akhir berupa \(T\) yang menyimpan total hutang yang dipinjam.
Jika dikembangkan, maka model matematis akhir yang kita dapatkan adalah:
\[T = T + (\frac{15}{100} * T)\]
yang akan dijalankan sebanyak $t$ kali, dengan nilai
$T$ yang bertambah setiap iterasinya. Dengan informasi ini, kita dapat
mengimplementasikan pseudocode seperti berikut:
b = 15
T = 0
READ p, t
T = p
for i = 1 to t do
T = T + (15
/ 100 * T)
end for
WRITE T
yang kemudian akan kita implementasikan sebagai fungsi
penghitung total pinjaman.
- Bagaimana kita dapat mengaplikasikan model dari solusi kita sehingga model tersebut dapat dibuat menjadi program komputer dengan mudah?
Pseudocode yang ada sudah sangat jelas, dan baris per
barisnya dapat diimplementasikan secara langsung menggunakan bahasa pemrograman
apapun.
Setelah
mendapatkan model penyelesaian masalah sampai pada pseudocode-nya, kita
kemudian dapat mengimplementasikan solusi yang dikembangkan menggunakan bahasa
pemrograman yang diinginkan. Berikut adalah contoh implementasi algoritma
tersebut pada python:
b = 15
T = 0
p = input("Masukkan jumlah pinjaman: ")
t = input("Masukkan lama pinjaman: ")
T = int(p)
for i in range(1, int(t)):
T = T + (15 /
100 * T)
print("Total pinjaman yang harus dibayarkan
adalah: " + str(T))
Kesimpulan
Pada bagian
ini kita telah mempelajari tentang ciri khas algoritma yang baik, yaitu benar,
efisien, dan mudah diimplementasikan. Kita juga mempelajari bagaimana
membuktikan sebuah algoritma adalah sebuah algoritma yang benar, dan bagaimana
mengembangkan algoritma yang benar, menggunakan model matematis.
Terdapat
enam jenis model matematis yang kita bahas, beserta dengan cara menggunakan
model matematis tersebut ke kasus pada dunia nyata. Selanjutnya kita akan
mempelajari bagaimana mengembangkan algoritma yang efisien, beserta definisi
dari efisiensi algoritma tentunya.
Sumber:
https://bertzzie.com/knowledge/analisis-algoritma/PengenalanDesaindanAnalisisAlgoritma.html
Tidak ada komentar:
Posting Komentar