knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)
set.seed(123) # Seed global untuk replikasi
#persiapan paket
# Tambahkan package "tibble" agar fungsi tibble() tersedia
need_pkg <- c("simmer", "simmer.plot", "ggplot2", "dplyr", "tibble")
for (p in need_pkg) {
if (!requireNamespace(p, quietly = TRUE)) {
install.packages(p, dependencies = TRUE)
}
library(p, character.only = TRUE)
}
Teori menyatakan \(E[X^2] = \frac{1}{3} \approx 0{,}3333\). Kita mendekatinya dengan 10 000 bilangan acak.
X <- runif(10000)
estimasi_ex2 <- mean(X^2)
estimasi_ex2
## [1] 0.3297405
Untuk setiap \(n\) kita hitung rata‑rata, simpangan baku, serta histogram.
ns <- c(100, 1000, 10000)
for (n in ns) {
samp <- rnorm(n, mean = 100, sd = 15)
cat(sprintf("n = %5d | mean = %.2f | sd = %.2f\n", n, mean(samp), sd(samp)))
hist(samp,
main = paste0("Histogram N(100, 15^2) – n=", n),
xlab = "Nilai",
col = "lightblue")
}
## n = 100 | mean = 101.02 | sd = 13.34
## n = 1000 | mean = 100.49 | sd = 14.92
## n = 10000 | mean = 99.97 | sd = 15.05
Estimasi \(P(X\ge 15)\) berdasarkan simulasi.
B <- rbinom(5000, size = 30, prob = 0.25)
p_ge15 <- mean(B >= 15)
p_ge15
## [1] 0.0014
Rumus: \[s = \sqrt{\dfrac{\sum x^2 - \dfrac{(\sum x)^2}{n}}{n-1}}\]
calc_s_custom <- function(x) {
n <- length(x)
sqrt((sum(x^2) - (sum(x)^2) / n) / (n - 1))
}
Contoh penggunaan dengan data \(\mathcal N(89,10^2)\) ukuran 1000.
data_norm <- rnorm(1000, mean = 89, sd = 10)
list(
s_custom = calc_s_custom(data_norm),
sd_builtin = sd(data_norm)
)
## $s_custom
## [1] 10.29769
##
## $sd_builtin
## [1] 10.29769
Bank buka 6 jam per hari, 20 hari kerja.
# Parameter umum
hari <- 20
jam_hari <- 6
lama_menit <- hari * jam_hari * 60 # total durasi simulasi (menit)
interarrival <- function() rexp(1, 1/12) # λ = 5 nasabah/jam = 1/12 per mnt
service_time <- function() rexp(1, 1/8) # rata2 pelayanan 8 mnt
traj <- trajectory("Nasabah") %>%
seize("teller", 1) %>%
timeout(service_time) %>%
release("teller", 1)
sim_bank <- function(n_teller) {
interarrival <- function() rexp(1, 1/12)
service_time <- function() rexp(1, 1/8)
traj <- trajectory("Nasabah") %>%
seize("teller", 1) %>%
timeout(service_time) %>%
release("teller", 1)
env <- simmer(paste0("Bank_", n_teller, "T")) %>%
add_resource("teller", n_teller) %>%
add_generator("Nasabah", traj, distribution = interarrival) %>%
run(until = lama_menit)
list(
arrivals = get_mon_arrivals(env),
resources = get_mon_resources(env)
)
}
res2 <- sim_bank(2)
if (nrow(res2$arrivals) == 0 || nrow(res2$resources) == 0) {
cat("Simulasi tidak menghasilkan data. Coba jalankan ulang.\n")
} else {
wait2 <- mean(res2$arrivals$waiting_time)
util2 <- mean(res2$resources$utilization[res2$resources$resource == "teller"]) * 100
cat(sprintf("Rata2 tunggu = %.2f mnt | Utilisasi = %.2f%%\n", wait2, util2))
}
## Rata2 tunggu = NA mnt | Utilisasi = NA%
res3 <- sim_bank(3)
if (nrow(res3$arrivals) == 0 || nrow(res3$resources) == 0) {
cat("Simulasi tidak menghasilkan data. Coba jalankan ulang.\n")
} else {
wait3 <- mean(res3$arrivals$waiting_time)
util3 <- mean(res3$resources$utilization[res3$resources$resource == "teller"]) * 100
cat(sprintf("Rata2 tunggu = %.2f mnt | Utilisasi = %.2f%%\n", wait3, util3))
}
## Rata2 tunggu = NA mnt | Utilisasi = NA%
plot(res2$resources, metric = "usage", resource = "teller",
main = "Panjang Antrian Teller – 2 Teller")
sim_inventory <- function(days = 60, stok_init = 100, order_qty = 50, order_freq = 5,
harga_jual = 0, lost_profit_per = 50000,
demand_fun = function() sample(8:15, 1)) {
stok <- stok_init
stok_vec <- numeric(days)
lost_profit <- 0
stockout_events <- 0
for (t in 1:days) {
# Pemesanan terjadwal
if (t %% order_freq == 0) stok <- stok + order_qty
# Permintaan harian
demand <- demand_fun()
if (demand > stok) {
lost_profit <- lost_profit + (demand - stok) * lost_profit_per
stockout_events <- stockout_events + 1
stok <- 0
} else {
stok <- stok - demand
}
stok_vec[t] <- stok
}
list(stok = stok_vec,
lost_profit = lost_profit,
stockouts = stockout_events)
}
baseline <- sim_inventory()
cat("Kehabisan stok", baseline$stockouts, "kali | Rugi ↓ Rp",
format(baseline$lost_profit, big.mark = ","), "\n")
## Kehabisan stok 7 kali | Rugi ↓ Rp 3,300,000
qty_vec <- c(40, 50, 60)
var_qty <- lapply(qty_vec, function(q) sim_inventory(order_qty = q))
qty_tbl <- tibble(qty = qty_vec,
stockouts = sapply(var_qty, `[[`, "stockouts"),
lost_profit = sapply(var_qty, `[[`, "lost_profit"))
qty_tbl
## # A tibble: 3 × 3
## qty stockouts lost_profit
## <dbl> <dbl> <dbl>
## 1 40 15 7750000
## 2 50 2 300000
## 3 60 0 0
freq_vec <- c(3, 5, 7)
var_freq <- lapply(freq_vec, function(f) sim_inventory(order_freq = f))
freq_tbl <- tibble(freq = freq_vec,
stockouts = sapply(var_freq, `[[`, "stockouts"),
lost_profit = sapply(var_freq, `[[`, "lost_profit"))
freq_tbl
## # A tibble: 3 × 3
## freq stockouts lost_profit
## <dbl> <dbl> <dbl>
## 1 3 0 0
## 2 5 4 1450000
## 3 7 18 8800000
library(ggplot2)
tibble(day = 1:60, stok = baseline$stok) %>%
ggplot(aes(day, stok)) + geom_line() + geom_point() +
labs(title = "Pergerakan Stok Beras – Strategi Dasar (50 karung / 5 hari)",
x = "Hari", y = "Sisa Stok") + theme_minimal()
# Pilih strategi dengan lost_profit minimum, jika seri pakai stockouts minimum
best_qty <- qty_tbl %>% arrange(lost_profit, stockouts) %>% slice(1)
best_freq <- freq_tbl %>% arrange(lost_profit, stockouts) %>% slice(1)
cat("▶ Jumlah pesan optimal (tiap 5 hari):", best_qty$qty, "karung\n")
## ▶ Jumlah pesan optimal (tiap 5 hari): 60 karung
cat(" — kehabisan", best_qty$stockouts, "kali | rugi Rp",
format(best_qty$lost_profit, big.mark = ","), "\n\n")
## — kehabisan 0 kali | rugi Rp 0
cat("▶ Frekuensi pesan optimal (50 karung per pemesanan): setiap", best_freq$freq, "hari\n")
## ▶ Frekuensi pesan optimal (50 karung per pemesanan): setiap 3 hari
cat(" — kehabisan", best_freq$stockouts, "kali | rugi Rp",
format(best_freq$lost_profit, big.mark = ","), "\n")
## — kehabisan 0 kali | rugi Rp 0
Strategi stok terbaik berdasarkan simulasi 60 hari adalah:
🔹 Jumlah pemesanan optimal: 60 karung setiap 5 hari
🔹 Frekuensi pemesanan optimal: setiap 3 hari dengan jumlah 50 karung
🔹 Kedua strategi ini menghasilkan jumlah kehabisan stok dan kerugian terkecil selama periode simulasi.
📊 Bu Sari disarankan memilih kombinasi strategi tersebut untuk meminimalkan risiko kehilangan penjualan dan menjaga ketersediaan stok secara optimal.