Anda di halaman 1dari 10

PRAKTIKUM VIII

ALGORITMA MATEMATIKA

8.1. Pendahuluan
Algoritma matematika adalah algoritma yang digunakan untuk memecahkan masalah
yang berhubungan dengan bidang komputasi numerik seperti algoritma untuk melakukan
operasi matriks, algoritma untuk menghitung diferensial dan integral dan sebagainya. Masalah
yang tercakup bidang ini sangat banyak sekali, tetapi dalam bab ini hanya akan dibahas
mengenai algoritma untuk membangkitkan bilangan acak dan operasi dengan polinomial.

8.2. Bilangan Acak

Bilangan acak adalah bilangan yang memenuhi definisi konsep matematika, yaitu setiap
bilangan mempunyai kemungkinan yang sama untuk muncul. Sebenarnya, tidak mungkin
mendapatkan bilangan yang benar-benar acak karena setiap bilangan yang dihasilkan oleh
program komputer selalu dapat diprediksi. Program yang dibuat untuk membangkitkan
bilangan acak semu, disebut sebagai pembangkit bilangan acak (random number generator)
dan bilangan acak yang dihasilkannya disebut sebagai bilangan acak semu (pseudo random
number).

8.2.1. Pembangkit Bilangan Acak

Ada beberapa metode untuk membangkitkan bilangan acak semu. Metode yang paling
banyak digunakan adalah linear congruential method. Metode ini ditemukan oleh D. Lehmer
tahun 1951. Jika A[0] berisi bilangan sembarang maka statement berikut ini digunakan untuk
membuat array yang berisi N bilangan acak:
for ( I = 1 ; I <= N ; I++ )
A[I] = (A[I-1] * b + 1) % m

Dengan metode ini, tentukan lebih dulu bilangan awal yang disebut sebagai seed, lalu
untuk mendapatkan bilangan acak yang baru maka kalikan bilangan acak yang lama dengan
suatu konstanta b, lalu ditambah 1, kemudian bagi dengan konstanta m lalu ambil sisa
pembagiannya. Hasilnya adalah bilangan integer yang berada di antara 0 dan m-1.

66
Praktikum C++ Lanjut – Modul 8

Yang menjadi masalah adalah bagaimana menentukan b dan m sehingga dihasilkan


bilangan acak yang “baik”. Seorang ilmuan komputer, D. E. Knuth menuliskan bahwa, pertama
nilai untuk m harus cukup besar, kira-kira sebesar nilai 1 word komputer. Kedua, nilai dari b
lebih kecil 1 digit dari m. Ketiga, bilangan pada b harus berupa bilangan yang mempunyai pola
berupa ….x21 dengan x adalah bilangan genap.

Sebagai contoh, jika komputer mempunyai 32-bit word maka dapat diambil m =
100000000, b = 31515821 dan seed = 1234567. Untuk menghindari kemungkinan terjadinya
overflow pada perkalian a * b + 1 maka bilangan a dan b diubah menjadi p dan q berikut ini:
p = 104 p1 + p0 ; p1 = a/m1 , p0 = a%m1
q = 104 q1 + q0 ; q1 = b/m1 , q0 = b%m1
dengan m1 = 10000

Dengan demikian perkalian pq menjadi:


p * q = (104 p1 + p0 ) (104 q1 + q0 )
= 108 p1 q1 + 104 ( p1 q0 + p0 q1 ) + p0 q0

Untuk mendapatkan bilangan acak yang terdiri dari 8 digit, maka suku pertama dapat diabaikan
sehingga hanya digunakan suku kedua dan ketiga saja.

Kumpulan bilangan acak yang dihasilkan disebut mempunyai sifat uniform distribution
yaitu semua bilangan dalam range mempunyai kemungkinan yang sama untuk muncul. Sebagai
contoh, jika membangkitkan 100 bilangan acak integer antara 1 sampai 999 maka:

(a) bilangan pertama mungkin berada di antara 1… 999

(b) bilangan ke I mungkin berada di antara 1… 999

(c) rata-rata bilangan yang dibangkitkan adalah 500

8.2.2. Menguji Bilangan Acak

Seperti telah dijelaskan sebelumnya, bilangan acak yang dihasilkan oleh program
komputer bukan bilangan acak yang sebenarnya, tetapi bilangan acak semu. Ada beberapa
metode statistik yang dapat digunakan untuk menguji apakah bilangan acak yang dibangkitkan
memenuhi kriteria bilangan acak atau tidak. Salah satu di antaranya adalah uji χ2 (chi square).
Tujuan dari uji ini adalah untuk memeriksa apakah sekelompok bilangan tersebar merata dalam
suatu range atau tidak. Jika ada N bilangan dalam suatu range r maka dapat diharapkan bahwa
bilangan itu secara rata-rata bernilai N/r. Secara matematika dirumuskan sebagai:

67
Praktikum C++ Lanjut – Modul 8

χ2 =
 0 i  r
( fi  N / r)2
N /r

dengan:

- fi = bilangan yang diperiksa

- N = banyaknya bilangan

- r = range dari bilangan

Jika hasil perhitungan χ2 mendekati r atau berada diantara r ± (2√r) maka dapat dikatakan
kumpulan bilangan yang diperiksa memenuhi kriteria bilangan acak. Jika hasilnya jauh dari r
maka dikatakan kumpulan bilangan tersebut bukan bilangan acak.

#include <iostream>
#include <math.h>

using namespace std;


long mult(long p, long q, int m1)
// Fungsi untuk "mengalikan" 2 bilangan p dan q yang
// akan digunakan membangkitkan bilangan acak
{ long p1, p0, q1, q0, pq;
p1 = p/m1;
p0 = p%m1;
q1 = q/m1;
q0 = q%m1;
pq = (p0 * q1 + p1* q0)* m1 + p0*q0;
return (pq);
}

long terbesar(long key[],int n)


{
int besar = key[0];
for (int j = 0 ; j < n ; j++)
if (besar < key[j])
besar = key[j];
return besar;
}

// menguji bilangan acak


double chisq(long data[], int n)
{
long r;
double t, sum, r1, r2, R, D;

r = terbesar(data,n);
R = static_cast<double>(r);
t = (R+1.0)/2.0;
sum = 0;
for (int i = 0 ; i < n ; i++)
{ D = static_cast<double>(data[i]);
sum = sum + ((D - t)*(D - t))/t;
}
r1 = R - 2.0*sqrt(R);
r2 = R + 2.0*sqrt(R);
if ((sum < r1) || sum > r2)
cout<< " Tidak uniform" << endl;
return sum;
}

void main()
{ int N;
long R[1000];
long s = 12345;
long b = 425821;

68
Praktikum C++ Lanjut – Modul 8

long m = 1000000;
int m1 = 1000;
double uji;
R[0] = s;
cout <<"Ketikkan banyaknya bilangan yang akan dibangkitkan: ";
cout << endl;
cin >> N;
// membuat loop untuk membangkitkan bilangan random
for (int I = 1 ; I <= N ; I++)
{
R[I]=(mult(R[I-1],b, m1) + 1) % m;
}
// menuliskan isi array R
for (I = 0 ; I <= N ; I++ )
{
cout <<R[I]<<", ";
}
cout << endl,
//menguji bilangan yang dibangkitkan
uji = chisq(R,N);
cout << "uji = " <<uji << endl;
}

8.3. Polinomial

Polinomial adalah fungsi matematika yang terdiri dari konstanta, operator aritmatika
dan variabel. Bentuk umum polinomial adalah:

P(x) = a0 + a1 x + a2 x2 + ... + an xn

Contoh polinomial:

p(x) = 5 + 2 x – 3 x2 ; q(x) = 2 - x

P(x) disebut polinomial orde 2 atau polinomial pangkat 2 karena pangkat yang tertinggi
dari variabel x adalah 2. Dan polinomial q(x) disebut polinomial orde 1 atau pangkat 1 karena
pangkat tertinggi dari variabel x adalah 1. Pangkat terendah dari kedua polinomial tersebut
adalah 0.

8.3.1 Menyimpan polinomial


Ada 2 cara untuk menyimpan polinomial agar dapat diolah oleh komputer, yaitu dengan
menggunakan array dan linked list. Untuk polinomial yang disimpan dengan menggunakan
array, tiap suku pada polinomial disimpan dalam satu komponen array. Penyimpanan dilakukan
secara berurutan mulai dari suku dengan pangkat yang terendah. Indeks array digunakan untuk
menyimpan pangkat dari variabel x sedang komponen array menyimpan konstanta dari variabel
x. Dengan demikian panjang array sama dengan pangkat tertinggi dari polinomial + 1. Sebagai

69
Praktikum C++ Lanjut – Modul 8

contoh, array P digunakan untuk menyimpan polinomial p(x) dan array Q untuk menyimpan
polinomial q(x). Ilustrasinya dapat dilihat pada gambar 8.1 berikut ini.

P: 5 2 3 Q: 2 -1
Indeks: 0 1 2 Indeks: 0 1

Gambar 8.1 Polinomial yang disimpan dalam array P dan Q

Penyimpanan polinomial dengan array sangat efisien dan mudah jika pangkat variabel
polinomial berurutan seperti contoh di atas, tetapi sering juga ditemui polinomial yang
pangkatnya besar dan tidak berurutan seperti contoh di bawah ini.

s(x) = 15 + 3 x10 - 22 x20 ; t(x) = 7 - 3 x20

Untuk polinomial s(x) dan t(x) di atas, sebaiknya disimpan dengan linked list. Tiap suku pada
polinomial disimpan dalam sebuah node dalam linked list. Tiap node terdiri dari 3 field yaitu
masing-masing digunakan untuk menyimpan konstanta, pangkat dari variabel dan pointer next
untuk menunjuk ke suku berikutnya dalam polinomial. Sebagai contoh, list S digunakan untuk
menyimpan polinomial s(x) dan list T untuk menyimpan polinomial t(x). Ilustrasinya dapat
dilihat pada gambar 8.2 di bawah ini.

S: 15 0 3 10 -22 20
c j next c j next c j next

T 7 0 -3 20
c j next c j next

Keterangan:
c : field untuk meyimpan konstanta
j : field untuk menyimpan pangkat
next : field untuk menyimpan pointer next

Gambar 8.2 Polinomial yang disimpan dalam linked list S dan T

70
Praktikum C++ Lanjut – Modul 8

8.3.2 Menjumlahkan polinomial


Menjumlahkan 2 polinomial dilakukan secara suku per suku dari tiap polinomial.
Konstanta dari dua buah suku hanya dapat dijumlahkan jika pangkat variabelnya sama. Sebagai
contoh akan dijumlahkan 2 polinomial p(x) dan q(x) sebagai berikut:
p(x) + q(x) = ( 5 + 2 x – 3 x2 ) + ( 2 – x )
= 7 + x + 3 x2
Untuk polinomial yang disimpan dalam array, penjumlahan 2 polinomial, p(x) dan q(x)
lebih mudah dilakukan, yaitu dengan menggunakan statement loop berikut:
for ( I = 0; I < N; I ++ )
{ r[I] = p[I] + q[I]
}

Keterangan:
N : pangkat tertinggi dari polinomial yang dijumlahkan
r[i] : array tempat menyimpan polinomial hasil penjumlahan

Tetapi untuk polinomial yang disimpan dengan linked list perlu dibuat fungsi tersendiri
yaitu fungsi INSERT untuk membuat node baru sebagai tempat untuk menyimpan suku-suku
polinomial hasil penjumlahan. Sebagai contoh, akan dijumlahkan polinomial s(x) dan t(x)
sebagai berkut:

s(x)+ t(x) = (15 + 3 x10 - 22 x20) + (7 - 3 x20)


= 22 + 3 x10 - 25 x20

Dengan demikian, untuk menambahkan 2 polinomial perlu ditambahkan statement untuk


memeriksa pangkat dari masing-masing suku polinomial yang akan dijumlahkan. Jika
pangkatnya sama maka operasi jumlah dapat dilakukan. Jika pangkatnya tidak sama, maka
suku polinomial tersebut langsung disalin ke list yang menyimpan hasil jumlah.

8.3.3 Mengalikan polinomial


Sama seperti pada operasi penjumlahan, perkalian antara 2 polinomial dilakukan secara
suku per suku. Sebagai contoh akan dikalikan 2 polinomial p(x) dan q(x) sebagai berikut:

p(x) * q(x) = ( 5 + 2 x – 3 x2 ) + ( 2 – x )
= 10 + 4 x - 6 x2 – 5 x - 2 x2 + 3 x3
= 10 – x – 8 x2 + 3 x3

71
Praktikum C++ Lanjut – Modul 8

Untuk polinomial yang disimpan dengan array, operasi perkalian dilakukan dengan
statement loop bertingkat. Yang perlu diperhatikan adalah banyaknya komponen array yang
diperlukan untuk menyimpan polinomial hasil perkalian yaitu hasil jumlah dari pangkat kedua
polinomial yang tertinggi ditambah 1. Untuk contoh di atas, pangkat tertinggi dari polinomial
p(x) adalah 2 dan pangkat tertinggi dari polinomial q(x) adalah 1. Dengan demikian, array yang
digunakan untuk menyimpan hasil perkalian polinomial p(x) dan q(x) mempunyai 4 komponen
dengan indeks mulai dari 0 sampai 3.

Statement untuk mengalikan 2 polinomial p dan q yang disimpan dalam array adalah
seperti berikut:

for ( I = 0; I < N ; I ++ )
{ for ( J = 0 ; J < M ; J++ )
{ r[I+J] = r[I+J] + p[I] * q[J]
}
}
Keterangan:
I, J : counter
N : pangkat tertinggi dari polinomial p
M : pangkat terendah dari polinomial q
r : array hasil perkalian, r[N+M]

Latihan Soal Praktikum 8


1. Jalankan program untuk membangkitkan dan menguji bilangan acak. Bandingkan
hasilnya dengan bilangan acak yang dihasilkan dari fungsi random pada program
C++. Program mana yang menghasilkan angka random yang uniform?

2.a. Buat program untuk menyimpan 2 polinomial dalam array.


2.b. Buat fungsi untuk menampilkan polinomial dengan format yang sesuai
2.c. Tambahkan dalam program anda perintah untuk menambahkan kedua polinomial tadi
dan menampilkan hasilnya
2.d. Tambahkan dalam program anda perintah untuk mengalikan kedua polinomial tadi
dan menampilkan hasilnya

72
Praktikum C++ Lanjut – Modul 8

#include <iostream>
using namespace std;
//penjumlahan dan perkalian polinomial dengan array

void tampil(int a[], int n)


{
for (int i = 0 ; i < n ; i++)
{ if (i == 0)
cout << a[0] <<" + ";
else
if (i == 1)
cout << a[1] << " x + ";
else
if (i == n-1)
cout << a[i] <<" x^"<< i << endl;
else
cout << a[i] << " x^"<< i << " + ";
}
}

void main()
{
int p[20], q[20], r[20], s[40];
int n, m, i,j;

for (i = 0 ; i < 20 ; i++)


{ p[i] = 0;
q[i] = 0;
r[i] = 0;
}
for (i = 0 ; i < 40 ; i++)
s[i] = 0;

cout<<" Ketikkan pangkat tertinggi dari polinomial 1: ";


cin>> n;
cout<< endl;
cout<<" Ketikkan konstanta polinomial mulai dari suku pangkat terendah ";
cout<<endl;
cout<<" Ketikkan angka 0 jika tidak ada konstanta pada suku tersebut";
cout << endl;
for (i = 0 ; i < n ; i++)
{ cout<<" Konstanta untuk suku polinomial ke "<< i+1 <<" ";
cin>> p[i];
}
cout<<endl;
cout<<" Ketikkan pangkat tertinggi dari polinomial 2: ";
cin>> m;
cout<<" Ketikkan konstanta polinomial mulai dari suku pangkat terendah ";
cout<<endl;
cout<<" Ketikkan angka 0 jika tidak ada konstanta pada suku tersebut";
cout << endl;
for (i = 0 ; i < m ; i++)
{ cout<<" Konstanta untuk suku polinomial ke "<< i+1 <<" ";
cin>> q[i];
}
cout<<endl;
cout<<"Polinomial 1: "<<endl;
tampil(p,n);
cout<<"Polinomial 2: "<<endl;
tampil(q,m);
if (n > m)
{ for ( i = 0; i < n ; i++)
r[i] = p[i] + q[i];
cout<< " Hasil penjumlahan 2 polinomial: "<<endl;
tampil(r,n);
}
else
{ for ( i = 0; i < m ; i++)
r[i] = p[i] + q[i];
cout<< " Hasil penjumlahan 2 polinomial: "<<endl;
tampil(r,m);
}
for (i = 0; i < n ; i ++ )
{ for ( j = 0 ; j < m ; j++ )
{ s[i+j] = s[i+j] + p[i] * q[j];
}
}
cout<<endl;
cout<< " Hasil perkalian 2 polinomial: "<<endl;
73
tampil(s, m+n-1);
}
Praktikum C++ Lanjut – Modul 8

#include <iostream>
using namespace std;

struct Node //penjumlahan polinomial dengan linked list


{
int data;
int p;
Node *link;
};

void InsertN(Node **L, int c, int j)


{
Node *baru, *t;
baru = new Node;
baru->link=NULL;
baru->data = c;
baru->p = j;
if (*L == NULL)
*L = baru;
else
{ t = *L;
while (t->link != NULL)
t = t->link;
t->link = baru;
}
}

void Tampil(Node *L)


{
Node *N;
N = L;
while (N->link != NULL)
{
cout <<N->data <<" x^" <<N->p << " + ";
N = N->link;
}
if (N->link == NULL)
cout <<N->data <<" x^" <<N->p << endl;
}

void main()
{
int n, m, x, y;
Node *P1, *P2, *P3;

P1 = NULL;
P2 = NULL;
P3 = NULL;
cout<<" Ketikkan banyaknya suku dalam polinomial 1: ";
cin>> n;
cout<< endl;
cout<<" Ketikkan konstanta dan pangkat polinomial secara berurutan ";
cout <<endl;
for (int i = 0 ; i < n ; i++)
{ cout<<" Konstanta untuk suku polinomial ke "<< i+1 <<" = ";
cin>> x;
cout<<" Pangkat untuk suku polinomial ke "<< i+1 <<" = ";
cin>> y;
InsertN(&P1, x, y);
}
cout<<endl;
cout<<" Ketikkan banyaknya suku dalam polinomial 2: ";
cin>> m;
cout<< endl;
cout<<" Ketikkan konstanta dan pangkat polinomial secara berurutan ";
cout <<endl;
for (i = 0 ; i < m ; i++)
{ cout<<" Konstanta untuk suku polinomial ke "<< i+1 <<" = ";
cin>> x;
cout<<" Pangkat untuk suku polinomial ke "<< i+1 <<" = ";
cin>> y;
InsertN(&P2, x, y);
}
cout<<endl;

74
Praktikum C++ Lanjut – Modul 8

cout<<"Polinomial 1: "<<endl;
Tampil(P1);
cout<<"Polinomial 2: "<<endl;
Tampil(P2);

cout<<"Menjumlahkan polinomial" <<endl;

Node *a, *b ;
a = P1;
b = P2;

//membuat loop untuk menelusuri p dan q]


while ( a->link != NULL && b->link!= NULL )
{ // memeriksa pangkat tiap node]
if ((a->p == b->p) && ((a->data + b->data) != NULL))
{ // pangkat sama dan hasil jumlah tidak nol, lakukan penjumlahan
InsertN(&P3, (a->data + b->data), a->p);
a = a->link; // lanjutkan dengan node berikutnya
b = b->link;
}
else
{ //pangkat polinomial p < q]
if (a->p < b->p) //salin polinomial p
{ InsertN(&P3, a->data, a->p);
a = a->link;
}
else
{ //[pangkat polinomial p > q]
if (a->p > b->p) //salin polinomial q
{ InsertN(&P3, b->data, b->p);
b = b->link;
}
}
}
}
if (a->link == NULL) // node terakhir dari polinomial p
{ //masih ada node di pilonomial q
while ((a->p > b->p) && (b->link != NULL))
{ InsertN(&P3, b->data, b->p);
b = b->link;
}
if (a->p == b->p)
{ InsertN(&P3, (a->data +b->data), a->p);
b = b->link;
}
else
InsertN(&P3, a->data, a->p);
while (b->link != NULL) //menyalin sisa node polinomial q
{ InsertN(&P3, b->data, b->p);
b = b->link;
}
}
if (b->link == NULL) // node terakhir dari polinomial q
{ // masih ada node di polinomial p
while ((b->p > a->p) && (a->link != NULL))
{ InsertN(&P3, a->data, a->p);
a = a->link;
}
if (a->p == b->p)
{ InsertN(&P3, (a->data + b->data), b->p);
a = a->link;
}
else
InsertN(&P3, b->data, b->p);
while (a ->link != NULL) //menyalin sisa node polinomial p
{ InsertN(&P3, a->data, a->p);
a = a->link;
}
}
Tampil(P3);
system (“pause”);
}

75

Anda mungkin juga menyukai