#=======================================================================================
# Algoritmo_1
#=======================================================================================
ncomp <<- 0
sim1N <- function(n=1000){
X <- numeric(n)
for(isim in 1:n)
{
U <- runif(1,0,1)
if(U<=0.11){X[isim]<-1
ncomp<<-ncomp+1}
else{if(U<=0.33){X[isim]<-2
ncomp<<-ncomp+2}
else{if(U<=0.78){X[isim]<-3
ncomp<<-ncomp+3}
else{if(U<=0.91){X[isim]<-4
ncomp<<-ncomp+4}
else{X[isim]<-5
ncomp<<-ncomp+4}}}}
}
return(X)
}
## Nº medio de comparaciones = 2.7749
Tenemos el siguiente árbol binario:
Donde las probabilidades asociadas a los nodos están dados por:
| Nodos | {1,2,3,4,5 } | {1,4,5 } | {2,3 } | {1,5} |
|---|---|---|---|---|
| p | 1 | 0.33 | 0.67 | 0.2 |
Asi pues, proponemos el sigueinte algoritmo.
#=======================================================================================
# Algoritmo_2
#Arbol Binario Óptimo
#Obteniendo previamente el árbol binario óptimo
#=======================================================================================
ncomp <<- 0
sim2N <- function(n=1000){
X <- numeric(n)
for (isim in 1:n) {
U <- runif(1,0,1)
if (U>0.33){if(U>0.78){X[isim]<-2
ncomp <<- ncomp+2}
else{X[isim]<-3
ncomp <<- ncomp+2}}
else{if(U>0.2){X[isim]<-4
ncomp <<- ncomp+2}
else{if(U>0.11){X[isim]<-5
ncomp <<- ncomp+3}
else{X[isim]<-1
ncomp <<- ncomp+3}}}
}
return(X)
return(ncomp)
}
## Nº medio de comparaciones = 2.1998
#=======================================================================================
# Algoritmo_3
# Tabla Guía.
#=======================================================================================
#---------------------------------------------------------------------------------------
x <- c(1:5)
p <- c(0.11,0.22,0.45,0.13,0.09)
#---------------------------------------------------------------------------------------
ncomp <<- 0
rfmp.tabla <- function(x, prob = 1/length(x), m, nsim = 1000) {
# Simulación v.a. discreta a partir de función de masa de probabilidad
# por tabla guia de tamaño m
# Inicializar tabla y FD
Fx <- cumsum(prob)
g <- rep(1,m)
i <- 1
for(j in 2:m) {
while (Fx[i] < (j-1)/m) i <- i+1
g[j] <- i
}
# Generar valores
X <- numeric(nsim)
U <- runif(nsim)
for(j in 1:nsim) {
i <- g[floor(U[j]*m)+1]
while (Fx[i] < U[j]) i <- i + 1
X[j] <- x[i]
ncomp <<- ncomp+1
}
return(X)
}
## Nº medio de comparaciones = 1
Notamos que a medida que vamos mejorando los algoritmos el numero medio de comparaciones disminuye, llegando a ser 1 al momento de usar la tabla guía, lo cual significaria una gran eficiencia para simular esta variable.
Tenemos el siguiente árbol binario:
Donde las probabilidades asociadas a los nodos están dados por:
| Nodos | {0,1,2,3,4,5,6 } | {2,3,4,5,6 } | {0,1 } | {3,4,5,6} | {4,5,6 } | {5,6} |
|---|---|---|---|---|---|---|
| p | 1 | 0.45 | 0.55 | 0.30 | 0.19 | 0.1 |
Asi pues, proponemos el siguiente algoritmo.
Proponemos el siguiente algoritmo
sim21N <- function(n=10000){
X <- numeric(n)
for(i in 1:n){
U <- runif(1)
if(U>0.45){if(U>0.78){X[i]<-1
ncomp1<<-ncomp1+2}
else{X[i]<-0
ncomp0<<-ncomp0+2}}
else{if(U>0.3){X[i]<-2
ncomp2<<-ncomp2+3}
else{if(U>0.19){X[i]<-3
ncomp3<<-ncomp3+4}
else{if(U>0.1){X[i]<-4
ncomp4<<-ncomp4+5}
else{if(U>0.04){X[i]<-5
ncomp5<<-ncomp5+6}
else{X[i]<-6
ncomp6<<-ncomp6+6}}}}}
}
return(X)
}
Número medio de comparaciones para cada elemento
## Número medio de comparaciones para 0 = 2.011515
## Número medio de comparaciones para 1 = 1.945455
## Número medio de comparaciones para 2 = 3.058
## Número medio de comparaciones para 3 = 4.032727
## Número medio de comparaciones para 4 = 5.072222
## Número medio de comparaciones para 5 = 5.73
## Número medio de comparaciones para 6 = 6.255
Usando el algoritmo de tabla guía se espera que el número de comparaciones para cada elemento sea 1. Asi pues, tenemos:
ncomp <<- 0
rfmp.tabla <- function(x, prob = 1/length(x), m, nsim = 1000) {
# Simulación v.a. discreta a partir de función de masa de probabilidad
# por tabla guía de tamaño m
# Inicializar tabla y FD
Fx <- cumsum(prob)
g <- rep(1,m)
i <- 1
for(j in 2:m) {
while (Fx[i] < (j-1)/m) i <- i+1
g[j] <- i
}
# Generar valores
X <- numeric(nsim)
U <- runif(nsim)
for(j in 1:nsim) {
i <- g[floor(U[j]*m)+1]
while (Fx[i] < U[j]) i <- i + 1
X[j] <- x[i]
ncomp <<- ncomp+1
}
return(X)
}
## Nº medio de comparaciones = 1
Tenemos el siguiente árbol binario:
Donde las probabilidades asociadas a los nodos están dados por:
| Nodos | {0,1,2,3,4,5 } | {0,3,4,5 } | {1,2 } | {0,4,5} | {4,5} |
|---|---|---|---|---|---|
| p | 1 | 0.40 | 0.60 | 0.21 | 0.12 |
Asi pues, proponemos el siguiente algoritmo.
#Datos Iniciales
s <- c(0:5)
p <- c(0.09,0.21,0.39,0.19,0.08,0.04)
sim31N <- function(n=1000){
X <- numeric(n)
for (i in 1:n) {
U <- runif(1)
if(U>0.4){if(U>0.79){X[i]<-1
ncomp1 <<- ncomp1+2}
else{X[i]<-2
ncomp2 <<- ncomp2+2}}
else{if(U>0.21){X[i]<-3
ncomp3 <<- ncomp3+3}
else{if(U>0.12){X[i]<-0
ncomp0 <<- ncomp0+4}
else{if(U>0.08){X[i]<-5
ncomp5 <<- ncomp5+5}
else{X[i]<-4
ncomp4 <<- ncomp4+5}}}
}
}
return(X)
}
system.time(u <- sim31N(nsim))
## user system elapsed
## 0.08 0.00 0.08
## Numero de comparaciones para 0 = 4.08
## Numero de comparaciones para 1 = 1.948571
## Numero de comparaciones para 2 = 2.041026
## Numero de comparaciones para 3 = 2.97
## Numero de comparaciones para 4 = 5.10625
## Numero de comparaciones para 5 = 4.475
#=======================================================================
# Método de busqueda secuencial
#=======================================================================
rfmp <- function(x, prob = 1/length(x), nsim = 1000) {
# Simulación nsim v.a. discreta a partir de fmp
# por inversión generalizada (transformación cuantil)
# Inicializar FD
Fx <- cumsum(prob)
# Simular
X <- numeric(nsim)
U <- runif(nsim)
for(j in 1:nsim) {
i <- 1
while (Fx[i] < U[j]) i <- i + 1
X[j] <- x[i]
ncomp <<- ncomp + i
}
return(X)
}
system.time(v <- rfmp(s,p,nsim))
## user system elapsed
## 0.02 0.00 0.01
## Nº medio de comparaciones = 3.0689
#=======================================================================
# Método secuencial, ordenando previamente
#=======================================================================
so <- c(2,1,3,0,4,5)
po <- c(0.39,0.21,0.19,0.09,0.08,0.04)
system.time(v <- rfmp(so,po,nsim))
## user system elapsed
## 0 0 0
## Nº medio de comparaciones = 2.3845
El método de árbol binario tiene ventaja al ser mas sencillo de implementar, aun asi, no es tan eficiente como los demas métodos, al menos para este ejercicio, como se ve, el tiempo de computo del método de árbol binario es el mas grande.
Tenemos el siguiente árbol binario:
Donde las probabilidades asociadas a los nodos están dados por:
| Nodos | {0,1,3,4,7 } | {3,4,7 } | {0,1 } | {4,7} |
|---|---|---|---|---|
| p | 1 | 0.37 | 0.63 | 0.21 |
Asi pues, proponemos el siguiente algoritmo.
s <- c(0,1,3,4,7)
p <- c(0.28,0.35,0.16,0.12,0.09)
sim41N <- function(n=10000){
X<-numeric(n)
for (i in 1:n) {
U <- runif(1)
if(U>0.37){if(U>0.72){X[i]<-0}
else{X[i]<-1}}
else{if(U>0.21){X[i]<-3}
else{if(U>0.12){X[i]<-7}
else{X[i]<-4}}}
}
return(X)
}
system.time(u <- sim41N(nsim))
## user system elapsed
## 0.06 0.00 0.06
system.time(v <- rfmp.tabla(s,p,4,nsim))
## user system elapsed
## 0.03 0.00 0.03
## Nº medio de comparaciones = 1
La eficiencia entre uno y otro algoritmo es muy simular, estudiando los tiempos de computo vemos que la diferencia entre el método usando arboles binarios y el método usando Tablas Guía, es apenas de un 0.01s, aun asi es claro que el método de Tablas Guía es más eficiente.
| x | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| P(X=x) | 0.35 | 0.20 | 0.16 | 0.12 | 0.08 | 0.05 | 0.03 | 0.01 |
s <- c(0:7)
p <- c(0.35,0.20,0.16,0.12,0.08,0.05,0.03,0.01)
ncomp <<- 0
rfmp.tabla <- function(x, prob = 1/length(x), m, nsim = 1000) {
# Simulación v.a. discreta a partir de función de masa de probabilidad
# por tabla guia de tamaño m
# Inicializar tabla y FD
Fx <- cumsum(prob)
g <- rep(1,m)
i <- 1
for(j in 2:m) {
while (Fx[i] < (j-1)/m) i <- i+1
g[j] <- i
}
# Generar valores
X <- numeric(nsim)
U <- runif(nsim)
for(j in 1:nsim) {
i <- g[floor(U[j]*m)+1]
while (Fx[i] < U[j]) i <- i + 1
X[j] <- x[i]
ncomp <<- ncomp+1
}
return(X)
}
system.time(v <- rfmp.tabla(s,p,7,nsim))
## user system elapsed
## 0.03 0.00 0.03
## Nº medio de comparaciones = 1
Generar 12 muestras (1 año, doce meses) \(X_{i}\) de tamaño n.
Hacer \(X=\sum_{1}^{12} X_{i}\).
Obtener el número m, \(m \leq n\) de posibles resultados \(X[j] \geq 30\), con \(j \in [1,n]\)
Devolver \(p=\frac{m}{n}\).
Proponemos el siguiente algoritmo:
set.seed(123)
n <- 12
nsim <- 1000
X<<-numeric(nsim)
for (i in 1:n) {
u <- rfmp.tabla(s,p,7,nsim)
X <<- X+u
}
hist(X,freq = FALSE)
#Como vemos, la variable aleatoria numero de fallos por año para seguir una distribucion
# N(nsigma, nmu)
probabilidad <- function(X,nsim){
aux1 <-0
for (i in 1:nsim) {
if(X[i]>=30){aux1 <- aux1+1}
}
return(aux1/nsim)
}
probabilidad(X,nsim)
## [1] 0.07
Teoricamente podemos encontrar la masa de probabilidad de la variable aleatoria numero de fallos anuales. Modificando el algoritmo inicial dado, podremos obtener la probabilidad de que hayan de 0 a 84 fallos.
Si los valores de la variable estan fuera de ese intervalo, tenemos que \(phyper = 0\)
#===============================================================================
# Distribucion Hipergeometrica
#===============================================================================
system.time(u<-rfmp(s,p,nsim))
## user system elapsed
## 0.03 0.00 0.03
## Simulacion de la media muestral = 11.3939
## Media Teorica = 11.42857
Esta bien aproximado.
#===============================================================================
# Ordenando las probabilidades
#===============================================================================
ind <- order(vectorp(m,n,k), decreasing=TRUE)
system.time(rx <- rfmp(s[ind],p[ind],nsim))
## user system elapsed
## 0 0 0
res <- as.data.frame(table(rx)/nsim)
names(res) <- c("rx", "psim")
plot(as.matrix(res), col='green',lwd=3,type="h")
points(c(0:k),vectorp(m,n,k),pch=18)
#===============================================================================
# Usando la funcion Sample
#===============================================================================
system.time( rx <- sample(s, nsim, replace = TRUE, prob = p) )
## user system elapsed
## 0 0 0
res <- as.data.frame(table(rx)/nsim)
names(res) <- c("rx", "psim")
plot(as.matrix(res), col='brown',lwd=3,type="h")
points(c(0:k),vectorp(m,n,k),pch=16)
#===============================================================================
# Usando Tablas Guia
#===============================================================================
system.time( rx <- rfmp.tabla(s, p, k-1, nsim) )
## user system elapsed
## 0.03 0.00 0.03
res <- as.data.frame(table(rx)/nsim)
names(res) <- c("rx", "psim")
plot(as.matrix(res), col='violet',lwd=3,type="h")
points(c(0:k),vectorp(m,n,k),pch=13)
#===============================================================================
#Usando el metodo de Alias
#===============================================================================
system.time( rx <- rfmp.alias(s,p,nsim) )
## user system elapsed
## 0.04 0.00 0.05
res <- as.data.frame(table(rx)/nsim)
names(res) <- c("rx", "psim")
plot(as.matrix(res), col='orange',lwd=3,type="h")
points(c(0:k),vectorp(m,n,k),pch=9)
** Proponemos los siguientes algoritmos **
#=========================================================================
# Distribucion de Beornulli
#=========================================================================
rbeornulli <- function(p){
U <- runif(1)
if(U<=p){return(X<-1)}
else{return(X<-0)}
}
rbeornulliN <- function(p,n=10000){
X<-numeric(n)
for (i in 1:n) {
X[i]<-rbeornulli(p)
}
return(X)
}
system.time( rx <- rbeornulliN(0.5) )
## user system elapsed
## 0.06 0.00 0.09
hist(rx)
#res <- as.data.frame(table(rx)/nsim)
#names(res) <- c("rx", "psim")
#plot(as.matrix(res), col='orange',lwd=3,type="h")
#points(c(0,1),c(0.5,0.5),pch=9)
#=========================================================================
# Distribucion Hipergeometrica
#=========================================================================
#=======================================================================
# Metodo de busqueda secuencial
#=======================================================================
ncomp <<- 0
rfmp <- function(x, prob = 1/length(x), nsim = 1000) {
# Simulación nsim v.a. discreta a partir de fmp
# por inversión generalizada (transformación cuantil)
# Inicializar FD
Fx <- cumsum(prob)
# Simular
X <- numeric(nsim)
U <- runif(nsim)
for(j in 1:nsim) {
i <- 1
while (Fx[i] < U[j]) i <- i + 1
X[j] <- x[i]
ncomp <<- ncomp + i
}
return(X)
}
#======================================================================
#Vector de probabilidades
vectorp <-function(m,n,k){
s <- c(0:k)
p <- (choose(m,s)*choose(n,k-s))/choose(m+n,k)
return(p)
}
Hgeom <- function(m,n,k,nsim=10^4){
s <- c(0:k)
p <- (choose(m,s)*choose(n,k-s))/choose(m+n,k)
X <- rfmp(s,p,nsim)
return(X)
}