Anda di halaman 1dari 14

POHON (TREE)

Objektif :
1. Mahasiswa Mengetahui Pengetahuan Dasar tentang Pohon.
2. Mahasiswa Mampu Memahami tentang Pohon Rentangan.
3. Mahasiswa Mampu Memahami dan Menghitung Pohon Rentangan Minimum dengan
Menggunakan Algoritma Kruskal.
4. Mahasiswa Mampu Memahami dan Menghitung Pohon Rentangan Minimum dengan
Menggunakan Algoritma Prim.

6.1 Pohon (Tree)


Pohon (tree) adalah sebuah graf tak berarah yang setiap dua simpul atau titiknya saling terhubung
melalui hanya sebuah sisi atau garis, dan tidak membentuk sirkuit atau putaran. Dari berbagai sudut
pandang pohon merupakan jenis graf non-trivial yang paling sederhana.

Pohon Pohon Bukan Pohon

Sifat-sifat Pohon
Pohon memiliki beberapa sifat yang ‘indah’, misalnya setiap dua simpulnya dihubungkan oleh tepat
satu buah lintasan. Dalam membuktikan sebuah teorema umum untuk graf, terkadang kita akan sangat
terbantu dengan terlebih dahulu membuktikan kebenarannya untuk pohon. Pada kenyataannya, terdapat
beberapa gagasan baru yang belum dapat dibuktikan kebenarannya bagi graf secara umum, namun telah
diketahui berlaku bagi pohon.
Teorema berikut memamparkan beberapa ciri sederhana sebuah pohon.
 Misalkan G adalah graf tak berarah sederhana dan jumlah simpulnya n. Maka, pernyataan-
pernyataan berikut semuanya setara:
1. G adalah sebuah pohon
2. G tidak memuat siklus, dan memiliki n – 1 rusuk
3. G terhubung, dan memiliki n – 1 rusuk
4. G terhubung, dan setiap rusuknya adalah sebuah jembatan
5. Setiap dua simpul dalam G dihubungkan oleh persis satu buah lintasan
6. G tidak memuat siklus, namun penambahan setiap rusuk baru akan membentuk persis satu
buah siklus

6.2 Pohon Rentangan (Spanning Tree)


Pohon rentangan dari graf terhubung adalah subgraf merentang yang berupa pohon. Pohon
rentangan diperoleh dengan memutus sirkuit di dalam graf. Setiap graf terhubung mempunyai paling sedikit
satu buah pohon rentangan.

Contoh Pohon Rentangan

6.3 Pohon Rentangan Minimal (Minimum Spanning Tree)


Pohon rentang minimum (minimal spanning tree) adalah teknik mencari jalan penghubung yang
dapat menghubungkan semua titik dalam jaringan secara bersamaan sampai diperoleh jarak minimum.
Jaringan yang dihasilkan merentangkan (menghubungkan) semua titik dalam jaringan tersebut pada total
jarak (panjang) minimum.
Ada dua cara dalam mencari minimum spanning tree:
1. Algoritma Kruskal
2. Algoritma Prim

Algoritma Kruskal
Algoritma Kruskal adalah algoritma pohon merentang minimum yang mengambil graf sebagai input
dan menemukan himpunan bagian dari sisi-sisi dari graf tersebut yang membentuk pohon yang
mencakup setiap simpul dan memiliki jumlah bobot minimum di antara semua pohon yang dapat
dibentuk dari grafik.
Langkah-langkah penyusunan minimum spanning tree menggunakan algoritma kruskal:
o Langkah 1: Pilih e1 sebuah sisi di graf G sehingga w(e1) sekecil mungkin dan e1 bukan loop
o Langkah 2: Jika sisi-sisi e1, e2,…, ei telah dipilih, lalu pilih sebuah sisi e1+1, yang belum
dipilih sedemikian sehingga
 Subgraf G = [{e1,…, ei+1}] adalah asiklik dan
 w(ei+1) adalah sekecil mungkin (syarat no (i))
o Langkah 3: Jika graf G memiliki n simpul, hentikan langkah tersebut setelah memilih n – 1
sisi. Jika tidak, ulangi langkah 2
A
3 1
F 3 B
3 4 2
4
1
E 5 C
4 2
D
Graf G

Mencari bobot minimum spanning tree graf G dengan menggunakan algoritma kruskal:

Bobot w(G) dari graf G adalah


W(G) = w(e1) + w(e2) + w(e3) + w(e4) + w(e5)
=1+1+2+3+3
= 10
Algoritma Prim
Algoritma Prim adalah algoritma pohon merentang minimum yang mengambil graf sebagai input
dan menemukan himpunan bagian dari sisi-sisi dari graf tersebut yang membentuk pohon yang
mencakup setiap simpul dan memiliki jumlah bobot minimum di antara semua pohon yang dapat
dibentuk dari grafik.
Langkah-langkah penyusunan minimum spanning tree menggunakan algoritma kruskal:
Langkah-langkah penyusunan minimum spanning tree menggunakan algoritma prim:
1. Langkah 1: Pilih sebarang titik v1 di graf G
2. Langkah 2: Pilih sebuah sisi e1 = v1 v2 di graf G sehingga v2 ≠ v1 dan e1 memiliki bobot
terkecil diantara sisi graf G yang bersisian dengan v1
3. Langkah 3: Jika sisi e1, e2,…, ei yang telah dipilih melibatkan ujung titik-titik e1, e2,…, ei+1
pilih sisi ei+1 = vj vk dengan vj {v1,v2,…,vi+1} dan vk {v1,v2,…,vi+1} sehingga ei+1 memiliki
bobot terkecil diantara sisi graf G yang tepat berujung di {v1,v2,…,vi+1}
4. Hentikan langkah tersebut setelah n – 1 sisi telah dipilih. Jika sebaliknya ulangi langkah 3

A
3 1
F 3 B
3 4 2
4
1
E 5 C
4 2
D
Graf G

Mencari bobot minimum spanning tree graf G dengan menggunakan algoritma prim:

Bobot w(G) dari graf G adalah


W(G) = w(e1) + w(e2) + w(e3) + w(e4) + w(e5)
=2+1+1+3+3
= 10
Contoh Demo Program Algoritma Kruskal:

Algoritma Kruskal adalah algoritma pohon merentang minimum yang mengambil graf sebagai input dan
menemukan himpunan bagian dari sisi-sisi graf tersebut yang

 membentuk pohon yang mencakup setiap simpul


 memiliki jumlah bobot minimum di antara semua pohon yang dapat dibentuk dari grafik

Cara Kerja Algoritma Kruskal

Ini termasuk dalam kelas algoritma yang disebut algoritma greedy yang menemukan optimal lokal
dengan harapan menemukan optimal global.

Kita mulai dari sisi dengan bobot terendah dan terus menambahkan sisi sampai kita mencapai tujuan
kita

Langkah-langkah untuk mengimplementasikan algoritma kruskal adalah sebagai berikut:

1. Urutkan semua sisi dari berat rendah ke tinggi


2. Ambil sisi dengan bobot terendah dan tambahkan ke pohon merentang. Jika menambahkan sisi
menciptakan siklus, maka tolak sisi ini.
3. Terus tambahkan sisi sampai kita mencapai semua simpul.

Contoh algoritma Kruskal

1. Mulailah dengan grafik berbobot

2. Pilih sisi yang bobotnya paling kecil, jika lebih dari 1 pilih siapa saja
3. Pilih sisi terpendek berikutnya dan tambahkan

4. Pilih sisi terpendek berikutnya yang tidak membuat siklus dan tambahkan

5. Pilih sisi terpendek berikutnya yang tidak membuat siklus dan tambahkan

6. Ulangi sampai Anda memiliki pohon merentang


Pseudocode Algoritma Kruskal
Algoritme pohon rentang minimum apa pun berkisar pada pemeriksaan apakah menambahkan sisi yang
membuat loop atau tidak.

Cara paling umum untuk mengetahui hal ini adalah algoritma yang disebut Union Find. Algoritma Union
Find membagi simpul ke dalam cluster dan memungkinkan kita untuk memeriksa apakah dua simpul
milik cluster yang sama atau tidak dan karenanya memutuskan apakah menambahkan sisi menciptakan
sebuah siklus.

KRUSKAL(G):
A = ∅
Untuk setiap simpul v G.V:
MAKE-SET(v)
Untuk setiap sisi (u, v) G.E diurutkan berdasarkan bertambahnya bobot(u, v):
if FIND-SET(u) ≠ FIND-SET(v):
A = A ∪ {(u, v)}
UNION(u, v)
return A

/* Demo Algoritma Kruskal */

#include <stdio.h>

#define MAX 30

typedef struct sisi {


int u, v, w;
} sisi;

typedef struct sisi_list {


sisi data[MAX];
int n;
} sisi_list;

sisi_list elist;

int Graph[MAX][MAX], n;
sisi_list spanlist;

void kruskalAlgo();
int cari(int belongs[], int vertexno);
void applyUnion(int belongs[], int c1, int c2);
void urut();
void cetak();

// Mengaplikasikan algoritma kruskal


void kruskalAlgo() {
int belongs[MAX], i, j, cno1, cno2;
elist.n = 0;

for (i = 1; i < n; i++)


for (j = 0; j < i; j++) {
if (Graph[i][j] != 0) {
elist.data[elist.n].u = i;
elist.data[elist.n].v = j;
elist.data[elist.n].w = Graph[i][j];
elist.n++;
}
}

urut();

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


belongs[i] = i;
spanlist.n = 0;

for (i = 0; i < elist.n; i++) {


cno1 = cari(belongs, elist.data[i].u);
cno2 = cari(belongs, elist.data[i].v);

if (cno1 != cno2) {
spanlist.data[spanlist.n] = elist.data[i];
spanlist.n = spanlist.n + 1;
applyUnion(belongs, cno1, cno2);
}
}
}

int cari(int belongs[], int vertexno) {


return (belongs[vertexno]);
}

void applyUnion(int belongs[], int c1, int c2) {


int i;

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


if (belongs[i] == c2)
belongs[i] = c1;
}

// Algoritma penyortiran
void urut() {
int i, j;
sisi temp;

for (i = 1; i < elist.n; i++)


for (j = 0; j < elist.n - 1; j++)
if (elist.data[j].w > elist.data[j + 1].w) {
temp = elist.data[j];
elist.data[j] = elist.data[j + 1];
elist.data[j + 1] = temp;
}
}

// Mencetak hasil
void cetak() {
int i, cost = 0;

for (i = 0; i < spanlist.n; i++) {


printf("\n%d - %d : %d", spanlist.data[i].u, spanlist.data[i].v, spanlist.data[i].w);
cost = cost + spanlist.data[i].w;
}

printf("\nSpanning tree cost: %d", cost);


}

int main() {
int i, j, total_cost;

n = 6;

Graph[0][0] = 0;
Graph[0][1] = 4;
Graph[0][2] = 4;
Graph[0][3] = 0;
Graph[0][4] = 0;
Graph[0][5] = 0;
Graph[0][6] = 0;

Graph[1][0] = 4;
Graph[1][1] = 0;
Graph[1][2] = 2;
Graph[1][3] = 0;
Graph[1][4] = 0;
Graph[1][5] = 0;
Graph[1][6] = 0;

Graph[2][0] = 4;
Graph[2][1] = 2;
Graph[2][2] = 0;
Graph[2][3] = 3;
Graph[2][4] = 4;
Graph[2][5] = 0;
Graph[2][6] = 0;

Graph[3][0] = 0;
Graph[3][1] = 0;
Graph[3][2] = 3;
Graph[3][3] = 0;
Graph[3][4] = 3;
Graph[3][5] = 0;
Graph[3][6] = 0;

Graph[4][0] = 0;
Graph[4][1] = 0;
Graph[4][2] = 4;
Graph[4][3] = 3;
Graph[4][4] = 0;
Graph[4][5] = 0;
Graph[4][6] = 0;

Graph[5][0] = 0;
Graph[5][1] = 0;
Graph[5][2] = 2;
Graph[5][3] = 0;
Graph[5][4] = 3;
Graph[5][5] = 0;
Graph[5][6] = 0;

kruskalAlgo();
cetak();
}

Output Program:
Contoh Demo Program Algoritma Prim
Algoritma prim adalah algoritma pohon merentang minimum yang mengambil graf sebagai input dan
menemukan himpunan bagian dari sisi-sisi dari graf tersebut yang
• membentuk pohon yang mencakup setiap simpul
• memiliki jumlah bobot minimum di antara semua pohon yang dapat dibentuk dari grafik

Cara kerja algoritma Prim


Ini termasuk dalam kelas algoritma yang disebut algoritma greedy yang menemukan optimal lokal dengan
harapan menemukan optimal global.
Kita mulai dari satu simpul dan terus menambahkan tepi dengan bobot terendah sampai kita mencapai
tujuan kita.
Langkah-langkah untuk mengimplementasikan algoritma prim adalah sebagai berikut:

1. Inisialisasi pohon merentang minimum dengan simpul yang dipilih secara acak.
2. Temukan semua tepi yang menghubungkan pohon ke simpul baru, temukan minimum dan tambahkan ke
pohon
3. Terus ulangi langkah 2 sampai kita mendapatkan pohon merentang minimum

Contoh Algoritma Prim

1. Mulailah dengan graf berbobot

2. Pilih salah satu titik

3. Pilih sisi terpendek dari titik ini dan tambahkan


4. Pilih titik terdekat yang belum ada dalam solusi

5. Pilih sisi terdekat yang belum ada dalam solusi, jika ada beberapa pilihan, pilih salah satu secara
acak

6. Ulangi sampai Anda memiliki pohon merentang

Pseudocode Algoritma Prim


Pseudocode untuk algoritma prim menunjukkan bagaimana kita membuat dua set simpul U dan V-U. U
berisi daftar simpul yang telah dikunjungi dan V-U daftar simpul yang belum dikunjungi. Satu per satu, kita
pindahkan simpul dari himpunan V-U ke himpunan U dengan menghubungkan edge dengan bobot terkecil.

T = ∅;
U = { 1 };
while (U ≠ V)
biarkan (u, v) menjadi sisi biaya terendah sehingga u U dan v V - U;
T = T ∪ {(u, v)}
U = U ∪ {v}

Kita dapat merepresentasikan keterhubungan graf ini dalam bentuk matriks seperti di bawah ini, dengan
kondisi:
A direpresentasikan menjadi 0
B direpresentasikan menjadi 1
C direpresentasikan menjadi 2
D direpresentasikan menjadi 3
E direpresentasikan menjadi 4
F direpresentasikan menjadi 5
0 1 2 3 4 5
0 0 4 4 0 0 0
1 4 0 2 0 0 0
2 4 2 0 3 2 4
3 0 0 3 0 0 3
4 0 0 2 0 0 3
5 0 0 4 3 3 0
/* Program C untuk Algoritma Prim */
/* Algoritma Spanning Tree (MST). Programnya adalah
untuk representasi matriks ketetanggaan dari grafik */

#include <limits.h>
#include <stdbool.h>
#include <stdio.h>

// Jumlah simpul dalam graf


#define V 6

/* Fungsi utilitas untuk mencari titik dengan


nilai key minimum, dari himpunan simpul yang belum termasuk dalam MST */

int minKey(int key[], bool mstSet[])


{
// Inisialisasi nilai min
int min = INT_MAX, min_index;

for (int v = 0; v < V; v++)


if (mstSet[v] == false && key[v] < min)
min = key[v], min_index = v;

return min_index;
}

// Fungsi utilitas untuk mencetak MST yang dibuat yang disimpan di induk[]

void printMST(int parent[], int graph[V][V])


{
printf("Sisi Bobot\n");
for (int i = 1; i < V; i++)
printf("%d - %d %d \n", parent[i], i, graph[i][parent[i]]);
}

/* Berfungsi untuk membuat dan mencetak MST untuk graf


yang direpresentasikan menggunakan representasi matriks ketetanggaan */

void primMST(int graph[V][V])


{
// Array untuk menyimpan MST yang telah dibuat
int parent[V];
// Nilai key yang digunakan untuk memilih sisi bobot minimum
int key[V];
// Untuk merepresentasikan himpunan simpul yang termasuk dalam MST
bool mstSet[V];

// Inisialisasi semua key sebagai INFINITE


for (int i = 0; i < V; i++)
key[i] = INT_MAX, mstSet[i] = false;
// Selalu sertakan simpul pertama di MST.
// Jadikan key 0 sehingga simpul ini dipilih sebagai simpul pertama.
key[0] = 0;
parent[0] = -1; // Node pertama selalu merupakan root dari MST

// MST akan memiliki V simpul


for (int count = 0; count < V - 1; count++) {
// Pilih simpul key minimum dari himpunan simpul yang belum termasuk
dalam MST
int u = minKey(key, mstSet);

// Tambahkan simpul yang dipilih ke Set MST


mstSet[u] = true;

// Perbarui nilai key dan indeks induk dari simpul yang berdekatan
dari simpul yang dipilih.
// Pertimbangkan hanya simpul yang belum termasuk dalam MST
for (int v = 0; v < V; v++)

// graf[u][v] bukan nol hanya untuk simpul bertetangga dari m


// mstSet[v] salah untuk simpul yang belum termasuk dalam MST
// Perbarui key hanya jika grafik[u][v] lebih kecil dari key[v]
if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v])
parent[v] = u, key[v] = graph[u][v];
}

printMST(parent, graph);
}

// Program utama
int main()
{

int graph[V][V] = {
{0, 4, 4, 0, 0, 0},
{4, 0, 2, 0, 0, 0},
{4, 2, 0, 3, 2, 4},
{0, 0, 3, 0, 0, 3},
{0, 0, 2, 0, 0, 3},
{0, 0, 4, 3, 3, 0}};

// Cetak Solusi
primMST(graph);

return 0;
}

Output Program:

Sisi Bobot
0 - 1 4
1 - 2 2
2 - 3 3
2 - 4 2
4 - 5 3
Referensi
Daniel, F., & Taneo, P. N. (2019). Teori Graf. Yogyakarta: Deepublish.
Lipschutz, S. (2008). Matematika Diskrit (Schaum's Outlines). Jakarta: Erlangga.
Wilson, R. J. (2010). Pengantar Teori Graf. Jakarta: Erlangga
https://www.programiz.com/.

Anda mungkin juga menyukai