Parte 4. Ejercicio práctico individual

Distribución objetivo

En este ejercicio se desea simular una variable aleatoria cuya función de densidad es:

\[ f(x)=2x,\qquad x\in[0,1]. \]

Primero verificamos que esta función sea una densidad de probabilidad:

\[ \int_0^1 2x\,dx = [x^2]_0^1 = 1. \]

Por lo tanto, \(f(x)=2x\) es una función de densidad válida.

Esta distribución tiene mayor probabilidad de generar valores cercanos a 1 que valores cercanos a 0.

Distribución propuesta y constante \(c\)

Se utiliza como distribución propuesta una uniforme en el intervalo \([0,1]\):

\[ g(x)=1. \]

Para el método de aceptación y rechazo necesitamos encontrar una constante \(c\) que cumpla:

\[ f(x)\leq c g(x). \]

Como:

\[ \frac{f(x)}{g(x)} = \frac{2x}{1} = 2x, \]

y el máximo de \(2x\) en el intervalo \([0,1]\) es 2, se obtiene:

\[ \boxed{c=2}. \]

Código

# Parámetros de la simulación
n_sim <- 5000
muestras <- numeric(n_sim)
intentos <- 0
aceptados <- 0

# Semilla para obtener resultados reproducibles
set.seed(123)

# Distribución propuesta:
# g(x) = 1, Uniforme(0,1)

# Constante adecuada
c <- 2

cat("Distribución objetivo: f(x) = 2x\n")
## Distribución objetivo: f(x) = 2x
cat("Distribución propuesta: g(x) = 1\n")
## Distribución propuesta: g(x) = 1
cat("Constante c =", c, "\n")
## Constante c = 2

Resultado

La constante utilizada es:

\[ \boxed{c=2}. \]

Comentario

La constante \(c=2\) es adecuada porque representa el valor máximo de la razón \(f(x)/g(x)\) en el intervalo \([0,1]\). Esto garantiza que la función envolvente cubra completamente la distribución objetivo.

Condición de aceptación

La condición general del método de aceptación y rechazo es:

\[ U\leq\frac{f(Y)}{c\,g(Y)}. \]

En este caso:

\[ f(Y)=2Y,\qquad g(Y)=1,\qquad c=2. \]

Por lo tanto:

\[ U\leq\frac{2Y}{2(1)}, \]

y simplificando:

\[ \boxed{U\leq Y}. \]

Código

# Condición de aceptación:
#
# U <= f(Y)/(c*g(Y))
# U <= (2Y)/(2*1)
# U <= Y
#
# Esta condición se implementará dentro del algoritmo.

Resultado

La condición de aceptación que se utilizará es:

\[ \boxed{U\leq Y}. \]

Comentario

Esto significa que un candidato \(Y\) será aceptado cuando el valor aleatorio \(U\), generado entre 0 y 1, sea menor o igual que \(Y\).

Generación de las 5000 muestras

Ahora se implementa el algoritmo de aceptación y rechazo. En cada intento:

  1. Se genera un candidato \(Y\sim U(0,1)\).
  2. Se genera \(U\sim U(0,1)\).
  3. Se verifica si \(U\leq Y\).
  4. Si se cumple la condición, se acepta \(Y\).
  5. El procedimiento continúa hasta obtener 5000 valores aceptados.

Código

# Reiniciar contadores
intentos <- 0
aceptados <- 0
muestras <- numeric(n_sim)

# Algoritmo de aceptación y rechazo
while (aceptados < n_sim) {
  
  # Contar el número de intentos
  intentos <- intentos + 1
  
  # Generar candidato Y ~ Uniforme(0,1)
  Y <- runif(1, min = 0, max = 1)
  
  # Generar U ~ Uniforme(0,1)
  U <- runif(1, min = 0, max = 1)
  
  # Condición de aceptación
  if (U <= Y) {
    aceptados <- aceptados + 1
    muestras[aceptados] <- Y
  }
}

# Guardar los resultados de c = 2
intentos_c2_observados <- intentos
eficiencia_c2_observada <- aceptados / intentos
muestras_c2 <- muestras

# Mostrar resultados
cat("Número de muestras solicitadas:", n_sim, "\n")
## Número de muestras solicitadas: 5000
cat("Número de muestras aceptadas:", aceptados, "\n")
## Número de muestras aceptadas: 5000
cat("Número total de intentos:", intentos, "\n")
## Número total de intentos: 9976

Resultado

Al ejecutar el código se obtienen 5000 muestras válidas.

El número total de intentos obtenido fue 9976. Teóricamente, se espera un valor cercano a 10.000, aunque puede variar por el carácter aleatorio de la simulación.

Comentario

Como la probabilidad teórica de aceptación es del 50 %, se espera que sean necesarios aproximadamente 10.000 intentos para obtener 5000 muestras válidas. El número obtenido puede ser ligeramente mayor o menor.

Tasa de eficiencia

La eficiencia del algoritmo se calcula mediante:

\[ \text{Eficiencia} = \frac{\text{muestras aceptadas}} {\text{intentos totales}}. \]

Para \(c=2\), la eficiencia teórica es:

\[ \frac{1}{c} = \frac{1}{2} = 0.5. \]

Por lo tanto:

\[ \boxed{\text{Eficiencia teórica}=50\%}. \]

Código

# Eficiencia real
eficiencia <- eficiencia_c2_observada

# Eficiencia teórica
eficiencia_teorica <- 1 / 2

cat(
  "Eficiencia real:",
  round(eficiencia * 100, 2),
  "%\n"
)
## Eficiencia real: 50.12 %
cat(
  "Eficiencia teórica:",
  round(eficiencia_teorica * 100, 2),
  "%\n"
)
## Eficiencia teórica: 50 %

Resultado

La eficiencia real obtenida fue de 50.12 %.

La eficiencia teórica es exactamente:

\[ \boxed{50\%}. \]

Comentario

La eficiencia real puede no ser exactamente 50 % debido a la aleatoriedad de la simulación. Sin embargo, al aumentar el número de simulaciones, la eficiencia observada tiende a aproximarse al valor teórico.

Histograma de las muestras

Para comprobar que las muestras obtenidas siguen la distribución objetivo, se realiza un histograma de los valores aceptados. Sobre el histograma se agrega la función teórica:

\[ f(x)=2x. \]

Código

hist(
  muestras_c2,
  probability = TRUE,
  breaks = 40,
  col = "lightblue",
  border = "white",
  main = "Muestreo por aceptación y rechazo",
  xlab = "X",
  ylab = "Densidad",
  xlim = c(0, 1)
)

# Agregar la función teórica f(x) = 2x
curve(
  2 * x,
  from = 0,
  to = 1,
  add = TRUE,
  col = "red",
  lwd = 2
)

legend(
  "topleft",
  legend = c("Muestras simuladas", "Densidad teórica f(x) = 2x"),
  fill = c("lightblue", NA),
  border = c("white", NA),
  lty = c(NA, 1),
  lwd = c(NA, 2),
  col = c("black", "red"),
  bty = "n"
)
Histograma de las muestras aceptadas y densidad teórica.

Histograma de las muestras aceptadas y densidad teórica.

Resultado

El histograma presenta una forma creciente desde 0 hasta 1 y la curva roja \(f(x)=2x\) se ajusta aproximadamente al comportamiento de las muestras.

Comentario

El resultado gráfico permite comprobar que el algoritmo está generando muestras de acuerdo con la distribución objetivo. Se observa una mayor concentración de valores cerca de \(x=1\), que es precisamente lo esperado porque la densidad \(2x\) aumenta conforme aumenta \(x\).

Parte 5. Reto de experimentación: el costo de una mala elección

Cambio de la constante a \(c=15\)

Ahora se modifica temporalmente la constante:

\[ \boxed{c=15}. \]

Se mantiene la misma distribución objetivo:

\[ f(x)=2x, \]

y la misma distribución propuesta:

\[ g(x)=1. \]

La nueva condición de aceptación será:

\[ U\leq\frac{2Y}{15}. \]

Código

# Cambiar la constante
c <- 15

cat("Nueva constante c =", c, "\n")
## Nueva constante c = 15
# Reiniciar los parámetros
n_sim <- 5000
muestras <- numeric(n_sim)
intentos <- 0
aceptados <- 0

# Semilla para reproducibilidad
set.seed(123)

Resultado

La nueva constante utilizada es:

\[ \boxed{c=15}. \]

Comentario

Aunque \(c=15\) también permite cubrir la densidad objetivo, es una elección poco eficiente porque es mucho mayor que el valor mínimo necesario, que era \(c=2\).

Ejecución del algoritmo con \(c=15\)

Con \(c=15\), la condición de aceptación es:

\[ U\leq\frac{2Y}{15}. \]

Código

# Algoritmo con c = 15
while (aceptados < n_sim) {
  
  # Contar intento
  intentos <- intentos + 1
  
  # Generar candidato Y ~ Uniforme(0,1)
  Y <- runif(1, min = 0, max = 1)
  
  # Generar U ~ Uniforme(0,1)
  U <- runif(1, min = 0, max = 1)
  
  # Condición de aceptación con c = 15
  if (U <= (2 * Y) / c) {
    aceptados <- aceptados + 1
    muestras[aceptados] <- Y
  }
}

# Guardar resultados de c = 15
intentos_c15_observados <- intentos
eficiencia_c15_observada <- aceptados / intentos
muestras_c15 <- muestras

# Mostrar resultados
cat("Muestras solicitadas:", n_sim, "\n")
## Muestras solicitadas: 5000
cat("Muestras aceptadas:", aceptados, "\n")
## Muestras aceptadas: 5000
cat("Total de intentos:", intentos, "\n")
## Total de intentos: 74581

Resultado

El número total de intentos obtenido fue 7.4581^{4}.

Teóricamente, para obtener 5000 muestras válidas se necesitan aproximadamente:

\[ 5000(15)=75000 \]

intentos.

Comentario

Al aumentar \(c\) de 2 a 15, la probabilidad de aceptación disminuye considerablemente. Por esta razón, el algoritmo necesita muchos más intentos para conseguir las mismas 5000 muestras válidas.

Eficiencia con \(c=15\)

La eficiencia teórica ahora es:

\[ \frac{1}{15} = 0.0667. \]

Por lo tanto:

\[ \boxed{\text{Eficiencia}\approx 6.67\%}. \]

Código

# Calcular eficiencia con c = 15
eficiencia_c15 <- eficiencia_c15_observada
eficiencia_teorica_c15 <- 1 / 15

cat(
  "Eficiencia real con c = 15:",
  round(eficiencia_c15 * 100, 2),
  "%\n"
)
## Eficiencia real con c = 15: 6.7 %
cat(
  "Eficiencia teórica con c = 15:",
  round(eficiencia_teorica_c15 * 100, 2),
  "%\n"
)
## Eficiencia teórica con c = 15: 6.67 %

Resultado

La eficiencia observada fue de 6.7 %.

La eficiencia teórica con \(c=15\) es:

\[ \boxed{6.67\%}. \]

Comentario

La eficiencia disminuye de aproximadamente 50 % con \(c=2\) a aproximadamente 6.67 % con \(c=15\). Esto significa que la gran mayoría de los candidatos generados son rechazados.

Comparación entre \(c=2\) y \(c=15\)

Código

# Comparación teórica
c_bueno <- 2
c_malo <- 15

eficiencia_teorica_c2 <- 1 / c_bueno
eficiencia_teorica_c15 <- 1 / c_malo

intentos_esperados_c2 <- n_sim / eficiencia_teorica_c2
intentos_esperados_c15 <- n_sim / eficiencia_teorica_c15

comparacion <- data.frame(
  Constante = c("c = 2", "c = 15"),
  Eficiencia_teorica = c(
    paste0(round(eficiencia_teorica_c2 * 100, 2), " %"),
    paste0(round(eficiencia_teorica_c15 * 100, 2), " %")
  ),
  Intentos_esperados = c(
    intentos_esperados_c2,
    intentos_esperados_c15
  ),
  Intentos_observados = c(
    intentos_c2_observados,
    intentos_c15_observados
  )
)

knitr::kable(
  comparacion,
  align = c("l", "c", "r", "r"),
  caption = "Comparación de la eficiencia para c = 2 y c = 15."
)
Comparación de la eficiencia para c = 2 y c = 15.
Constante Eficiencia_teorica Intentos_esperados Intentos_observados
c = 2 50 % 10000 9976
c = 15 6.67 % 75000 74581

Resultado

La comparación muestra que \(c=2\) requiere alrededor de 10.000 intentos, mientras que \(c=15\) requiere alrededor de 75.000.

Comentario

La elección de \(c=2\) es mucho más eficiente porque es la constante mínima necesaria para cubrir la densidad objetivo. Al utilizar \(c=15\), la región de aceptación se vuelve mucho menor en comparación con la región total utilizada para generar candidatos.

Auditoría del modelo

Pregunta 1. ¿Por qué el histograma final se ajusta a la curva \(2x\)?

Aunque el algoritmo rechaza una gran cantidad de candidatos, los valores que son aceptados no tienen una distribución uniforme.

La probabilidad de aceptación depende de:

\[ \frac{f(Y)}{c g(Y)}. \]

En este caso:

\[ \frac{2Y}{2(1)}=Y. \]

Por lo tanto, los valores de \(Y\) cercanos a 1 tienen una mayor probabilidad de ser aceptados que los valores cercanos a 0.

Respuesta

El histograma final se ajusta a la curva teórica \(2x\) porque el mecanismo de aceptación y rechazo selecciona los candidatos de acuerdo con una probabilidad proporcional a la densidad objetivo. Aunque muchos candidatos sean rechazados, los valores aceptados tienen la distribución deseada.

Por eso, al utilizar una cantidad suficientemente grande de muestras, el histograma se aproxima a la curva \(f(x)=2x\).

Pregunta 2. Relación entre el área bajo la curva y la probabilidad de aceptación

La función:

\[ f(x)=2x \]

tiene área:

\[ \int_0^1 2x\,dx=1. \]

Esto ocurre porque es una función de densidad. Sin embargo, la probabilidad de aceptar un candidato en el método de aceptación y rechazo es:

\[ P(\text{aceptación})=\frac{1}{c}. \]

Para \(c=2\):

\[ P(\text{aceptación})=\frac{1}{2}=0.5. \]

Respuesta

El área bajo la curva roja \(f(x)=2x\) es igual a 1 porque representa una función de densidad. La probabilidad de que un candidato sea aceptado está relacionada con la constante \(c\) y es igual a \(1/c\).

Para \(c=2\), la probabilidad de aceptación es del 50 %. Geométricamente, la curva \(c g(x)\) forma una región que contiene a la densidad objetivo; la proporción del área de la densidad respecto a esa región determina la eficiencia del método.

Pregunta 3. ¿Qué ocurre si el dominio cambia a \([0,2]\)?

Si se mantiene:

\[ f(x)=2x, \]

pero ahora el dominio es \([0,2]\), su integral sería:

\[ \int_0^2 2x\,dx=4. \]

Por lo tanto, ya no sería una función de densidad. Es necesario normalizarla:

\[ f(x)=\frac{x}{2}, \]

porque:

\[ \int_0^2\frac{x}{2}\,dx=1. \]

Además, la distribución propuesta uniforme debe cambiar de \(U(0,1)\) a \(U(0,2)\). Su densidad es:

\[ g(x)=\frac{1}{2},\qquad 0\leq x\leq 2. \]

La razón entre las densidades es:

\[ \frac{f(x)}{g(x)} = \frac{x/2}{1/2} = x. \]

El máximo de esta razón en \([0,2]\) es 2. Por lo tanto, nuevamente se puede utilizar:

\[ c=2. \]

La condición de aceptación queda:

\[ U\leq\frac{x/2}{2(1/2)} = \frac{x}{2}. \]

Código

# Parámetros para el nuevo dominio
n_sim_dos <- 5000
muestras_dos <- numeric(n_sim_dos)
aceptados_dos <- 0
intentos_dos <- 0
c_dos <- 2

set.seed(123)

while (aceptados_dos < n_sim_dos) {
  
  # Candidato Y ~ Uniforme(0,2)
  Y <- runif(1, min = 0, max = 2)
  
  # Variable auxiliar
  U <- runif(1, min = 0, max = 1)
  
  intentos_dos <- intentos_dos + 1
  
  # Condición de aceptación: U <= Y/2
  if (U <= Y / 2) {
    aceptados_dos <- aceptados_dos + 1
    muestras_dos[aceptados_dos] <- Y
  }
}

cat("Muestras aceptadas:", aceptados_dos, "\n")
## Muestras aceptadas: 5000
cat("Intentos:", intentos_dos, "\n")
## Intentos: 9976
cat(
  "Eficiencia:",
  round(aceptados_dos / intentos_dos * 100, 2),
  "%\n"
)
## Eficiencia: 50.12 %

Resultado

La función runif() ahora genera candidatos en el intervalo \([0,2]\), y la condición de aceptación cambia a \(U\leq Y/2\).

Comentario

Al cambiar el dominio también es obligatorio cambiar los límites de runif(). Además, la función \(2x\) debe normalizarse, ya que su integral en \([0,2]\) es 4 y una densidad debe tener integral igual a 1.

Conclusión

El método de aceptación y rechazo permitió generar 5000 observaciones de la distribución:

\[ f(x)=2x,\qquad 0\leq x\leq1, \]

utilizando una distribución uniforme como propuesta.

La constante óptima es:

\[ c=2, \]

con una eficiencia teórica de:

\[ 50\%. \]

Cuando se utilizó \(c=15\), la eficiencia teórica disminuyó a:

\[ 6.67\%, \]

y el número esperado de intentos aumentó de aproximadamente 10.000 a 75.000.

Esto demuestra que elegir una constante \(c\) adecuada es fundamental para que el algoritmo de aceptación y rechazo sea eficiente. Una constante demasiado grande produce muchas más muestras rechazadas y aumenta considerablemente el costo computacional del procedimiento.