【问题标题】:Generate random number but exclude multiple ranges without looping生成随机数但排除多个范围而不循环
【发布时间】:2020-03-05 03:14:45
【问题描述】:

我正在寻找一种数学方法来生成 [a, b) 之间的随机数,在 [c, d)、[e, f)、[g, h) 等处有孔,其中 a

我在这里找到了许多示例,说明如果缺少一个范围,如何使算法起作用,但似乎无法找到一种可以推广到多个范围的空间/时间有效方法。我的意思是:

一个。所有可能范围的列表并从该列表中选择:不适用于大范围

b.生成一个随机数并检查它是否是范围之一,否则重试:运行时的无限项

一些突出的测试用例可能是:

generate_random(start=0, end=100, exclude: [(2,50),(51, 100)])
generate_random(start=0, end=1e16, exclude: [(1e6,1e7),(1e3, 1e4)])

以下是我找到的一些示例:

【问题讨论】:

    标签: algorithm pseudocode


    【解决方案1】:

    所以您想选择a..c-1d..e-1、...、x..b-1 中的任何一个?

    所以N = (c-a) + (e-d) + ... + (b - x)。在0..N-1 中随机选择r。如果r < c,你就完成了。设置r = r + d,如果r < e,就完成了……

    【讨论】:

    • 如果有 M 个范围(其中 M 很大),那么我们有一个线性搜索 (O(M)) 来确定 r 的偏移量。按范围进行特殊二进制搜索会更快(O(log M))。
    • 啊这更有意义,好吧,现在如果我想将它扩展到二维呢。 (即,我最初的目标是在预设宽度和高度的图像中找到未占用的边界框)这里会出现的问题是,如果我不能在特定范围内制作特定高度的框,我会有更多限制也应该排除在外。
    • @Adithya:我猜你的意思是对于a..c-1d..e-1x 的每个范围,y 都有一组不同的范围?在选择x的过程中,需要注意x在哪个范围内——比如rx = 0对应a..c-1rx = 1对应d..e-1等等。然后根据rx 范围集。
    • @ChrisHall 是有道理的,有没有一种简洁的方法可以以类似于上面 N 的计算的方式概括它,或者我是否需要维护某种查找表来跟踪我的约束是相对于 x 的 y。我还将在 python 中的一些代码下面发布我自己的解决方案,这些代码实现了你上面的内容。
    • @ChrisHall 我意识到我之前的问题可能超出了上述问题的范围,所以我总结了我的新尝试并提出了一个新问题:stackoverflow.com/questions/60533510/…
    【解决方案2】:

    下面是来自@Chris Hall 回答的上述算法的 Python 实现

    def random_exclude(low: int, high: int, exclude: List[Tuple[int]]) -> int:
      N = -low+sum([(l-h) for l,h in exclude])+high
      r = np.random.randint(low, N)
      for l, h in exclude:
        if r < l:
          return r
        else:
          r+=h
      return r
    

    【讨论】:

      猜你喜欢
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-22
      相关资源
      最近更新 更多