n <- 10000
x <- runif(n, 0, 1)
mean(x^2)
## [1] 0.3295122
Jika \(X \sim \text{Uniform}(0,1)\), maka ekspektasi dari \(X^2\) adalah: \[ \mathbb{E}[X^2] = \int_0^1 x^2 \, dx = \left[ \frac{x^3}{3} \right]_0^1 = \frac{1}{3} \]
n_list <- c(100, 1000, 10000)
mean_list <- c()
sd_list <- c()
for (n in n_list) {
data <- rnorm(n, mean = 100, sd = 15)
hist(data, main = paste("Histogram N =", n), xlab = "X", col = "skyblue", breaks = 20)
mean_list <- c(mean_list, mean(data))
sd_list <- c(sd_list, sd(data))
}
data.frame(N = n_list, Mean = mean_list, SD = sd_list)
## N Mean SD
## 1 100 101.2488 14.23113
## 2 1000 100.1425 15.07417
## 3 10000 100.0786 15.26400
Dari hasil histogram dan statistik deskriptif, semakin besar ukuran sampel, maka distribusi mendekati distribusi normal dengan parameter populasi.
sim_binom <- rbinom(500, size = 30, prob = 0.25)
hist(sim_binom, col = "orange", main = "Histogram Simulasi Binomial", xlab = "Jumlah Sukses")
mean(sim_binom)
## [1] 7.538
var(sim_binom)
## [1] 5.575707
Kesimpulan:
\[ s = \sqrt{ \frac{\sum x^2 - \frac{(\sum x)^2}{n}}{n - 1} } \] Hitung nilai𝑠dengan membangkitkan data berdistribusi normal sebanyak data 1000, rata-rata 89, dan standar deviasi 10.
s_manual <- function(x) {
n <- length(x)
sqrt((sum(x^2) - (sum(x)^2) / n) / (n - 1))
}
data_norm <- rnorm(1000, mean = 89, sd = 10)
s_manual(data_norm)
## [1] 10.09124
sd(data_norm) # Bandingkan dengan fungsi built-in
## [1] 10.09124
Kerjakanlah tugas berikut:
set.seed(123)
# Parameter
jam_operasi <- 6
rata_datang_per_jam <- 5
jumlah_teller <- 2
lama_hari <- 20
rata_pelayanan <- 8 # dalam menit
# Konversi waktu ke menit
waktu_hari <- jam_operasi * 60
# Simulasi 20 hari
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
hasil_simulasi <- list()
for (hari in 1:lama_hari) {
jumlah_nasabah <- rpois(1, rata_datang_per_jam * jam_operasi)
waktu_kedatangan <- sort(runif(jumlah_nasabah, min = 0, max = waktu_hari))
waktu_pelayanan <- rexp(jumlah_nasabah, rate = 1/rata_pelayanan)
selesai <- rep(0, jumlah_nasabah)
mulai <- rep(0, jumlah_nasabah)
antrian <- rep(0, jumlah_nasabah)
teller_tersedia <- rep(0, jumlah_teller)
for (i in 1:jumlah_nasabah) {
mulai[i] <- max(waktu_kedatangan[i], min(teller_tersedia))
selesai[i] <- mulai[i] + waktu_pelayanan[i]
antrian[i] <- mulai[i] - waktu_kedatangan[i]
teller_id <- which.min(teller_tersedia)
teller_tersedia[teller_id] <- selesai[i]
}
hasil_simulasi[[hari]] <- data.frame(
hari = hari,
datang = waktu_kedatangan,
mulai = mulai,
selesai = selesai,
tunggu = antrian,
durasi = waktu_pelayanan
)
}
# Gabungkan semua hari
simulasi_df <- bind_rows(hasil_simulasi)
rata_tunggu <- mean(simulasi_df$tunggu)
rata_tunggu # dalam menit
## [1] 1.136017
total_pelayanan <- sum(simulasi_df$durasi)
total_waktu_teller <- jumlah_teller * waktu_hari * lama_hari
persentase_sibuk <- total_pelayanan / total_waktu_teller * 100
persentase_sibuk # dalam persen
## [1] 33.25149
# Ulangi simulasi dengan 3 teller
jumlah_teller_baru <- 3
hasil_simulasi3 <- list()
for (hari in 1:lama_hari) {
jumlah_nasabah <- rpois(1, rata_datang_per_jam * jam_operasi)
waktu_kedatangan <- sort(runif(jumlah_nasabah, min = 0, max = waktu_hari))
waktu_pelayanan <- rexp(jumlah_nasabah, rate = 1/rata_pelayanan)
selesai <- rep(0, jumlah_nasabah)
mulai <- rep(0, jumlah_nasabah)
antrian <- rep(0, jumlah_nasabah)
teller_tersedia <- rep(0, jumlah_teller_baru)
for (i in 1:jumlah_nasabah) {
mulai[i] <- max(waktu_kedatangan[i], min(teller_tersedia))
selesai[i] <- mulai[i] + waktu_pelayanan[i]
antrian[i] <- mulai[i] - waktu_kedatangan[i]
teller_id <- which.min(teller_tersedia)
teller_tersedia[teller_id] <- selesai[i]
}
hasil_simulasi3[[hari]] <- data.frame(
hari = hari,
datang = waktu_kedatangan,
mulai = mulai,
selesai = selesai,
tunggu = antrian,
durasi = waktu_pelayanan
)
}
simulasi_df3 <- bind_rows(hasil_simulasi3)
# Bandingkan waktu tunggu rata-rata
mean(simulasi_df$tunggu) # teller 2
## [1] 1.136017
mean(simulasi_df3$tunggu) # teller 3
## [1] 0.04733909
library(ggplot2)
simulasi_df$jam <- floor(simulasi_df$datang / 60)
antrian_per_jam <- simulasi_df %>%
group_by(hari, jam) %>%
summarise(panjang = n(), .groups = "drop")
# Visualisasi
ggplot(antrian_per_jam, aes(x = jam, y = panjang)) +
geom_boxplot(fill = "skyblue") +
labs(title = "Panjang Antrian per Jam (20 Hari)",
x = "Jam ke- (sejak buka)",
y = "Jumlah Nasabah") +
theme_minimal()
## Warning: Continuous x aesthetic
## ℹ did you forget `aes(group = ...)`?
Bu Sari memiliki toko kelontong yang menjual beras dengan kondisi sebagai berikut:
Kerjakanlah tugas berikut:
set.seed(123)
simulasi_stok <- function(hari_total = 60, pesan_setiap = 5, jumlah_pesan = 50) {
stok <- numeric(hari_total)
penjualan <- numeric(hari_total)
kekurangan <- numeric(hari_total)
stok[1] <- 100
for (hari in 1:hari_total) {
# Penjualan harian: uniform 8–15 karung
jual <- sample(8:15, 1)
# Hitung kekurangan jika stok tidak cukup
if (stok[hari] >= jual) {
penjualan[hari] <- jual
kekurangan[hari] <- 0
} else {
penjualan[hari] <- stok[hari]
kekurangan[hari] <- jual - stok[hari]
}
# Update stok ke hari berikutnya
if (hari < hari_total) {
stok[hari + 1] <- stok[hari] - penjualan[hari]
# Pemesanan ulang
if (hari %% pesan_setiap == 0) {
stok[hari + 1] <- stok[hari + 1] + jumlah_pesan
}
}
}
data.frame(Hari = 1:hari_total, Stok = stok, Penjualan = penjualan, Kehabisan = kekurangan)
}
# Simulasi default
hasil_a <- simulasi_stok()
head(hasil_a)
## Hari Stok Penjualan Kehabisan
## 1 1 100 14 0
## 2 2 86 14 0
## 3 3 72 10 0
## 4 4 62 13 0
## 5 5 49 10 0
## 6 6 89 9 0
Di atas mensimulasikan jumlah stok harian berdasarkan penjualan dan jadwal pemesanan ulang.
jumlah_kekurangan <- sum(hasil_a$Kehabisan > 0)
total_rugi <- sum(hasil_a$Kehabisan) * 50000
jumlah_kekurangan
## [1] 3
total_rugi
## [1] 9e+05
Menunjukkan berapa hari stok tidak mencukupi, dan total kerugian akibat kehilangan penjualan.
strategi <- c(40, 50, 60)
hasil_c <- lapply(strategi, function(jml) {
df <- simulasi_stok(jumlah_pesan = jml)
data.frame(
Pesan = jml,
KehabisanHari = sum(df$Kehabisan > 0),
Rugi = sum(df$Kehabisan) * 50000
)
})
do.call(rbind, hasil_c)
## Pesan KehabisanHari Rugi
## 1 40 17 8350000
## 2 50 9 3950000
## 3 60 0 0
Kesimpulan:
frekuensi <- c(3, 5, 7)
hasil_d <- lapply(frekuensi, function(freq) {
df <- simulasi_stok(pesan_setiap = freq)
data.frame(
Frekuensi = freq,
KehabisanHari = sum(df$Kehabisan > 0),
Rugi = sum(df$Kehabisan) * 50000
)
})
do.call(rbind, hasil_d)
## Frekuensi KehabisanHari Rugi
## 1 3 0 0
## 2 5 2 700000
## 3 7 17 8700000
Kesimpulan:
library(ggplot2)
ggplot(hasil_a, aes(x = Hari, y = Stok)) +
geom_line(color = "darkgreen", size = 1.2) +
geom_point(data = hasil_a[hasil_a$Kehabisan > 0, ], aes(x = Hari, y = Stok),
color = "red", size = 2) +
labs(title = "Pergerakan Stok Beras Selama 60 Hari",
subtitle = "Titik merah = stok tidak cukup",
x = "Hari",
y = "Jumlah Stok Karung") +
theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Rekomendasi Bu Sari: