set.seed(123)
x <- runif(10000, min = 0, max = 1)
x2 <- x^2
E_X2 <- mean(x2)
E_X2
## [1] 0.3297405
set.seed(123)
# n = 100
x1 <- rnorm(100, mean = 100, sd = 15)
mean(x1); sd(x1)
## [1] 101.3561
## [1] 13.69224
hist(x1, main = "Histogram N(100, 225), n=100", col = "skyblue")
# n = 1000
x2 <- rnorm(1000, mean = 100, sd = 15)
mean(x2); sd(x2)
## [1] 100.2862
## [1] 15.06891
hist(x2, main = "Histogram N(100, 225), n=1000", col = "pink")
# n = 10000
x3 <- rnorm(10000, mean = 100, sd = 15)
mean(x3); sd(x3)
## [1] 99.96336
## [1] 14.98314
hist(x3, main = "Histogram N(100, 225), n=10000", col = "green")
set.seed(123)
x <- rbinom(5000, size = 30, prob = 0.25)
mean(x >= 15)
## [1] 0.0024
Dari hasil simulasi 5000 angka acak dari distribusi Binomial(30, 0.25), diperoleh estimasi 0.0024. Ini berarti, berdasarkan simulasi, peluang kejadian bahwa nilai X lebih dari atau sama dengan 15 adalah sekitar 0.24%, yang tergolong kecil. Estimasi ini diperoleh dengan menghitung proporsi nilai yang memenuhi syarat dalam data simulasi.
sd_manual <- function(x) {
n <- length(x)
sqrt((sum(x^2) - (sum(x)^2 / n)) / (n - 1))
}
set.seed(123)
data <- rnorm(1000, mean = 89, sd = 10)
sd_manual(data)
## [1] 9.91695
sd(data)
## [1] 9.91695
Fungsi sd_manual() menghitung simpangan baku sebesar 9.91695, sama persis dengan hasil dari fungsi bawaan sd() di R. Ini menunjukkan bahwa fungsi buatan sudah sesuai dengan rumus simpangan baku yang diberikan dalam soal.
set.seed(1)
# Parameter
jam_per_hari <- 6
menit_per_jam <- 60
total_hari <- 20
total_menit <- jam_per_hari * menit_per_jam * total_hari
lambd <- 5 / 60
rata_pelayanan <- 8
jumlah_teller <- 2
waktu_kedatangan <- c()
waktu <- 0
while (waktu < total_menit) {
antar <- rexp(1, rate = lambd)
waktu <- waktu + antar
if (waktu < total_menit) {
waktu_kedatangan <- c(waktu_kedatangan, waktu)
}
}
# Simulasi pelayanan
selesai_teller <- rep(0, jumlah_teller)
waktu_tunggu <- numeric(length(waktu_kedatangan))
for (i in seq_along(waktu_kedatangan)) {
idx <- which.min(selesai_teller)
mulai <- max(waktu_kedatangan[i], selesai_teller[idx])
durasi <- rexp(1, rate = 1/rata_pelayanan)
selesai_teller[idx] <- mulai + durasi
waktu_tunggu[i] <- mulai - waktu_kedatangan[i]
}
cat("Jumlah nasabah:", length(waktu_kedatangan), "\n")
## Jumlah nasabah: 604
cat("Rata-rata waktu tunggu:", round(mean(waktu_tunggu), 2), "menit\n")
## Rata-rata waktu tunggu: 1.35 menit
dengan waktu 20 hari kerja mendapatkan jumlah nasabah604 dengan rata rata waktu tunggu adalah 1,35 menit
total_waktu_kerja <- total_menit
selesai_teller <- rep(0, jumlah_teller)
waktu_sibuk <- rep(0, jumlah_teller)
for (waktu in waktu_kedatangan) {
idx <- which.min(selesai_teller)
mulai <- max(waktu, selesai_teller[idx])
durasi <- rexp(1, rate = 1/rata_pelayanan)
selesai_teller[idx] <- mulai + durasi
waktu_sibuk[idx] <- waktu_sibuk[idx] + durasi
}
persen_sibuk <- waktu_sibuk / total_waktu_kerja * 100
persen_sibuk
## [1] 32.59604 32.51806
Selama 20 hari simulasi, teller 1 dan 2 masing-masing sibuk sekitar 32,6% dan 32,5% dari total waktu kerja. Ini menunjukkan bahwa teller belum bekerja secara penuh dan masih memiliki banyak waktu luang
set.seed(1)
total_menit <- 20 * 6 * 60
jumlah_teller <- 3
lambd <- 5 / 60
rata_pelayanan <- 8
waktu <- 0
waktu_kedatangan <- c()
while (waktu < total_menit) {
waktu <- waktu + rexp(1, rate = lambd)
if (waktu < total_menit) waktu_kedatangan <- c(waktu_kedatangan, waktu)
}
selesai <- rep(0, jumlah_teller)
sibuk <- rep(0, jumlah_teller)
tunggu <- numeric(length(waktu_kedatangan))
for (i in seq_along(waktu_kedatangan)) {
idx <- which.min(selesai)
mulai <- max(waktu_kedatangan[i], selesai[idx])
durasi <- rexp(1, 1/rata_pelayanan)
selesai[idx] <- mulai + durasi
sibuk[idx] <- sibuk[idx] + durasi
tunggu[i] <- mulai - waktu_kedatangan[i]
}
cat("Rata-rata tunggu:", round(mean(tunggu),2), "menit\n")
## Rata-rata tunggu: 0.14 menit
cat("Persen sibuk teller:\n")
## Persen sibuk teller:
print(round(sibuk / total_menit * 100, 2))
## [1] 23.01 24.49 24.22
Dengan 3 teller, rata-rata waktu tunggu nasabah turun menjadi 0,14 menit. Namun, masing-masing teller hanya sibuk sekitar 23–24% dari total waktu kerja. Ini menunjukkan pelayanan sangat cepat, tetapi efisiensi kerja teller menjadi rendah.
set.seed(1)
# Parameter
total_hari <- 20
jumlah_teller <- 2
total_menit <- total_hari * 6 * 60
lambd <- 5 / 60
rata_pelayanan <- 8
waktu <- 0
waktu_kedatangan <- c()
while (waktu < total_menit) {
waktu <- waktu + rexp(1, lambd)
if (waktu < total_menit) waktu_kedatangan <- c(waktu_kedatangan, waktu)
}
selesai <- rep(0, jumlah_teller)
panjang_antrian <- rep(0, total_hari)
for (i in seq_along(waktu_kedatangan)) {
waktu <- waktu_kedatangan[i]
hari <- ceiling(waktu / (6 * 60))
idx <- which.min(selesai)
mulai <- max(waktu, selesai[idx])
durasi <- rexp(1, 1/rata_pelayanan)
selesai[idx] <- mulai + durasi
antrian <- sum(selesai > waktu)
panjang_antrian[hari] <- panjang_antrian[hari] + antrian
}
plot(1:total_hari, panjang_antrian, type = "o", pch = 16, col = "blue",
xlab = "Hari ke-", ylab = "Total Panjang Antrian",
main = "Grafik Panjang Antrian per Hari")
Grafik menunjukkan perubahan panjang antrian selama 20 hari simulasi.
Terlihat bahwa panjang antrian bervariasi tiap hari, dengan beberapa
hari mencapai lebih dari 70 antrian dan hari lainnya di bawah 30. Ini
menunjukkan beban pelayanan tidak selalu merata setiap hari.
set.seed(1)
# Inisialisasi
hari <- 60
stok <- numeric(hari)
penjualan <- sample(8:15, hari, replace = TRUE)
stok[1] <- 100 - penjualan[1]
for (i in 2:hari) {
# Tambah stok setiap 5 hari
if (i %% 5 == 1) {
stok[i] <- stok[i-1] + 50
} else {
stok[i] <- stok[i-1]
}
# Kurangi stok sesuai penjualan
stok[i] <- stok[i] - penjualan[i]
# Jika stok < 0, tetap dicatat agar bisa dihitung rugi nanti
}
# Buat tabel hasil
hasil <- data.frame(
Hari = 1:hari,
Penjualan = penjualan,
Stok_Sisa = stok
)
print(head(hasil, 60))
## Hari Penjualan Stok_Sisa
## 1 1 8 92
## 2 2 11 81
## 3 3 14 67
## 4 4 8 59
## 5 5 9 50
## 6 6 12 88
## 7 7 14 74
## 8 8 10 64
## 9 9 13 51
## 10 10 9 42
## 11 11 10 82
## 12 12 10 72
## 13 13 8 64
## 14 14 12 52
## 15 15 12 40
## 16 16 9 81
## 17 17 13 68
## 18 18 13 55
## 19 19 9 46
## 20 20 14 32
## 21 21 8 74
## 22 22 14 60
## 23 23 12 48
## 24 24 12 36
## 25 25 8 28
## 26 26 8 70
## 27 27 13 57
## 28 28 12 45
## 29 29 12 33
## 30 30 9 24
## 31 31 9 65
## 32 32 13 52
## 33 33 8 44
## 34 34 11 33
## 35 35 14 19
## 36 36 8 61
## 37 37 11 50
## 38 38 10 40
## 39 39 13 27
## 40 40 9 18
## 41 41 9 59
## 42 42 13 46
## 43 43 14 32
## 44 44 11 21
## 45 45 11 10
## 46 46 11 49
## 47 47 9 40
## 48 48 11 29
## 49 49 8 21
## 50 50 14 7
## 51 51 13 44
## 52 52 8 36
## 53 53 15 21
## 54 54 11 10
## 55 55 8 2
## 56 56 14 38
## 57 57 15 23
## 58 58 13 10
## 59 59 9 1
## 60 60 14 -13
# Hitung jumlah hari stok habis atau kurang dari sama dengan 0
jumlah_kehabisan_stok <- sum(stok <= 0)
jumlah_kehabisan_stok
## [1] 1
toko pernah kehabisan stok 1x dan bu sari kehilangan untung 50.000
set.seed(1)
# Fungsi sederhana untuk hitung berapa kali stok habis
cek_kehabisan <- function(pesan_ulang) {
stok <- 100
kehabisan <- 0
for (i in 1:60) {
penjualan <- sample(8:15, 1)
# Pesan ulang setiap 5 hari
if (i %% 5 == 1 && i != 1) {
stok <- stok + pesan_ulang
}
stok <- stok - penjualan
if (stok <= 0) {
kehabisan <- kehabisan + 1
}
}
return(kehabisan)
}
# Coba 3 strategi
cat("Pesan 40 karung - kehabisan:", cek_kehabisan(40), "hari\n")
## Pesan 40 karung - kehabisan: 34 hari
cat("Pesan 50 karung - kehabisan:", cek_kehabisan(50), "hari\n")
## Pesan 50 karung - kehabisan: 24 hari
cat("Pesan 60 karung - kehabisan:", cek_kehabisan(60), "hari\n")
## Pesan 60 karung - kehabisan: 0 hari
Strategi pemesanan 60 karung paling efektif dalam mencegah kehabisan stok, meskipun kemungkinan membutuhkan ruang dan biaya penyimpanan lebih besar. Strategi 50 karung bisa menjadi alternatif kompromi antara efisiensi dan risiko kehabisan.
set.seed(1)
cek_kehabisan <- function(frekuensi_pesan) {
stok <- 100
kehabisan <- 0
for (i in 1:60) {
penjualan <- sample(8:15, 1)
# Tambah stok jika hari sesuai frekuensi
if (i %% frekuensi_pesan == 1 && i != 1) {
stok <- stok + 50
}
stok <- stok - penjualan
if (stok <= 0) {
kehabisan <- kehabisan + 1
}
}
return(kehabisan)
}
# Coba 3 frekuensi: setiap 3, 5, dan 7 hari
cat("Pesan setiap 3 hari - kehabisan:", cek_kehabisan(3), "hari\n")
## Pesan setiap 3 hari - kehabisan: 0 hari
cat("Pesan setiap 5 hari - kehabisan:", cek_kehabisan(5), "hari\n")
## Pesan setiap 5 hari - kehabisan: 24 hari
cat("Pesan setiap 7 hari - kehabisan:", cek_kehabisan(7), "hari\n")
## Pesan setiap 7 hari - kehabisan: 43 hari
Semakin jarang melakukan pemesanan ulang, semakin besar risiko kehabisan stok. Strategi pemesanan setiap 3 hari memberikan jaminan ketersediaan stok, namun mungkin menimbulkan biaya logistik yang lebih tinggi.
set.seed(1)
stok <- numeric(60)
stok[1] <- 100 - sample(8:15, 1)
for (i in 2:60) {
penjualan <- sample(8:15, 1)
# Ganti angka 5 di bawah ini untuk mencoba strategi lain (3, 5, atau 7)
if (i %% 5 == 1) {
stok[i] <- stok[i-1] + 50
} else {
stok[i] <- stok[i-1]
}
stok[i] <- stok[i] - penjualan
}
# Buat grafik stok
plot(stok, type = "l", col = "blue", lwd = 2,
main = "Pergerakan Stok Selama 60 Hari",
xlab = "Hari", ylab = "Stok Sisa")
abline(h = 0, col = "red", lty = 2)
Grafik pergerakan stok selama 60 hari menunjukkan pola siklus naik-turun
yang tajam. Setiap 5 hari sekali stok bertambah (pesan ulang), lalu
menurun akibat penjualan harian. Namun, seiring waktu, puncak stok
semakin rendah dan pada hari ke-60 stok turun hingga negatif, menandakan
kehabisan stok. Strategi pemesanan setiap 5 hari sebanyak 50 karung
belum cukup menjaga kestabilan stok, terlihat dari tren penurunan hingga
kehabisan pada hari ke-60. Disarankan untuk meningkatkan jumlah pesanan
atau memperpendek frekuensi pemesanan menjadi setiap 3 hari agar stok
tetap aman dan tidak kehabisan.