使用接受-拒绝方法模拟随机变量

时间:2019-04-19 17:55:36

标签: r algorithm simulation

我有以下算法

第1步。用qj = P(Y = j)模拟Y的值

第2步。生成一个统一变量

步骤3。如果U <= Pj /(c * qj),​​则X = j并停止。否则,请返回到步骤1。

以及具体示例:

X = 1,2,3,4,其中P1 = .2,P2 = .15,P3 = .25,P4 = .4

生成X的值

  1. 让Y〜UD(1,4)

  2. c = .4 / .25

这是我在R中实现此算法的方法:

f<-function(){
n<-4

probY<-c(.25,.25,.25,.25)
probX<-c(2,.15,.25,.4)

X<-rep(0,4)

U<-runif(n)

c<-.4/.25

for(j in 1:4)
{
if(U[j]<= probX[j]/(c*probY[j]))
   X<-j

}


return(X)

}

输出为4,我认为这是不正确的。我不确定是否应该写Y<-runif(n,1,4)还是此行probY<-c(.25,.25,.25,.25)。此外,这行“否则返回到步骤1”。虽然总是相同的.25

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

我认为这里的问题与算法的工作方式有些混淆。

为了从您的分布中生成一个单个值(X = 1,2,3,4,其中P(X = 1)= .2,P(X = 2)= .15 ,P(X = 3)= .25,P(X = 4)= .4),我们需要遵循算法的步骤。假设我们选择 c = .4 / .25

1。从Y〜UD(1,4)生成 y

2。从U〜U(0,1)生成 u

3。检查是否u≤f(y)/ cg(y)。如果,则定义 x = y ,您就完成了!如果不是,请返回步骤1。

在您提供的代码中,您实际上从未生成过 y 变量。这是应该适合您的功能!希望我的评论足够好解释!

accRej <- function(){

  #The probabilities for generating a r.v. from X
  probX <- c(.2,.15,.25,.4)

  #The Value for c
  c <- .4/.25

  #x is a placeholder for our final value of x 
  #and i is a counter variable which will allow us to stop the loop when we complete step 3
  x <- numeric(1)
  i <- 1

  #Now, start the loop!
  while(i <= 1){
    #Step 1, get y
    y <- sample(1:4,1)
    #Step 2, get u
    u <- runif(1)
    #Step 3, check to see if the inequality holds
    #If it does, assign y to x and add 1 to i (making it 2) to stop the while loop
    #If not, do nothing and try again!
    if(u <= probX[y]/c*.25){
      x[i] <- y
      i <- i+1
    }
  }
  #Return our value of x
  return(x)
}

在此代码中请注意,probX[i]等于我们算法中的 f(y),并且由于Y〜UD(1,4),.25 = g(y)。希望这会有所帮助!

此外,这是使用此方法生成n随机变量的代码。基本上与上述相同,只是可以选择将1更改为n

accRej <- function(n){

  #The probabilities for generating a r.v. from X
  probX <- c(.2,.15,.25,.4)

  #The Value for c
  c <- .4/.25

  #x is a placeholder for our final value of x 
  #and i is a counter variable which will allow us to stop the loop when we complete step 3
  x <- numeric(n)
  i <- 1

  #Now, start the loop!
  while(i <= n){
    #Step 1, get y
    y <- sample(1:4,1)
    #Step 2, get u
    u <- runif(1)
    #Step 3, check to see if the inequality holds
    #If it does, assign y to x and add 1 to i
    #If not, do nothing and try again!
    if(u <= probX[y]/c*.25){
      x[i] <- y
      i <- i+1
    }
  }
  #Return our value of x
  return(x)
}