我正在尝试生成一个环形内的随机数,即我们有一个最大和最小半径.我试过做:
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
通常,您可以直接绘制正确的分布或使用拒绝.
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的情况.
如果中间的孔很小,这是合理有效的,如果孔很大,效率非常低.