我正在尝试生成一个环形内的随机数,即我们有一个最大和最小半径。我试过了:
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
提供更多的约束,还是有另一种方法?
答案 0 :(得分:18)
通常,您可以直接绘制正确的分布或使用拒绝。
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)
请注意,这会产生轻度不均匀的结果(每单位角度的点数不变,而不是每单位面积)。