在环空中创建随机数

时间:2012-01-28 19:56:24

标签: python random

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

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提供更多的约束,还是有另一种方法?

2 个答案:

答案 0 :(得分:18)

通常,您可以直接绘制正确的分布或使用拒绝。

直接使用

  • 在[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 = 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(x x + y y)超过r_max或小于r_min的情况。

如果中间的孔很小,这是合理有效的,如果孔很大,效率非常低。

答案 1 :(得分:-2)

您正在使用的方法对于厚环(其中r1 <&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; r2)如果你用窄环(r2-r1&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

r = random.uniform(r1, r2)
theta = random.uniform(0, 2 * PI)
x = r * math.sin(theta)
y = r * math.cos(theta)

请注意,这会产生轻度不均匀的结果(每单位角度的点数不变,而不是每单位面积)。