# Sintaks Project mandiri PROSES STOKASTIK
# BAGIAN D - SIMULASI KOMPUTASI
# 1. LIBRARY
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
library(igraph)
## Warning: package 'igraph' was built under R version 4.4.3
##
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
##
## decompose, spectrum
## The following object is masked from 'package:base':
##
## union
# 2. PARAMETER SIMULASI
# Jumlah hari simulasi
n <- 1000
# Kondisi awal
S0 <- 0
# Matriks probabilitas transisi
P <- matrix(c(
0.65, 0.30, 0.05,
0.25, 0.55, 0.20,
0.10, 0.40, 0.50
), nrow = 3, byrow = TRUE)
rownames(P) <- c("S0", "S1", "S2")
colnames(P) <- c("S0", "S1", "S2")
# Menampilkan matriks transisi
P
## S0 S1 S2
## S0 0.65 0.30 0.05
## S1 0.25 0.55 0.20
## S2 0.10 0.40 0.50
# 3. SIMULASI KONDISI CUACA
# Seed agar hasil simulasi dapat direproduksi
set.seed(123)
# Menyimpan kondisi cuaca
S <- numeric(n)
# Kondisi awal
S[1] <- S0
# Membangkitkan kondisi hari berikutnya
for (t in 1:(n - 1)) {
S[t + 1] <- sample(
x = 0:2,
size = 1,
prob = P[S[t] + 1, ]
)
}
# Melihat 20 kondisi pertama
head(S, 20)
## [1] 0 0 1 1 2 0 0 0 1 0 0 2 2 1 0 0 1 1 1 1
# 4. SIMULASI CURAH HUJAN
R <- numeric(n)
for (t in 1:n) {
if (S[t] == 0) {
# S0 : Uniform(0,5)
R[t] <- runif(
1,
min = 0,
max = 5
)
} else if (S[t] == 1) {
# S1 : Exponential(lambda = 1/20)
R[t] <- rexp(
1,
rate = 1 / 20
)
} else {
# S2 : Gamma(k = 2, theta = 30)
R[t] <- rgamma(
1,
shape = 2,
scale = 30
)
}
}
# 5. MEMBUAT DATA FRAME
data_simulasi <- data.frame(
Hari = 1:n,
Kondisi = S,
Curah_Hujan = R
)
# Label kondisi
data_simulasi$Kondisi_Label <- factor(
data_simulasi$Kondisi,
levels = c(0, 1, 2),
labels = c(
"S0 - Cerah/Berawan",
"S1 - Hujan Sedang",
"S2 - Hujan Lebat/Ekstrem"
)
)
# Melihat 10 data pertama
head(data_simulasi, 10)
## Hari Kondisi Curah_Hujan Kondisi_Label
## 1 1 0 0.5441204 S0 - Cerah/Berawan
## 2 2 0 1.3681137 S0 - Cerah/Berawan
## 3 3 1 3.7546773 S1 - Hujan Sedang
## 4 4 1 33.3554574 S1 - Hujan Sedang
## 5 5 2 91.9143284 S2 - Hujan Lebat/Ekstrem
## 6 6 0 2.3894341 S0 - Cerah/Berawan
## 7 7 0 3.8684606 S0 - Cerah/Berawan
## 8 8 0 1.4770004 S0 - Cerah/Berawan
## 9 9 1 42.5898266 S1 - Hujan Sedang
## 10 10 0 2.2026656 S0 - Cerah/Berawan
# 6. JUMLAH DAN PROPORSI KONDISI CUACA
jumlah_kondisi <- table(
data_simulasi$Kondisi
)
proporsi_kondisi <- prop.table(
jumlah_kondisi
)
persentase_kondisi <- proporsi_kondisi * 100
jumlah_kondisi
##
## 0 1 2
## 340 433 227
proporsi_kondisi
##
## 0 1 2
## 0.340 0.433 0.227
persentase_kondisi
##
## 0 1 2
## 34.0 43.3 22.7
# Membuat tabel hasil
tabel_kondisi <- data.frame(
Kondisi = c(
"Cerah/Berawan",
"Hujan Sedang",
"Hujan Lebat/Ekstrem"
),
Jumlah_Hari = as.numeric(
jumlah_kondisi
),
Proporsi = as.numeric(
proporsi_kondisi
),
Persentase = as.numeric(
persentase_kondisi
)
)
tabel_kondisi
## Kondisi Jumlah_Hari Proporsi Persentase
## 1 Cerah/Berawan 340 0.340 34.0
## 2 Hujan Sedang 433 0.433 43.3
## 3 Hujan Lebat/Ekstrem 227 0.227 22.7
# VISUALISASI 1
# DISTRIBUSI KONDISI CUACA
# Warna kondisi cuaca
warna_state <- c(
"S0 - Cerah/Berawan" = "#F4B942",
"S1 - Hujan Sedang" = "#4C9BD3",
"S2 - Hujan Lebat/Ekstrem" = "#263F66"
)
# Urutan kondisi
tabel_kondisi$Kondisi <- factor(
tabel_kondisi$Kondisi,
levels = c(
"Cerah/Berawan",
"Hujan Sedang",
"Hujan Lebat/Ekstrem"
)
)
ggplot(
tabel_kondisi,
aes(
x = Kondisi,
y = Persentase,
fill = Kondisi
)
) +
geom_col(
width = 0.65,
color = "white",
linewidth = 0.5
) +
geom_text(
aes(
label = paste0(
round(Persentase, 1),
"%"
)
),
vjust = -0.5,
fontface = "bold",
size = 4
) +
scale_fill_manual(
values = c(
"Cerah/Berawan" = "#F4B942",
"Hujan Sedang" = "#4C9BD3",
"Hujan Lebat/Ekstrem" = "#263F66"
)
) +
labs(
title = "Distribusi Kondisi Cuaca Hasil Simulasi",
x = "Kondisi Cuaca",
y = "Persentase (%)"
) +
scale_y_continuous(
expand = expansion(
mult = c(0, 0.10)
)
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(
hjust = 0.5,
face = "bold",
size = 14
),
axis.title = element_text(
face = "bold"
),
axis.text.x = element_text(
angle = 0,
hjust = 0.5
),
legend.position = "none",
panel.grid.minor = element_blank()
)

# 7. DIAGRAM TRANSISI CUACA
# 7.1 DATA TRANSISI
edges <- data.frame(
from = c(
"S0", "S0", "S0",
"S1", "S1", "S1",
"S2", "S2", "S2"
),
to = c(
"S0", "S1", "S2",
"S0", "S1", "S2",
"S0", "S1", "S2"
),
prob = c(
P[1,1], P[1,2], P[1,3],
P[2,1], P[2,2], P[2,3],
P[3,1], P[3,2], P[3,3]
)
)
# Label probabilitas
edges$label <- sprintf(
"%.2f",
edges$prob
)
# 7.2 DATA NODE
vertices <- data.frame(
name = c(
"S0",
"S1",
"S2"
),
label = c(
"S0\nCerah/Berawan",
"S1\nHujan Sedang",
"S2\nHujan Lebat/Ekstrem"
)
)
# 7.3 MEMBUAT GRAPH
g <- graph_from_data_frame(
d = edges,
directed = TRUE,
vertices = vertices
)
# 7.4 WARNA NODE
warna_node <- c(
S0 = "#F4B942",
S1 = "#4C9BD3",
S2 = "#263F66"
)
V(g)$color <- warna_node[
V(g)$name
]
V(g)$size <- 8
V(g)$frame.color <- "white"
V(g)$frame.width <- 2
V(g)$label.color <- "white"
V(g)$label.cex <- 1
# 7.5 PENGATURAN PANAH
E(g)$color <- "#64748B"
E(g)$width <- 2
E(g)$arrow.size <- 0.35
E(g)$label <- edges$label
E(g)$label.color <- "black"
E(g)$label.cex <- 2
# 7.6 MEMBUAT PANAH TIDAK BERTUMPUK
E(g)$curved <- c(
# S0 -> S0
0.6,
# S0 -> S1
0.18,
# S0 -> S2
-0.18,
# S1 -> S0
-0.18,
# S1 -> S1
0.6,
# S1 -> S2
0.18,
# S2 -> S0
0.18,
# S2 -> S1
-0.18,
# S2 -> S2
0.6
)
# 7.7 POSISI NODE
layout_cuaca <- matrix(
c(
-1.2, -0.8, # S0
1.2, -0.8, # S1
0.0, 1.0 # S2
),
ncol = 2,
byrow = TRUE
)
# 7.8 MENAMPILKAN DIAGRAM
plot(
g,
layout = layout_cuaca,
# Node
vertex.color = V(g)$color,
vertex.size = V(g)$size,
vertex.label = V(g)$label,
vertex.label.color = V(g)$label.color,
vertex.label.cex = V(g)$label.cex,
vertex.frame.color = V(g)$frame.color,
vertex.frame.width = V(g)$frame.width,
# Panah
edge.color = E(g)$color,
edge.width = E(g)$width,
edge.arrow.size = E(g)$arrow.size,
edge.curved = E(g)$curved,
# Probabilitas
edge.label = E(g)$label,
edge.label.color = E(g)$label.color,
edge.label.cex = E(g)$label.cex,
# Tampilan
rescale = TRUE,
asp = 0.90,
margin = 0.88
)

# 8. RATA-RATA CURAH HUJAN SETIAP KONDISI
mean_per_kondisi <- tapply(
data_simulasi$Curah_Hujan,
data_simulasi$Kondisi,
mean
)
mean_per_kondisi
## 0 1 2
## 2.618053 20.586376 58.026557
# Tabel rata-rata
tabel_mean <- data.frame(
Kondisi = c(
"Cerah/Berawan",
"Hujan Sedang",
"Hujan Lebat/Ekstrem"
),
Rata_rata_Simulasi = as.numeric(
mean_per_kondisi
),
Rata_rata_Teoritis = c(
2.5,
20,
60
)
)
tabel_mean
## Kondisi Rata_rata_Simulasi Rata_rata_Teoritis
## 1 Cerah/Berawan 2.618053 2.5
## 2 Hujan Sedang 20.586376 20.0
## 3 Hujan Lebat/Ekstrem 58.026557 60.0
# VISUALISASI 2
# PERBANDINGAN RATA-RATA CURAH HUJAN
# Data untuk grafik
data_mean_plot <- data.frame(
Kondisi = rep(
c(
"S0",
"S1",
"S2"
),
each = 2
),
Label = rep(
c(
"Cerah/Berawan",
"Hujan Sedang",
"Hujan Lebat/Ekstrem"
),
each = 2
),
Metode = rep(
c(
"Teoritis",
"Simulasi"
),
times = 3
),
Nilai = c(
2.5,
as.numeric(mean_per_kondisi)[1],
20,
as.numeric(mean_per_kondisi)[2],
60,
as.numeric(mean_per_kondisi)[3]
)
)
ggplot(
data_mean_plot,
aes(
x = Kondisi,
y = Nilai,
fill = Metode
)
) +
geom_col(
position = position_dodge(
width = 0.75
),
width = 0.62
) +
geom_text(
aes(
label = round(
Nilai,
2
)
),
position = position_dodge(
width = 0.75
),
vjust = -0.4,
fontface = "bold",
size = 3.5
) +
scale_fill_manual(
values = c(
"Teoritis" = "#263F66",
"Simulasi" = "#F4B942"
)
) +
scale_x_discrete(
labels = c(
"S0" = "S0\nCerah/Berawan",
"S1" = "S1\nHujan Sedang",
"S2" = "S2\nHujan Lebat"
)
) +
labs(
title = "Perbandingan Rata-Rata Curah Hujan",
x = "Kondisi Cuaca",
y = "Rata-rata Curah Hujan (mm)",
fill = "Metode"
) +
scale_y_continuous(
expand = expansion(
mult = c(0, 0.12)
)
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(
hjust = 0.5,
face = "bold",
size = 14
),
axis.title = element_text(
face = "bold"
),
legend.position = "bottom",
panel.grid.minor = element_blank()
)

# 9. DATA DISTRIBUSI TEORITIS
# S0 - Uniform(0,5)
x0 <- seq(
0,
5,
length.out = 300
)
teori_s0 <- data.frame(
Curah_Hujan = x0,
Density = dunif(
x0,
min = 0,
max = 5
),
Kondisi_Label = "S0 - Cerah/Berawan"
)
# S1 - Exponential(lambda = 1/20)
x1 <- seq(
0,
quantile(
data_simulasi$Curah_Hujan[
data_simulasi$Kondisi == 1
],
0.99
),
length.out = 300
)
teori_s1 <- data.frame(
Curah_Hujan = x1,
Density = dexp(
x1,
rate = 1 / 20
),
Kondisi_Label = "S1 - Hujan Sedang"
)
# S2 - Gamma(k = 2, theta = 30)
x2 <- seq(
0,
quantile(
data_simulasi$Curah_Hujan[
data_simulasi$Kondisi == 2
],
0.99
),
length.out = 300
)
teori_s2 <- data.frame(
Curah_Hujan = x2,
Density = dgamma(
x2,
shape = 2,
scale = 30
),
Kondisi_Label = "S2 - Hujan Lebat/Ekstrem"
)
# Menggabungkan data teoritis
data_teoritis <- rbind(
teori_s0,
teori_s1,
teori_s2
)
# VISUALISASI 3
# DISTRIBUSI CURAH HUJAN TEORITIS DAN SIMULASI
ggplot(
data_simulasi,
aes(
x = Curah_Hujan
)
) +
# Histogram simulasi
geom_histogram(
aes(
y = after_stat(density),
fill = Kondisi_Label
),
bins = 30,
alpha = 0.45,
color = "white",
linewidth = 0.2
) +
# Kurva teoritis
geom_line(
data = data_teoritis,
aes(
x = Curah_Hujan,
y = Density,
color = Kondisi_Label
),
linewidth = 1.2
) +
# Rata-rata teoritis
geom_vline(
data = data.frame(
Kondisi_Label = c(
"S0 - Cerah/Berawan",
"S1 - Hujan Sedang",
"S2 - Hujan Lebat/Ekstrem"
),
Mean = c(
2.5,
20,
60
)
),
aes(
xintercept = Mean
),
linetype = "dashed",
color = "#374151",
linewidth = 0.7
) +
# Facet
facet_wrap(
~Kondisi_Label,
scales = "free"
) +
# Warna histogram
scale_fill_manual(
values = warna_state
) +
# Warna kurva
scale_color_manual(
values = warna_state
) +
labs(
title = "Distribusi Curah Hujan Teoritis dan Hasil Simulasi",
subtitle = "Histogram menunjukkan hasil simulasi dan garis menunjukkan fungsi densitas teoritis",
x = "Curah Hujan (mm)",
y = "Kepadatan"
) +
theme_minimal(base_size = 11) +
theme(
plot.title = element_text(
hjust = 0.5,
face = "bold",
size = 14
),
plot.subtitle = element_text(
hjust = 0.5,
size = 10
),
strip.text = element_text(
face = "bold",
size = 10
),
legend.position = "none",
panel.grid.minor = element_blank()
)

# 10. RATA-RATA CURAH HUJAN KESELURUHAN
mean_simulasi <- mean(
data_simulasi$Curah_Hujan
)
# Nilai teoritis
mean_teoritis <-
(2.5 * 0.3647799) +
(20 * 0.4276729) +
(60 * 0.2075472)
mean_simulasi
## [1] 22.97607
mean_teoritis
## [1] 21.91824
# Galat relatif
error_mean <- abs(
mean_simulasi - mean_teoritis
) / mean_teoritis * 100
error_mean
## [1] 4.826241
# 11. PROPORSI CURAH HUJAN > 50 MM
jumlah_lebih_50 <- sum(
data_simulasi$Curah_Hujan > 50
)
proporsi_lebih_50 <- mean(
data_simulasi$Curah_Hujan > 50
)
persentase_lebih_50 <-
proporsi_lebih_50 * 100
jumlah_lebih_50
## [1] 148
proporsi_lebih_50
## [1] 0.148
persentase_lebih_50
## [1] 14.8
# Nilai teoritis
teori_prob_50 <-
(0 * 0.3647799) +
(0.082084999 * 0.4276729) +
(0.503668 * 0.2075472)
teori_persentase_50 <-
teori_prob_50 * 100
teori_prob_50
## [1] 0.1396404
teori_persentase_50
## [1] 13.96404
# Galat relatif
error_50 <- abs(
proporsi_lebih_50 - teori_prob_50
) / teori_prob_50 * 100
error_50
## [1] 5.98651
# 12. TABEL PERBANDINGAN
tabel_perbandingan <- data.frame(
Ukuran = c(
"Rata-rata Curah Hujan (mm)",
"P(R > 50 mm)"
),
Teoritis = c(
mean_teoritis,
teori_prob_50 * 100
),
Simulasi = c(
mean_simulasi,
persentase_lebih_50
),
Galat_Relatif = c(
error_mean,
error_50
)
)
tabel_perbandingan
## Ukuran Teoritis Simulasi Galat_Relatif
## 1 Rata-rata Curah Hujan (mm) 21.91824 22.97607 4.826241
## 2 P(R > 50 mm) 13.96404 14.80000 5.986510
# 13. VISUALISASI PERBANDINGAN HASIL TEORITIS DAN SIMULASI
data_perbandingan_plot <- data.frame(
Ukuran = rep(
c(
"Rata-rata Curah Hujan",
"Proporsi R > 50 mm"
),
each = 2
),
Metode = rep(
c(
"Teoritis",
"Simulasi"
),
2
),
Nilai = c(
mean_teoritis,
mean_simulasi,
teori_prob_50 * 100,
persentase_lebih_50
)
)
ggplot(
data_perbandingan_plot,
aes(
x = Metode,
y = Nilai,
fill = Metode
)
) +
geom_col(
width = 0.60
) +
geom_text(
aes(
label = round(
Nilai,
2
)
),
vjust = -0.4,
fontface = "bold",
size = 4
) +
facet_wrap(
~Ukuran,
scales = "free_y"
) +
scale_fill_manual(
values = c(
"Teoritis" = "#263F66",
"Simulasi" = "#F4B942"
)
) +
labs(
title = "Perbandingan Hasil Teoritis dan Simulasi",
x = NULL,
y = "Nilai",
fill = "Metode"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(
hjust = 0.5,
face = "bold",
size = 14
),
strip.text = element_text(
face = "bold",
size = 11
),
legend.position = "bottom",
panel.grid.minor = element_blank(),
axis.title = element_text(
face = "bold"
)
)

# SELESAI