Схема Бернулли с большим количеством испытаний - исправление ошибок в коде - C (СИ)
Формулировка задачи:
double BernulliProb (int m, int n, double p, double q)//m - благоприятствующие исходы, n - всего исходов
{
double C = 1;
int i;
double ber = 1;
double buf = 1;
for (i = 1; i <= n; i++)
{
if (i < N)
{
buf = (N - i + 1);
buf = buf / i;
C = buf * C * p;
}
else
{
C = 1.0000 * pow(p, N);
}
if(i <= N - n)
{
C = C * q;
}
}
ber = C;
if(N - n > n)
{
for (i = n + 1; i <= N - n; i++)
{
ber = ber * q;
}
}
printf("%.100lf", ber);
}
Полный код программы:
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <Windows.h>
double BernulliProb (int m, int n, double p, double q)//m - благоприятствующие исходы, n - всего исходов
/*{
double C = 1;
int i;
double ber = 1;
double buf = 1;
for (i = 1; i <= n; i++)
{
if (i < N)
{
buf = (N - i + 1);
buf = buf / i;
C = buf * C * p;
}
else
{
C = 1.0000 * pow(p, N);
}
if(i <= N - n)
{
C = C * q;
}
}
ber = C;
if(N - n > n)
{
for (i = n + 1; i <= N - n; i++)
{
ber = ber * q;
}
}
printf("%.100lf", ber);
}*/
{//p - вероятность благоприятствующего исхода, q - вероятность не благоприятствующего исхода
double prob = 1.0;
int count=0;
int k = n - m;
int l = 0;
for (int i = 0; i < m; i++)
{
prob *= double (n - i) / double (m - i) * p;//C n по m, * p^m
if(l != k)//если l == (n - m) т.е. q, было умножено k раз, т.е. вероятность неблагоприятных исходов перемножена в нужную стпе
{
prob *= q;
l++;
}
// printf("\n%d\n%d*%.2lf*%.2lf = %.200lf\n", n-i,m - i,p, q, prob);
}
if(l < k)
{
printf(" OK");
for(int i = l; i < k; i++)
{
prob *= q;
l++;
}
}
printf(" LLLLL = %d\n", l);
printf("\n\nPROB = %.30lf\n\n", prob);
return prob;
}
/*for (i = 1; i <= n; i++)
{
if (i < N)
{
buf = (N - i + 1);
buf = buf / i;
C = buf * C * p;
}
else
{
C = 1.0000 * Math.Pow(p, N);
}
if(i <= N - n)
{
C = C * q;
}
}
ber = C;
if(N - n > n)
{
for (i = n + 1; i <= N - n; i++)
{
ber = ber * q;
}
}
}*/
double MoivreLaplaceProb (int m, int n, double p, double q)
{
double prob = 0.0;
double xNorm = ( (m - n*p) / sqrt (n*p*q) );
prob = ( 1.0 / sqrt (2.0*M_PI*n*p*q) ) * exp (-0.5* pow (xNorm, 2.0));
return prob;
}
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
int n = 2400, k = 1200; // n - всего исходов, к - благоприятствующие исходы
double p = 0.7; // вероятность благоприятствующего исхода
printf ("Введите:\nn - общее количество исходов\nк - количество благоприятствующих исходов\np - вероятность благоприятствующего исхода\n");
scanf ("%d %d %lf", &n, &k, &p);
while ( ( (p < 0.0) || (p > 1.0) ) || k >= n )
{
printf ("Неверные данные! Введите n, k, p еще раз\n");
scanf ("%d %d %lf", &n, &k, &p);
}
double q = 1.0 - p;
double diff = 0.0;// разница значений по Бернулли и М-Л
double dBernulli = BernulliProb(k, n, p, q);
double dML = MoivreLaplaceProb(k, n, p, q);
printf ("\n\nn = %d\t\t\t%d\nnpq = %.1lf\t\t%d\n", n, (n > 100), n*p*q, (n*p*q > 20) );
printf ("\nВероятность по Бернулли:\nP = %.200lf\n\n", dBernulli);
printf ("Приближенное значение по Муавру-Лапласу:\nP = %.200lf\n", dML);
diff = fabs (dBernulli - dML) / dBernulli;
printf ("\nАбсолютная погрешность %.100lf \n", fabs (dBernulli - dML ));
printf ("Относительная погрешность %.3lf % \n", 100*diff);
getch();
}
}Решение задачи: «Схема Бернулли с большим количеством испытаний - исправление ошибок в коде»
textual
Листинг программы
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
#include <locale>
#include <Windows.h>
double binomial(long n, long k){
//если k больше n, очевидно что выбрать у нас ничего не получиться
if(n < k || 0 == n){
return 0;
}
//если они равны, то способ только один, как не поверни
if(n == k){
return 1;
}
//считаем m, он будет постоянен
long m = n - k;
long i;
//тут будет храниться результат
double b = 1;
//эти переменные вводятся, чтобы исключить преобразование типов в каждой итерации
double k1 = k;
double m1 = m;
if(k <= m){
//если первый случай, k меньше чем m
for(i = 1; i <= k; i++){
//перемножаем наш ряд
b *= 1 + m1 / i;
}
}else{
//второй случай, противоположный
for(i = 1; i <= m; i++){
//перемножаем другой ряд
b *= 1 + k1 / i;
}
}
//возвращаем округлённое значение
return round(b);
}
//формула Бернулли для вероятности, вычисляет вероятность того, что среди n событий
//произойдёт m событий с вероятностью p
double BernulliProb(long n, long m, double p){
return binomial(n, m) * pow(p, m) * pow(1.0 - p, n - m);
}
double MoivreLaplaceProb (int m, int n, double p, double q)
{
double prob=0.0;
double xNorm=((m-n*p)/sqrt(n*p*q));
prob=(1.0/sqrt(2.0*M_PI*n*p*q))*exp(-0.5*pow(xNorm, 2.0));
return prob;
}
int main()
{
setlocale(LC_ALL, "Russian");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
int n = 2400, k = 1200; // n - всего исходов, к - благоприятствующие исходы
double p = 0.7; // вероятность благоприятствующего исхода
printf ("Vvedite:\nn - obschee kol-vo iskhidov\nk - kol-vo blagopr iskhodov\np - veroyatnost' blagopr iskhoda\n");
scanf ("%d %d %lf", &n, &k, &p);
while ( ( (p < 0.0) || (p > 1.0) ) || k >= n )
{
printf ("Wrong data! Enter n, k, p again\n");
scanf ("%d %d %lf", &n, &k, &p);
}
double q = 1.0 - p;
double diff = 0.0;// разница значений по Бернулли и М-Л
double dBernulli = BernulliProb(k, n, p);
double dML = MoivreLaplaceProb(k, n, p, q);
printf ("\n\nn = %d\t\t\t%d\nnpq = %.1lf\t\t%d\n", n, (n > 100), n*p*q, (n*p*q > 20) );
printf ("Bernulli:\nP = %.200lf\n\n", dBernulli);
printf ("PRIBL (Moivre-Laplace):\nP = %.200lf\n", dML);
diff = fabs (dBernulli - dML) / dBernulli;
printf ("\nABS %.100lf \n", fabs (dBernulli - dML ));
printf ("OTNOS %.3lf % \n", 100*diff);
getch();
}
Объяснение кода листинга программы
- В функции
binomialрассчитывается значение биномиального коэффициента. - В функции
BernulliProbиспользуется формула Бернулли для вероятности. - В функции
MoivreLaplaceProbрассчитывается вероятность по формуле М-Л. - В функции
mainвводятся исходные данные: n, k, p. - Выполняется проверка корректности введенных данных.
- Вычисляются значения вероятностей по формулам Бернулли и М-Л.
- Вычисляется разница между этими значениями.
- Выводится сообщение об ошибке, если данные введены некорректно.
- Выводится результат вычислений.