Почему я всегда получаю 2.8284 при оценке Пи с использованием PRNG?

Я новичок в C ++. Я пытаюсь статистически определить значение Pi на основе теоремы Эрнесто Чезаро, используя генератор случайных чисел компьютерной системы. Но то, что я сделал сейчас, может ввести начальное число и сгенерировать 100 псевдослучайных чисел, а затем оценить значение числа пи. Генератор может генерировать разные группы псевдослучайных чисел. Однако путаница в том, что я всегда получаю оценку числа пи для 2.8284 без изменений. Вот код:

#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int seed;
cout << "input a seed number: " << endl;
cin >> seed;
srand(seed);
int i, a[100];
for (i = 0; i < 100; i++)
a[i] = rand() % 100 + 1;
cout << "The generated random numbers are: " << endl;
for (i = 0; i < 100; i++)
cout << a[i] << "\t";
int m, n, j, r;
int  sum = 0;
for (j = 0; j < 100; j++)
{
m = a[j];
n = a[j + 1];
j = j + 2;
do
{
r = m%n;
m = n;
n = r;
} while (r != 0);
if (n = 1)
sum = sum + 1;
}
double Pi, p;
p = 300 / sum;
Pi = sqrt(p);
cout << "The estimate value of Pi is: " << Pi << endl;
system("pause");
return 0;
}

Обратите внимание, что теорема Чезаро утверждает, что для двух случайных чисел, x и y, вероятность того, что gcd (x, y) = 1, равна 6 / (Pi ^ 2). И используемый PRNG влияет на то, насколько близка полученная оценка к Pi (3.1416).

0

Решение

Есть несколько проблем с вашим кодом.

Проблема № 1:

if (n = 1)

Так должно быть if (n == 1) или вы назначаете 1 в n и всегда оценивать как истину.

Выпуск № 2:

      n = r;
} while (r != 0);
if (n == 1)

Если вы думаете об этом, цикл закончится только тогда, когда r является 0, но потом n также будет 0 из-за последней строки цикла. Так n никогда не будет равным 1, Вы, вероятно, хотите if (m == 1),

Выпуск № 3:

for (j = 0; j < 100; j++)
{
...
j = j + 2;

Вы увеличиваете j в for линия и в теле цикла. Тебе просто нужен один.

for (j = 0; j < 100; j += 2)
{
//no j increment

Выпуск № 4:

p = 300 / sum;

Это целочисленное деление, потому что оба числа являются целыми числами. Вы хотите точку воспламенения: p = 300.0 / sum;,

С этими изменениями я о 3.16,

5

Другие решения

У вас есть две ошибки в алгоритме. (не четыре: р)

Во-первых — числа взаимно просты, когда gcd не больше 1, также вы должны проверить m значение не n (см. ответ Родриго). Так что вам нужно изменить, если на это:

if (m <= 1)
sum = sum + 1; // ++sum;

Вторая ошибка — ваша оценка: p = 300 / sum;, Почему вы используете 300? Правильный:

float pi = sqrt ( 6.f * iterations / sum) // from p = 6 / pi^2

где iterations в вашем коде 34 (потому что вы меняете j-индекс в теле цикла).

0

Проблема в том, что у вас неправильная форма. Вместо отношения длины окружности к ее диаметру (pi) вы успешно оценили отношение длины окружности к его диагонали.

то есть квадрат со стороной 1 имеет окружность 4 и его диагональ будет:

sqrt (1 ^ 2 + 1 ^ 2) = sqrt (2)

Следовательно, отношение длины окружности к диагонали будет:

4: sqrt (2) = 2,8284

Просто измените квадрат на круг, и вы должны быть правы.

0
По вопросам рекламы [email protected]