随机算法_蒙特卡洛

准备

C语言生成伪随机数的函数:

int rand(void);

该函数随机生成0~RAND_MAX之间内的整数:

#define RAND_MAX 0x7fff  // 0x7fff == 32767

这两个函数所在的头文件是stdlib.h或者cstdlib,后者又被包含在iostream头文件中。

rand()这个可以生成0-RAND_MAX随机数(整数)的函数,经过一定的四则运算和取模运算,便可很容易地得到任意区间的随机数。
以生成(2, 5)之间的随机数(可整可小)为例:

double x = 3*(double(rand())/RAND_MAX)+2;
蒙特卡洛

蒙特卡洛是指以概率统计理论为指导的一类非常重要的数值计算方法。
是指使用随机数(或伪随机数)来解决很多计算问题的方法。

蒙特卡洛方法的理论基础是大数定律
大数定律是描述相当多次数重复试验的结果的定律,根据这个定律知道
样本数量越多,其平均就越趋近于真实值

蒙特卡洛简单应用
求π

在这里插入图片描述
用面积 A A + B \frac{A}{A+B} 之比为 π 4 \frac{π}{4} 求 π ,在图中随机选点,对于每一对点,判断 X 2 + Y 2 < = 1 X^2+Y^2<= 1

#include <bits/stdc++.h>
using namespace std;
#define MAX_ITERS 10000000
double Rand(double l,double r){
  return l+(r-l)*rand()*1.0/RAND_MAX;
}
double GetPi(){
  srand(time(NULL));
  int num=0;
  for(int i=0;i<MAX_ITERS;i++){
    double x=Rand(0,1.0);
    double y=Rand(0,1.0);
    if(x*x+y*y<1.0) num++;
  }
  return num*4.0/MAX_ITERS;
}
int main(){
    for(int i=0;i<10;i++)
    cout<<GetPi()<<endl;
  return 0;
}
求积分

S = 1 2 1 x d x S = \int^2_1 \frac{1}{x} dx
利用蒙特卡洛方法,图像大致如下
在这里插入图片描述
相当于用概率求面积,随机选点,对于每一对点,是否满足 1 x &gt; = y \frac{1}{x} &gt;= y

而依据牛顿莱布尼兹公式可以得到 1 2 1 x d x = l n 2 l n 1 = l n 2 = 0.693147 \int^2_1 \frac{1}{x} dx = ln2 - ln1 = ln 2 = 0.693147

#include <bits/stdc++.h>
using namespace std;
#define MAX_ITERS 10000000
double Rand(double l,double r){
  return l+(r-l)*rand()*1.0/RAND_MAX;
}
double GetCal(){
  srand(time(NULL));
  int num=0;
  for(int i=0;i<MAX_ITERS;i++){
    double x=Rand(1.0,2.0);
    double y=Rand(0,1.0);
    if(1/x>=y) num++;
  }
  return num*1.0/MAX_ITERS;
}
int main(){
    cout<<"ln2 = "<<log(2)<<endl;
    for(int i=0;i<10;i++)
    cout<<GetCal()<<endl;
  return 0;
}

求特殊图形的面积

在这里插入图片描述
计算B的面积
可以得出B的概率是 X 2 + Y 2 &gt; 1 ( X 1 ) 2 + Y 2 &gt; 1 X^2+Y^2&gt;1 和 (X-1)^2+Y^2&gt;1

#include <bits/stdc++.h>
using namespace std;
#define MAX_ITERS 10000000
double Rand(double l,double r){
  return l+(r-l)*rand()*1.0/RAND_MAX;
}
double Get(){
  srand(time(NULL));
  int num=0;
  for(int i=0;i<MAX_ITERS;i++){
    double x=Rand(0,1.0);
    double y=Rand(0,1.0);
    if(x*x+y*y>1.0&&(x-1)*(x-1)+y*y>1.0) num++;
  }
  return num*1.0/MAX_ITERS;
}
int main(){
    cout<<"s = "<<Get()<<endl;
  return 0;
}

发布了70 篇原创文章 · 获赞 22 · 访问量 6512

猜你喜欢

转载自blog.csdn.net/weixin_44410512/article/details/99929342