R 生成间距至少为10的随机数

R 生成间距至少为10的随机数,r,random,numbers,R,Random,Numbers,我想从1到100000生成100个数字,其中每个数字之间的空间至少为10 一种方法是将100000除以10,然后做样本(1000100),得到答案,乘以10,但数字都以0结尾 如何生成不仅以0结尾的随机数?我想不出一种非递归的方法来实现这一点(首先想到的是在你的方法中添加“抖动”,但这几乎肯定会使一些观察值彼此过于接近),但这会起作用: set.seed(102438) include <- 1:100000 smpl <- integer(100) for (i in 1:len

我想从1到100000生成100个数字,其中每个数字之间的空间至少为10

一种方法是将100000除以10,然后做样本(1000100),得到答案,乘以10,但数字都以0结尾


如何生成不仅以0结尾的随机数?

我想不出一种非递归的方法来实现这一点(首先想到的是在你的方法中添加“抖动”,但这几乎肯定会使一些观察值彼此过于接近),但这会起作用:

set.seed(102438)
include <- 1:100000
smpl <- integer(100)

for (i in 1:length(smpl)){
  smpl[i] <- si <- sample(include, 1)
  #now remove anything within 10 of the current draw
  include <- setdiff(include, (si - 10L):(si + 10L))
}

min(abs(diff(smpl)))
# [1] 1105
set.seed(102438)

包括尝试拒绝取样。不受限制地进行采样,如果任意两个采样间隔小于10,则丢弃结果并再次进行采样,直到成功:

repeat {
  s <- sample(100000, 100)
  mindiff <- min(diff(sort(s)))
  if (mindiff >= 10) break
}
给予:

[1] 8
[1] 1
[1] 17

类似于@G.Grothendieck,我想,重复取样,但如果不符合您的标准,则拒绝

set.seed(1337)

## minimum separation
min_gap <- 10

## first entry
samp_vec <- sample(seq(1,1e5L,1), 1)
for (isamp in 1:100) { 

  possible_new_value <- samp_vec[1]
  while(any(abs(samp_vec - possible_new_value) < min_gap)) {
    possible_new_value <- sample(seq(1,1e5L,1), 1)
  }
  samp_vec <- c(samp_vec, possible_new_value)


}

min(abs(diff(samp_vec)))
# 92
set.seed(1337)
##最小间距

min_gap这里有一些不依赖于递归的东西:

mysample <- function(n, lower, upper, space) {
  b <- ceiling((upper - lower + 1) / (space - 1))
  bs <- sample(seq(2, b - 1, by = 2), n - 1)
  gr <- split(setdiff(1:b,bs), cumsum(c(0, diff(setdiff(1:b, bs))) != 1))
  out <- sapply(gr, function(x) (x[1] - 1) * (space - 1) + ceiling(runif(1) * length(x) * (space - 1)))
  out[n] <- min(out[n], upper)
  out
}

set.seed(123)
min(replicate(min(diff(mysample(100, 1, 100000, 10))), n = 1000))
# [1] 10
在哪里


MichaelChirico我认为这种方法对于小型企业(n_desired/n_initial——也就是说,这里是100/100000)来说非常快,但随着规模的扩大,它会经常被拒绝。我的存在另一个缺陷——如果可用绘图用完,它将失败(通过鸽子洞,这必须发生在n_desired>n_initial/10的情况下,大致上,但当n_desired接近绑定时,绝大多数绘图路径都会发生)很好的方法。您应该随机化偶数或奇数是否为“禁止”块(即,
seq(sample(2,1),b-1,by=2)
)--您仍然无法获得可能的“有效”样本,但您会得到很多closer@MichaelChirico,我同意我的解决方案可以朝这个方向改进,但考虑到奇数块可能会有一些复杂情况,我决定避免它们。这就是我的意思;假设
n=3
,总共有5个块。通过禁止区块2和区块4,我们从区块1、3、5中各抽取一个数字,得到结果,尽管不是完美的结果。通过禁止区块1、3和5,我们可能必须从区块3、4、5组中抽取3个数字,其中可能出现故障。
mysample <- function(n, lower, upper, space) {
  b <- ceiling((upper - lower + 1) / (space - 1))
  bs <- sample(seq(2, b - 1, by = 2), n - 1)
  gr <- split(setdiff(1:b,bs), cumsum(c(0, diff(setdiff(1:b, bs))) != 1))
  out <- sapply(gr, function(x) (x[1] - 1) * (space - 1) + ceiling(runif(1) * length(x) * (space - 1)))
  out[n] <- min(out[n], upper)
  out
}

set.seed(123)
min(replicate(min(diff(mysample(100, 1, 100000, 10))), n = 1000))
# [1] 10
set.seed(123)
upper <- 100000
benchmark(
  mysample(100, 1, upper, 10), MichaelChirico(100, 1, upper, 10), 
  Grothendieck(100, 1, upper, 10), Jonathan(100, 1, upper, 10), 
  replications = 1, columns = c("test", "relative"))
#                                    test relative
# 3   Grothendieck(100, lower, upper, 10)        1
# 4       Jonathan(100, lower, upper, 10)      344
# 2 MichaelChirico(100, lower, upper, 10)     2133
# 1       mysample(100, lower, upper, 10)        4

upper <- 10000
benchmark(
  mysample(100, 1, upper, 10), MichaelChirico(100, 1, upper, 10), 
  Grothendieck(100, 1, upper, 10), Jonathan(100, 1, upper, 10), 
  replications = 1, columns = c("test", "relative"))
#                                    test relative
# 3   Grothendieck(100, lower, upper, 10)    132.5
# 4       Jonathan(100, lower, upper, 10)     56.0
# 2 MichaelChirico(100, lower, upper, 10)     27.5
# 1       mysample(100, lower, upper, 10)      1.0
MichaelChirico <- function(n, lower, upper, space) {
  include <- lower:upper
  smpl <- integer(n)
  for (i in 1:length(smpl)){
    smpl[i] <- si <- sample(include, 1)
    include <- setdiff(include, (si - space):(si + space))
  }
  smpl
}

Grothendieck <- function(n, lower, upper, space) {
  repeat {
    s <- sample(lower:upper, n)
    mindiff <- min(diff(sort(s)))
    if (mindiff >= space) break
  }
  s
}

Jonathan <- function(n, lower, upper, space) {
  min_gap <- space
  samp_vec <- sample(seq(lower,upper,1), 1)
  for (isamp in 1:n) {
    possible_new_value <- samp_vec[1]
    while(any(abs(samp_vec - possible_new_value) < min_gap)) {
      possible_new_value <- sample(seq(lower,upper,1), 1)
    }
    samp_vec <- c(samp_vec, possible_new_value)
  }
  samp_vec
}