【一些挣扎】蒙特卡洛

一些实验课崩溃现学人,甚至找的时python的教程,人间疾苦啊

1、蒙特卡罗方法(Monte Carlo method)的基本思想

蒙特卡罗方法是由冯诺依曼和乌拉姆等人发明的,“蒙特卡罗”这个名字是出自摩纳哥的蒙特卡罗赌场,这个方法是一类基于概率的方法的统称,不是特指一种方法。

蒙特卡罗方法也成统计模拟方法,是指使用随机数(或者更常见的伪随机数)来解决很多计算问题的方法。他的工作原理就是两件事:不断抽样、逐渐逼近。下面用两个例子[1]来理解一下这个方法的思想。

2、蒙特卡罗方法的应用

通常蒙特卡罗方法可以粗略地分成两类[2]:

一类是所求解的问题本身具有内在的随机性,借助计算机的运算能力可以直接模拟这种随机的过程。例如在核物理研究中,分析中子在反应堆中的传输过程。中子与原子核作用受到量子力学规律的制约,人们只能知道它们相互作用发生的概率,却无法准确获得中子与原子核作用时的位置以及裂变产生的新中子的行进速率和方向。科学家依据其概率进行随机抽样得到裂变位置、速度和方向,这样模拟大量中子的行为后,经过统计就能获得中子传输的范围,作为反应堆设计的依据。

另一种类型是所求解问题可以转化为某种随机分布的特征数,比如随机事件出现的概率,或者随机变量的期望值。通过随机抽样的方法,以随机事件出现的频率估计其概率,或者以抽样的数字特征估算随机变量的数字特征,并将其作为问题的解。这种方法多用于求解复杂的多维积分问题。

 后面数学部分没看懂,大概理解下来就是,通过在一定区域随机模拟数据,看落在区域内点数用频率估计概率,酱

参考资料放在这里

蒙特卡罗方法详解 - 知乎 (zhihu.com)

希望会看

 

实验本身——卖火柴的小女孩

一根长为l的火柴,像间距为d的平行线掷去,算火柴和线相交的概率

概率以频率近似,估计方式为,通过模拟N次扔火柴统计相交次数M,概率p=M/N;

输出N分别时是10^2,10^3,10^4的p值

 

写中感

我改个屁我真心实意觉得数据真的长这样

好像摸鱼——好想摸鱼——好想摸鱼——

 

懂了,这个破针,是能旋转的,啊

就算还差0.002,我不调了,哪天心情好再说吧

 

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#pragma warning(disable:4996)
#define N 1000
int d, l;
bool pd(double x)
{
    int a = rand() % 90;
    double k = sin((double)a);
    //printf("%lf\n", k);
    //printf("%lf %lf \n", x - 0.5 * l * k, x + 0.5 * l * k);
    double L, R;
    L = x - 0.5 * 1 * k;
    R = x + 0.5 * l * k;
    if (L > R)
    {
        int t = L; L = R; R = t;
    }
    //printf("%lf %lf \n", L, R);
    if (L > 0 && R < d) return false;
    else return true;
}
int main()
{
    scanf("%d %d", &d, &l);
    srand((unsigned)time(NULL));
    int M = 0;
    for (int ii = 0; ii < N; ii++)
    {
        double k = (double)rand() / RAND_MAX * (d)+0.0;//模拟火柴落下的坐标
        //k = k % d;
        //printf("%lf\n", k);
        if (pd(k) == true)
            M++;
    }
    printf("10^2: m=%d n=%d p=%lf\n", M, N, (double)M / N);
    M = 0;
    for (int ii = 0; ii < N * 10; ii++)
    {
        double k = (double)rand() / RAND_MAX * (d)+0.0;//模拟火柴落下的坐标
        //k = k % d;
        if (pd(k) == true)
            M++;
    }
    printf("10^3: m=%d n=%d p=%lf\n", M, N * 10, (double)M / (N * 10));
    M = 0;
    for (int ii = 0; ii < N * 100; ii++)
    {
        double k = (double)rand() / RAND_MAX * (d)+0.0;//模拟火柴落下的坐标
        //k = k % d;
        if (pd(k) == true)
            M++;
    }
    printf("10^3: m=%d n=%d p=%lf\n", M, N * 100, (double)M / (N * 100));
    return 0;
}

 

 

posted @ 2023-11-13 19:27  莳萝萝  阅读(25)  评论(0编辑  收藏  举报