简体   繁体   English

在 R 中生成满足约束的随机数

[英]Generate random numbers in R satisfying constraints

I need help with a code to generate random numbers according to constraints.我需要代码帮助来根据约束生成随机数。 Specifically, I am trying to simulate random numbers ALFA and BETA from, respectively, a Normal and a Gamma distribution such that ALFA - BETA < 1.具体来说,我试图分别从正态分布和 Gamma 分布模拟随机数 ALFA 和 BETA,使得 ALFA - BETA < 1。

Here is what I have written but it does not work at all.这是我写的,但它根本不起作用。

set.seed(42) 
n <- 0 
repeat {
  n <- n + 1
  a <- rnorm(1, 10, 2)
  b <- rgamma(1, 8, 1)
  d <- a - b
  if (d < 1) 
  alfa[n] <- a
  beta[n] <- b
  l = length(alfa)
  if (l == 10000) break
}

Due to vectorization, it will be faster to generate the numbers "all at once" rather than in a loop:由于矢量化,“一次”而不是循环生成数字会更快:

set.seed(42)
N = 1e5
a = rnorm(N, 10, 2)
b = rgamma(N, 8, 1)
d = a - b
alfa = a[d < 1]
beta = b[d < 1]
length(alfa)
# [1] 36436

This generated 100,000 candidates, 36,436 of which met your criteria.这产生了 100,000 名候选人,其中 36,436 名符合您的标准。 If you want to generate n samples, try setting N = 4 * n and you'll probably generate more than enough, keep the first n .如果要生成n样本,请尝试设置N = 4 * n ,您可能会生成足够多的样本,请保留第一个n


Your loop has 2 problems: (a) you need curly braces to enclose multiple lines after an if statement.您的循环有 2 个问题:(a)您需要花括号在if语句之后括起多行。 (b) you are using n as an attempt counter, but it should be a success counter. (b) 您使用n作为尝试计数器,但它应该是成功计数器。 As written, your loop will only stop if the 10000th attempt is a success.如前所述,只有在第 10000 次尝试成功时,您的循环才会停止。 Move n <- n + 1 inside the if statement to fix:if语句中移动n <- n + 1以修复:

set.seed(42) 
n <- 0 
alfa = numeric(0)
beta = numeric(0)
repeat {
  a <- rnorm(1, 10, 2)
  b <- rgamma(1, 8, 1)
  d <- a - b
  if (d < 1) {
    n <- n + 1
    alfa[n] <- a
    beta[n] <- b
    l = length(alfa)
    if (l == 500) break
  }
}

But the first way is better... due to "growing" alfa and beta in the loop, and generating numbers one at a time, this method takes longer to generate 500 numbers than the code above takes to generate 30,000.但是第一种方法更好......由于在循环中“增长” alfabeta ,并且一次生成一个数字,这种方法生成 500 个数字比上面的代码生成 30,000 个需要更长的时间。

As commented by @Gregor Thomas, the failure of your attempt is due to the missing of curly braces to enclose the if statement.正如@Gregor Thomas 评论的那样,您的尝试失败是由于缺少花括号来括住if语句。 If you would like to skip {} for if control, maybe you can try the code below如果您想跳过{}进行if控制,也许您可以尝试下面的代码

set.seed(42) 
r <- list()
repeat {
  a <- rnorm(1, 10, 2)
  b <- rgamma(1, 8, 1)
  d <- a - b
  if (d < 1) r[[length(r)+1]] <- cbind(alfa = a, beta = b)
  if (length(r) == 100000) break
}
r <- do.call(rbind,r)

such that这样

> head(r)
          alfa      beta
[1,]  9.787751 12.210648
[2,]  9.810682 14.046190
[3,]  9.874572 11.499204
[4,]  6.473674  8.812951
[5,]  8.720010  8.799160
[6,] 11.409675 10.602608

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM