蒙特卡罗算法

来源:互联网 发布:淘宝助手导出数据包 编辑:程序博客网 时间:2024/06/16 06:13
考虑一个圆半径R,它有一个外切正方形边长2R。
易知:
圆面积pi*R^2
正方形面积 2R*2R=4R^2
从这个正方形内随机抽取一个点,对这个点的要求是在正方形内任意一点的概率平均分布。
那么这个点在圆以内的概率大概就是pi*R^2/4R^2=pi/4
生成若干个这样的点,利用平面上两点间距离公式计算这个点到圆心的距离来判断是否在圆内。

当我们使用足够多的点来进行统计时,我们得到的概率值十分接近pi/4

这样就可以得到pi值


也可以通过蒙特卡罗算法求解两个集合是否相同


//判断两个集合是否相等的偏假蒙特卡罗算法
#include <stdio.h>
#include <stdlib.h>
#include "random.hpp"

static RandomNumber rnd; //随机数发生器

//判断元素k是否属于集合a
template <class Type>
bool belongTo(Type k,Type a[],int n){
    for(int i=0;i<n;i++){
        if(k==a[i])
            return true;
    }
    return false;
}

//判断两个集合是否相等
//偏假的蒙特卡罗算法
template <class Type>
bool isEqual(Type S[],Type T[],int n){
    int i=rnd.Random(n); //随机选取i,j
    int j=rnd.Random(n);
    if(belongTo(S[i],T,n) && belongTo(T[j],S,n)) //S[i]属于T 且 T[j]属于S
        return true;        //不准确
    return false;//准确
}

int main(){
    FILE *fp=fopen("setequal_input.txt","r");
    if(!fp){
        printf("输入文件不存在!\n");
        exit(0);
    }
    int i;
    int n; //集合元素数目
    int k; //算法调用次数
    int S[100],T[100];
    fscanf(fp,"%d %d",&n,&k);
    for(i=0;i<n;i++){
        fscanf(fp,"%d",&S[i]);
    }
    for(i=0;i<n;i++){
        fscanf(fp,"%d",&T[i]);
    }
    bool equal=true;
    for(i=0;i<k;i++){
        if(!isEqual(S,T,n)){  //如果返回假 则肯定为假
            equal=false;
            break;
        }
    }
    if(equal){
        printf("两个集合相等!\n");
    }
    else{
        printf("两个集合不相等!\n");
    }
    return 1;
}

原创粉丝点击