天天看點

機率算法求定積分的值

/*
           

* Abstract:

*           設a, b, c和d是實數,且a ≤ b, c ≤ d, 

*           f:[a, b] → [c, d]是一個連續函數,寫一機率算法計算積分的值。 

* Author :Ace.Ma

* Date:2012/9/18

* Version:0.1

*/

#include<iostream>

#include<ctime>

#include<cmath>

using namespace std;

//定義積分函數類型 

typedef double pFunc(double x);

double definiteIntegration(double x1, double x2, double y1, double y2,

                           unsigned long n, pFunc f){

       unsigned long k = 0;

       srand((unsigned long)time(0));

  double area = (x2-x1) * y2;

       double x = 0.0;

       double y = 0.0;

       for (unsigned long i=0; i<n; ++i){

           x = rand()/(double)RAND_MAX;

           y = rand()/(double)RAND_MAX;

           x = (x2-x1)*x + x1;

           y = y2*y;

           if ( y <= f(x) )

              ++k;

       }

       return ((double)k/double(n))*area;

}

double func1(double x){

       return sqrt(1-x*x);

}

double func2(double x){

       return 2*x+8;

}

double func3(double x){

       return 3*x*x+20;

}

int main(){

    unsigned long num=10000;

    cout<<"問題描述:設a, b, c和d是實數,且a ≤ b, c ≤ d, f:[a, b] → [c, d]是一個連續函數,寫一機率算法計算積分的值。"<<endl;

    cout<<"假設有求以下3個函數的積分值"<<endl;

    cout<<"func1=sqrt(1-x*x),[a,b]=[0,1];[c,d]=[0,1]. 精确值為0.78539815"<<endl;

    cout<<"func2=(2*x+8),[a,b]=[3,9];[c,d]=[14,26]. 精确解120"<<endl;

    cout<<"func3=3*x*x+20),[a,b]=[-3,6],[c,d]=[20,128] 精确值:423\n"<<endl;

    for (int i=0; i<4; ++i){

        cout<<"在随機總次數 n= "<<num<<" 時,函數的積分值如下"<<endl; 

        cout<<"func1=sqrt(1-x*x)的積分值"<<definiteIntegration(0.0, 1.0, 0.0, 1.0, num, func1)<<endl;

        cout<<"func2=(2*x+8)的積分值"<<definiteIntegration(3.0, 9.0, 14.0, 26.0, num, func2)<<endl;

        cout<<"func3=(3*x*x+20)的積分值"<<definiteIntegration(-3.0, 6.0, 20.0, 128.0, num, func3)<<endl;

        num*=10;

    }

cout<<"可以看到随着随即次數的增加,精确度呈上升趨勢"<<endl;

    system("pause"); 

    return 0;

}

/*

備注:本題求定積分的值,還可用平均值法來求。
           
*/