概率算法1-应用定积分计算

概率算法

      概率算法的特性:使用概率算法去处理同一个问题,计算两次会得到不同的计算结果。概率算法是对于我们在现实社会中是非常有效的,大家都是学理工科的,知道这里世界上是没有绝对的事情,也没有绝对发生的事情。我们认为一些事情会发生了,它也不是绝对发生,也可以认为它发生是存在着一定的可能性,只是认为可能性发生的大小而决定的。我认为我们要把计算机当成自己的tool to sovle social problems。How to use it 是一个关键,也就是将我们的现实中的问题给抽象出来。我们该如何去建立这种模型,该模型该如何去理清关系。模型实际上可以抽象在一个大坐标系中建立它的位置,我们可以来预测将来发生着什么。

     我们把模型发生或是要发生的事情抽象成一个事件,该事件是如何来预测发生了还是没有发生?这就是取决其相对发生的概率问题。例如:现实生活中,我们的小孩子最爱玩的是剪刀石头布游戏,我们有m个孩子一起玩这个,有着3中不同出拳的方式,m个孩子中想要一个孩子给胜出。小明恰好是其中的一个聪明的孩子,他在一旁开始统计着每个孩子可能出现的出拳的方式,如果你能给猜到,你实际上有很大的概率胜出。可是经过足够多的统计发现:每个孩子出剪刀、石头、布的方式都是集中在:0.33左右,也就是每个出现的概率是基本相等的。这存在着一种随机性在其中。如果我们把他们都给抽象成一个entity,统计分别出现的次数和出拳的可能性,在足够多的次数情况下其实可以分析出一个实体可能出现的方式。(这是基于statistics)

   回到我们的计算机世界,我们要用计算机这个工具来帮我们来解决一个实际问题:我们想要计算一座大桥的车流量问题。一座长M公里的大桥,我们要分析该桥的车流量。而我们比如人只有2人,如果我们有足够多的人,我们就是通过计数都可以知道,这显然是不科学的。我们两个人放一个桥头计数,放一个桥尾计数,取一个平均数,好像是不准确的。我们测量出来的数据也是不准确的。我们好像还学过微积分哈,我们可以使用问积分的方法来解决它哈。这个车流量本来就不是一个准确值,我们要的是一个近似值,减小误差。我们很简单的测量一个小的距离内的车流量,这样我们就有了基础,也就是可以看成M公里的大桥上的一段,我们 现在简单从0~M进行积分,求解出来该值也就是车流量的值。

    关键的核心是去解决怎样解决定积分问题?

    方法一、概率方法(有数据足够大)

C++写的一个随机函数类,要注意一个问题有符号数就是在计算机的右移问题 "<<"可能是逻辑右移,也可能是算术右移,这取决于计算的操作系统(C/C++),如果是java “<<<”逻辑右移哈,这里就不考虑该问题。

class Random{

private:

    long seed;

    long mutilply=0x5deece66l;

    long adder=0xbl;

    long mask=(1L<<48)-1;

    

public:

     Random()

    {

        seed=time(NULL);

    }

    Random(const long &seed)

    {

        if(seed!=0)

            this->seed=seed;

        else

            this->seed=time(NULL);

    }

    int random(const int &n)

    {

        if(n<=0)

            err_quit("error");

        seed=(seed*mutilply+adder)&mask;

        return ((int)(seed>>17)%n);

    }

    double frandom()

    {

        return this->random(Max)/(double)Max;

    }

    

};

//计算的公式为: value=(b-a)/n*求和1~n-1的x的函数值f(Xi)

double darts(const double&a,const double &b,  const int &n)

{

    Random *ran=new Random();

    double y=0;

    for(int i=1;i<=n;++i)

    {

        double x=(b-a)*ran->frandom()+a;

        y+=f(x);

    }

    delete ran;

    return (b-a)*y/(double)n;    

}

该方法是有随机性的,不是很准确

方法2:复合梯形方法

算法如下:double get_value(double f(double x),double a,double b,int n)
{
  double h=(b-a)/(double)n;
  double value=0;
  for(int i=1;i<=n-1;++i)
{
    double x=a+i*h;
    value+=2*f(x);
}


   return h/2*(f(a)+value+f(b));
}

测试一个f(x)=x*x;

测试用例为:

printf("the value is %.08f\n",get_value(f, 0, 1, 10000));

输出为:


方法3:

    smpron方法:

 double get_T(double a,double b,int n)
{
  double h=(b-a)/(double)n;
  double T=(f(a)-f(b))/2;
  for(int i=1;i<n;i++)
  {
    double x=a+h*i;
    T+=f(x);
  }
  return T*h;
}


double get_value(double a,double b,int n)
{
  return (get_T(a,b,2*n)*4-get_T(a,b,n))/3;
}

测试一下:

printf("the result of :%.10lf\n",get_value(2,5,10000));

  

这里简单说明其n越大表示其精度回越高。高斯方法才是精度非常高的方法之一。大学大家都学过高斯函数和高斯公式吧。

我们既然解决了积分问题,但是这里有很大的bug这里解决的简单的连续的函数的问题,有断点出现时候也就是我们思考不全面,还有些函数还不能在目前直接获取其定积分的值。还得继续学习。



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值