Punto 1

Se requiere que la densidad de una pieza de plástico usada en un teléfono celular sea de al menos 0.70 g/cm3. Las piezas se suministran en grandes lotes y se piensa usar un plan de aceptación por variables para evaluar los lotes. Se desea que un lote con 2% de unidades no conformes sea aceptado con una probabilidad del 90%, mientras que los lotes con 10% de unidades no conformes sean aceptados con una probabilidad de solo 6%.

a. Encuentre el plan de muestreo (n, k) por el método k, suponiendo que la desviación estándar del proceso es conocida.

Límite de especificación

LEI <- 0.70

Parámetros y plan

AQL <- 0.02          
alpha <- 0.10
Pa_AQL <- 1 - alpha

LTPD <- 0.10        
beta <- 0.06
Pa_LTPD <- beta

library(AcceptanceSampling)

plan_conocida <- find.plan(PRP = c(AQL, 1 - alpha),
                           CRP = c(LTPD, beta),
                           type = "normal",
                           s.type = "known")

n_calculada <- plan_conocida$n
k_calculada <- plan_conocida$k

construirTabla(
  data.frame(
    Parametro = c("n (tamaño de muestra)", "k (constante de aceptación)"),
    Valor = c(n_calculada, round(k_calculada, 5))
  ),
  titulo = "Parámetros del muestreo (σ conocida)",
  decimales = 5
)
Parámetros del muestreo (σ conocida)
Parametro Valor
n (tamaño de muestra) 14.00000
k (constante de aceptación) 1.71124

Curva OC

p <- seq(0, 0.14, 0.001)

plan1 <- OCvar(n = 14, k = 1.71124, pd = p, s.type = "known")

plot(p, plan1@paccept, type = 'l', lty = 1, col = 1,
     xlab = 'Proporción de no conformes', ylab = 'OC')
legend(0.04, 0.95, c("Variable, sigma conocida"), lty = 1, col = 1)
grid()

Análisis

Con sigma conocida el plan dio n = 14 y k = 1.71124. O sea que se toman 14 piezas, se saca el promedio de la densidad y se acepta el lote si ese promedio queda al menos 1.71124 desviaciones estándar por encima de 0.70 g/cm³. La curva OC lo confirma: con 2% de no conformes el plan acepta más o menos el 90% de los lotes, y con 10% baja a cerca del 6%.

b. Plan con σ desconocida y comparación

Planteamiento

datos <- data.frame(
  Elemento = c("LEI", "Punto 1 (calidad buena)", "Punto 2 (calidad mala)"),
  Valor = c("0.70 g/cm³",
            "p₁ = 0.02, Pa = 0.90, entonces α = 0.10",
            "p₂ = 0.10, Pa = 0.06, entonces β = 0.06")
)

datos %>%
  kbl(col.names = c("Datos", "Valor")) %>%
  kable_styling(full_width = FALSE, position = "left")
Datos Valor
LEI 0.70 g/cm³
Punto 1 (calidad buena) p₁ = 0.02, Pa = 0.90, entonces α = 0.10
Punto 2 (calidad mala) p₂ = 0.10, Pa = 0.06, entonces β = 0.06

Valores de z

Los z se sacaron con la normal estándar (qnorm). Como qnorm pide la probabilidad acumulada, se usa 1 - p.

z_p1    <- qnorm(1 - 0.02)  
z_p2    <- qnorm(1 - 0.10)  
z_alpha <- qnorm(1 - 0.10)  
z_beta  <- qnorm(1 - 0.06) 

valores_z <- data.frame(
  Parametro = c("z(p₁)", "z(p₂)", "z(α)", "z(β)"),
  Probabilidad_Entrada = c("0.02", "0.10", "0.10", "0.06"),
  Valor_Z = round(c(z_p1, z_p2, z_alpha, z_beta), 4)
)

tabla_valores_z <- kable(valores_z, digits = 4, 
                         caption = "Valores Z calculados",
                         col.names = c("Parámetro", "Probabilidad de entrada", "Valor Z")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center") %>%
  row_spec(0, bold = TRUE, color = "white", background = "#264653")

tabla_valores_z
Valores Z calculados
Parámetro Probabilidad de entrada Valor Z
z(p₁) 0.02 2.0537
z(p₂) 0.10 1.2816
z(α) 0.10 1.2816
z(β) 0.06 1.5548

Paso 1: plan con σ conocida (a mano)

Se usan las fórmulas de las diapositivas:

\[n=\left(\frac{z_\alpha+z_\beta}{z_{p_1}-z_{p_2}}\right)^2=\left(\frac{1.2816+1.5548}{2.0537-1.2816}\right)^2=\left(\frac{2.8364}{0.7721}\right)^2\approx 13.5\;\to\; n=14\]

\[k=z_{p_1}-\frac{z_\alpha}{\sqrt{n}}=2.0537-\frac{1.2816}{\sqrt{14}}=2.0537-0.3425=1.7112\]

Primero se obtuvieron los z de la normal estándar que corresponden a las proporciones y los riesgos del enunciado: z(p₁ = 2%) = 2.0537, z(p₂ = 10%) = 1.2816, z(α = 10%) = 1.2816 y z(β = 6%) = 1.5548. Con eso n dio 13.5 y se subió a n = 14. Para k se usó el n ya redondeado (14), y dio 1.7112, que es lo mismo que devuelve find.plan (1.71124).

Paso 2: plan con σ desconocida

plan_desconocida <- find.plan(PRP = c(AQL, 1 - alpha),
                              CRP = c(LTPD, beta),
                              type = "normal",
                              s.type = "unknown")

tabla_plan_desconocida <- kable(
  data.frame(
    Parametro = c("n (tamaño de muestra)", "k (constante de aceptación)"),
    Valor = c(plan_desconocida$n, round(plan_desconocida$k, 5))
  ),
  caption = "Parámetros del muestreo (σ desconocida)",
  col.names = c("Parámetro", "Valor")
) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center") %>%
  row_spec(0, bold = TRUE, color = "white", background = "#264653")

tabla_plan_desconocida
Parámetros del muestreo (σ desconocida)
Parámetro Valor
n (tamaño de muestra) 34.00000
k (constante de aceptación) 1.71694

Para σ desconocida se usó otra vez find.plan, pero con s.type = "unknown", porque σ no se conoce y se estima con la desviación estándar de la muestra (S). La función dio n = 34 y k = 1.716943. Es decir, se toman 34 piezas y el lote se acepta si (x̄ − LEI)/S ≥ 1.7169. Comparado con el plan de σ conocida (n = 14), se necesita más del doble de muestra, porque al estimar σ con S se mete más incertidumbre y se compensa con más piezas.

Paso 3: comparación

n1 <- 14; k1 <- 1.71124    
n2 <- 34; k2 <- 1.716943   

tabla_comparacion_planes <- kable(
  data.frame(
    Plan = c("σ conocida", "σ desconocida"),
    n = c(n1, n2),
    k = c(k1, k2),
    Razon_n2_n1 = c("", round(n2 / n1, 2))
  ),
  caption = "Comparación de planes de muestreo (σ conocida vs. desconocida)",
  col.names = c("Plan", "n (tamaño de muestra)", "k (constante de aceptación)", "Razón n2/n1")
) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center") %>%
  row_spec(0, bold = TRUE, color = "white", background = "#264653")

tabla_comparacion_planes
Comparación de planes de muestreo (σ conocida vs. desconocida)
Plan n (tamaño de muestra) k (constante de aceptación) Razón n2/n1
σ conocida 14 1.711240
σ desconocida 34 1.716943 2.43
p <- seq(0, 0.14, 0.001)
oc1 <- OCvar(n = n1, k = k1, pd = p, s.type = "known")
oc2 <- OCvar(n = n2, k = k2, pd = p, s.type = "unknown")

plot(p, oc1@paccept, type = "l", lty = 1, col = 1, lwd = 2,
     xlab = "Proporcion de no conformidades", ylab = "Pa",
     main = "Curva OC: sigma conocida vs. desconocida")
lines(p, oc2@paccept, lty = 2, col = 2, lwd = 2)
points(c(AQL, LTPD), c(Pa_AQL, Pa_LTPD), pch = 19, col = "blue")
legend("topright", c("Sigma conocida", "Sigma desconocida", "Puntos pedidos"),
       lty = c(1, 2, NA), pch = c(NA, NA, 19), col = c(1, 2, "blue"), bty = "n")
grid()

Aquí se compararon los dos planes. El de sigma conocida pide n igual a 14 y el de sigma desconocida pide n igual a 34, o sea unas 2.4 veces más piezas. La diferencia se debe a que cuando no conocemos sigma hay que estimarla con la desviación estándar muestral S que cambia de una muestra a otra y esa incertidumbre extra se compensa con más muestra. Por eso si existen datos históricos confiables de la variabilidad del proceso como en el ejemplo de las botellas de la clase conviene usarlos porque permiten inspeccionar menos piezas.

En las curvas OC la probabilidad de aceptar es casi 1 cuando hay pocos no conformes y se acerca a 0 cuando p pasa de 12%. Las dos curvas pasan por los puntos pedidos donde Pa es 0.90 con p de 2% y Pa es 0.06 con p de 10% así que ambos planes protegen igual al productor y al consumidor. Además las curvas casi se montan una encima de la otra o sea que discriminan igual entre lotes buenos y malos. La única diferencia está en el costo de inspección que es de 14 piezas contra 34.

Análisis

Cuando la desviación estándar es desconocida y se estima con la muestra el plan resultante es n igual a 34 y k igual a 1.716943. Al compararlo con el plan de sigma conocida que tiene n igual a 14 y k igual a 1.71124 se observa que se necesitan unas 2.4 veces más unidades. La razón es que al no conocer sigma hay que estimarla con S que varía entre una muestra y otra y agrega incertidumbre. Para mantener los mismos riesgos de 10% y 6% esa incertidumbre se compensa con una muestra más grande. En cambio con sigma conocida lo único que varía es la media muestral por eso se alcanza una muestra menor. Los dos planes se comportan casi igual y la diferencia está en el costo de inspección.

c. Decisión con la muestra

Planteamiento

datos_nuevos <- data.frame(
  Elemento = c("Plan (literal b)", "LEI", "Muestra"),
  Valor = c("n = 34, k = 1.716943",
            "0.70 g/cm³",
            "x̄ = 0.73 g/cm³, S = 0.018 g/cm³")
)

datos_nuevos %>%
  kbl(col.names = c("Datos", "Valor")) %>%
  kable_styling(full_width = FALSE, position = "left")
Datos Valor
Plan (literal b) n = 34, k = 1.716943
LEI 0.70 g/cm³
Muestra x̄ = 0.73 g/cm³, S = 0.018 g/cm³

Fórmula del método k con S:

\[Z_{LIE}=\frac{\bar{x}-LIE}{S}\]

Regla de decisión: si Z_LIE ≥ k se acepta el lote; si Z_LIE < k se rechaza.

Cálculo:

\[Z_{LIE}=\frac{0.73-0.70}{0.018}=\frac{0.03}{0.018}=1.667\]

Como 1.667 < 1.716943, no llega al k mínimo exigido, entonces el lote se rechaza.

Criterio para el inspector

Se despeja x̄ de la regla Z_LIE ≥ k:

\[\bar{x}\ \ge\ LIE + k\cdot S = 0.70 + (1.716943)(0.018) = 0.70 + 0.0309 = 0.7309\]

La regla para el inspector, con n = 34 unidades y S = 0.018 g/cm³, es: aceptar el lote solo si el promedio es mayor o igual a 0.7309 g/cm³. Como el promedio fue 0.73 g/cm³, el lote no cumple y se rechaza.

Verificación

LEI <- 0.70; xbar <- 0.73; S <- 0.018
k <- 1.716943

Z <- (xbar - LEI) / S
Z_min <- LEI + k * S
decision <- ifelse(Z >= k, "Se ACEPTA el lote", "Se RECHAZA el lote")

tabla_decision_lote <- kable(
  data.frame(
    Parametro = c("LEI (g/cm³)", "Promedio de la muestra (x̄)", "Desviación estándar (S)", 
                  "Constante de aceptación (k)", "Estadístico calculado (Z)", 
                  "Promedio mínimo para aceptar (LEI + k·S)", "Decisión"),
    Valor = c(LEI, xbar, S, k, round(Z, 4), round(Z_min, 4), decision)
  ),
  caption = "Evaluación de la muestra con el plan de σ desconocida",
  col.names = c("Parámetro", "Valor")
) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center") %>%
  row_spec(0, bold = TRUE, color = "white", background = "#264653")

tabla_decision_lote  
Evaluación de la muestra con el plan de σ desconocida
Parámetro Valor
LEI (g/cm³) 0.7
Promedio de la muestra (x̄) |0.73
Desviación estándar (S) 0.018
Constante de aceptación (k) 1.716943
Estadístico calculado (Z) 1.6667
Promedio mínimo para aceptar (LEI + k·S) 0.7309
Decisión Se RECHAZA el lote

En el código se pusieron los datos del límite de especificación inferior el promedio de la muestra y la desviación estándar. Se calculó Z como el promedio menos el límite dividido entre la desviación estándar lo que dio 1.6667 y se comparó con k usando la condición mayor o igual que devolvió FALSE por eso se rechaza. Por último el cálculo del promedio mínimo necesario dio 0.7309 que es lo que se necesitaba para aceptar.

Análisis

Con el plan del literal b donde n es 34 y k es 1.716943 se evaluó la muestra que tuvo promedio de 0.73 g/cm³ y desviación estándar de 0.018 g/cm³. Con el método k el estadístico Z se calculó como 0.73 menos 0.70 dividido entre 0.018 lo que dio 1.667. Como es menor que la constante de aceptación k de 1.716943 la decisión es rechazar el lote. El criterio en términos del promedio indica que debe ser mayor o igual al límite más k por la desviación lo que con una desviación de 0.018 da un promedio mínimo de 0.7309 g/cm³. El inspector toma las 34 piezas calcula el promedio y la desviación y acepta el lote solo si el promedio supera ese valor. Aquí el promedio de 0.73 quedó apenas por debajo del mínimo requerido. Aunque está por encima del límite de 0.70 no lo está por un margen suficiente para la variabilidad observada así que no hay garantía de que la proporción de no conformes sea tan baja como la que el plan tolera.

Punto 2

Datos del problema

  • Variable de calidad: peso de los sacos de azúcar (kg)
  • Peso nominal: 50 kg. Un saco con 49.8 kg o menos está bajo de peso, entonces solo hay límite inferior de especificación (unilateral): \(LEI = 49.8\) kg
  • Tamaño del lote: \(N = 2500\)
  • Nivel general de inspección: IV
  • \(AQL = 0.15\%\)
  • Inspección normal y desviación estándar desconocida (se estima con \(s\))
  • Norma: MIL STD 414, método M

Por qué el método M: como la desviación es desconocida se usa la tabla de variabilidad desconocida, y como solo hay un límite, la regla es: se rechaza el lote si \(P_i > M\).

limiteInferior  <- 49.8
tamanoLote      <- 2500
AQL             <- 0.15     
nivelInspeccion <- "IV"

construirTabla(
  data.frame(
    Parametro = c("LEI (kg)", "Tamaño del lote (N)", "AQL (%)", "Nivel de inspección", "Desviación estándar"),
    Valor = c(limiteInferior, tamanoLote, AQL, nivelInspeccion, "Desconocida")
  ),
  titulo = "Datos y parámetros del problema - Punto 2"
)
Datos y parámetros del problema - Punto 2
Parametro Valor
LEI (kg) 49.8
Tamaño del lote (N) 2500
AQL (%) 0.15
Nivel de inspección IV
Desviación estándar Desconocida

a) Plan de muestreo (letra código, n y M)

Paso 1, letra código (Tabla 1): un lote de 2500 está en el rango de 1301 a 3200 y con nivel de inspección IV la letra es L.

Paso 2, n y M (Tabla 2, variabilidad desconocida): con la letra L el tamaño de muestra es \(n = 40\) y, en la columna AQL = 0.15 de inspección normal, el máximo porcentaje de no conformes es \(M = 0.566\%\).

letraCodigo   <- "L"
tamanoMuestra <- 40
MNormal       <- 0.566  
construirTabla(
  data.frame(
    Concepto = c("Letra código", "n (tamaño de muestra)", "M (inspección normal, %)"),
    Valor = c(letraCodigo, tamanoMuestra, MNormal)
  ),
  titulo = "Plan de muestreo - Punto 2a"
)
Plan de muestreo - Punto 2a
Concepto Valor
Letra código L
n (tamaño de muestra) 40
M (inspección normal, %) 0.566

Comprobación con la librería, como en el código del profesor:

plan_normal <- list(letter = "L", n = 40, M = 0.566)

plan_severa <- list(letter = "L", n = 40, M = 0.401)

Plan: letra código L, \(n = 40\) y \(M = 0.566\%\).

b) Decisión con la muestra

De un lote se toman las \(n = 40\) unidades y se obtiene \(\bar{x} = 50.05\) kg y \(s = 0.1\) kg. Como solo hay límite inferior:

\[Z_{LEI} = \frac{\bar{x} - LEI}{s} = \frac{50.05 - 49.8}{0.1} = 2.5\]

La tabla de estimación de las diapositivas solo llega hasta Z = 1.50, así que para Z = 2.5 se usa EPn de la librería AQLSchemes, igual que en el código del profesor.

mediaMuestra      <- 50.05
desviacionMuestra <- 0.1

ZLimiteInferior <- (mediaMuestra - limiteInferior) / desviacionMuestra

library(AQLSchemes)
PiLibreria <- EPn(sided = "one", stype = "unknown", LSL = limiteInferior,
                  xbar = mediaMuestra, s = desviacionMuestra, n = tamanoMuestra) * 100

construirTabla(
  data.frame(
    Cantidad = c("Z (LEI)", "Pi estimado - EPn (%)", "M normal (%)"),
    Valor = c(ZLimiteInferior, PiLibreria, MNormal)
  ),
  titulo = "Estimación del porcentaje de no conformes - Punto 2b"
)
Estimación del porcentaje de no conformes - Punto 2b
Cantidad Valor
Z (LEI) 2.5000
Pi estimado - EPn (%) 0.4725
M normal (%) 0.5660
decisionNormal <- ifelse(PiLibreria <= MNormal, "Se ACEPTA el lote", "Se RECHAZA el lote")
decisionNormal
## [1] "Se ACEPTA el lote"

Con \(Z = 2.5\) y \(n = 40\), EPn da un \(P_i\) de aproximadamente 0.473%. Comparado con \(M = 0.566\%\) de inspección normal, la decisión es: Se ACEPTA el lote.

c) Inspección severa

Al pasar a inspección severa se mantiene la letra L y \(n = 40\), pero en la Tabla 2 la escala de AQL de la inspección severa está corrida una columna: el AQL = 0.15 severo queda debajo de la columna 0.10 de la inspección normal, y ahí \(M = 0.401\%\).

MSevera <- 0.401  

decisionSevera <- ifelse(PiLibreria <= MSevera, "Se ACEPTA el lote", "Se RECHAZA el lote")

tablaDecision <- data.frame(
  Inspeccion = c("Normal", "Severa"),
  n          = c(tamanoMuestra, tamanoMuestra),
  M          = c(MNormal, MSevera),
  Pi         = c(PiLibreria, PiLibreria),
  Decision   = c(decisionNormal, decisionSevera)
)

construirTabla(tablaDecision, titulo = "Comparación de la decisión - Punto 2c")
Comparación de la decisión - Punto 2c
Inspeccion n M Pi Decision
Normal 40 0.566 0.4725 Se ACEPTA el lote
Severa 40 0.401 0.4725 Se RECHAZA el lote
datosGrafico <- data.frame(
  Inspeccion = factor(c("Normal", "Severa"), levels = c("Normal", "Severa")),
  M = c(MNormal, MSevera)
)

ggplot(datosGrafico, aes(x = Inspeccion, y = M, fill = Inspeccion)) +
  geom_col(width = 0.5, alpha = 0.85) +
  geom_text(aes(label = paste0("M = ", M, "%")), vjust = -0.5, size = 3.5) +
  geom_hline(yintercept = PiLibreria, linetype = "dashed", color = colorPrincipal, linewidth = 1) +
  annotate("text", x = 1.5, y = PiLibreria, vjust = -0.7, size = 3.5, color = colorPrincipal,
           label = paste0("Pi estimado = ", round(PiLibreria, 3), "%")) +
  scale_fill_manual(values = c("Normal" = colorAcepta, "Severa" = colorRechaza)) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.2))) +
  labs(title = "El Pi de la muestra frente al M de cada nivel de rigurosidad",
       x = NULL, y = "Porcentaje de no conformes (%)", fill = NULL) +
  temaTaller +
  theme(legend.position = "none")

Con inspección severa el Pi estimado es de 0.473% y el valor M es de 0.401% entonces el lote se rechaza. Si la decisión es distinta a la de inspección normal quiere decir que la rigurosidad sí cambia el resultado.

lo que que significa para el ingenio, es decir, que la misma muestra con el mismo resultado puede pasar de aceptada a rechazada solo porque cambia el nivel de rigurosidad. La inspección severa se usa cuando el historial reciente de calidad es malo y exige un lote claramente mejor para aceptarlo. Para el ingenio esto significa más lotes rechazados mientras no demuestre una calidad estable así que le conviene centrar el proceso de llenado y reducir la variabilidad del peso de los sacos para poder volver a inspección normal.

Punto 3

Se usan las mismas condiciones del punto 1 (p₁ = 2%, α = 10%, p₂ = 10%, β = 6%).

a. Plan simple por atributos (n, c)

Planteamiento

datos <- data.frame(
  Elemento = c("Nivel de calidad aceptable (p₁)", "Nivel de calidad límite (p₂)"),
  Valor = c("p₁ = 0.02, Pa = 0.90, entonces α = 0.10",
            "p₂ = 0.10, Pa = 0.06, entonces β = 0.06")
)

datos %>%
  kbl(col.names = c("Datos", "Valor")) %>%
  kable_styling(full_width = FALSE, position = "left")
Datos Valor
Nivel de calidad aceptable (p₁) p₁ = 0.02, Pa = 0.90, entonces α = 0.10
Nivel de calidad límite (p₂) p₂ = 0.10, Pa = 0.06, entonces β = 0.06

Como los lotes son grandes, el número de no conformes en la muestra se modela con la binomial. La probabilidad de aceptar un lote con fracción p de no conformes es:

\[P_a(p)=P(X\le c)=\sum_{x=0}^{c}\binom{n}{x}p^x(1-p)^{n-x}\]

El plan (n, c) tiene que cumplir las dos cosas a la vez:

\[P_a(p_1)\ge 1-\alpha=0.90 \qquad \text{y} \qquad P_a(p_2)\le \beta=0.06\]

Plan de muestreo

AQL <- 0.02
alpha <- 0.10
Pa_AQL <- 1 - alpha

LTPD <- 0.10
beta <- 0.06
Pa_LTPD <- beta

library(AcceptanceSampling)

plan_atributos <- find.plan(PRP = c(AQL, 1 - alpha),
                            CRP = c(LTPD, beta),
                            type = "binomial")

tabla_plan_atributos <- kable(
  data.frame(
    Parametro = c("n (tamaño de muestra)", "c (número de aceptación)"),
    Valor = c(plan_atributos$n, plan_atributos$c)
  ),
  caption = "Plan de muestreo simple por atributos",
  col.names = c("Parámetro", "Valor")
) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center") %>%
  row_spec(0, bold = TRUE, color = "white", background = "#264653")

tabla_plan_atributos
Plan de muestreo simple por atributos
Parámetro Valor
n (tamaño de muestra) 73
c (número de aceptación) 3

Se usó find.plan con type = "binomial" porque se trabaja con piezas conformes y no conformes. La función devuelve el plan con el menor n que cumple las dos condiciones.

Verificación y curva OC

n_att <- 73
c_att <- 3

p <- seq(0, 0.20, 0.001)
oc_att <- OC2c(n = n_att, c = c_att, type = "binomial", pd = p)

eval_plan <- assess(oc_att, PRP = c(AQL, 1 - alpha), CRP = c(LTPD, beta))
## Acceptance Sampling Plan (binomial)
## 
##                Sample 1
## Sample size(s)       73
## Acc. Number(s)        3
## Rej. Number(s)        4
## 
## Plan CAN meet desired risk point(s):
## 
##            Quality   RP P(accept) Plan P(accept)
## PRP           0.02           0.90     0.94115669
## CRP           0.10           0.06     0.05795227
Pa_p1 <- oc_att@paccept[which.min(abs(p - 0.02))]
Pa_p2 <- oc_att@paccept[which.min(abs(p - 0.10))]

tabla_verificacion_atributos <- kable(
  data.frame(
    Punto = c("p₁ = 2%", "p₂ = 10%"),
    Pa_Calculado = c(round(Pa_p1, 4), round(Pa_p2, 4)),
    Requisito = c("Pa ≥ 0.90", "Pa ≤ 0.06"),
    Cumple = c(ifelse(Pa_p1 >= 0.90, "Sí", "No"), ifelse(Pa_p2 <= 0.06, "Sí", "No"))
  ),
  caption = "Verificación de riesgos del plan por atributos",
  col.names = c("Fracción de no conformes", "Probabilidad de aceptación (Pa)", "Requisito", "¿Cumple?")
) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center") %>%
  row_spec(0, bold = TRUE, color = "white", background = "#264653")

tabla_verificacion_atributos
Verificación de riesgos del plan por atributos
Fracción de no conformes Probabilidad de aceptación (Pa) Requisito ¿Cumple?
p₁ = 2% 0.9412 Pa ≥ 0.90 Sí
p₂ = 10% 0.0580 Pa ≤ 0.06 Sí

assess revisa si el plan cumple los dos puntos de la curva OC, igual que en el código del profesor.

plot_ly() %>%
  add_lines(x = p, y = oc_att@paccept, name = "Atributos",
            hovertemplate = "p = %{x:.3f}<br>Pa = %{y:.4f}<extra></extra>") %>%
  add_markers(x = c(AQL, LTPD), y = c(Pa_AQL, Pa_LTPD), name = "Puntos pedidos",
              marker = list(size = 10, color = "red"),
              hovertemplate = "p = %{x:.2f}<br>Pa = %{y:.2f}<extra></extra>") %>%
  layout(title = paste0("Curva OC: plan por atributos (n = ", n_att, ", c = ", c_att, ")"),
         xaxis = list(title = "Proporción de no conformidades"),
         yaxis = list(title = "Pa", range = c(0, 1)))

Análisis

El plan simple por atributos es de n igual a 73 y c igual a 3. Se toman 73 piezas y se acepta el lote si hay 3 o menos no conformes, si hay 4 o más se rechaza. Con este plan la probabilidad de aceptar un lote con 2% de no conformes es de 0.9412 que es mayor a 0.90 y con 10% baja a 0.058 que es menor a 0.06. La curva OC lo confirma al pasar por encima del primer punto y por debajo del segundo así que se cumplen los dos requisitos del enunciado.

b. Comparación con los planes por variables

Planes por variables del punto 1

n1 <- 14; k1 <- 1.71124    
n2 <- 34; k2 <- 1.716943  

comparacion <- data.frame(
  Plan = c("Variables, σ conocida", "Variables, σ desconocida", "Atributos"),
  n = c(n1, n2, n_att),
  Criterio = c(paste0("k = ", round(k1, 4)),
               paste0("k = ", round(k2, 4)),
               paste0("c = ", c_att)),
  Razon = round(c(n1, n2, n_att) / n_att, 2)
)

comparacion %>%
  kbl(col.names = c("Plan", "n", "Criterio de aceptación", "n / n atributos")) %>%
  kable_styling(full_width = FALSE, position = "left")
Plan n Criterio de aceptación n / n atributos
Variables, σ conocida 14 k = 1.7112 0.19
Variables, σ desconocida 34 k = 1.7169 0.47
Atributos 73 c = 3 1.00

En la última columna se ve qué fracción del tamaño de muestra por atributos representa cada plan.

Curvas OC de los tres planes

oc_var1 <- OCvar(n = n1, k = k1, pd = p, s.type = "known")
oc_var2 <- OCvar(n = n2, k = k2, pd = p, s.type = "unknown")

plot_ly() %>%
  add_lines(x = p, y = oc_var1@paccept,
            name = paste0("Variables, σ conocida (n = ", n1, ")"),
            hovertemplate = "p = %{x:.3f}<br>Pa = %{y:.4f}<extra></extra>") %>%
  add_lines(x = p, y = oc_var2@paccept,
            name = paste0("Variables, σ desconocida (n = ", n2, ")"),
            hovertemplate = "p = %{x:.3f}<br>Pa = %{y:.4f}<extra></extra>") %>%
  add_lines(x = p, y = oc_att@paccept,
            name = paste0("Atributos (n = ", n_att, ")"),
            hovertemplate = "p = %{x:.3f}<br>Pa = %{y:.4f}<extra></extra>") %>%
  add_markers(x = c(AQL, LTPD), y = c(Pa_AQL, Pa_LTPD), name = "Puntos pedidos",
              marker = list(size = 10, color = "red"),
              hovertemplate = "p = %{x:.2f}<br>Pa = %{y:.2f}<extra></extra>") %>%
  layout(title = "Curva OC: variables vs. atributos",
         xaxis = list(title = "Proporción de no conformidades"),
         yaxis = list(title = "Pa", range = c(0, 1)),
         legend = list(orientation = "h", y = -0.25))

Análisis

El plan por atributos pide 73 piezas el de variables con sigma desconocida pide 34 y el de variables con sigma conocida pide 14. Entonces el que requiere menos unidades inspeccionadas es el de variables con sigma conocida seguido del de variables con sigma desconocida. La diferencia viene de la información que da cada pieza ya que en variables se mide la densidad de cada una así que se sabe qué tan lejos está del límite de 0.70 g/cm³ mientras que en atributos solo se anota si la pieza es conforme o no y cada unidad aporta menos información. Por eso para lograr los mismos riesgos de 10% y 6% el plan por atributos necesita más muestra. Esto concuerda con la ventaja que se vio en clase ya que con curvas OC parecidas variables usa un menor tamaño de muestra. Las tres curvas pasan por los puntos pedidos así que los tres planes protegen igual al productor y al consumidor y lo que cambia es cuántas piezas se inspeccionan.

c. Recomendación si el ensayo de densidad es costoso y destructivo

Planteamiento

La decisión no depende solo del tamaño de muestra sino del costo total por lote. Si C_ensayo es el costo de medir una pieza en el laboratorio y C_clasificación el de clasificarla como conforme o no conforme:

\[C_{var}=n_{var}\cdot C_{ensayo} \qquad C_{att}=n_{att}\cdot C_{clasificación}\]

El plan por variables solo sale más barato si:

\[\frac{C_{ensayo}}{C_{clasificación}}<\frac{n_{att}}{n_{var}}\]

razon_critica <- n_att / n2

tabla_razon_critica <- kable(
  data.frame(
    Concepto = c("n por atributos", "n por variables (σ desconocida)", "Razón crítica de costos (n_att / n2)"),
    Valor = c(n_att, n2, round(razon_critica, 2))
  ),
  caption = "Razón crítica de costos",
  col.names = c("Concepto", "Valor")
) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center") %>%
  row_spec(0, bold = TRUE, color = "white", background = "#264653")

tabla_razon_critica
Razón crítica de costos
Concepto Valor
n por atributos 73.00
n por variables (σ desconocida) 34.00
Razón crítica de costos (n_att / n2) 2.15

Para la razón crítica se tomó el plan por variables con σ desconocida (n = 34), porque en este caso la variabilidad se estima con la muestra.

Costo total según la razón de costos

razon <- seq(0.5, 6, 0.1)
costo_att <- rep(n_att * 1, length(razon))
costo_var <- n2 * razon

plot_ly() %>%
  add_lines(x = razon, y = costo_att, name = "Atributos",
            hovertemplate = "Razón = %{x:.1f}<br>Costo = %{y:.1f}<extra></extra>") %>%
  add_lines(x = razon, y = costo_var, name = "Variables, σ desconocida",
            hovertemplate = "Razón = %{x:.1f}<br>Costo = %{y:.1f}<extra></extra>") %>%
  add_markers(x = razon_critica, y = n_att, name = "Punto de equilibrio",
              marker = list(size = 10, color = "red"),
              hovertemplate = "Razón = %{x:.2f}<br>Costo = %{y:.1f}<extra></extra>") %>%
  layout(title = "Costo de inspección por lote",
         xaxis = list(title = "C_ensayo / C_clasificación"),
         yaxis = list(title = "Costo total (en unidades de C_clasificación)"),
         legend = list(orientation = "h", y = -0.25))

Se dibujó el costo total de cada plan según la razón entre el costo del ensayo y el de clasificar tomando el costo de clasificar una pieza como la unidad. El costo del plan por atributos es constante porque son 73 piezas mientras que el del plan por variables crece con la razón. Las líneas se cruzan en 2.15 que es el punto de equilibrio.

Análisis

Se recomienda el plan por atributos con n igual a 73 y c igual a 3. El plan por variables inspecciona menos piezas ya que son 34 frente a 73 pero solo sale más barato si el ensayo de laboratorio cuesta menos de 2.15 veces la clasificación de una pieza. Como el enunciado dice que el ensayo es costoso y destructivo y que clasificar es rápido y barato es de esperar que la razón de costos pase de ese valor y entonces el plan por atributos es el de menor costo total. Esto hay que confirmarlo con los costos reales de la empresa ya que si el ensayo costara menos de 2.15 veces la clasificación convendría el plan por variables con sigma desconocida.

Otros factores que se tendrían en cuenta:

1 Normalidad de la densidad. El plan por variables supone que la densidad es normal y si no lo es el plan pierde validez mientras que el de atributos no necesita ese supuesto.

2 Distribución entre lotes. La proporción puede cambiar de un lote a otro y eso afecta el plan por variables.

3 Estabilidad del proceso. El plan por variables necesita un proceso estable para que la desviación estándar muestral sea una buena estimación de la variabilidad.

4 Piezas destruidas. Cada ensayo destructivo es una pieza perdida lo que suma costo al plan por variables.

5 Tiempo de respuesta. El ensayo de laboratorio retrasa la decisión del lote mientras que clasificar es rápido.

6 Error de medición. El ensayo de densidad requiere un equipo calibrado y un método repetible.

7 Varias características. Si la calidad depende de varias variables se necesita un plan por variables para cada una y eso encarece el plan.

8 Información para el proveedor. Los datos de los lotes consecutivos se acumulan y permiten caracterizar la calidad del proveedor y darle retroalimentación algo que el plan por atributos no permite.

9 Historial del proveedor. Si el proceso es estable y se conoce la desviación con datos históricos se podría reevaluar el plan por variables con sigma conocida que es el de menor tamaño de muestra.

Referencias

Schilling, E. G., & Neubauer, D. V. (2017). Acceptance Sampling in Quality Control (3rd ed.). CRC Press. (Este libro es la biblia del muestreo de aceptación, tiene todo el sustento de las curvas AOQ, ATI y los planes MIL-STD).