在环空中创建随机数

mad*_*ast 8 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
Run Code Online (Sandbox Code Playgroud)

但这很慢.是否有可能提供更多的约束random.uniform或是否有另一种方法?

dmc*_*kee 18

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

直接绘制使用

  • 在[0,2pi]上统一绘制theta: theta = random.uniform(0,2*pi)
  • 幂律分布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)
    
    Run Code Online (Sandbox Code Playgroud)

    暗示

    r = sqrt(2*random.uniform(0,1)/A + r_min*r_min)
    
    Run Code Online (Sandbox Code Playgroud)

    你可以略微简化.

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

这种集成PDF,归一化CDF和反转的方法是通用的,有时被称为"采样的基本定理".

拒绝

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

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