Generate random numbers located at a distance of at least 10

I want to generate 100 numbers from 1 to 100,000, where there must be at least 10 between them.

One way is to divide 100,000 by 10 and sample (1000 100) and get the answer, times 10, but the numbers end in 0.

How to generate random numbers, not only ending with 0?

+4
source share
4 answers

I couldn't think of a non-recursive way to do this (the first thought was to add a β€œchuckle” to your approach, but it would almost certainly bring some observations too close together), but this will work

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
+2
source

. , - 10, , :

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

, , 10 , 10. , > if, .

123 3 ( 100 100 000 ). set.seed print, , .

set.seed(123)
repeat {
  s <- sample(100000, 100)
  mindiff <- min(diff(sort(s)))
  print(mindiff)
  if (mindiff >= 10) break
}

:

[1] 8
[1] 1
[1] 17
+2

@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
0

-, :

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

mysample , , , sample(mysample(...)).

, [, ] space - 1 n-1 2-, 4-, 6-,... ; "" , . "" , , 1, 2, 5; (1- 2-, 5-), , . , .

:

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
}
0

Source: https://habr.com/ru/post/1629819/


All Articles