モンテカルロ法と円周率について。【数学】
今年もあと残すところ1ヶ月となった今日この頃、
皆さんいかがお過ごしでしょうか。
どうも、”とりすてぃっく”です。
みなさんは、ふとしたときに円周率を求めてみたいと
思ったことはありますか?
もちろん私はあります。
でも、どうやって円周率を求めるんだろう?
円周率を求めるって大変じゃないの?
と思う人も多いでしょう。
しかし、そんな心配はいりません!
めちゃくちゃ簡単に、しかもお手軽に円周率を求める方法が
あるんですよ。
今回はそれを紹介していこうと思います。
ちなみに、今回の見出し画像は『Edge』で作りました。
モンテカルロ法ってなに?
まずはこの記事のタイトルにある、
モンテカルロ法について紹介していきます。
モンテカルロ法とは、乱数を使っていろんな値を求めるというやつです。
今回は円周率を求めるために使っていきます。
まずは、こんな感じで正方形とその中にピッタリ収まる正円をかきます。
そしたら、この正方形の中にランダムに点を打ち込んでいきます。
すると、こんな風になると思います。
ここで、(円の内側にある点の数)÷(全体の点の数)× 4を求めると、
$${40 / 46 \times 4 = 3.478…}$$となります。
今回はうまくいきませんでしたが、点の数を増やしていけば、
3.14159265… に近づいていきます。
このようにして円周率を求めるのがモンテカルロ法です。
なんで求められるのかというと、
円の半径を r とおくと、図形の面積は、
正方形の面積:$${(2r)^2 = 4r^2}$$
円の面積:$${\pi r^2}$$
このようになるので、
打たれる点が円の中に入っている確率は、
$$
\frac{\pi r^2}{4r^2} = \frac{\pi}{4}
$$
こんな感じになります。ちなみに、πは円周率のことです。
そのため、点をどんどん打っていけばこの値に近づくはずなので、
ここに4をかければ円周率が出せるというわけです。
私は小学生の頃は、これで時間を潰していました。
もっと簡単に求めるには
モンテカルロ法の最大の欠点は、打った点を数えるのが
とてつもなく面倒くさいということです。
これを解消するために、プログラミングをして、
自動で計算してくれるものを作っていきます。
今回は『Python』を使いました。
import random
points = 500
inside = 0
for i in range(points):
x = random.uniform(0,2)
y = random.uniform(0,2)
if (x - 1)**2 + (y - 1)**2 <= 1:
inside += 1
print(inside / points * 4)
とりあえず、簡易的なものを作ってみました。
変数pointsは、打った点の数で、
変数insideは、円の内側の点の数を表しています。
条件文にある$${(x-1)^2+(y-1)^2 \leqq 1}$$は、
中心が(1,1)の半径1の円の中に
点が入っているのかいないのかを判別しています。
もしもよく分からかったら、円の方程式について調べて下さい。
これを実行すると、
こんな感じでバラツキはありますが、3.14に近い値が出せます。
Tkinterでモンテカルロ法の図を描画する
先ほどのコードでは、値のみしか出せないので、
ここでは『Tkinter』を使って図形を描画していこうと思います。
コードはこんな感じです。
import random
import tkinter as tk
root = tk.Tk()
root.geometry("500x500")
canvas = tk.Canvas(root, bg = "white")
canvas.pack(fill = tk.BOTH, expand = True)
canvas.create_rectangle(50,50,450,450)
canvas.create_oval(50,50,450,450)
points = 2000
inside = 0
for i in range(points):
x = random.uniform(0,2)
y = random.uniform(0,2)
if (x - 1)**2 + (y - 1)**2 <= 1:
inside += 1
canvas.create_oval(x*200+47, y*200+47, x*200+53, y*200+53, fill="blue")
pi = tk.Label(root, text = (inside / points * 4))
pi.place(x=30,y=470)
root.mainloop()
基本的には、
root = tk.Tk()
root.geometry("500x500")
canvas = tk.Canvas(root, bg = "white")
canvas.pack(fill = tk.BOTH, expand = True)
ここの部分で、キャンバスを作っています。
そして、図形の描画は、
canvas.create_rectangle(50,50,450,450)
canvas.create_oval(50,50,450,450)
canvas.create_oval(x*200+47, y*200+47, x*200+53, y*200+53, fill="blue")
こいつらがやっています。
create_rectangle()は、四角形を描画するやつで、
create_oval()は、円を描画するやつです。
円周率の値を表示するのは、
pi = tk.Label(root, text = (inside / points * 4))
pi.place(x=30,y=470)
ここの部分でやっています。
これを実行すると、(以下集合体恐怖症注意)
こんな感じになります。
出された値は、3.184のようです。
円周率との誤差は、約0.04というかなりいい感じの値が出ました。
もっと点を多くすればより近い値が出せると思います。
他にもたくさんの円周率を求める方法があるので、
気になった方はいろいろ調べてみても面白いのではないでしょうか。
ビュフォンの針、多角形の近似、etc…
ちょっとしたお知らせ
ここでは本当にちょっとしたお知らせをします。
クリエイターページのヘッダー画像を変更しました。
前のやつは、"Welcome to とりすてぃっく"って書かれていたんですが、
よくよく考えたらこれっておかしくないかと思い、
変更しました。
"Welcome to とりすてぃっく"だと、"とりすてぃっく"が
場所みたいな感じだったから…
以上ちょっとしたお知らせでした。