Soal 2: Histogram dan statistik deskriptif untuk data normal
set.seed(2)
n1 <- 100
n2 <- 1000
n3 <- 10000
sim_norm <- function(n) {
data <- rnorm(n, mean = 100, sd = sqrt(15^2))
hist(data, main = paste("Histogram n =", n), xlab = "Nilai", col = "yellow")
mean_val <- mean(data)
sd_val <- sd(data)
return(c(mean = mean_val, sd = sd_val))
}
sim_norm(n1)

## mean sd
## 99.53953 17.40284
sim_norm(n2)

## mean sd
## 101.05351 14.89456
sim_norm(n3)

## mean sd
## 100.07452 15.02745
Soal 5: Simulasi Antrian Bank
(a) Simulasi antrian selama 20 hari kerja
knitr::opts_chunk$set(echo = TRUE)
set.seed(5)
lambda <- 5/60
mu <- 1/8
jam_kerja <- 360
n_hari <- 20
sim_bank <- function(n_teller) {
total_tunggu <- 0
total_nasabah <- 0
total_sibuk <- 0
antrian_harian <- matrix(0, n_hari, 6)
for(hari in 1:n_hari) {
n <- rpois(1, lambda * jam_kerja)
kedatangan <- sort(runif(n, 0, jam_kerja))
pelayanan <- rexp(n, mu)
teller_selesai <- rep(0, n_teller)
tunggu <- numeric(n)
for(i in 1:n) {
teller_idx <- which.min(teller_selesai)
mulai <- max(kedatangan[i], teller_selesai[teller_idx])
tunggu[i] <- mulai - kedatangan[i]
teller_selesai[teller_idx] <- mulai + pelayanan[i]
}
total_tunggu <- total_tunggu + sum(tunggu)
total_nasabah <- total_nasabah + n
total_sibuk <- total_sibuk + sum(pmin(teller_selesai, jam_kerja))
for(jam in 1:6) {
start_t <- (jam-1) * 60
end_t <- jam * 60
dalam_jam <- kedatangan >= start_t & kedatangan < end_t
if(sum(dalam_jam) > 0) {
antrian_harian[hari, jam] <- mean(tunggu[dalam_jam] > 0)
}
}
}
list(
rata_tunggu = total_tunggu / total_nasabah,
utilisasi = total_sibuk / (n_teller * jam_kerja * n_hari),
antrian_jam = colMeans(antrian_harian)
)
}
hasil_2 <- sim_bank(2)
cat("Simulasi 20 hari dengan 2 teller selesai\n")
## Simulasi 20 hari dengan 2 teller selesai
cat("Total nasabah dilayani rata-rata:", round(rpois(1, lambda * jam_kerja)), "orang/hari\n")
## Total nasabah dilayani rata-rata: 40 orang/hari
(c) Hitung persen waktu teller sibuk bekerja
set.seed(178)
cat("Utilisasi teller:", round(hasil_2$utilisasi * 100, 1), "%\n")
## Utilisasi teller: 97.2 %
(d) Bandingkan dengan menambah 1 teller (total 3 teller)
set.seed(7)
hasil_3 <- sim_bank(3)
perbandingan <- data.frame(
Metrik = c("Waktu tunggu (menit)", "Utilisasi (%)", "Efisiensi"),
Teller_2 = c(round(hasil_2$rata_tunggu, 2),
round(hasil_2$utilisasi * 100, 1),
round(hasil_2$rata_tunggu / hasil_2$utilisasi, 2)),
Teller_3 = c(round(hasil_3$rata_tunggu, 2),
round(hasil_3$utilisasi * 100, 1),
round(hasil_3$rata_tunggu / hasil_3$utilisasi, 2))
)
print(perbandingan)
## Metrik Teller_2 Teller_3
## 1 Waktu tunggu (menit) 1.45 0.11
## 2 Utilisasi (%) 97.20 95.60
## 3 Efisiensi 1.49 0.11
penurunan <- (hasil_2$rata_tunggu - hasil_3$rata_tunggu) / hasil_2$rata_tunggu * 100
cat("\nPenurunan waktu tunggu:", round(penurunan, 1), "%\n")
##
## Penurunan waktu tunggu: 92.5 %
cat("Kesimpulan:", ifelse(penurunan > 25, "EFISIEN - tambah teller", "KURANG EFISIEN"))
## Kesimpulan: EFISIEN - tambah teller
(e) Grafik panjang antrian sepanjang hari
library(simmer)
library(simmer.plot)
## Loading required package: ggplot2
##
## Attaching package: 'simmer.plot'
## The following objects are masked from 'package:simmer':
##
## get_mon_arrivals, get_mon_attributes, get_mon_resources
library(dplyr)
##
## Attaching package: 'dplyr'
## The following object is masked from 'package:simmer':
##
## select
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
# Buat simulasi bank2 dulu
teller_sim <- function(n_teller = 2, days = 20, hours_per_day = 6) {
bank <- simmer("Bank")
customer <- trajectory("Nasabah") %>%
seize("teller", 1) %>%
timeout(function() rexp(1, 1/8)) %>%
release("teller", 1)
bank %>%
add_resource("teller", n_teller) %>%
add_generator("nasabah", customer, function() rexp(1, 1/5))
bank %>% run(days * hours_per_day * 60)
return(bank)
}
# Jalankan simulasi dan simpan hasilnya ke bank2
bank2 <- teller_sim(n_teller = 2)
set.seed(8)
queue_plot <- get_mon_resources(bank2) %>%
filter(resource == "teller") %>%
ggplot(aes(x = time, y = queue)) +
geom_line(color = "steelblue") +
labs(title = "Panjang Antrian Sepanjang Hari (20 Hari)", x = "Waktu (menit)", y = "Jumlah Antrian") +
theme_minimal()
queue_plot

Soal 6: Simulasi Toko Kelontong
(a) Simulasikan stok beras selama 60 hari (pesan 50 karung tiap 5
hari)
set.seed(11)
simulasi_stok <- function(hari = 60, stok_awal = 100, pesan_setiap = 5, jumlah_pesan = 50) {
penjualan <- round(runif(hari, 8, 15)) # 8–15 karung/hari
stok <- numeric(hari)
stok[1] <- stok_awal - penjualan[1]
habis <- 0
rugi <- 0
for (i in 2:hari) {
if (i %% pesan_setiap == 0) {
stok[i] <- stok[i-1] + jumlah_pesan - penjualan[i]
} else {
stok[i] <- stok[i-1] - penjualan[i]
}
if (stok[i] < 0) {
rugi <- rugi + abs(stok[i]) * 50000 # rugi Rp50.000/karung
habis <- habis + 1
stok[i] <- 0
}
}
return(list(stok = stok, habis = habis, rugi = rugi))
}
hasil_a <- simulasi_stok()
hasil_a <- simulasi_stok()
# Tampilkan output
cat("Total kerugian : Rp", format(hasil_a$rugi, big.mark = ","), "\n")
## Total kerugian : Rp 6e+05
cat("Sisa stok akhir :", tail(hasil_a$stok, 1), "karung\n")
## Sisa stok akhir : 40 karung
(b) Hitung berapa kali toko kehabisan stok
cat("Hari stok habis :", hasil_a$habis, "hari\n")
## Hari stok habis : 2 hari
(c) Coba strategi: pesan 40, 50, dan 60 karung → Mana yang
terbaik?
set.seed(12)
pesan_40 <- simulasi_stok(jumlah_pesan = 40)
pesan_50 <- simulasi_stok(jumlah_pesan = 50)
pesan_60 <- simulasi_stok(jumlah_pesan = 60)
data.frame(
Jumlah_Pesan = c(40, 50, 60),
Hari_Stok_Habis = c(pesan_40$habis, pesan_50$habis, pesan_60$habis),
Total_Rugi = c(pesan_40$rugi, pesan_50$rugi, pesan_60$rugi)
)
## Jumlah_Pesan Hari_Stok_Habis Total_Rugi
## 1 40 14 6550000
## 2 50 4 1350000
## 3 60 0 0
(d) Ubah frekuensi pesan: setiap 3, 5, dan 7 hari → Mana yang
optimal?
set.seed(13)
freq_3 <- simulasi_stok(pesan_setiap = 3)
freq_5 <- simulasi_stok(pesan_setiap = 5)
freq_7 <- simulasi_stok(pesan_setiap = 7)
data.frame(
Frekuensi_Pesan = c(3, 5, 7),
Hari_Stok_Habis = c(freq_3$habis, freq_5$habis, freq_7$habis),
Total_Rugi = c(freq_3$rugi, freq_5$rugi, freq_7$rugi)
)
## Frekuensi_Pesan Hari_Stok_Habis Total_Rugi
## 1 3 0 0
## 2 5 4 1400000
## 3 7 20 9650000
(e) Grafik pergerakan stok & rekomendasi strategi
# Grafik
plot(1:60, hasil_a$stok, type = "o", col = "pink", xlab = "Hari", ylab = "Sisa Stok",
main = "Pergerakan Stok Beras Bu Sari (Pesan 50 tiap 5 hari)")
abline(h = 0, col = "purple", lty = 2)

# Rekomendasi verbal
cat("\n REKOMENDASI UNTUK BU SARI \n")
##
## REKOMENDASI UNTUK BU SARI
cat("Berdasarkan hasil simulasi berbagai strategi:\n")
## Berdasarkan hasil simulasi berbagai strategi:
cat("- Strategi pemesanan 60 karung tiap 5 hari menghasilkan kerugian paling kecil.\n")
## - Strategi pemesanan 60 karung tiap 5 hari menghasilkan kerugian paling kecil.
cat("- Bu Sari disarankan menggunakan strategi tersebut untuk meminimalkan kehilangan untung.\n")
## - Bu Sari disarankan menggunakan strategi tersebut untuk meminimalkan kehilangan untung.