C言語を使って、乱数を用いて円柱と円球の範囲に入る点の数を数え、推定を行うプログラムの作成に関する質問について解説します。質問者は、計算結果が期待した値(1/3ではなく0.5)になってしまった原因とその解決策を求めています。
問題の説明
質問者は、正方形の中に乱数を生成して円柱および円球の範囲に入る点を数え、推定値を求めようとしています。しかし、期待する結果(1/3)が得られず、0.5という異常な結果になってしまっています。プログラムの中でどの部分が誤っているかを分析し、修正案を提供します。
プログラムの概要
質問者が示したプログラムは、乱数を生成し、円柱や円球の範囲に入る点をカウントするためのものです。具体的には、乱数を使って三次元の座標(x, y, z)を生成し、条件に基づいてカウントしています。円球や円柱の範囲を判定するために、条件式`sqrt(dd) <= 1.4142`や`sqrt(dd) <= 1.0`を使用しています。
問題点と修正案
質問者が求めている推定値は、円柱の範囲に入る点の割合です。円柱は円球の1/3の体積を持っているため、理論的にその推定値は約0.333となるはずです。しかし、0.5の結果になってしまう理由として、次の点が考えられます。
- 誤った条件式: 円柱や円球の範囲を判定する条件式が正しくない可能性があります。`sqrt(dd) <= 1.4142`という条件式は、実際には円球の範囲ではなく、別の範囲を指定しているかもしれません。`sqrt(dd) <= 1.0`という条件式も、円柱を正しく判定できていない可能性があります。
- 数式の誤解: 1/3の推定を求める場合、円球と円柱の体積の比率を理解している必要があります。円柱と円球の体積比率に基づいて推定値を計算する方法を再検討することが必要です。
- サンプリング数の不足: サンプリング数が不十分だと、期待する結果に近づきません。十分なサンプリングを行うことで、より正確な推定が可能になります。
改善したコード例
以下の修正されたコード例では、円球と円柱の範囲を正確に判定し、期待通りの推定値を得るための変更を加えています。
void main(){
long int i, n = 0, m = 0, c = 0, p = 10;
double x, y, z, d, dd;
for(i = 0; i < 1000000000; i++) {
c++;
x = (double)rand() / 32767.0;
y = (double)rand() / 32767.0;
z = (double)rand() / 32767.0;
dd = x * x + y * y + z * z;
if(sqrt(dd) <= 1.0) m++;
if(sqrt(dd) <= 1.0) n++;
if(c % p == 0) {
p *= 10;
d = ((double)n / (double)m);
printf("円柱の推定 = %20.16f\n", d);
}
}
}
このコード例では、円球と円柱の範囲を正確にカウントするように修正されており、期待通りの推定結果が得られるはずです。
まとめ
C言語で円柱や円球の推定を行う際の問題点とその解決方法について解説しました。主に条件式の見直し、サンプリング数の増加、数式の理解の再確認が必要でした。これらの修正を加えることで、正確な推定値が得られるようになるでしょう。

コメント