我正在尝试使用蒙特卡罗模拟来估计pi的值。我需要使用两个与原点相距用户输入距离的单位圆。我理解这个问题如何适用于单个圆圈,我只是不明白我是如何使用两个圆圈的。这是我到目前为止所得到的(这是我用于前一个问题的修改代码,使用了一个半径为2的圆。
import random
import math
import sys
def main():
numDarts=int(sys.argv[1])
distance=float(sys.argv[2])
print(montePi(numDarts,distance))
def montePi(numDarts,distance):
if distance>=1:
return(0)
inCircle=0
for I in range(numDarts):
x=(2*(random.random()))-2
y=random.random()
d=math.sqrt(x**2+y**2)
if d<=2 and d>=-2:
inCircle=inCircle+1
pi=inCircle/numDarts*4
return pi
main()
我需要更改此代码才能使用2个单位圆,但我不明白如何使用三角函数来做这个,或者我是否在思考这个问题?无论哪种方式帮助将被欣赏,因为我继续试图解决这个问题。 我所知道的是我需要改变X坐标,以及确定“d”的等式(d = math.sqrt(x * 2 + y * 2)),我只是不确定如何。
这些是我的指示 -
编写一个名为mcintersection.py的程序,该程序使用蒙特卡罗方法 估计这个形状的面积(并打印结果)。你的程序应该采取 两个命令行参数:distance和numDarts。距离参数 指定圆与x轴上的原点相距多远。所以,如果距离 为0,则两个圆都以原点为中心,并完全重叠。如果 距离为0.5,则一个圆心((-0.5,0)为中心,另一个圆为(0.5,0)。如果 距离是1或更大,那么圆圈根本不重叠!在最后一种情况下,你的 程序可以简单地输出0. numDarts参数应该指定数字 随机点在蒙特卡罗过程中选择。
在这种情况下,矩形应该是2个单位高(顶部在y = 1和 底部在y = -1)。您也可以安全地将矩形设为2个单位宽,但这样 通常比必要的要大得多。相反,你应该弄清楚 根据距离参数确定形状的宽度。那样你就可以 尽可能使用像瘦的矩形。
答案 0 :(得分:1)
如果我正确理解了问题,您有两个以(distance, 0)
和(-distance, 0)
为中心的单位圆(也就是说,一个位于原点右侧,一个位于左侧)。您正在尝试确定给定点(x, y)
是否在两个圈内。
最简单的方法可能是简单地计算每个圆的点和中心之间的距离。您已经在之前的代码中完成了此操作,只需重复计算两次,一次偏移偏移距离,然后使用and
查看您的点是否在两个圆圈中。
但更优雅的解决方案是注意你的两个圆圈如何在y
- 轴上完全相交。在轴的右侧,左侧圆圈完全包含在右侧。在y
- 轴的左侧,右侧圆圈完全位于左侧圆圈内。由于形状是对称的,两半的大小完全相同。
这意味着你可以限制你的飞镖只能击中轴的一侧,然后通过一次距离测试就可以逃脱:
def circle_intersection_area(num_darts, distance):
if distance >= 1:
return 0
in_circle = 0
width = 1-distance # this is enough to cover half of the target
for i in range(num_darts):
x = random.random()*width # random value from 0 to 1-distance
y = random.random()*2 - 1 # random value from -1 to 1
d = math.sqrt((x+distance)**2 + y**2) # distance from (-distance, 0)
if d <= 1:
in_circle += 1
sample_area = width * 2
target_area = sample_area * (in_circle / num_darts)
return target_area * 2 # double, since we were only testing half the target