2. Algoritma, Kompleksitas dan Teori Bilangan

advertisement
2. Algoritma, Kompleksitas dan Teori
Bilangan
2.1 Algoritma dan Fungsi Kompleksitas
Algoritma adalah sekumpulan berhingga dari instruksi-instruksi untuk melakukan
perhitungan/ komputasi atau memecahkan suatu masalah. Suatu algoritma yang baik harus
memiliki sifat-sifat berikut ini:
•
Masukan (input) dari himpunan tertentu
•
Keluaran (output) pada himpunan tertentu (solusi)
•
Definiteness dari setiap langkah perhitungan
•
Kebenaran (correctness) dari keluaran untuk setiap masukan yang mungkin
•
Keberhinggaan (finiteness) dari banyaknya langkah perhitungan
•
Kefektifan (effectiveness) dari setiap langkah perhitungan dan
•
Keterumuman (generality) dalam suatu kelompok permasalahan yang dipecahkan
Kita akan memakai pseudocode untuk menuliskan algoritma, yang mirip dengan bahasa
Pascal. Sebagai contoh pertama, tinjau algoritma mencari nilai maksimum dari suatu barisan
yang panjangnya berhingga berikut ini.
procedure max(a1, a2, …, an: integers)
max := a1
for i := 2 to n
if max < ai then max := ai
{max adalah elemen terbesar dalam barisan}
Dari masukan barisan a1, a2, ..., pertama-tama variabel max di-inisiasi dengan suku pertama
barisan. Selanjutnya suku-suku berikutnya diambil dan dibandingkan dengan max, jika lebih
besar maka nila lama max diganti dengan nilai baru—yaitu suku sekarang, sedangkan jika
(sama atau lebih kecil), algoritma mengambil suku berikutnya—demikian seterusnya. Diakhir
proses, suku terbesar dari barisan akan tertampung di dalam max.
2. Algoritma, Kompleksitas dan Teori Bilangan - 1
Contoh kedua adalah algoritma pencarian linier (linear search), yaitu algoritma yang mencari
elemen tertentu dari barisan berhingga secara linier.
procedure linear_search(x: integer; a1, a2, …, an:
integers)
i := 1
while (i ≤ n and x ≠ ai)
i := i + 1
if i ≤ n then location := i
else location := 0
{letak dari elemen yang dicari adalah subscript dari suku
yang sama dengan x, atau nol jika tidak ditemukan.}
Pada algoritma pencarian linier, pertama-tama pencacah indeks i di-inisiasi ke harga 1.
Selanjutnya suku barisan diambil satu persatu secara ber-urutan dan dibandingkan dengan
bilangan yang dicari, yaitu x. Jika ditemukan, maka variable location di-assign dengan
indeks dari suku tersebut, sedangkan jika tidak ditemukan, maka variable tersebut diberi
harga nol. Eksekusi berakhir setelah ujung barisan dicapai, dengan variable location
berisi indeks suku barisan yang dicari atau berisi nol jika tidak ditemukan. Pencarian yang
demikian tentu saja akan memakan waktu yang sebanding dengan panjangnya barisan
sehingga tidak efisien atau disebut bahwa kompleksitas algoritma ini besar.
Interval-1
Interval-2
Interval-3
a
c
d
f
g
h
j
l
m
o
p
r
s
u
v
x
z
pusat pertama
pusat kedua
pusat ketiga, KETEMU!
Gb. 2.1 Ilustrai algoritma pencarian biner
2. Algoritma, Kompleksitas dan Teori Bilangan - 2
Kompleksitas bisa diturunkan jika dipakai teknik pencarian biner (binary search), akan tetapi
masukannya harus terlebih dahulu diurutkan (ordered). Dalam pencarian biner, algoritma
secara iteratif membatasi interval pencarian yang relevan hingga mendekati posisi suku
barisan yang dicari. Berikut ini ilustrasi pencarian biner untuk huruf “j”
Algoritma dalam bentuk pseudocode dari pencarian biner adalah sebagai berikut.
procedure binary_search(x: integer; a1, a2, …, an:
integers)
i := 1
{i is left endpoint of search interval}
j := n
{j is right endpoint of search interval}
while (i < j)
begin
m := ⎣(i + j)/2⎦
if x > am then i := m + 1
else j := m
end
if x = ai then location := i
else location := 0
{letak dari elemen yang dicari adalah subscript dari suku
yang sama dengan x, atau nol jika tidak ditemukan.}
Jelas bahwa dalam barisan yang terurut, pencarian biner lebih efisien daripada pencarian
liniar. Selanjutnya muncul pertanyaan bagaimana cara menganalisa efisiensi dari suatu
algoritma? Kita dapat mengukur efisiensi ini dengan
•
Waktu (time): yakni banyaknya komputasi elementer dalam algoritma
•
Ruang (space): adalah banyaknya sel memori yang dibutuhkan oleh algoritma.
Ukuran ini secara berturut-turut disebut sebagai kompleksitas komputasi (computational
complexity) dan kompleklsitas ruang (space complexity).
Berapakah kompleksitas waktu dari algoritma pencarian linier ? Kita akan menentukan
banyaknya proses perbandingan pada kasus terburuk (worst-case) sebagai fungsi dari panjang
barisan n. Kasus terburuk dari algoritma pencarian linier muncul ketika elemen yang dicari
2. Algoritma, Kompleksitas dan Teori Bilangan - 3
ternyata tidak ada didalam barisan masukan. Pada kasus tersebut, setiap suku dalam barisan
akan dibandingkan dengan elemen yang dicari. Sehingga, untuk n buah elemen, loop
while (i ≤ n and x ≠ ai)
i := i + 1
dilaksanakan n kali, sehingga memerlukan 2n buah proses perbandingan. Saat memasuki loop
ke (n+1) kalinya, yang dieksekusi hanyalah perbandingan i ≤ n dan loop diakhiri.
Akhirnya perbandingan
if i ≤ n then location := i
dieksekusi, sehingga pada kasus terburuk kompleksitas waktu adalah 2n + 2. Ini adalah nilai
kompleksitas dari algoritma pencarian linier. Selanjutnya, berapakah kompleksitas waktu dari
algoritma pencarian biner?
Sekali lagi kita akan menentukan jumlah perbandingan pada kondisi terburuk sebagai fungsi
dari banyaknya suku dalam deretan n. Kita asumsikan terdapat n=2k buah elemen di dalam
barisan yang berarti bahwa k = log(n). Jika n bukan pangkat 2 dari suatu bilangan, barisan
tersebut dapat dianggap sebagai bagian dari barisan lain yang lebih besar, dimana
2k<n<2k+1. Pada siklus pertama dari loop
while (i < j)
begin
m := ⎣(i + j)/2⎦
if x > am then i := m + 1
else j := m
end
interval pencarian dibatasi pada (2k–1) buah elemen, menggunakan dua operasi perbandingan.
Pada siklus kedua, interval pencarian dibatasi pada sejumlah 2k-2 elemen, sekali lagi dengan
dua buah perbandingan. Proses ini diulangi terus hingga terdapat hanya satu buah (=20)
2. Algoritma, Kompleksitas dan Teori Bilangan - 4
elemen tersisa dalam interval pencarian. Pada kondisi ini, sejumlah 2k perbandingan telah
dilakukan.
Kemudian, dilakukan perbandingan: while (i < j). Setelah itu keluar dari loop dan
perbandingan akhir adalah
if x = ai then location := i
Menentukan apakah elemen yang dicari sudah ketemu. Dengan demikian, total dari
kompleksitas waktu untuk algoritma pencarian biner adalah 2k + 2 = 2 ⎡log(n)⎤ + 2. (NB: kita
selalu mengasumsikan logaritma basis dua).
Pada umumnya, untuk input yang kecil, kita tidak tertarik pada kompleksitas ruang maupun
waktu. Perbedaan kompleksitas waktu untuk pencarian linier dengan pencarian biner tidak
begitu berarti untuk n=10, tetapi sangat signifikan untuk n = 230. Misalkan, ada dua buah
algoritma, sebut sebagai algoritma A dan algoritma B yang dapat memecahkan suatu kelas
permasalahan. Kompleksitas waktu dari algoritma A adalah 5000n sedangkan kompleksitas
dari algoritm B adalah ⎡1.1n⎤ untuk masukan n buah elemen (barisan). Sekarang kita
perhatikan perbandingan kompleksitas waktu dari algoritma A dan B sebagai berikut:
Besarnya masukan
Kompleksitas algoritma-A
Kompleksitas algoritma-B
n
5000n
⎡1.1n⎤
10
50.000
3
100
500.000
13.781
1.000
5.000.000
2.5×1041
1000.000
5×109
4,8×1041392
Ini berarti bahwa algoritma B tidak dapat dipakai untuk masukan dengan elemen yang besar,
sedangkan dengan algoritma A, hal ini masih bisa diatasi. Jadi, yang paling penting dalam
menghitung kompleksitas suatu algoritma adalah pertumbuhan dari fungsi kompleksitas.
Pertumbuhan dari kompleksitas dengan meningkatnya besarnya masukan, n, adalah ukuran
yang
sesuai
untuk
membandingkan
algoritma.
Pertumbuhan
fungsi
kompleksitas
dilambangkan dengan notasi O (dibaca big-O). Perhatikan definisi berikut ini.
2. Algoritma, Kompleksitas dan Teori Bilangan - 5
Definisi: Misalkan f dan g adalah dua buah fungsi dari bilangan bulat ke bilangan riil. Kita
katakan bahwa f(x) adalah O(g(x)) jika ada suatu konstanta C dan k sedemikian hingga
|f(x)| ≤ C|g(x)|, saat x > k.
Saat menganalisa perumbuhan dari fungsi kompleksitas, f(x) dan g(x) selalu positif. Oleh
karena itu, kita dapat menyederhanakan persyaratan big-O menjadi
f(x) ≤ C⋅g(x) saat x > k.
Jika kita ingin menunjukkan bahwa f(x) adalah O(g(x)), kita hanya perlu menentukan satu
buah pasangan (C, k) (yang tidak pernah unik).
Ide dibelakang notasi big-O adalah penentuan batas atas (upper boundary) dari perumbuhan
suatu fungsi f(x) untuk x besar. Batas ini diberikan oleh fungsi g(x) yang biasanya jauh lebih
sederhana daripada f(x). Kita menerima konstanta C dalam persyaratan
f(x) ≤ C⋅g(x) saat x > k.
karena C tidak pernah tumbuh sejalan dengan tumbuhnya x. Kita hanya tertarik pada x besar,
sehingga jika f(x) > C⋅g(x) untuk x ≤ k, bukanlah suatu masalah. Perhatikan contoh soal
berikut.
Soal: Tunjukkan bahwa f(x) = x2 + 2x + 1 adalah O(x2).
Jawab: Untuk x > 1: x2 + 2x + 1 ≤ x2 + 2x2 + x2
⇒ x2 + 2x + 1 ≤ 4 x2
Karena itu, untuk C = 4 dan k = 1:
f(x) ≤ C x2 ketika x > k.
⇒ f(x) adalah O(x2).
Selanjutnya mungkin timbul pertanyaan: “jika f(x) adalah O(x2), apakah f(x) juga O(x3)?”.
Jawabnya adalah “ya”, karena x3 tumbuh lebih cepat daripada x2, sehingga x3 juga tumbuh
lebih cepat dibandingkan dengan f(x). Karena itu, kita selalu harus menemukan fungsi
sederhana terkecil g(x) dimana f(x) adalah O(g(x)).
2. Algoritma, Kompleksitas dan Teori Bilangan - 6
Fungsi-fungsi g(n) yang populer adalah: n log(n), 1, 2n, n2, n!, n, n3, log(n). Jika diurutkan
dari yang pertumbuhannya paling lambat ke paling cepat, kita dapatkan daftar berikut:
¾
1
¾
log(n)
¾
n
¾
n log(n)
¾
n2
¾
n3
¾
2n
¾
n!
Permasalahan yang dapat dipecahkan dengan kompleksitas pada kondisi-terburuk berbentuk
polinomial (polynomial worst-case) disebut sebagai permasalahan yang tractable.
Permasalahan dengan kompleksitas yang lebih tinggi dari bentuk fungsi polynomial disebut
sebagai intractable. Sedangkan permasalahan yang tidak dapat dipecahkan dengan algoritma
apapun disebut sebagai unsolvable. Berikut ini beberapa aturan yang berguna untuk big-O.
•
Untuk sebarang polinomial f(x) = anxn + an-1xn-1 + … + a0, dimana a0, a1, …, an
bilangan riil, maka f(x) adalah O(xn).
•
Jika f1(x) adalah O(g1(x)) dan f2(x) adalah O(g2(x)), maka (f1+f2)(x) adalah
O(max(g1(x), g2(x)))
•
Jika f1(x) adalah O(g(x)) dan f2(x) adalah O(g(x)), maka (f1 + f2)(x) adalah O(g(x)).
•
Jika f1(x) adalah O(g1(x)) dan f2(x) adalah O(g2(x)), maka (f1f2)(x) adalah
O(g1(x)g2(x)).
Perhatikan contoh permasalahan kompleksitas berikut ini. Apakah yang dikerjakan algoritma
berikut ini?
procedure who_knows(a1, a2, …, an: integers)
m := 0
for i := 1 to n-1
for j := i + 1 to n
if |ai – aj| > m then m := |ai – aj|
2. Algoritma, Kompleksitas dan Teori Bilangan - 7
{m adalah beda maksimum sebarang dua bilangan dari deretan
masukan}
Proses perbandingan dalam algoritma ini dilakukan sebanyak:
n-1 + n-2 + n-3 + … + 1= (n – 1)n/2 = 0.5n2 – 0.5n
Dengan demikian, besarnya kompleksitas waktu dari algoritma ini adalah O(n2). Selanjutnya
bandingkan dengan algoritma berikut ini yang juga memecahkan masalah yang sama!
procedure max_diff(a1, a2, …, an: integers)
min := a1
max := a1
for i := 2 to n
if ai < min then min := ai
else if ai > max then max := ai
m := max – min
Dalam algoritma ini, proses perbandingan dilakukan sebanyak 2n – 2. Dengan demikian,
besarnya kompleksitas waktu dari algoritma ini adalah O(n). Terlihat bahwa untuk
mengerjakan hal yang sama, dua buah algoritma berbeda bisa memiliki kompleksitas yang
jauh berbeda.
2.2 Teori Bilangan
Yang dimaksud dengan teori bilangan dalam Matematika Diskrit adalah teori mengenai
bilangan bulat dan sifat-sifatnya. Pada bagian ini akan dijelaskan prinsip-prinsip teori
bilangan, meliputi :
•
Keterbagian (divisibility)
•
Pembagi persekutuan terbesar (greatest common divisors/gcd)
•
Kelipatan persekutuan terkecil (least common multiples/lcm), dan
•
Aritmetika modular (modular arithmetics)
2. Algoritma, Kompleksitas dan Teori Bilangan - 8
dan beberapa algoritma terkait. Jika a dan b bilangan bulat dimana a ≠ 0, dikatakan a
membagi b (a divides b) jika ada bilangan bulat c sedemikian hingga b = ac. Jika a membagi
b, maka a disebut sebagai faktor (factor) dari b, dan b adalah kelipatan (multiple) dari a.
Penulisan a|b dibaca sebagai a membagi b, dan notasi a / b berarti a tidak membagi b. Untuk
bilangan-bilangan bulat a, b, dan c akan berlaku hal hal berikut ini:
•
jika a|b dan a|c, maka a|(b + c). Contoh: 3|6 dan 3|9, maka 3|15.
•
jika a|b, maka a|bc untuk sebarang bilangan bulat c. Contoh: 5|10, jadi 5|20, 5|30, …
•
jika a|b dan b|c, maka a|c. Contoh: 4|8 dan 8|24, maka 4|24.
Suatu bilangan bulat positif p yang lebih besar dari satu disebut sebagai bilangan prima jika
faktor positif dari p hanyalah 1 dan p. Bilangan bulat positif lebih besar dari 1 yang bukan
bilangan prima disebut sebagai bilangan komposit.
Teorema Fundamental Aritmetika. Setiap bilangan bulat positif bisa dituliskan secara unik
sebagai hasil perkalian dari bilangan-bilangan prima, yang
actor primanya bisa dituliskan
secara meningkat berurutan.
Berikut ini contoh dari teorema tersebut:
•
15 = 3×5
•
48 = 2×2×2×2×3 = 24×3
•
17 = 17
•
100 = 2×2×5×5 = 22×55
•
512 = 2×2×2×2×2×2×2×2×2 = 29
•
515 = 5×103
•
28 = 2×2×7 = 22×7
Jika n sebuah bilangan bulat komposit, maka n memiliki pembagi prima yang kurang dari
atau sama dengan ÷n. Pemikiran: jika n komposit, maka n memiliki dua buah pembagi p1 dan
p2 sedemikian hingga p1×p2 = n dan p1≥ 2 dan p2 ≥ 2. Tetapi p1 dan p2 tidak dapat sekaligus
lebih besar dari ÷n sebab jika demikian maka p1×p2 akan menjadi lebih besar dari n. Jika
bilangan p1 dan p2 sendiri bukan bilangan prima, maka kedua bilangan tersebut dapat
diuraikan kedalam faktor prima yang lebih kecil dari dirinya sendiri tetapi ≥ 2.
2. Algoritma, Kompleksitas dan Teori Bilangan - 9
Andaikan a suatu bilangan bulat dan d suatu bilangan bulat positif. Maka ada bilangan bulat
q dan r yang unik, dimana 0 ≤ r < d, sedemikian hingga a = d×q + r. Dalam persamaan ini :
•
d disebut sebagai pembagi (divisor)
•
a disebut sebagai deviden(dividend)
•
q disebut sebagai kosien (quotient) dan
•
r disebut sebagai sisa pembagian (remainder).
Contoh: Jika 17 dibagi dengan 5, maka akan diperoleh
17 = 5×3 + 2.
Dengan demikian, maka:
•
17 adalah deviden (dividend)
•
5 adalah pembagi (divisor),
•
3 adalah kosien (quotient), dan
•
2 adalah sisa pembagian (remainder).
Contoh lain: Bagaimana jika -11 dibagi dengan 3 ?
Catat bahwa remainder tidak bisa bernilai negative, maka
-11 = 3×(-4) + 1.
Dengan demikian, maka:
•
-11 adalah deviden
•
3 adalah pembagi
•
-4 adalah kosien, dan
•
1 adalah sisa pembagian.
Andaikan a dan b adalah bilangan bulat yang tidak sekaligus keduanya berharga nol.
Bilangan bulat terbesar d sedemikian hingga d|a dan d|b disebut sebagai pembagai
persekutuan terbesar (greatest common diviso/gcd)r dari a dan b, dan dituliskan gcd(a, b).
Contoh: Berapakah gcd(48, 72)? Pembagi bersama yang bernilai positif dari 48 dan 72 adalah
1, 2, 3, 4, 6, 8, 12, 16, dan 24, sehingga gcd(48, 72) = 24.
2. Algoritma, Kompleksitas dan Teori Bilangan - 10
Contoh: Berapakah gcd(19, 72)? Satu-satunya pembagi bersama yang positif dari 19 dan 72
adalah 1, sehingga gcd(19, 72) =1.
Nilai gcd dapat ditentukan dengan faktorisasi prima:
a = p1a1× p2a2×… × pnan , b = p1b1× p2b2×… × pnbn,
dimana p1 < p2 < … < pn dan ai, bi∈N untuk 1 ≤ i ≤ n
maka: gcd(a, b) = p1min(a1, b1)× p2min(a2, b2)× … × pnmin(an, bn)
Contoh:
•
a = 60 = 22×31×51 , b = 54 = 21×33×50
maka gcd(a, b) = 21×31×50 = 6
Definisi. Dua bilangan bulat, a dan b adalah prima relatif jika gcd(a,b)=1.
Contoh:
•
Apakah 15 dan 28 prima relatif? Ya, karena gcd(15, 28) = 1.
•
Apakah 55 dan 28 prima relatif? Ya, karena gcd(55, 28) = 1.
•
Apakah 35 dan 28 prima relatif? Tidak, karena gcd(35, 28) = 7.
Definisi. Bilangan-bilangan a1, a2, …, an adalah prima-relatif-berpasangan (pairwise
relatively prime) jika gcd(ai, aj) = 1 untuk 1 ≤ i < j ≤ n.
Dengan demikian, sekumpulan bilangan bisa ditunjukkan apakah prima-relatif-berpasangan
atau tidak dengan mengevaluasi gcd dari semua pasangan bilangan yang mungkin. Jika gcd
pasangan-pasangan tersebut semuanya bernilai 1, maka syarat prima-relatif-berpasangan
dipenuhi. Sebaliknya, jika salah satu gcd dari pasangan bilangan tersebut tidak sama dengan
satu, maka kumpulan bilangan tersebut bukan prima-relatif-berpasangan. Perhatikan contoh
berikut ini :
•
Bilangan-bilangan 15, 17, dan 27 adalah bukan prima relatif berpasangan karena
gcd(15, 27) = 3.
•
Bilangan-bilangan 15, 17, dan 28 adalah prima relatif berpasangan karena
gcd(15, 17) = 1, gcd(15, 28) = 1 dan gcd(17, 28) = 1.
2. Algoritma, Kompleksitas dan Teori Bilangan - 11
Definisi. Kelipatan persekutuan terkecil (least common multiple) dari bilangan bulat positif a
dan b adalah bilangan bulat positif terkecil yang dapat dibagi oleh a maupun oleh b.
Kelipatan persekutuan terkecil dari a dan b dituliskan sebagai lcm(a, b). Contoh:
lcm(3, 7) = 21, lcm(4, 6) = 12, dan lcm(5, 10) = 10
Seperti halnya gcd, nilai lcm dapat dihitung melalui faktorisasi prima sebagai berikut.
a = p1a1 × p2 a2 × ... × pn an , b = p1b1 × p2b2 × ... × pnbn
dimana p1 < p2 < ... pn −1 < pn dan ai, bi∈ N untuk 1 ≤ i ≤ n,
maka lcm ( a, b ) = p1 max ( a1 , b1 ) × p2 max ( a2 , b2 ) × ... × pn max ( an , bn )
Contoh: a = 60 = 22×31×51, b = 54 = 21×33×50 maka lcm(a, b) =22×33×51 = 4×27×5 = 540
sedangkan gcd(a, b) =21×31×50 = 2×3×1 = 6
Teorema. a×b = gcd(a, b) ×lcm(a, b)
Andaikan a bilangan bulat dan m bilangan bulat positif. Notasi a mod m menyatakan sisa
pembagian (remainder) dari a dibagi dengan m.
Contoh: 9 mod 4 = 1, 9 mod 3 = 0, 9 mod 10 = 10, dan -13 mod 4 = 3
Andaikan a dan b adalah bilangan-bilangan bulat dan m suatu bilangan bulat positif. Maka, a
disebut kongruen dengan b modulo m jika m membagi a – b dan dituliskan a ≡ b (mod m).
Dengan kata lain a ≡ b (mod m) jika dan hanya jika a mod m = b mod m. Perhatikan contohcontoh berikut ini:
•
Apakah 46 ≡ 68 (mod 11)? Ya, karena 11 | (46 – 68) = 11 | -22.
•
Apakah 46 ≡ 68 (mod 22)? Ya, karena 22 | (46 – 68) = 22 | 22.
•
Tentukan bilangan bulat z sehingga berlaku z ≡ 12 (mod 10)?
Jawab: z ∈{…,-28, -18, -8, 2, 12, 22, 32, …}
2. Algoritma, Kompleksitas dan Teori Bilangan - 12
Teorema. Andaikan m suatu bilangan bulat positif. Bilangan bulat a dan b adalah kongruen
modulo m jika dan hanya jika ada bilangn bulat k sedemikian hingga a = b + k×m.
Teorema. Andaikan m suatu bilangan bulat positif. Jika a ≡ b (mod m) dan c ≡ d (mod m),
maka a + c ≡ b + d (mod m) dan a×c ≡ b×d (mod m).
Algoritma Euklid adalah algoritma untuk mencari gcd dari dua buah bilangan bulat a dan b.
Penjelasan diberikan oleh contoh berikut ini: untuk menentukan gcd(287, 91), bilangan 287
(yang lebih besar) dibagai dengan 91 (yang lebih kecil) :
287 = 91×3 + 14
⇒ 287 - 91×3 = 14
⇒ 287 + 91× (-3) = 14
Berdasarkan teorema di atas, kita tahu bahwa untuk sebarang bilangan bulat a, b dan c; jika
a|b, maka a|b×c untuk semua bilangan bulat c. Oleh karena itu, sebarang pembagi 91 adalah
juga pembagi 91×(-3). Maka
287 + 91× (-3) = 14
Berdasarkan teorema, kita juga tahu bahwa untuk bilangan bulat a, b dan c, jika a|b dan a|c,
maka a| (b + c). Oleh karena itu, sebarang pembagi dari 287 dan 91 haruslah juga pembagi
dari 287 + 91× (-3), yaitu 14. Dengan demikian, gcd dari 287 dan 91 haruslah juga sama
dengan gcd dari 14 dan 91:
gcd(287, 91) = gcd(14, 91).
Pada langkah berikutnya, kita bagi 91 dengan 14: 91 = 14×6 + 7. Ini berarti bahwa
gcd(14, 91) = gcd(14, 7).
Selanjutnya 14 dibagi 7: 14 = 7⋅2 + 0. Ditemukan bahwa 7|14, sehingga gcd(14, 7) = 7. Oleh
karena itu diperoleh
2. Algoritma, Kompleksitas dan Teori Bilangan - 13
gcd(287, 91) = 7.
Dari ilustrasi diatas, algoritma Euklid dapat diterjemahkan ke dalam pseudocode berikut ini.
procedure gcd(a, b: positive integers)
x := a
y := b
while y ≠ 0
begin
r := x mod y
x := y
y := r
end {x adalah gcd(a, b)}
Andaikan b sebagai suatu bilangan bulat positif yang lebih besar dari 1. Jika n bilangan bulat
positif, n dapat dinyatakan secara unik dalam bentuk:
n = ak × b k + ak −1 × b k −1 + ...a1 × b1 + a0
dimana k adalah bilangan bulat tak negatif, dan a0, a1, …, ak adalah bilangan bulat tak negatif
yang kurang dari b, dan ak ≠ 0.
Contoh:
•
untuk b =10 kita peroleh ekspresi desimal: 859 = 8×102 + 5×101 + 9×100
•
untuk b = 2 (ekspansi biner): (10110)2 = 1×24 + 1×22 + 1×21 = (22)10
•
untuk b =16 (ekspansi heksadecimal):
(kita gunakan lambing bilangan A hingga F utk angka 10 sampai 15)
(3A0F)16 = 3×163 + 10×162 + 15×160 = (14863)10
Untuk membuat ekspansi basis b dari suatu bilangan bulat n kita lakukan hal berikut.
Pertama-tama, bagi n dengan b untuk mendapatkan kosien q0 dan sisa a0, yaitu,
n = b×q0 + a0, dimana 0 ≤ a0 < b.
2. Algoritma, Kompleksitas dan Teori Bilangan - 14
Sisa a0 menempati dijit paling kanan didalam basis b dari ekspansi n. Berikutnya, bagi q0
dengan b untuk memperoleh:
q0 = b×q1 + a1, dimana 0 ≤ a1 < b.
a1 adalah dijit kedua paling kanan pada basis b untuk ekspansi n. Proses ini diteruskan hingga
nilai kosien sama dengan nol. Perhatikan contoh berikut ini.
Ekspansikan (12345)10 ke basis 8 dari ! Dengan cara yang diuraikan di atas, maka diperoleh
12345 = 8×1543 + 1
1543 = 8×192 + 7
192 = 8×24 + 0
24 = 8×3 + 0
3 = 8×0 + 3
Hasilnya adalah: (12345)10 = (30071)8.
Ekspansi suatu bilangan decimal ke basis b dapat dilakukan dengan algoritma berikut ini.
procedure base_b_expansion(n, b: positive integers)
q := n
k := 0
while q ≠ 0
begin
ak := q mod b
q := ⎣q/b⎦
k := k + 1
end
{ekspansi basis b dari n adalah (ak-1 … a1a0)b}
Berikutnya kita tinjau operasi penjumlahan bilangan. Operasi ini bias dijelaskan dengan
contoh berikut:
2. Algoritma, Kompleksitas dan Teori Bilangan - 15
Desimal:
Biner
1 1 carry
111 carry
(1011)2
(1010 )2
+
(10101)2
7583
4932
+
12515
Tinjau dua bilangan biner a = (an-1 an-2… a1 a0)2, b = (bn-1 bn-2… b1b0)2. Bagaimana
sebenarnya penambahan kedua bilangan biner ini dilakukan? Pertama-tama, jumlahkan bit
paling kanan:
a0 + b0 = c0×2 + s0,
dimana s0 adalah bit paling kanan dalam ekspansi biner a + b, dan c0 adalah nilai carry. Lalu,
tambahkan pasangan berikutnya bersama-sama dengan carry:
a1 + b1 + c0 = c1×2 + s1,
dimana s1 adalah bit berikutnya dalam ekspansi biner dari a + b, dan c1 adalah carry. Proses
ini dilanjutkan hingga didapatkan cn-1. Bit terdepan (ter-kiri) dari hasil penjumlahan adalah
sn = cn-1.
Sehingga hasilnya adalah: a + b = (snsn-1…s1s0)2.
Selanjutnya perhatikan contoh berikut ini: jumlahkan a = (1110)2 dan b = (1011)2. Maka
dilakukan tahap-tahap berikut ini:
a0 + b0= 0 + 1 = 0⋅2 + 1, shg c0= 0 dan s0= 1.
a1+ b1+ c0 = 1 + 1 + 0 = 1⋅2 + 0, shg c1 = 1 dan s1 = 0.
a2 + b2 + c1 = 1 + 0 + 1 = 1⋅2 + 0, shg c2 = 1 dan s2 = 0.
a3 + b3 + c2 = 1 + 1 + 1 = 1⋅2 + 1, shg c3 = 1 dan s3 = 1.
s4 = c3 = 1.
2. Algoritma, Kompleksitas dan Teori Bilangan - 16
Oleh karena itu, s = a + b = (11001)2.
Prosedur penjumlahan bilangan basis dua memiliki algoritma berikut ini.
procedure add(a, b: positive integers)
c := 0
for j := 0 to n-1
begin
d := ⎣(aj + bj + c)/2⎦
sj := aj + bj + c – 2d
c := d
end
sn := c
{ekspansi biner dari hasil penjumlahan adalah: s(snsn1…s1s0)2}
Matriks adalah susunan bilangan berbentuk persegiempat. Matriks yang memiliki m buah
baris dan n buah kolom disebut sebagai matriks m×n. Contoh:
1 ⎤
⎡ −1
⎢
A = ⎢ 2.5 −0.3⎥⎥
⎢⎣ 8
0 ⎥⎦
adalah matriks 3×2
Sebuah matriks yang jumlah baris dan kolomnya sama disebut sebagai matriks bujursangkar.
Dua buah matriks disebut sama jika keduanya memilliki jumlah baris dan jumlah kolom yang
sama dan elemen-elemen yang bersesuaian bernilai sama. Suatu matriks m×n, A = [aij], dapat
dituliskan sebagai:
⎡ a11
⎢a
⎢ 21
⎢ .
⎢
⎢ .
⎢ .
⎢
⎣⎢ am1
a12
a22
.
.
.
am 2
... a1n ⎤
... a2 n ⎥⎥
. ⎥
⎥
. ⎥
. ⎥
⎥
... amn ⎦⎥
⎡ a1 j ⎤
⎢a ⎥
⎢ 2j⎥
⎢ . ⎥
⎢ ⎥
⎢ . ⎥
⎢ . ⎥
⎢ ⎥
⎣⎢ amj ⎦⎥
kolom ke-j dari A
2. Algoritma, Kompleksitas dan Teori Bilangan - 17
[ ai1 ,
ai 2 , ..., ain ]
baris ke-i dari A
Tinjau dua buah matriks A = [aij] dan B = [bij] berukuran m×n. Penjumlahan A dan B,
dituliskan sbg A + B, adalah matriks m×n dengan elemen ke (i, j) adalah aij + bij, dengan kata
lain, A+B = [aij + bij]. Contoh:
⎡ −2 1 ⎤ ⎡ 5 9 ⎤ ⎡ −2 + 5 1 + 9 ⎤ ⎡ 3 10 ⎤
⎢ 4 8 ⎥ + ⎢ −3 6 ⎥ = ⎢ 4 − 3 8 + 6 ⎥ = ⎢ 1 14 ⎥
⎥
⎢
⎥ ⎢
⎥ ⎢
⎥ ⎢
⎢⎣ −3 0 ⎥⎦ ⎢⎣ −4 1 ⎥⎦ ⎢⎣ −3 − 4 0 + 1⎥⎦ ⎢⎣ −7 1 ⎥⎦
Andaikan A sebuah matriks m×k dan B matriks k×n. Hasil kali A dan B, dituliskan sebagai
AB, adalah sebuah matriks dengan elemen ke-(i,j) nya sama dengan penjumlahan dari hasil
perkalian baris ke-i dari A dan kolom ke-j dari B. Dengan kata lain, jika AB = [cij], maka
k
cij = ai1b1 j + ai 2b2 j + ... + aik bkj = ∑ ait btj
t =1
Perkalian dua buah matriks dapat dilukiskan sebagia berikut:
⎡3 0
⎢ −2 −1
A=⎢
⎢0 0
⎢
⎣ −1 1
1⎤
4 ⎥⎥
5⎥
⎥
0⎦
⎡2 1 ⎤
B = ⎢⎢0 −1⎥⎥
⎢⎣3 4 ⎥⎦
•
Ambil baris pertama dari A, putar 90o dan pasangkan dengan kolom pertama dari B.
•
Kalikan elemen-elemen yang bersesuaian dari A dan B, kemudian jumlahkan hasil
kalinya 3⋅2 + 0⋅0 + 1⋅3 = 9
•
Masukkan hasilnya kedalam posisi paling kiri atas dari C.
Lanjutkan dengan perkalian baris pertama A dengan kolom ke-dua, ketiga ... dst dari B untuk
mendapatkan elemen-elemen pada baris pertama C. Ulangi proses ini untuk baris ke-dua,
2. Algoritma, Kompleksitas dan Teori Bilangan - 18
tiga, ..dst dari A menghasilkan elemen pada kolom C sisa-nya. Setelah proses ini selesai,
matriks C berisi akan berisi hasil kali AB. Contoh
⎡3 0
⎢ −2 −1
A=⎢
⎢0 0
⎢
⎣ −1 1
1⎤
4 ⎥⎥
5⎥
⎥
0⎦
⎡9 7 ⎤
⎡2 1 ⎤
⎢8 15 ⎥
⎢
⎥
⎥
B = ⎢ 0 −1⎥ , maka AB = C = ⎢
⎢15 20 ⎥
⎢⎣ 3 4 ⎥⎦
⎢
⎥
⎣ −2 −2 ⎦
Matriks identitas order-n adalah matriks n×n, In=[δij], dimana δij =1 jika i=j dan δij=0 jika i≠j:
⎡1
⎢0
⎢
A = ⎢...
⎢
⎢0
⎢⎣ 0
0
1
...
...
...
...
...
...
1
0
0⎤
0 ⎥⎥
.. ⎥
⎥
0⎥
1 ⎥⎦
Perkalian sebarang matriks A berukuran m×n dengan matriks identitas (dengan dimensi yang
sesuai) tidak mengubah matriks tsb:
AIn = ImA = A
Berikut ini kita tinjau kuasa (power) dari suatu matriks. Fungsi kuasa hanya terdefinisi untuk
matriks bujursangkar. Jika A sebuah matriks n×n, maka:
A0 = In,
Ar = AAA …A
(r-buah A)
Transpose dari suatu matriks m×n, A = [aij], dituliskan sbg At, adalah matriks n×m yang
diperoleh dengan menukarkan baris dengan kolom dari matriks A. Dengan kata lain, jika At =
B = [bij], maka bij = aji untuk i = 1, 2, …, n dan j = 1, 2, …, m. Contoh:
2. Algoritma, Kompleksitas dan Teori Bilangan - 19
⎡2 1 ⎤
⎡2 0 3⎤
A = ⎢⎢ 0 −1⎥⎥ , maka A t = ⎢
1 −1 4 ⎥⎦
⎣
⎢⎣ 3 4 ⎥⎦
Suatu matriks bujursangkar A disebut simetrik jika A = At. Jadi A = [aij] adalah simetrik jika
aij = aji untuk semua i = 1, 2, …, n dan j = 1, 2, …, m. Tinjau dua buah matriks berikut
3⎤
⎡5 1
⎡1 3 1⎤
⎢
⎥
A = ⎢1 2 −9 ⎥ , B = ⎢⎢1 3 1⎥⎥
⎢⎣3 −9 4 ⎥⎦
⎢⎣1 3 1⎥⎦
Maka, A adalah matriks simetrik sedangkan B bukanlah matriks simetrik.
Sebuah matriks dengan elemen yang berharga 0 atau 1 disebut sebagai matriks Boolean
(matriks zero-one). Matriks biner ini sering dipakai sebagai “tabel” untuk me-representasikan
suatu struktur diskrit. Kita dapat mendefinisikan operasi Boolean pada elemen-elemen
matriks Boolean sebagai berikut
a
b
a∧b
a
b
a∨b
0
0
0
0
0
0
0
1
0
0
1
1
1
0
0
1
0
1
1
1
1
1
1
1
Misalkan A=[aij] dan B=[bij] adalah matriks Boolean berukuran m×n. Maka, join (gabungan)
dari A dan B adalah sebuah matriks Boolean yang elemen ke-(i,j)-nya adalah aij∨bij. Join dari
A dan B dituliskan sebagai A∨B. Meet (pertemuan) dari A dan B adalah sebuah matriks
Boolean dengan elemen ke-(i,j)-nya aij ∧ bij. Meet dari A dan B dituliskan sebagai A∧B.
Contoh: tinjau matriks-matriks berikut
⎡1 1 ⎤
⎡0 1 ⎤
⎥
⎢
A = ⎢ 0 1 ⎥ , dan B = ⎢⎢1 1 ⎥⎥ maka
⎢⎣1 0 ⎥⎦
⎢⎣0 0 ⎥⎦
2. Algoritma, Kompleksitas dan Teori Bilangan - 20
⎡1 ∧ 0 1 ∧ 1 ⎤ ⎡0 1 ⎤
⎡1 ∨ 0 1 ∨ 1 ⎤ ⎡1 1 ⎤
⎥
⎢
⎥
⎢
A ∨ B = ⎢ 0 ∨ 1 1 ∨ 1 ⎥ = ⎢1 1 ⎥ dan A ∧ B = ⎢⎢ 0 ∧ 1 1 ∧ 1 ⎥⎥ = ⎢⎢0 1 ⎥⎥
⎢⎣1 ∨ 0 0 ∨ 0 ⎥⎦ ⎢⎣1 0 ⎥⎦
⎢⎣1 ∧ 0 0 ∧ 0 ⎥⎦ ⎢⎣ 0 0 ⎥⎦
Misalkan A = [aij] adalah suatu matriks Boolean yang berukuran m×k dan B = [bij] adalah
matriks Boolean yang berukuran k×n. Perkalian Boolean dari A dan B, dituliskan sebagai
A o B , adalah sebuah matriks m×n yang elemen ke-(i, j)-nya, [cij], ditentukan sebagai berikut
cij = ( ai1 ∧ b1 j ) ∨ ( ai 2 ∧ b2 j ) ∨ ... ∨ ( aik ∧ bkj )
Pada dasarnya perkalian Boolean dilakukan seperti perkalian matriks biasa, tetapi operasi
perkalian bilangan digantikan dengan konjungsi “∧”, sedangkan operasi penjumlahan
bilangan digantikan dengan disjungsi “∨”.
Andaikan A sebuah matriks Boolean bujursangkar dan r adalah bilangan bulat positif. Kuasa
Boolean (boolean power) ke-r dari A adalah perkalian Boolean sebanyak r-buah dari matriks
A. Kuasa Boolean ke-r dari A dituliskan sebagai A[r], dengan kurung kotak pada operasi
perpangkatannya. Dengan demikian
A[ ] = I n
0
A[ ] = A o A o A ... o A
r
( r − kali)
2. Algoritma, Kompleksitas dan Teori Bilangan - 21
Download