Arrays 从R中至少具有最小差异的数组中拾取随机元素的最佳方法

Arrays 从R中至少具有最小差异的数组中拾取随机元素的最佳方法,arrays,r,random,Arrays,R,Random,我想从一个数组中随机选择一定数量的元素,这些元素的相互距离总是有一个限制。 例如,有一个向量a我认为在某种意义上保证随机性的最佳解决方案可能是: 选择一个随机元素 删除所有与该图元过近的图元 选择另一个元素 返回到2 因此: minu dist我认为在某种意义上保证随机性的最佳解决方案可能是: 选择一个随机元素 删除所有与该图元过近的图元 选择另一个元素 返回到2 因此: min_dist如果您想避免命中和未命中方法,您必须将问题转化为距离采样,并对距离总和进行约束 基本上,我是如何翻译你想要的

我想从一个数组中随机选择一定数量的元素,这些元素的相互距离总是有一个限制。
例如,有一个向量
a我认为在某种意义上保证随机性的最佳解决方案可能是:

  • 选择一个随机元素
  • 删除所有与该图元过近的图元
  • 选择另一个元素
  • 返回到2
  • 因此:


    minu dist我认为在某种意义上保证随机性的最佳解决方案可能是:

  • 选择一个随机元素
  • 删除所有与该图元过近的图元
  • 选择另一个元素
  • 返回到2
  • 因此:


    min_dist如果您想避免命中和未命中方法,您必须将问题转化为距离采样,并对距离总和进行约束

    基本上,我是如何翻译你想要的:你的N个采样位置相当于N+1距离,范围从最小距离到向量-N*心智者的大小(你所有的样本都打包在一起的情况)。然后需要将距离之和限制为1000(向量的大小)

    在这种情况下,解决方案将使用来自代理包(请参阅)的代理::RandVec,它允许使用固定和进行采样

    library(Surrogate)
    a <- seq(1,1000)
    mind <- 15
    N <- 20
    dist <- Surrogate::RandVec(a=mind, b=(1000-(N)*mind), s=1000, n=(N+1), m=1, Seed=sample(1:1000, size = 1))$RandVecOutput
    pos <- cumsum(round(dist))[1:20]
    pos
    
    > pos
     [1]  22  59  76 128 204 239 289 340 389 440 489 546 567 607 724 773 808 843 883 927
    
    库(代理)
    
    a如果您想避免命中和未命中方法,您必须将问题转化为距离采样,并限制距离总和

    基本上,我是如何翻译你想要的:你的N个采样位置相当于N+1距离,范围从最小距离到向量-N*心智者的大小(你所有的样本都打包在一起的情况)。然后需要将距离之和限制为1000(向量的大小)

    在这种情况下,解决方案将使用来自代理包(请参阅)的代理::RandVec,它允许使用固定和进行采样

    library(Surrogate)
    a <- seq(1,1000)
    mind <- 15
    N <- 20
    dist <- Surrogate::RandVec(a=mind, b=(1000-(N)*mind), s=1000, n=(N+1), m=1, Seed=sample(1:1000, size = 1))$RandVecOutput
    pos <- cumsum(round(dist))[1:20]
    pos
    
    > pos
     [1]  22  59  76 128 204 239 289 340 389 440 489 546 567 607 724 773 808 843 883 927
    
    库(代理)
    
    a这个问题在python中类似,但在我看来,它缺少随机化过程:一个解决方案是,如果您有一个类似于
    a
    的范围,则在最后一个选择中添加一个随机数:
    picked[i]感谢您的测试!!看起来dash2的答案在大多数情况下都更快,分布也更平滑(与我的答案相比,使用dash2的答案,位置的历史图非常平坦)。我认为距离分布应该是这样的,峰值应该是1000/20=50。通过位置分布图(应该是平的)更容易检查。我还添加了这个分析,看起来你是对的;)这个问题在python中类似,但在我看来,它缺少随机化过程:一个解决方案是,如果您有一个类似于
    a
    的范围,则在最后一个选择中添加一个随机数:
    picked[i]感谢您的测试!!看起来dash2的答案在大多数情况下都更快,分布也更平滑(与我的答案相比,使用dash2的答案,位置的历史图非常平坦)。我认为距离分布应该是这样的,峰值应该是1000/20=50。通过位置分布图(应该是平的)更容易检查。我还添加了这个分析,看起来你是对的;)如我的编辑所示,你的答案是最快和最可靠的。谢谢!只需做一点小小的更改,就可以确保在最后一次运行时不会调用
    stop
    。这太棒了!谢谢,我也更新了我的答案评论:)如我的编辑所示,你的答案是最快和最可靠的。谢谢!只需做一点小小的更改,就可以确保在最后一次运行时不会调用
    stop
    。这太棒了!谢谢,我还更新了我的答案评论:)
    pa <- ggplot() + theme_classic() +
      geom_density(aes_string(x = dist_vec), fill = 'lightgreen') +
      geom_vline(aes_string(xintercept = mean(dist_vec)), col = 'darkred') + xlab('Distances')
    pb <- ggplot() + theme_classic() +
      geom_density(aes_string(x = dist_vec2), fill = 'lightgreen') +
      geom_vline(aes_string(xintercept = mean(dist_vec)), col = 'darkred') + xlab('Distances')
    print(pa)
    print(pb)
    
    comp_times <- microbenchmark::microbenchmark(
      'solution_1' = rand_pick_min(a, md, np),
      'solution_2' = rand_pick_min2(a, md, np),
      times = 500
    )
    ggplot2::autoplot(comp_times); ggsave('stckoverflow2.png')
    
    min_dist <- 15
    a <- seq(1, 1000)
    picked <- integer(20)
    copy <- a
    for (i in 1:20) {
      stopifnot(length(copy) > 0)
      picked[i] <- sample(copy, 1)
      copy <- copy[ abs(copy - picked[i]) >= min_dist ]
    }
    
    library(Surrogate)
    a <- seq(1,1000)
    mind <- 15
    N <- 20
    dist <- Surrogate::RandVec(a=mind, b=(1000-(N)*mind), s=1000, n=(N+1), m=1, Seed=sample(1:1000, size = 1))$RandVecOutput
    pos <- cumsum(round(dist))[1:20]
    pos
    
    > pos
     [1]  22  59  76 128 204 239 289 340 389 440 489 546 567 607 724 773 808 843 883 927