1

モンテカルロ シミュレーションを使用して pi の値を推定しようとしています。原点からのユーザー入力距離である 2 つの単位円を使用する必要があります。この問題が単一の円でどのように機能するかは理解していますが、2 つの円を使用する方法がわかりません。これが私がこれまでに得たものです(これは、半径2の1つの円を使用した以前の問題に使用した変更されたコードです.

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 の 2 つのコマンド ライン パラメータを使用する必要があります。距離パラメーターは、円が x 軸の原点からどれだけ離れているかを指定します。したがって、距離が 0 の場合、両方の円は原点を中心とし、完全に重なります。距離が 0.5 の場合、1 つの円は (-0.5, 0) を中心とし、もう 1 つの円は (0.5, 0) を中心とします。距離が 1 以上の場合、円はまったく重なりません! 最後のケースでは、プログラムは単純に 0 を出力できます。numDarts パラメータは、モンテカルロ プロセスで選択するランダム ポイントの数を指定する必要があります。

この場合、長方形の高さは 2 単位である必要があります (上部が y = 1、下部が y = -1)。長方形を安全に 2 単位幅にすることもできますが、これは通常、必要以上に大きくなります。代わりに、距離パラメーターに基づいて、形状の幅を正確に把握する必要があります。そうすれば、できるだけ細い長方形を使用できます。

4

1 に答える 1

1

私が問題を正しく理解していれば、 and を中心とする 2 つの単位円が(distance, 0)あります(-distance, 0)(つまり、1 つは原点のわずかに右に、もう 1 つはわずかに左に)。(x, y)特定の点が両方の円内にあるかどうかを判断しようとしています。

最も単純な方法は、点と各円の中心との間の距離を単純に計算することです。前のコードで既にこれを行っています。計算を 2 回繰り返し、1 回はオフセット距離を反転させてから、 を使用andしてポイントが両方の円内にあるかどうかを確認します。

yしかし、より洗練された解決策は、2 つの円が -軸上で正確に交差する方法に注目することです。軸の右側では、左の円が右の円に完全に含まれています。軸の左側ではy、右の円は完全に左の円の中に入っています。また、形状が対称であるため、2 つの半分のサイズはまったく同じです。

これは、ダーツを軸の片側のみに当てるように制限し、1 回の距離テストだけで済むことを意味します。

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
于 2014-03-01T04:50:07.117 に答える