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.
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}. \]
# 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
La constante utilizada es:
\[ \boxed{c=2}. \]
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.
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}. \]
# 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.
La condición de aceptación que se utilizará es:
\[ \boxed{U\leq Y}. \]
Esto significa que un candidato \(Y\) será aceptado cuando el valor aleatorio \(U\), generado entre 0 y 1, sea menor o igual que \(Y\).
Ahora se implementa el algoritmo de aceptación y rechazo. En cada intento:
# 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
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.
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.
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\%}. \]
# 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 %
La eficiencia real obtenida fue de 50.12 %.
La eficiencia teórica es exactamente:
\[ \boxed{50\%}. \]
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.
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. \]
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.
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.
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\).
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}. \]
# 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)
La nueva constante utilizada es:
\[ \boxed{c=15}. \]
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\).
Con \(c=15\), la condición de aceptación es:
\[ U\leq\frac{2Y}{15}. \]
# 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
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.
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.
La eficiencia teórica ahora es:
\[ \frac{1}{15} = 0.0667. \]
Por lo tanto:
\[ \boxed{\text{Eficiencia}\approx 6.67\%}. \]
# 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 %
La eficiencia observada fue de 6.7 %.
La eficiencia teórica con \(c=15\) es:
\[ \boxed{6.67\%}. \]
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 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."
)
| Constante | Eficiencia_teorica | Intentos_esperados | Intentos_observados |
|---|---|---|---|
| c = 2 | 50 % | 10000 | 9976 |
| c = 15 | 6.67 % | 75000 | 74581 |
La comparación muestra que \(c=2\) requiere alrededor de 10.000 intentos, mientras que \(c=15\) requiere alrededor de 75.000.
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.
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.
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\).
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. \]
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.
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}. \]
# 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 %
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\).
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.
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.