【问题标题】:Create random number within an annulus在环内创建随机数
【发布时间】:2012-02-21 07:34:52
【问题描述】:

我正在尝试生成一个环内的随机数,即我们有一个最大和最小半径。我试着做:

while True:
    x=random.uniform(-maxR, maxR)
    y=random.uniform(-maxR, maxR)
    R=math.sqrt(x**2 + y**2)
    if R <= maxRadius and R >= minRadius:
        if x>= -maxRadius and x <= maxRadius and x<=-minRadius and x>= minRadius:
            print "passed x"
            if y>= -maxRadius and y <= maxRadius and y<=-minRadius and y>= minRadius: 
                break

但这很慢。是否可以向random.uniform 提供更多约束,或者有其他方法吗?

【问题讨论】:

  • 最后两个 if 语句是干什么用的?为什么仅仅检查R(半径)是否在范围内是不够的?
  • 可以总是预先生成数字并将它们存储在字典映射中。
  • 关于从非 unifrom PDF 尤其是圆圈中绘图的问题已经无穷无尽。这些问题的更好答案包含从任意可反转 PDF 中绘制的方法。

标签: python random


【解决方案1】:

一般来说,您可以直接绘制正确的分布,也可以使用拒绝。

直接绘制使用

  • 在 [0,2pi) 上均匀地绘制 theta:theta = random.uniform(0,2*pi)
  • the power-law distribution r^1 绘制 r。

    与对圆执行此操作相比,唯一的复杂性是 PDF 从 [r_min,r_max] 而不是 [0,r_max] 运行。这导致

    CDF = A \int_{r_min}^{r} r' dr' = A (r^2 - r_min^2)/2

    对于A,归一化常数

    A = 2/(r_max*r_max - r_min*r_min)
    

    暗示

    r = sqrt(2*random.uniform(0,1)/A + r_min*r_min)
    

    你可以稍微简化一下。

  • 然后通过通常的径向坐标变换计算 (x,y)
    x = r * cos(theta)
    y = r * sin(theta)

这种对 PDF 进行积分、归一化 CDF 和反转的方法是通用的,有时被称为“采样基本定理”。

拒绝

在一个足够大以包含环的框上绘制 (x,y),然后拒绝所有 `r = sqrt(xx + yy) 超过 r_max 或小于 r_min 的情况。

如果中间的洞很小,这是相当有效的,如果洞很大,则效率很低。

【讨论】:

  • 感谢您的信息。完全没有想到。
  • 我在 Mathematica 中绘制了这个解决方案:i.imgur.com/7L04w.png 它看起来漂亮且统一! :D
  • "你可以稍微简化一下。"我是否认为在一般情况下(假设您选择的语言支持它)可以简化为:r = sqrt(random.uniform(r_min*r_min,r_max*r_max))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-07
  • 2012-05-20
  • 2020-02-13
  • 2016-07-24
  • 1970-01-01
相关资源
最近更新 更多