Problema 1: Ensamblaje de Barras Metálicas

1.1. Definición del Escenario

Se modelará un proceso de soldadura donde la longitud final (\(L\)) es la suma de dos componentes (\(x_1\) y \(x_2\)). Se busca evaluar la capacidad de este proceso para cumplir con las especificaciones de diseño.

  • Componente \(x_1\): \(x_1 \sim \text{Normal}(\mu = 30 \text{ cm}, \sigma^2 = 0.81 \text{ cm}^2)\)
    • Esto implica \(\sigma_1 = \sqrt{0.81} = 0.9\) cm.
  • Componente \(x_2\): \(x_2 \sim \text{Normal}(\mu = 18 \text{ cm}, \sigma = 0.3 \text{ cm})\)
  • Proceso Total: \(L = x_1 + x_2\).
  • Especificaciones (Límites): \(50 \pm 5\) cm.
    • Límite Inferior (LSL): 45 cm
    • Límite Superior (USL): 55 cm
  • Objetivo: Simular 500 ensamblajes, estimar la probabilidad de falla (fuera de especificación), y calcular \(C_p\) y \(C_{pk}\) para diagnosticar el proceso.

1.2. Generación de Datos (Simulación)

Se generan 500 muestras aleatorias para \(x_1\) y \(x_2\) y se suman para obtener 500 valores de \(L\).

# Semilla
set.seed(999) 
N_sim <- 500 # Número de ensamblajes

# Parámetros de las distribuciones
media_x1 <- 30
sd_x1 <- sqrt(0.81) # Varianza 0.81 -> SD 0.9
media_x2 <- 18
sd_x2 <- 0.3

# Límites de especificación
LSL <- 45
USL <- 55

# 1. Generación de las muestras aleatorias
x1_sim <- rnorm(N_sim, mean = media_x1, sd = sd_x1)
x2_sim <- rnorm(N_sim, mean = media_x2, sd = sd_x2)
L_sim <- x1_sim + x2_sim # Longitud total

# 2. Almacenamiento en un data.frame
df_barras <- data.frame(
  X1 = x1_sim,
  X2 = x2_sim,
  L_Total = L_sim
)

# 3. Visualización de los primeros resultados
cat("Primeras 6 simulaciones de ensamblaje:\n")
## Primeras 6 simulaciones de ensamblaje:
kable(head(df_barras), caption = "Muestra de los primeros 6 ensamblajes")
Muestra de los primeros 6 ensamblajes
X1 X2 L_Total
29.74643 17.89849 47.64492
28.81870 18.06039 46.87908
30.71567 18.18081 48.89648
30.24306 17.93249 48.17556
29.75042 17.99697 47.74739
29.49058 17.94192 47.43250

1.3. Evaluación de Capacidad del Proceso

Con los 500 resultados de L_Total, calculamos las métricas solicitadas.

# 1. Estimación de Probabilidad de Falla
# Contamos cuántas barras están OOS (Fuera de Especificación)
fallas <- sum(L_sim < LSL | L_sim > USL)
prob_falla <- fallas / N_sim

cat(paste("Total de simulaciones:", N_sim, "\n"))
## Total de simulaciones: 500
cat(paste("Barras fuera de especificación:", fallas, "\n"))
## Barras fuera de especificación: 0
cat(paste("Estimador de Probabilidad de Falla:", round(prob_falla * 100, 2), "%\n\n"))
## Estimador de Probabilidad de Falla: 0 %
# 2. Cálculo de Índices de Capacidad
# Necesitamos la media y sd de NUESTRO PROCESO simulado
media_proceso <- mean(L_sim)
sd_proceso <- sd(L_sim)

# Cp (Capacidad Potencial): Compara la variabilidad permitida vs la real
Cp <- (USL - LSL) / (6 * sd_proceso)

# Cpk (Capacidad Real): Ajusta el Cp por el centrado del proceso
Cpu <- (USL - media_proceso) / (3 * sd_proceso) # Capacidad vs Límite Superior
Cpl <- (media_proceso - LSL) / (3 * sd_proceso) # Capacidad vs Límite Inferior
Cpk <- min(Cpu, Cpl) # El Cpk siempre es el "peor lado"

# Imprimimos resultados
cat(paste("Media del Proceso (L_Total):", round(media_proceso, 4), "\n"))
## Media del Proceso (L_Total): 47.9446
cat(paste("Desv. Estándar del Proceso (L_Total):", round(sd_proceso, 4), "\n\n"))
## Desv. Estándar del Proceso (L_Total): 0.9216
cat(paste("Índice Cp (Potencial):", round(Cp, 4), "\n"))
## Índice Cp (Potencial): 1.8084
cat(paste("Índice Cpk (Real):", round(Cpk, 4), "\n"))
## Índice Cpk (Real): 1.065

1.4. Visualización del Proceso

Un histograma nos permite ver la distribución de nuestros 500 resultados contra los límites de diseño (LSL y USL).

# Media teórica (Target)
media_teorica_proceso <- media_x1 + media_x2
# Centro de las especificaciones (Target del Diseño)
target_diseno <- (LSL + USL) / 2

ggplot(df_barras, aes(x = L_Total)) +
  geom_histogram(aes(y = ..density..), binwidth = 0.2, fill = "lightblue", color = "black") +
  # Curva de densidad de los datos
  geom_density(color = "blue", size = 1) +
  # Límites de especificación (Rojos)
  geom_vline(xintercept = c(LSL, USL), color = "red", linetype = "dashed", size = 1.2) +
  # Media de nuestro proceso (Azul)
  geom_vline(xintercept = media_proceso, color = "blue", linetype = "dotted", size = 1) +
  # Target de diseño (Verde)
  geom_vline(xintercept = target_diseno, color = "darkgreen", linetype = "solid", size = 1) +
  labs(title = "Distribución del Proceso vs Especificaciones",
       x = "Longitud Total (cm)",
       y = "Densidad",
       caption = "Rojo = Límites (45-55) | Verde = Target (50) | Azul = Media Proceso (48)") +
  theme_bw()

1.5. Diagnóstico y Conclusión

El problema pregunta si el proceso “está bajo control”. Esta pregunta puede confundir dos conceptos: “control estadístico” (predecible en el tiempo, sin causas especiales de variación) y “capacidad” (cumplir especificaciones). Asumiremos que se refiere a Capacidad.

  • Tasa de Falla: En nuestra simulación, el 0% de las piezas (0 de 500) fallan. Esto es inaceptable.
  • \(C_p\) (Potencial): El \(C_p \approx 1.81\) es altísimo (mucho mayor que el estándar de 1.33). Esto nos dice algo bueno: la variabilidad (ruido) del proceso es muy baja. La campana es muy “estrecha”, lo cual es excelente.
  • \(C_{pk}\) (Real): El \(C_{pk} \approx 1.07\) es desastroso (mucho menor que 1.33). Esto revela el problema real.

Conclusión: El proceso NO es capaz.

Justificación: El problema no es la variabilidad (el \(C_p\) es bueno), sino el centrado.

  • El proceso está centrado (media) en 47.94 cm.
  • Las especificaciones están centradas en 50 cm.
  • El proceso está sistemáticamente descentrado en casi 2 cm.

La gráfica es clara: tenemos una campana muy fina (buena variabilidad), pero está peligrosamente cerca del límite inferior (LSL).

Recomendación: Este es un problema de diseño, no de operación. Se debe ajustar la media de \(x_1\) o \(x_2\) (ej. \(x_1\) de 30 a 32) para recentrar el proceso en 50 cm. Si se hiciera eso, el \(C_{pk}\) se dispararía y la tasa de fallos sería cero.

Problema 2: Estación de Reproceso (Simulación de Colas)

2.1. Interpretación del Modelo

Este es un modelo de colas de un solo servidor (G/G/1), aunque las llegadas son determinísticas (D/G/1).

  • Llegadas: Determinísticas (D). 1 pieza cada 20 minutos.
  • Servidor: 1 estación de reproceso.
  • Proceso de Servicio (G): Es complejo y depende de los defectos.
    • \(N_{\text{defectos}} \sim \text{Binomial}\). Máximo 3. Media 2.4.
    • Si \(Media = n \times p\), entonces \(2.4 = 3 \times p \implies p = 0.8\).
    • \(N_{\text{defectos}} \sim \text{Binomial}(n=3, p=0.8)\).
    • \(T_{\text{servicio}}\) por defecto \(\sim \text{Exponencial}(\lambda = 0.2 \text{ piezas/min})\).
    • Esto significa que la media de tiempo por defecto es \(\mu = 1/\lambda = 1/0.2 = 5\) minutos.
    • Si una pieza tiene \(k\) defectos, el tiempo total de servicio será \(T_{\text{total}} \sim \text{Exponencial}(\text{media} = k \times 5 \text{ min})\).
      • (Nota: El problema es ambiguo. Se asume que los tiempos se suman, y la suma de Exponenciales (distribución Erlang) es compleja. Una interpretación más simple es que la media del tiempo total es \(k \times 5\), y la distribución sigue siendo Exponencial. Usaremos esta segunda interpretación por simplicidad).
  • Objetivo: Calcular el tiempo total para procesar 200 piezas (Makespan).
  • Réplicas: 10.

2.2. Simulación de las 10 Réplicas

Se simula la lógica de colas: una pieza no puede ser atendida hasta que haya llegado Y el servidor esté libre.

set.seed(101) 
N_REPLICAS <- 10
N_PIEZAS <- 200
T_ENTRE_LLEGADAS <- 20 # min
MEDIA_T_DEFECTO <- 1 / 0.2 # 5 min
N_MAX_DEFECTOS <- 3
PROB_DEFECTO <- 2.4 / N_MAX_DEFECTOS # p = 0.8

# Vector para guardar el resultado (Makespan) de cada réplica
v_makespan <- numeric(N_REPLICAS)

# Bucle de Réplicas (i)
for (i in 1:N_REPLICAS) {
  
  # Relojes: 'reloj_salida_servidor' es la variable clave.
  # Indica cuándo el servidor estará disponible para la *siguiente* pieza.
  reloj_salida_servidor <- 0 
  
  # Bucle de Piezas (j)
  for (j in 1:N_PIEZAS) {
    
    # 1. ¿Cuándo llega esta pieza?
    t_llegada_pieza_j <- j * T_ENTRE_LLEGADAS
    
    # 2. ¿Cuántos defectos trae?
    n_defectos <- rbinom(1, size = N_MAX_DEFECTOS, prob = PROB_DEFECTO)
    
    # 3. ¿Cuánto tiempo de servicio necesita?
    t_servicio_pieza_j <- 0 # Si n_defectos = 0, tarda 0
    if (n_defectos > 0) {
      media_total_reparacion <- n_defectos * MEDIA_T_DEFECTO
      tasa_total_reparacion <- 1 / media_total_reparacion
      t_servicio_pieza_j <- rexp(1, rate = tasa_total_reparacion)
    }
    
    # 4. Lógica de Cola: ¿Cuándo EMPIEZA el servicio?
    # No puede empezar antes de que LLEGUE y antes de que el SERVIDOR ESTÉ LIBRE.
    t_inicio_servicio_j <- max(t_llegada_pieza_j, reloj_salida_servidor)
    
    # 5. ¿Cuándo TERMINA el servicio?
    t_fin_servicio_j <- t_inicio_servicio_j + t_servicio_pieza_j
    
    # 6. Actualizamos el reloj del servidor para la pieza (j+1)
    reloj_salida_servidor <- t_fin_servicio_j
  }
  
  # Guardamos el tiempo final de la última pieza (el Makespan)
  v_makespan[i] <- reloj_salida_servidor
}

2.3. Resultados del Reproceso

Se analizan los 10 resultados del tiempo total.

# Creamos una tabla de resultados
df_resultados_p2 <- data.frame(
  Replica = 1:N_REPLICAS,
  Tiempo_Total_Min = v_makespan,
  Tiempo_Total_Horas = v_makespan / 60
)

kable(df_resultados_p2, 
      caption = "Tiempo Total (Makespan) para procesar 200 piezas",
      digits = 2)
Tiempo Total (Makespan) para procesar 200 piezas
Replica Tiempo_Total_Min Tiempo_Total_Horas
1 4036.54 67.28
2 4005.62 66.76
3 4055.86 67.60
4 4005.84 66.76
5 4011.86 66.86
6 4004.18 66.74
7 4033.57 67.23
8 4075.40 67.92
9 4019.65 66.99
10 4081.92 68.03
# Calculamos el promedio
media_p2 <- mean(v_makespan)

cat(paste("\n\nRespuesta:",
          "El tiempo promedio (basado en 10 réplicas) para procesar 200 piezas es de", 
          round(media_p2, 2), "minutos."))
## 
## 
## Respuesta: El tiempo promedio (basado en 10 réplicas) para procesar 200 piezas es de 4033.04 minutos.

Problema 3: Logística del Camión de Reparto

3.1. Definición del Ciclo

Se simula un solo camión en un ciclo de 4 etapas.

  • 1. Carga (Base): \(T_{\text{carga}} \sim \text{Uniforme}(30 \pm 10) \implies \text{U}(20, 40)\) min.
  • 2. Viaje (Ida): \(T_{\text{ida}} \sim \text{Exponencial}(\text{media} = 40) \implies \text{Exp}(\lambda = 1/40)\) min.
  • 4. Viaje (Vuelta): \(T_{\text{vuelta}} \sim \text{Exponencial}(\text{media} = 40) \implies \text{Exp}(\lambda = 1/40)\) min.

Supuestos y Restricciones:

  • Jornada (Simulación): 10 horas = 600 minutos.
  • Réplicas: 5.
  • Restricción: Solo 1 espacio de carga. (Esto es irrelevante con 1 camión, pero clave para la pregunta C).
  • Objetivos:
      1. IC del 95% para el número de viajes por día.
      1. Recomendaciones para lograr 10 entregas/día.

3.2. Simulación de 5 Días (Réplicas)

Simulamos 5 jornadas de 600 minutos. Un “viaje” se cuenta cuando el camión termina la descarga.

set.seed(404)
N_REPLICAS_P3 <- 5
T_JORNADA <- 600 # 10 horas

# Vector para guardar el # de viajes (entregas) completados
v_viajes_completos <- numeric(N_REPLICAS_P3)

# Data.frame para guardar el log de absolutamente todo (trazabilidad)
df_log_viajes <- data.frame()

# Bucle de Días (Réplicas)
for (i in 1:N_REPLICAS_P3) {
  
  reloj_dia <- 0
  contador_viajes <- 0
  
  # Bucle de Ciclos (mientras haya tiempo en la jornada)
  while (TRUE) {
    
    # 1. Simular tiempos del ciclo
    t_carga <- runif(1, min = 20, max = 40)
    t_ida <- rexp(1, rate = 1/40)
    t_descarga <- runif(1, min = 15, max = 25)
    
    # 2. ¿Alcanza a cargar e ir a descargar?
    t_hasta_descarga <- t_carga + t_ida + t_descarga
    
    if (reloj_dia + t_hasta_descarga > T_JORNADA) {
      # No alcanza a completar la entrega. Se acaba el día.
      break 
    }
    
    # 3. Si alcanzó, se actualiza el reloj y se cuenta la entrega
    reloj_dia <- reloj_dia + t_hasta_descarga
    contador_viajes <- contador_viajes + 1
    
    # 4. Simular la vuelta
    t_vuelta <- rexp(1, rate = 1/40)
    
    # 5. ¿Alcanza a volver a la base?
    if (reloj_dia + t_vuelta > T_JORNADA) {
      # Quedó en la calle, no puede iniciar otro ciclo.
      break
    }
    
    # 6. Si alcanzó a volver, actualiza el reloj y el ciclo 'while' reinicia
    reloj_dia <- reloj_dia + t_vuelta
    
    # (Opcional) Guardar log
    df_log_viajes <- rbind(df_log_viajes, data.frame(
      Replica = i,
      Viaje = contador_viajes,
      T_Carga = t_carga, T_Ida = t_ida, T_Descarga = t_descarga, T_Vuelta = t_vuelta,
      T_Ciclo_Total = t_carga+t_ida+t_descarga+t_vuelta,
      Reloj_Fin_Vuelta = reloj_dia
    ))
  }
  
  # Guardamos el total de viajes de este día
  v_viajes_completos[i] <- contador_viajes
}

3.3. Análisis de Resultados

a) y b) Viajes por Día e Intervalo de Confianza

cat("--- Resultados (Preguntas A y B) ---\n\n")
## --- Resultados (Preguntas A y B) ---
# a) Tabla de viajes por réplica
tabla_p3 <- data.frame(Replica = 1:N_REPLICAS_P3, Viajes_Completados = v_viajes_completos)
kable(tabla_p3, caption = "Viajes Completados en 10 Horas (600 min)")
Viajes Completados en 10 Horas (600 min)
Replica Viajes_Completados
1 4
2 5
3 4
4 4
5 4
# b) Intervalo de Confianza del 95%
# Usamos t.test() que nos da la media y el IC
ic_test <- t.test(v_viajes_completos, conf.level = 0.95)

media_viajes <- ic_test$estimate
ic_inf <- ic_test$conf.int[1]
ic_sup <- ic_test$conf.int[2]

cat(paste("\nMedia de viajes (de 5 réplicas):", round(media_viajes, 2), "\n"))
## 
## Media de viajes (de 5 réplicas): 4.2
cat(paste("Intervalo de Confianza 95% para la media de viajes:", 
          "[", round(ic_inf, 3), ",", round(ic_sup, 3), "]\n"))
## Intervalo de Confianza 95% para la media de viajes: [ 3.645 , 4.755 ]

c) Recomendaciones para lograr 10 entregas

Diagnóstico (Análisis Teórico): El objetivo es 10 entregas, pero nuestro IC está cerca de 4. Estamos muy lejos. ¿Por qué? Calculemos el tiempo esperado (promedio) de un ciclo completo:

  • \(E[T_{\text{carga}}]\): \((20+40)/2 = 30\) min
  • \(E[T_{\text{ida}}]\): \(40\) min (media de la exponencial)
  • \(E[T_{\text{descarga}}]\): \((15+25)/2 = 20\) min
  • \(E[T_{\text{vuelta}}]\): \(40\) min (media de la exponencial)

Tiempo Esperado por Ciclo = \(30 + 40 + 20 + 40 = 130\) minutos.

En una jornada de 600 minutos, el número teórico de viajes es: \(600 \text{ min} / 130 \text{ min/viaje} \approx 4.61\) viajes.

La simulación (media de 4.2) confirma perfectamente el cálculo teórico.

Conclusión: Con un solo camión y los tiempos actuales, es matemáticamente imposible alcanzar 10 entregas. El sistema actual está topado en 4-5 viajes.

Recomendaciones para lograr las 10 entregas:

  1. Añadir un segundo camión: Esta es la solución más directa. Si 1 camión hace 4-5 viajes, 2 camiones harían 8-10.

    • Problema (Supuesto): Esto introduce un nuevo problema. El sistema ahora tendrá una cola en la bahía de carga, ya que solo hay 1 espacio. Mientras el Camión 1 se carga (30 min prom.), el Camión 2 (que ya volvió) quedará en espera.
    • Justificación: Se debe realizar una nueva simulación (modelo de colas G/G/1 para la bahía de carga) para confirmar si el tiempo de espera en la cola anula la ganancia de tener el segundo camión.
  2. Reducir Tiempos del Ciclo (Optimización):

    • Cuello de Botella: Los viajes (Ida/Vuelta) consumen \(40+40=80\) minutos (el 61.5% del ciclo).
    • Acción: Optimizar rutas (para bajar la media de 40 min) o mejorar la velocidad del camión.
    • Acción 2: Reducir el tiempo de carga (30 min, 23% del ciclo). Implementar pre-alistamiento de la carga para que el camión solo enganche.

Recomendación Final: La meta de 10 viajes solo se logrará comprando un segundo camión. Sin embargo, se advierte que esto moverá el cuello de botella a la bahía de carga. Se recomienda invertir también en mejorar la eficiencia de la carga (reducir los 30 min) para que la espera del segundo camión no sea tan larga.

# CSV de los datos del Problema 1 (los 500 ensamblajes)
write.csv(df_barras, "simulacion_del_problema1.csv", row.names = FALSE)

# CSV de viajes del Problema 3 (trazabilidad de todos los viajes)
write.csv(df_log_viajes, "simulacion_del_problema3.csv", row.names = FALSE)