はじめに
円の周りの長さや面積を求める際に使用される円周率は、小学校5年生で学習し、その値は3.14から無限に続くことが知られています。既に小数点以下、数百兆桁まで求められているものの、実際の計算で使用する際は数桁~十数桁あれば十分です。
日本語プログラミング言語「なでしこ」では、PIと記述することで、小数点以下15桁の円周率を利用できるようになります。
一方で、こうした円周率を求めるにはどうすれば良いのでしょうか。少し調べていると複数の円周率の求め方が考案されているようでした。
このうち、「モンテカルロ法」を用いた円周率の求め方は、非常に単純であり、情報の教員向けの研修用教材(第3章 学習16 演習3)でも取り上げられています。(なお、なぜ「モンテカルロ法」で円周率を求めることが出来るのかについては、別の方の記事を参照してください)
ということで今回は、なでしこにより、シミュレーションを用いたモンテカルロ法によって、円周率の近似値を求めてみたいと思います。
コードを書いてみる
事前準備
まずは分かりやすくするために、図を表示してみたいと思います。とりあえず、300×300の大きさの四角形を描画し、ついでに「描画開始ボタン」も作成しておきます。加えて、ボタンを押した時に、座標(100,100)に点を打つことにしたいと思います。これをまとめると以下のようなコードになります。
白色に塗色設定
[0,0,300,300]に四角描画
黒色に塗色設定
「描画開始」のボタン作成して、それをクリックした時には
[100,100]に1の円描画
ここまで
実行してみると、下の図のように点が打たれます。これで準備は完了です。
さて、モンテカルロ法による円周率の算出方法では、この正方形の中にランダムで点を打ちます。そこで乱数を用いて、X座標とY座標を決め、その場所に点を打つことにします。
白色に塗色設定
[0,0,300,300]に四角描画
黒色に塗色設定
「描画開始」のボタン作成して、それをクリックした時には
《X座標》=300の乱数
《Y座標》=300の乱数
[《X座標》,《Y座標》]に1の円描画
ここまで
上記のようなプログラムを実行すると、以下のように、正方形の中のランダムな箇所に点が配置されます。これは実行する度に変化し、また「描画開始」ボタンを押す毎に点が増えていきます。
ボタンを何十回もポチポチするのは疲れるので、繰り返しを利用して、一気に100個の点を生成するようにしましょう。
白色に塗色設定
[0,0,300,300]に四角描画
黒色に塗色設定
「描画開始」のボタン作成して、それをクリックした時には
100回繰り返す
《X座標》=300の乱数
《Y座標》=300の乱数
[《X座標》,《Y座標》]に1の円描画
ここまで
ここまで
このプログラムを実行することで、正方形の中に100個の点を打つことが出来ました。
円周率を求めてみる
さて、いよいよ円周率を求めてみたいと思います。前述のサイトによると以下の公式に従って計算することで円周率を求めることが出来るようです。
\pi = 4 \times \frac{ 原点からの距離が1辺の長さ以下の点の数 }{打った点の合計}
そこで変数《カウント》を作成し、原点からの距離が1辺の長さ以下の点の数を求めたいと思います。今回は、正方形の1辺の長さを300としているので、原点(0,0)と点(《X座標》,《Y座標》)の距離が300以下の点の数を数えればよいということです。2点間の距離は、三平方の定理を利用することで求めることが出来るので、《X座標》の二乗と《Y座標》の二乗を足して、平方根を取ることで距離を求められます。
これを踏まえて、以下のようなプログラムに改造してみましょう。
白色に塗色設定
[0,0,300,300]に四角描画
黒色に塗色設定
「描画開始」のボタン作成して、それをクリックした時には
《カウント》=0
100回繰り返す
《X座標》=300の乱数
《Y座標》=300の乱数
[《X座標》,《Y座標》]に1の円描画
《距離》=(《X座標》^2+《Y座標》^2)の平方根
もし《距離》が300以下なら
《カウント》=《カウント》+1
ここまで
ここまで
4*《カウント》÷100を表示
ここまで
このコードを実行すると以下のようになります。何度か実行してみたところ、整数部分はほぼブレませんが、小数第1位以下はあまり正確な値にはなりませんでした。
注意
上記プログラムでは演算子^を用いて二乗を求めています。一方でよく似た命令として二乗という命令もあります。この2つはよく似ているようで、前者が演算子なのに対し、後者が関数という違いがあります。よって、直観に反するようですが、以下のプログラムの実行結果は異なるものとなります。注意してください(私自身、この違いに気づかず、数十分を悩んでいた為)。
(3^2+4^2)を表示 //→25と表示
(3の二乗+4の二乗)を表示 //→169と表示
値を大きくしよう
さて、このモンテカルロ法による円周率の近似値の算出方法は、打つ点の数を増やせば増やすほど、正確に近似していく性質があります。そこで、100個の点ではなく、100万個の点を打つことにしてみましょう。
ついでに、線色設定を調整し、視覚的に分かりやすいよう、変数《距離》が300以下の点を赤色に、そうでない点を青色に色分けして、表示してみましょう。
白色に塗色設定
[0,0,300,300]に四角描画
「描画開始」のボタン作成して、それをクリックした時には
《カウント》=0
1000000回繰り返す
《X座標》=300の乱数
《Y座標》=300の乱数
《距離》=(《X座標》^2+《Y座標》^2)の平方根
もし《距離》が300以下なら
《カウント》=《カウント》+1
赤色に線色設定
違えば
青色に線色設定
ここまで
[《X座標》,《Y座標》]に0.01の円描画
ここまで
4*《カウント》÷1000000を表示
ここまで
こちらを実行した場合、例えば、以下の写真のようになります。
何度か実行してみたところ、小数第1~2位ぐらいまでは正確に求められるものの、それ以下の数はあまり当てはまらない様子が見られました。
おわりに
こうした、乱数を基にしたシミュレーションは、様々なところで利用されています。また、中学校や高等学校でも、プログラミングを用いたシミュレーションについての授業、というのは導入されていくことと考えられます。そんな中で、日本語プログラミング言語「なでしこ」がさらに広がれば良いな、と思っています。
以上。




