Modul Praktikum
10S2101 – Algoritma dan Struktur Data (Prodi S1 SI dan TE)
Graph ADT
Minggu : 13
Tanggal : 15 November 2021
Tujuan : Mampu menjelaskan definisi formal graf dan properties
nya.
Mampu memberikan contoh – contoh penerapan graf
untuk menyelesaikan masalah komputasi.
Mampu menggambarkan implementasi graf dengan
matriks dan lis kedekatan.
Mampu menulis program Graph ADT dengan
representasi matriks dan lis kedekatan.
Setoran : Lembar jawaban dan program (via e-course)
Waktu penyetoran : 21 November 2021 Pukul 22:00
Petunjuk Praktikum
1. Anda mengerjakan praktikum ini secara berkelompok dengan maksimum 3 mahasiswa
per kelompok.
2. Tugas dikerjakan dalam kelompok masing-masing. Tindakan-tindakan plagiarisme, jika
terbukti dapat menyebabkan pemberian sanksi akademik ke mahasiswa/ kelompok yang
terlibat.
Referensi
1. T.H. Cormen, C.E. Leiserson, R.L. Rivest and C. Stein, Introduction to Algorithm 3rd
eds., MIT Press 2009.
2. M.A. Weiss, Data Structures and Algorithm Analysis in C, 2nd Eds., Addison-Wesley,
1997.
Bagian 1: Essai
1. Berikanlah definisi formal dari graf, graf berarah, dan graf tidak berarah.
2. Jelaskan properties/karakteristik graf berikut ini:
a) Path atau lintasan
b) Cycle atau siklus
c) Connected dan strongly connected graph
d) Complete graph
e) Dense and sparse graph
3. Berikan contoh penerapan graf untuk memodelkan objek-objek berikut. Sebukan apa yang
menjadi simpul, busur, serta berikan contoh lintasan:
a) Jaringan komputer
b) Perangkat lunak
c) Peta
d) Jaringan saraf buatan (artificial neural network) dalam bidang kecerdasan buatan.
a) Tentukan:
i. jumlah simpul dan jumlah busur;
ii. apakah graf tersebut merupakan graf rapat (dense graph), jelaskan jawaban
anda;
iii. apakah graf tersebut merupakan graf siklus (cyclic graph);
iv. 2 buah lintasan pada graf dimana jumlah simpul pada lintasan > 3.
b) Gambarkan diagram implementasi matriks kedekatan untuk graf tersebut.
c) Gambarkan pula diagram implementasi lis kedekatan untuk graf tersebut.
d) Jelaskanlah implementasi graf mana yang paling efisien.
Bagian 2: Pemrograman
Implementasi graf dengan adjacency matrix (matriks kedekatan)
Pada bagian ini, anda akan membuat struktur data graf dengan matriks kedekatan.
Representasi ini sangat baik untuk graf padat (dense graph) atau pun complete graph serta
sederhana. Pada no. 2, anda akan menggunakan lis kedekatan (adjacency list),
representasi yang baik untuk graf renggang/jarang (sparse graph).
Antarmuka: graph_adjmatrix.h diberikan oleh kode di halaman berikut.
Antarmuka menggunakan penyertaan kondisional (conditional inclusion). Pernyataan
baris ke-8 memberikan deklarasi generik untuk Graph ADT (struct GraphADT)
sehingga graf dapat direpresentasikan sesuai dengan kebutuhan. Pernyataan baris ke-9
dan ke-10 membuat definisi tipe data berupa pointer ke struct GraphADT. Tipe
data Graph (baris ke-10) merupakan tipe data yang akan digunakan untuk deklarasi
dan alokasi memori graf matriks kedekatan. Nama – nama fungsi telah dibuat
sedemikian sehingga anda memahami tugas dari setiap fungsi. Misalnya, NumNodes,
merupakan fungsi yang dipanggil untuk mengembalikan jumlah simpul (number of
nodes). Fungsi Predecessors – dengan tipe kembalian array/pointer bertipe
unsigned int – bertugas untuk mengembalikan semua simpul pendahulu
(predecessors) dari suatu simpul (simpul dengan label/id n di parameter ke-2).
Demikian juga dengan fungsi-fungsi yang lain dapat anda pahami dari namanya. Ini
adalah praktek yang baik.
Pada struktur di atas, matriks kedekatan direpresentasikan oleh matriks dimensi 2 pada
baris ke-11 yang akan dialokasikan secara dinamik: variabel adjmatrix yang
merupakan pointer ganda (double indirection pointer). Varibel V menampung jumlah
simpul dan E, jumlah busur pada graf.
Fungsi ConstructGraph ditunjukkan oleh kode di halaman selanjutnya. Parameter
fungsi adalah g dan V yang masing-masing menunjukkan graf dan jumlah simpul.
Dengan demikian, konstruksi graf menggunakan matriks kedekatan memiliki
keterbatasan jumlah simpul maksimum yang dapat ditampung graf. Konstruksi
dimulai dengan alokasi memori Graph ADT yang diwakili oleh parameter g bertipe
b. Pernyataan baris ke-26 s/d 32 mengalokasikan memori untuk setiap baris data
dengan perulangan sebanyak V kali. Artinya, untuk setiap single indirection
pointer (Element Type *) yang telah dialokasikan di pernyataan baris ke-
21, dilakukan alokasi memori untuk menampung data bertipe ElementType
sejumlah V. Juga dilakukan pengecekan ketersediaan memori oleh pernyataan
baris ke-28 s/d 30.
Langkah terakhir dalam konstruksi graf adalah menginisiasi semua busur antara
simpul yang berbeda (distinct nodes) tidak ada. Pada konstruksi graf tersebut, tidak
ada busur ditandai dengan bobot/weight bernilai tak hingga yang diasumsikan sebesar
nilai maksimal bilangan bulat positif tak bertanda (unsigned int) kurang 1000
(UINT_MAX-1000). Busur dari simpul yang identik, diberi nilai 0 (nol). Anda harus
menyertakan <limits.h> agar dapat menggunakan UINT_MAX. Jika anda
menggunakan graf tanpa bobot/ bobot sama (graph with equal weight), anda
dapat menugaskan angka 0 untuk menunjukkan tidak ada busur dan angka 1
untuk menunjukkan ada busur.
Operasi untuk menambah busur dilakukan dengan menugaskan nilai cell dari
matriks dimensi 2 dengan bobot busur, dimana indeks baris matriks menunjukkan
simpul sumber (start/ predecessor) dan indeks kolom matriks sebagai simpul tujuan
(end/ successor). Operasi di ditunjukkan oleh fungsi AddEdge yang kodenya
diberikan di bawah ini. Ketika busur ditambahkan maka jumlah busur juga bertambah
1 (di-increment) sebagaimana ditunjukkan oleh pernyataan baris ke-48. Sebaliknya,
operasi menghapus busur dilakukan dengan menugaskan nilai cell sebesar
UINT_MAX-1000, sebagai penanda bahwa tidak ada busur antara simpul yang
ditunjukkan oleh indeks baris ke simpul yang ditunjukkan oleh indeks kolom. Ketika
busur dihapus, maka jumlah busur juga berkurang 1 (di-decrement).
Fungsi untuk mengembalikan jumlah simpul dan busur merupakan fungsi sederhana
dan ditunjukkan oleh kode di bawah ini.
mempunyai busur (bukan lintasan) menuju n. Baca komentar yang diberikan untuk
memahami cara kerja fungsi.
Fungsi Successors ditunjukkan oleh kode program di bawah ini. Parameter fungsi
adalah g yang menampung graf dan n yang menampung label/ identitas simpul.
Fungsi ini mengembalikan semua simpul yang merupakan penerus/ successors dari
simpul n. Pada prinsipnya, fungsi Successors memiliki cara kerja yang mirip
dengan fungsi Predecessors, bedanya Successors mengembalikan array yang
berisi label/ identitas simpul penerus. Baca komentar yang diberikan agar anda paham
cara kerja fungsi.
Fungsi Destroy diberikan di bawah ini. Fungsi bertugas untuk menghapus graf.
Parameter fungsi adalah g yang menampung graf yang memiliki memori.
Penghapusan graf berarti menghapus semua memori yang dialokasi ke g pada fungsi
Construct. Ada 3 langkah untuk penghapusan graf yang merupakan operasi yang
merupakan kebalikan dari alokasi sebagaimana diberikan di komentar program.
Fungsi mengembalikan g yang memiliki memori kosong atau saat ini bernilai NULL.
matriks kedekatan di bagian sebelumnya. Tulis ke-2 antarmuka tersebut dan simpan
dengan nama yang diberikan.
Untuk mengimplementasikan Graph ADT dengan lis kedekatan, pertama sekali anda
harus mendefinisikan struktur simpul, busur, dan graf. Tulis kode program di halaman
selanjutnya dan simpan sebagai graph.c.
Pada pernyataan baris ke-8 s/d 16, diimplementasikan struct GraphNode yang
merupakan representasi simpul yang memiliki 2 variabel anggota, yakni ID bertipe
WeightType dan next bertipe Edge. ID menampung identitas/ label simpul,
sedangkan next merupakan pointer ke busur pertama yang merupakan suksesor
simpul dengan label ID. Pada baris ke-12 s/d 15 dituliskan sebagai komentar beberapa
anggota variabel tambahan yang akan anda gunakan untuk melintasi graf
menggunakan algoritma breadth first search (BFS) dan depth first search (DFS). Ini
untuk menegaskan bahwa anda, sebagai programmer memiliki keleluasaan untuk
menambahkan kompleksitas terhadap graf dengan mudah jika menggunakan
implementasi lis kedekatan.
Pada baris ke-18 s/d 21 diimplementasikan struct GraphEdge yang merupakan
representasi busur dengan 3 anggota variabel, yakni node, weight, dan next.
Variabel node menampung simpul yang menjadi suksesor simpul dengan label ID,
weight menampung bobot, serta next merupakan pointer ke busur selanjutnya
yang merupakan suksesor dari simpul dengan label ID.
Fungsi NodeID diimplementasikan oleh pernyataan baris ke-69 dan 70. Fungsi ini
mengembalikan identitas/ label dari simpul. Parameter fungsi adalah node atau yang
menampung sebuah simpul atau lebih tepat, pointer ke simpul.
Implementasi fungsi Search ditunjukkan oleh kode program di bawah ini.
Parameter fungsi adalah g yang menampung graf dan x yang menampung identitas
simpul yang dicari. Baca komentar program agar anda mengerti cara kerja fungsi.
Operasi untuk menambahkan busur dilakukan oleh fungsi AddEdge di bawah ini.
Parameter fungsi adalah g yang menampung graf, s simpul awal/ asal, e simpul akhir/
tujuan, dan weight yang merupakan bobot. Dengan deskripsi ini, simpul s
merupakan predecessor/ pendahulu simpul e. Baca komentar yang diberikan untuk
dapat memahami cara kerja fungsi AddEdge.
Fungsi untuk mencari dan mengembalikan semua simpul pendahulu ditunjukkan oleh
fungsi Predecessors di bawah ini. Parameter fungsi adalah g yang menampung
graf dan x yang menampung identitas/ label dari simpul yang hendak dicari
pendahulu-pendahulunya. Fungsi mengembalikan pointer atau array dinamik yang
menampung simpul-simpul pendahulu. Baca komentar yang diberikan agar anda
memahami cara kerja fungsi.
Fungsi Successors yang bertugas untuk mencari dan mengembalikan semua simpul
penerus/ successors. Parameter fungsi adalah g yang menampung graf dan x yang
menampung identitas/ label dari simpul yang hendak dicari penerus-penerusnya.
Untuk menggunakan struktur data, anda akan membuat program klien yang bekerja
pada graf dengan implementasi lis kedekatan sebagaimana ditunjukkan oleh gambar di
bawah ini. Graf tersebut diambil dari referensi [2] halaman 286. Karena graf pada
gambar mengasumsikan bobot busur sama, maka hanya ada 2 variabel di busur, yakni
simpul dan pointer ke busur selanjutnya. Sementara pada program Graph ADT yang
anda tulis, anggota variabel dari struktur busur (GraphEdge) ada 3, termasuk bobot.
Kita akan menyesuaikannya dengan membuat bobot semua busur bernilai 1 (satu).
Program klien ditunjukkan oleh kode program di halaman selanjutnya. Tulis dan
simpan program dengan nama client_graph.c.
Dari tampilan, kita dapat menyimpulkan bahwa Graph ADT yang dibuat adalah
benar.
Setoran
Lembar jawaban untuk pertanyaan di Bagian I: Essai dan kode program untuk Bagian 3:
Tugas Pemrograman yang disetor melalui ecourse.del.ac.id pada halaman mata kuliah
10S2101 – Algoritma dan Struktur Data.