set.seed(123)
x <- runif(10000, min = 0, max = 1)
mean(x^2)
## [1] 0.3297405
n1 <- 100
sampel1 <- rnorm(n1, mean = 100, sd = 15)
mean(sampel1)
## [1] 101.0205
sd(sampel1)
## [1] 13.34109
hist(sampel1, main = "Histogram Sampel 100", col = "skyblue")
Berdasarkan output simulasi tersebut diperoleh rata-rata sampel sebesar
101,02 (Rata-rata sampel mendekati nilai teoritis) dan simpangan baku
sebesar 13,34(lebih kecil dari nilai teoritis tetapi tetap dlm batas
wajr) dan visualisasi data dalam bentuk histogram menunjukkan bahwa data
mulai membentuk pola distribusi normal (kurva lonceng), meskipun masih
terdapat ketidakteraturan dalam bentuk sebarannya. Hal ini disebabkan
oleh ukuran sampel yang masih relatif kecil, sehingga variabilitas antar
kelas frekuensi masih cukup terlihat.
n2 <- 1000
sampel2 <- rnorm(n1, mean = 100, sd = 15)
mean(sampel2)
## [1] 100.5335
sd(sampel2)
## [1] 12.95812
hist(sampel2, main = "Histogram Sampel 1000", col = "skyblue")
Berdasarkan hasil simulasi, diperoleh rata-rata sampel sebesar 100,49
dan simpangan baku sebesar 14,92. Histogram hasil simulasi menunjukkan
bentuk distribusi yang jauh lebih simetris dan menyerupai pola
distribusi normal dibandingkan dengan ukuran sampel sebelumnya (n =
100). Puncak distribusi berada di sekitar nilai 100, yang sesuai dengan
nilai rata-rata teoritis dari distribusi normal yang disimulasikan.
Frekuensi tertinggi tercatat pada interval sekitar 95–105, yang
merupakan daerah sekitar rata-rata. Ini menunjukkan bahwa sebagian besar
data berkumpul di sekitar nilai tengah, sebagaimana sifat distribusi
normal
n3 <- 10000
sampel3 <- rnorm(n1, mean = 100, sd = 15)
mean(sampel3)
## [1] 98.82689
sd(sampel3)
## [1] 14.46174
hist(sampel3, main = "Histogram Sampel 10000", col = "skyblue")
Dari hasil simulasi diperoleh rata-rata sampel sebesar 99,51 dan
simpangan baku sampel sebesar 15,04. Histogram hasil simulasi
menunjukkan bentuk distribusi yang simetris dan menyerupai kurva normal
secara sempurna. Puncak distribusi berada tepat di sekitar nilai tengah
(100), dan penyebaran data merata ke kiri dan kanan, mencerminkan sifat
simetris distribusi normal.
Dengan ukuran sampel yang besar, fluktuasi atau variasi acak yang sebelumnya tampak pada ukuran sampel kecil hampir tidak terlihat. Ini menunjukkan bahwa semakin besar ukuran sampel, estimasi statistik sampel akan semakin mendekati nilai parameter populasi, baik dari sisi rata-rata maupun simpangan baku.
set.seed(123)
x_binom <- rbinom(5000, size = 30, prob = 0.25)
# Estimasi peluang P(X >= 15)
peluang<- mean(x_binom >= 15)
peluang
## [1] 0.0024
# Fungsi simpangan baku
stdev_manual <- function(x) {
n <- length(x)
sqrt((sum(x^2) - (sum(x)^2)/n) / (n - 1))
}
# Simulasi data
set.seed(456)
data_norm <- rnorm(1000, mean = 89, sd = 10)
# Hitung simpangan baku
sd(data_norm)
## [1] 9.808198
Nasabah datang rata-rata 5 orang per jam (distribusi Poisson)
Waktu pelayanan per nassabah rata-rata 8 menit ( ditribusi eksponensial)
Bank buka 6 jam per hari
library(simmer)
## Warning: package 'simmer' was built under R version 4.3.3
set.seed(123)
# Parameter
lambda <- 5 # rata-rata kedatangan (nasabah per jam)
mu <- 1 / (8 / 60) # rata-rata pelayanan 8 menit -> konversi ke jam
jam_kerja <- 6 # jam buka bank
durasi_simulasi <- jam_kerja * 60 * 60 # dalam detik
hari_simulasi <- 20
Kerjakan :
set.seed(123)
# Jumlah nasabah disimulasikan
n <- rpois(1, lambda = 5 * 6) # 5 nasabah/jam × 6 jam
# Waktu kedatangan (distribusi acak dari 0 sampai 6 jam)
arrival_time <- sort(runif(n, min = 0, max = 6))
# Waktu pelayanan (eksponensial, rata-rata 8 menit = 0.133 jam)
service_time <- rexp(n, rate = 1 / 0.133)
# Inisialisasi
start_time <- rep(0, n)
end_time <- rep(0, n)
teller_available <- c(0, 0) # waktu bebas masing-masing teller
for (i in 1:n) {
# Pilih teller yang paling cepat selesai
teller_id <- which.min(teller_available)
# Mulai pelayanan setelah nasabah datang atau teller selesai
start_time[i] <- max(arrival_time[i], teller_available[teller_id])
# Selesai pelayanan
end_time[i] <- start_time[i] + service_time[i]
# Update waktu bebas teller
teller_available[teller_id] <- end_time[i]
}
# Hitung waktu tunggu
waiting_time <- start_time - arrival_time
# Buat tabel hasil
hasil <- data.frame(
Nasabah = 1:n,
Datang = round(arrival_time, 2),
Mulai = round(start_time, 2),
Selesai = round(end_time, 2),
Tunggu = round(waiting_time, 2),
Lama_Layanan = round(service_time, 2)
)
head(hasil, 10) # Lihat 10 data pertama
## Nasabah Datang Mulai Selesai Tunggu Lama_Layanan
## 1 1 0.25 0.25 0.46 0 0.21
## 2 2 0.27 0.27 0.34 0 0.06
## 3 3 0.62 0.62 0.70 0 0.08
## 4 4 1.48 1.48 2.01 0 0.54
## 5 5 1.73 1.73 1.85 0 0.11
## 6 6 1.97 1.97 2.10 0 0.13
## 7 7 2.72 2.72 2.92 0 0.20
## 8 8 2.74 2.74 2.92 0 0.18
## 9 9 3.17 3.17 3.32 0 0.16
## 10 10 3.26 3.26 3.48 0 0.21
# Rata-rata waktu tunggu
mean(waiting_time)
## [1] 0.008004178
rata-rata waktu nasabah menunggu yaitu 0,008 jam atau 29 detik
set.seed(124)
# Total waktu kerja per teller: 6 jam
total_jam_kerja <- 6
# Inisialisasi waktu sibuk tiap teller
teller_sibuk <- c(0, 0)
# Ulangi proses sebelumnya untuk hari ke-1
n <- rpois(1, 30)
arrival_time <- sort(runif(n, 0, 6))
service_time <- rexp(n, 1 / 0.133)
start_time <- rep(0, n)
end_time <- rep(0, n)
teller_available <- c(0, 0)
for (i in 1:n) {
t <- which.min(teller_available)
start_time[i] <- max(arrival_time[i], teller_available[t])
end_time[i] <- start_time[i] + service_time[i]
teller_available[t] <- end_time[i]
teller_sibuk[t] <- teller_sibuk[t] + service_time[i]
}
# Persentase waktu sibuk masing-masing teller
persen_sibuk <- round(teller_sibuk / total_jam_kerja * 100, 2)
names(persen_sibuk) <- c("Teller 1", "Teller 2")
persen_sibuk
## Teller 1 Teller 2
## 21.93 20.38
# Versi dengan 3 teller
set.seed(232)
n <- rpois(1, 30)
arrival_time <- sort(runif(n, 0, 6))
service_time <- rexp(n, 1 / 0.133)
start_time <- rep(0, n)
end_time <- rep(0, n)
teller_available <- c(0, 0, 0)
for (i in 1:n) {
t <- which.min(teller_available)
start_time[i] <- max(arrival_time[i], teller_available[t])
end_time[i] <- start_time[i] + service_time[i]
teller_available[t] <- end_time[i]
}
waiting_time <- start_time - arrival_time
mean(waiting_time)
## [1] 0.02288728
library(ggplot2)
# Nasabah masuk dan keluar sistem
event_time <- c(arrival_time, end_time)
event_type <- c(rep(1, n), rep(-1, n)) # 1 = masuk, -1 = keluar
event_data <- data.frame(waktu = event_time, perubahan = event_type)
# Mengurutkan event berdasarkan waktu
event_data <- event_data[order(event_data$waktu), ]
event_data$antrian <- cumsum(event_data$perubahan)
# Membuat plot
ggplot(event_data, aes(x = waktu, y = antrian)) +
geom_step(color = "blue", size = 1) +
labs(title = "Grafik Panjang Antrian (Hari ke-1)",
x = "Waktu (jam)", y = "Jumlah Nasabah dalam Sistem") +
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.
6. (Simulasi Toko Kelontong)Bu Sari Memiliki toko kelontong yang menjual
beras dengan kondisi sebagai berikut.
Penjualan beras per hari: 8-15 karung (distribusi Uniform)
Stok awal: 100 karung
Setiap 5 hari sekali, Bu Sari pesan ulang 50 karung beras
Jika stok habis, kehilangan untung Rp50.000 per karung
Kerjakanlah tugas berikut:
set.seed(123)
stok_awal <- 100
hari_total <- 60
frekuensi_pesan <- 5
jumlah_pesan <- 50
penjualan_per_hari <- sample(8:15, hari_total, replace = TRUE)
# Vektor untuk menyimpan stok harian
stok_harian <- numeric(hari_total)
stok_harian[1] <- stok_awal
# Simulasi stok per hari
for (hari in 2:hari_total) {
stok_harian[hari] <- stok_harian[hari - 1] - penjualan_per_hari[hari - 1]
if (hari %% frekuensi_pesan == 1) {
stok_harian[hari] <- stok_harian[hari] + jumlah_pesan
}
# Jika stok negatif, anggap habis (tidak bisa minus)
if (stok_harian[hari] < 0) stok_harian[hari] <- 0
}
# Menampilkan stok akhir tiap hari
print(stok_harian)
## [1] 100 86 72 62 49 89 80 71 58 48 86 75 62 49 41 82 72 57 45
## [20] 35 75 67 56 48 40 78 68 53 44 30 71 63 50 40 29 66 58 48
## [39] 34 22 61 47 32 23 11 47 39 31 22 8 48 37 25 11 0 40 25
## [58] 12 4 0
jumlah_kehabisan <- sum(stok_harian == 0)
cat("Jumlah hari kehabisan stok:", jumlah_kehabisan,"hari\n")
## Jumlah hari kehabisan stok: 2 hari
simulasi_strategi <- function(jumlah_pesan) {
stok <- numeric(hari_total)
stok[1] <- stok_awal
rugi <- 0
for (hari in 2:hari_total) {
penjualan <- penjualan_per_hari[hari - 1]
if (stok[hari - 1] < penjualan) {
rugi <- rugi + (penjualan - stok[hari - 1]) * 50000
stok[hari] <- 0
} else {
stok[hari] <- stok[hari - 1] - penjualan
}
if (hari %% frekuensi_pesan == 1) {
stok[hari] <- stok[hari] + jumlah_pesan
}
}
jumlah_kehabisan <- sum(stok == 0)
return(list(stok = stok, rugi = rugi, habis = jumlah_kehabisan))
}
strategi <- c(40, 50, 60)
for (j in strategi) {
hasil <- simulasi_strategi(j)
cat("Strategi pesan", j, "karung → Hari habis stok:", hasil$habis,
", Total rugi: Rp", format(hasil$rugi, big.mark=","),"\n")
}
## Strategi pesan 40 karung → Hari habis stok: 6 , Total rugi: Rp 5,800,000
## Strategi pesan 50 karung → Hari habis stok: 0 , Total rugi: Rp 550,000
## Strategi pesan 60 karung → Hari habis stok: 0 , Total rugi: Rp 0
Hasil analisis menunjukkan bahwa:
Strategi pemesanan 40 karung mengakibatkan 6 hari kehabisan stok dengan total kerugian sebesar Rp 5.800.000, yang menunjukkan risiko tinggi terhadap kelangsungan operasi.
Strategi pemesanan 50 karung tidak mengalami kehabisan stok, namun tetap mengalami kerugian sebesar Rp 550.000, kemungkinan disebabkan oleh biaya penyimpanan atau pemborosan stok.
Strategi pemesanan 60 karung merupakan strategi paling optimal, karena tidak ada hari kehabisan stok dan tidak menimbulkan kerugian (Rp 0).
Strategi pesan 60 karung merupakan pilihan terbaik berdasarkan indikator jumlah hari kehabisan stok dan total kerugian.
simulasi_frekuensi <- function(freq) {
stok <- numeric(hari_total)
stok[1] <- stok_awal
rugi <- 0
for (hari in 2:hari_total) {
penjualan <- penjualan_per_hari[hari - 1]
if (stok[hari - 1] < penjualan) {
rugi <- rugi + (penjualan - stok[hari - 1]) * 50000
stok[hari] <- 0
} else {
stok[hari] <- stok[hari - 1] - penjualan
}
if (hari %% freq == 1) {
stok[hari] <- stok[hari] + jumlah_pesan
}
}
jumlah_kehabisan <- sum(stok == 0)
return(list(stok = stok, rugi = rugi, habis = jumlah_kehabisan))
}
# Coba frekuensi pesan: 3, 5, 7
frekuensi <- c(3, 5, 7)
for (f in frekuensi) {
hasil <- simulasi_frekuensi(f)
cat("Frekuensi pesan tiap", f, "hari → Hari habis stok:", hasil$habis,
", Total rugi: Rp", format(hasil$rugi, big.mark=","),"\n")
}
## Frekuensi pesan tiap 3 hari → Hari habis stok: 0 , Total rugi: Rp 0
## Frekuensi pesan tiap 5 hari → Hari habis stok: 0 , Total rugi: Rp 550,000
## Frekuensi pesan tiap 7 hari → Hari habis stok: 12 , Total rugi: Rp 8,800,000
Hasilnya sebagai berikut:
Frekuensi pemesanan setiap 3 hari menunjukkan hasil terbaik, dengan 0 hari kehabisan stok dan tanpa kerugian (Rp 0).
Frekuensi pemesanan setiap 5 hari juga tidak menyebabkan kehabisan stok, namun menimbulkan kerugian sebesar Rp 550.000.
Frekuensi pemesanan setiap 7 hari adalah yang paling buruk, dengan 12 hari kehabisan stok dan total kerugian sebesar Rp 8.800.000.
Frekuensi pemesanan setiap 3 hari merupakan pilihan terbaik untuk menghindari kerugian dan menjaga ketersediaan stok secara optimal
# Ambil hasil strategi terbaik (misal 50 karung setiap 5 hari)
hasil_terbaik <- simulasi_strategi(50)
plot(hasil_terbaik$stok, type = "l", lwd = 2, col = "skyblue",
xlab = "Hari ke-", ylab = "Stok Beras", main = "Grafik Pergerakan Stok Harian Bu Sari")
abline(h = 0, col = "pink",lty=2)