1.

set.seed(123)
x <- runif(10000, min = 0, max = 1)
x2 <- x^2
E_X2 <- mean(x2)
E_X2
## [1] 0.3297405

2.

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")

3.

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.

4.

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.

5.

5a dan b

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

5c.

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

5d.

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.

5e.

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.

6a.

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

6b.

# 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

6c.

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.

6d.

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.

6e.

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.