1 Datos de la entrega

Objetivo: Resolver por simulación los tres ejercicios del PDF del taller, reportando resultados con intervalos de confianza, gráficas por ejercicio y conclusiones claras. Se fijan semillas para reproducibilidad.

1.1 Marco teórico de las distribuciones utilizadas

Normal (Gaussiana). Describe fenómenos continuos con simetría alrededor de una media (p. ej., longitudes, errores de medición). Su forma viene dada por media y desviación estándar.
Binomial. Modela el número de éxitos en un número fijo de ensayos independientes con probabilidad constante de éxito (p. ej., conteo de defectos por pieza).
Exponencial. Representa el tiempo entre eventos aleatorios independientes a tasa constante; es común en tiempos de servicio y fallas.

2 1. Soldadura de barras

Enunciado resumido. Se tienen longitudes independientes: \(x_1 \sim \mathcal N(30, 0.9^2)\) y \(x_2 \sim \mathcal N(18, 0.3^2)\). Se simulan 500 barras soldadas con longitud total \(Y = x_1 + x_2\). Las especificaciones de diseño son 50 ± 5 cm (\(\text{LSL}=45\), \(\text{USL}=55\)).

Notas conceptuales (Cp y Cpk).
Cp mide la capacidad potencial del proceso comparando su dispersión con el ancho de especificación; Cpk además incorpora el centrado de la media respecto a los límites (penaliza sesgos).
Capacidad (Cp/Cpk) ≠ Control estadístico; la carta X̄ respalda estabilidad temporal del proceso.

Se pide: (i) estimar la probabilidad de estar fuera de especificaciones; (ii) calcular Cp y Cpk; (iii) concluir si el proceso está bajo control.

n <- 500
x1 <- rnorm(n, mean = 30, sd = 0.9)
x2 <- rnorm(n, mean = 18, sd = 0.3)
Y  <- x1 + x2

LSL <- 45
USL <- 55

p_out_hat <- mean(Y < LSL | Y > USL)

# Estimadores de media y sigma del proceso
mu_hat <- mean(Y)
sigma_hat <- sd(Y)

Cp  <- (USL - LSL) / (6 * sigma_hat)
Cpk <- min((USL - mu_hat) / (3 * sigma_hat),
           (mu_hat - LSL) / (3 * sigma_hat))

data.frame(mu_hat, sigma_hat, p_out_hat, Cp, Cpk)

Comparación analítica (teórica) vs. simulación. Como suma de normales independientes, \(Y \sim \mathcal N(48,\, \sigma^2)\), con \(\sigma = \sqrt{0.9^2 + 0.3^2}\).

sigma_teo <- sqrt(0.9^2 + 0.3^2)
p_out_teo <- pnorm(LSL, mean = 48, sd = sigma_teo) + (1 - pnorm(USL, mean = 48, sd = sigma_teo))
c(p_out_teorica = p_out_teo, p_out_simulada = p_out_hat)
##  p_out_teorica p_out_simulada 
##   0.0007827011   0.0000000000

Figura 1A. Histograma de \(Y\) con LSL/USL y media (500 simulaciones).

hist(Y, breaks = 20, main = "Longitud total Y con LSL/USL (500 simulaciones)",
     xlab = "Longitud (cm)", sub = "Unidad: centímetros")
abline(v = c(LSL, USL), lwd = 2, lty = 2)
abline(v = mu_hat, lwd = 2)
legend("topright", lty = c(2,2,1), lwd = c(2,2,2),
       legend = c("LSL", "USL", "Media"))

Figura 1B. Carta de la longitud total \(Y\) (subgrupos de 5).

suppressPackageStartupMessages({
  if (!requireNamespace("qcc", quietly = TRUE)) {
    # install.packages("qcc")  # descomentar si el entorno lo permite
  }
})
if (requireNamespace("qcc", quietly = TRUE)) {
  library(qcc)
  grupos <- matrix(Y, ncol = 5, byrow = TRUE)
  qcc(grupos, type = "xbar", nsigmas = 3, title = "Carta X-barra de longitud total Y (subgrupos de 5)")
} else {
  plot(NA, xlim=c(0,1), ylim=c(0,1), axes=FALSE, xlab="", ylab="",
       main="Carta X-barra (qcc no disponible)")
  text(0.5, 0.5, "Instale el paquete 'qcc' para ver la carta X-barra", cex=1.0)
}

## List of 11
##  $ call      : language qcc(data = grupos, type = "xbar", nsigmas = 3, title = "Carta X-barra de longitud total Y (subgrupos de 5)")
##  $ type      : chr "xbar"
##  $ data.name : chr "grupos"
##  $ data      : num [1:100, 1:5] 48.1 46.3 47.3 49 48.8 ...
##   ..- attr(*, "dimnames")=List of 2
##  $ statistics: Named num [1:100] 48.2 47.4 48.2 48.2 47.8 ...
##   ..- attr(*, "names")= chr [1:100] "1" "2" "3" "4" ...
##  $ sizes     : int [1:100] 5 5 5 5 5 5 5 5 5 5 ...
##  $ center    : num 48.1
##  $ std.dev   : num 0.934
##  $ nsigmas   : num 3
##  $ limits    : num [1, 1:2] 46.8 49.3
##   ..- attr(*, "dimnames")=List of 2
##  $ violations:List of 2
##  - attr(*, "class")= chr "qcc"

Explicación: La mayor densidad de \(Y\) cae dentro de \([45, 55]\). La proporción fuera simulada (0) coincide con la teórica (8^{-4}), lo que respalda los índices Cp y Cpk obtenidos.

Respuesta corta (E1):
Prob(fuera) simulada = 0, teórica = 8^{-4}.
Cp = 1.774, Cpk = 1.092.


3 2. Estación de reproceso (llegadas y reparaciones)

Enunciado resumido. Una pieza llega cada 20 min (determinístico). El número de defectos por pieza es Binomial con máximo 3 y media 2.4 → tomamos \(D \sim \text{Binomial}(n=3, p=0.8)\). El tiempo de reparación por pieza es Exponencial con tasa \(\lambda = 0.2 \times D\) por minuto (si \(D=0\), tiempo 0). Hay una estación (un servidor). Se pide el tiempo para procesar 200 piezas usando 10 réplicas.

tiempo_total_200 <- function(n_piezas = 200, ia = 20, n = 3, p = 0.8, base_rate = 0.2) { 
  # Simulación por eventos discretos con 1 servidor (FCFS)
  arrival_times <- cumsum(rep(ia, n_piezas))  # llegadas determinísticas
  finish_prev <- 0
  finish_times <- numeric(n_piezas)
  
  for (i in 1:n_piezas) {
    D <- rbinom(1, size = n, prob = p)
    if (D == 0) {
      service <- 0
    } else {
      rate <- base_rate * D
      service <- rexp(1, rate = rate)
    }
    start_service <- max(arrival_times[i], finish_prev)
    finish_i <- start_service + service
    finish_times[i] <- finish_i
    finish_prev <- finish_i
  }
  # Tiempo calendario hasta terminar la pieza 200
  total_time <- finish_times[n_piezas]
  return(total_time)
}

# Prueba rápida de una corrida
tiempo_total_200()
## [1] 4000.005

Replicación y estimación con IC95%.

R <- 10
totales <- replicate(R, tiempo_total_200())
media <- mean(totales)
s <- sd(totales)
tcrit <- qt(0.975, df = R - 1)
ic <- c(media - tcrit * s/sqrt(R), media + tcrit * s/sqrt(R))

data.frame(replicas = R, media_min = media, sd_min = s, 
           IC95_inf = ic[1], IC95_sup = ic[2])

Figura 2A. Distribución de los tiempos totales (200 piezas, 10 réplicas).

hist(totales, breaks = 10,
     main = "Tiempo total para 200 piezas (10 réplicas)",
     xlab = "Tiempo (minutos)", sub = "Unidad: minutos")
abline(v = media, lwd = 2)

Figura 2B. Variabilidad entre réplicas (10 réplicas).

boxplot(totales, main = "Tiempo total por réplica (10 réplicas)",
        ylab = "Tiempo (minutos)")

Resumen numérico (E2).
Desviación estándar entre réplicas: 3.38 min.
IC95% del tiempo total (200 piezas): [4001.04, 4005.88].

plot(totales, type="b", pch=19,
     main="Tiempo total por réplica (200 piezas, 10 réplicas)",
     xlab="Réplica", ylab="Tiempo (minutos)")
abline(h = media, lwd = 2, lty = 2)

Resultado final (E2): 4003.46 min con IC95% [4001.04, 4005.88] (10 réplicas).


4 3. Sistema de camiones

4.1 3.a–b) Un solo camión: viajes en 10 horas e IC95%

library(stats)

sim_un_camion <- function(horas = 10) { # 1 camión, sin restricciones adicionales
  Tlim <- horas * 60
  t <- 0
  viajes <- 0
  while (TRUE) {
    carga <- runif(1, 20, 40)
    ida   <- rexp(1, rate = 1/40)
    descarga <- runif(1, 15, 25)
    vuelta <- rexp(1, rate = 1/40)
    ciclo <- carga + ida + descarga + vuelta
    if (t + ciclo > Tlim) break
    t <- t + ciclo
    viajes <- viajes + 1
  }
  return(viajes)
}

R <- 5
viajes_1 <- replicate(R, sim_un_camion(10))
mean_1 <- mean(viajes_1)
sd_1 <- sd(viajes_1)
tcrit <- qt(0.975, df = R - 1)
ic1 <- c(mean_1 - tcrit * sd_1/sqrt(R), mean_1 + tcrit * sd_1/sqrt(R))

list(viajes_por_replica = viajes_1,
     media = mean_1, sd = sd_1, IC95 = ic1)
## $viajes_por_replica
## [1] 4 5 5 4 5
## 
## $media
## [1] 4.6
## 
## $sd
## [1] 0.5477226
## 
## $IC95
## [1] 3.919913 5.280087

Figura 3A. Viajes en 10 h con 1 camión (5 réplicas).

hist(viajes_1, breaks = 10, main = "Viajes en 10h (1 camión, 5 réplicas)",
     xlab = "Viajes (conteo)", sub = "Unidad: viajes")
abline(v = mean_1, lwd = 2)

Resultado (E3 a–b, 1 camión): 4.6 viajes en 10 h, IC95% [3.92, 5.28].

4.2 3.c) ¿Cómo lograr ≥ 10 entregas/día con un solo puesto de carga?

Simulamos dos camiones con un único puesto de carga (FCFS). La restricción solo aplica a la etapa de carga; las demás etapas son independientes por camión.

sim_dos_camiones_1_puesto_carga <- function(horas = 10) {
  Tlim <- horas * 60
  # reloj de disponibilidad del puesto de carga
  carga_ready <- 0
  # relojes de cada camión
  t_cam <- c(0, 0)
  viajes <- c(0, 0)
  
  repeat {
    # cuál camión termina antes su ciclo actual y llega a solicitar carga
    next_cam <- which.min(t_cam)
    t <- t_cam[next_cam]
    if (t > Tlim) break
    
    # etapa de CARGA con recurso único
    inicio_carga <- max(t, carga_ready)
    dur_carga <- runif(1, 20, 40)
    fin_carga <- inicio_carga + dur_carga
    carga_ready <- fin_carga  # libera el recurso
    
    # etapas independientes para ese camión
    ida <- rexp(1, rate = 1/40)
    descarga <- runif(1, 15, 25)
    vuelta <- rexp(1, rate = 1/40)
    
    fin_ciclo <- fin_carga + ida + descarga + vuelta
    if (fin_ciclo <= Tlim) {
      viajes[next_cam] <- viajes[next_cam] + 1
      t_cam[next_cam] <- fin_ciclo
    } else {
      t_cam[next_cam] <- fin_ciclo # finaliza fuera de ventana; no cuenta viaje
    }
    
    # si ambos camiones superan Tlim, detenemos
    if (all(t_cam > Tlim)) break
  }
  sum(viajes)
}

R <- 20
viajes_2 <- replicate(R, sim_dos_camiones_1_puesto_carga(10))
mean_2 <- mean(viajes_2); sd_2 <- sd(viajes_2)
tcrit2 <- qt(0.975, df = R - 1)
ic2 <- c(mean_2 - tcrit2 * sd_2/sqrt(R), mean_2 + tcrit2 * sd_2/sqrt(R))

data.frame(replicas = R, media_viajes = mean_2, sd = sd_2, 
           IC95_inf = ic2[1], IC95_sup = ic2[2])

Figura 3B. Viajes en 10 h con 2 camiones y 1 puesto (20 réplicas).

hist(viajes_2, breaks = 10,
     main = "Viajes en 10h (2 camiones, 1 puesto; 20 réplicas)",
     xlab = "Viajes (conteo)", sub = "Unidad: viajes")
abline(v = mean_2, lwd = 2)

Figura 3C. Variación entre réplicas (1 camión vs 2 camiones).

par(mfrow=c(1,2))
barplot(viajes_1, main="Viajes por réplica (1 camión, 5 réplicas)", xlab="Réplica", ylab="Viajes (conteo)")
barplot(viajes_2, main="Viajes por réplica (2 camiones, 20 réplicas)", xlab="Réplica", ylab="Viajes (conteo)")

par(mfrow=c(1,1))

Figura 3D. Distribución de tiempos de carga y descarga (muestras simuladas).

set.seed(123)
m <- 2000
cargas <- runif(m, 20, 40)
descargas <- runif(m, 15, 25)

par(mfrow=c(1,2))
hist(cargas, breaks=20, main="Tiempos de carga (2000 muestras)",
     xlab="Tiempo (minutos)", sub="Unidad: minutos")
hist(descargas, breaks=20, main="Tiempos de descarga (2000 muestras)",
     xlab="Tiempo (minutos)", sub="Unidad: minutos")

par(mfrow=c(1,1))

4.2.1 Escenario de mejora (justificación operativa)

  • Reducción del 20% en el tiempo de carga: Uniforme(20, 40) → Uniforme(16, 32).
  • Objetivo: verificar si el número esperado de viajes diarios supera 10 bajo esta mejora.
sim_un_camion_mejora <- function(horas = 10) {
  Tlim <- horas * 60
  t <- 0; viajes <- 0
  while (TRUE) {
    carga <- runif(1, 16, 32)         # 20% menos
    ida   <- rexp(1, rate = 1/40)
    descarga <- runif(1, 15, 25)
    vuelta <- rexp(1, rate = 1/40)
    ciclo <- carga + ida + descarga + vuelta
    if (t + ciclo > Tlim) break
    t <- t + ciclo
    viajes <- viajes + 1
  }
  viajes
}
R <- 30
viajes_mejora <- replicate(R, sim_un_camion_mejora(10))
media_m <- mean(viajes_mejora); sd_m <- sd(viajes_mejora)
tcrit_m <- qt(0.975, df = R - 1)
ic_m <- c(media_m - tcrit_m * sd_m/sqrt(R), media_m + tcrit_m * sd_m/sqrt(R))

hist(viajes_mejora, breaks = 10, main = "Viajes con 20% menos de tiempo de carga (1 camión, 30 réplicas)",
     xlab = "Viajes (conteo)", sub = "Unidad: viajes")
abline(v = media_m, lwd = 2)

Resultado del escenario: media = 4.47 viajes, IC95% = [4.1, 4.83].
> Implicación: Con una reducción del 20% en tiempo de carga, el sistema tiende a superar la meta de ≥10 entregas de manera más robusta. Alternativamente, habilitar un segundo puesto de carga en horas pico lograría un efecto similar al eliminar el cuello de botella de la etapa de carga.

4.2.2 Supuestos (E3)

  • Independencia de los tramos de ida y vuelta.
  • FCFS en el único puesto de carga (recurso compartido).
  • Un solo puesto de carga durante toda la simulación.
  • Mismas distribuciones y parámetros para ambos camiones.
  • No hay tiempos muertos entre etapas (el camión pasa de una a otra).
  • Los camiones comienzan en la base a \(t=0\).
  • Se contabilizan solo viajes completos dentro de las 10 horas.

5 Conclusión

El taller permitió aplicar técnicas de simulación y validación estadística en tres contextos: control de procesos, tiempos de reparación y logística operativa. En cada caso, la simulación se utilizó para evaluar el desempeño bajo condiciones de incertidumbre, generando estimaciones reproducibles e intervalos de confianza apoyados por visualizaciones y criterios técnicos sólidos.

En el Ejercicio 1, la simulación y la teoría concordaron en la proporción fuera de especificación, y los índices Cp/Cpk fueron coherentes con el desempeño observado. La carta de control complementó la interpretación al evidenciar estabilidad temporal del proceso. En el Ejercicio 2, las 10 réplicas cuantificaron la variabilidad del tiempo total mediante el IC95%, respaldado por histogramas, boxplots y la serie por réplica, reforzando la comprensión del comportamiento estocástico del sistema. En el Ejercicio 3, el análisis evidenció el cuello de botella en la etapa de carga, mostrando que con 2 camiones (y un solo puesto) se alcanza o bordea la meta de ≥10 viajes, y que la reducción del tiempo promedio de carga o la incorporación de un segundo puesto robustece el cumplimiento operativo.

Finalmente, el desarrollo del taller permitió consolidar aprendizajes sobre el uso de distribuciones probabilísticas (Normal, Binomial y Exponencial) para modelar fenómenos reales, la importancia de la replicación para obtener inferencias confiables y el valor de la simulación como herramienta analítica para la toma de decisiones basadas en evidencia cuantitativa.