蒙特卡罗方法的代码实现——python

蒙特卡罗方法的代码实现——python

简单抽样

Exercise 1.

The Monte Carlo method can be used to generate an approximate value of pi. The figure below shows a unit square with a quarter of a circle inscribed. The area of the square is 1 and the area of the quarter circle is pi/4. Write a script to generate random points that are distributed uniformly in the unit square. The ratio between the number of points that fall inside the circle (red points) and the total number of points thrown (red and green points) gives an approximation to the value of pi/4. This process is a Monte Carlo simulation approximating pi. Let N be the total number of points thrown. When N=50, 100, 200, 300, 500, 1000, 5000, what are the estimated pi values, respectively? For each N, repeat the throwing process 100 times, and report the mean and variance. Record the means and the corresponding variances in a table.
蒙特卡洛方法可以用于产生接近pi的近似值。图1显示了一个带有1/4内切圆在内的边长为1的正方形。正方形的面积是1,该1/4圆的面积为pi/4。通过编程实现在这个正方形中产生均匀分布的点。落在圈内(红点)的点和总的投在正方形(红和绿点)上的点的比率给出了pi/4的近似值。这一过程称为使用蒙特卡洛方法来仿真逼近pi实际值。令N表示总的投在正方形的点。当投点个数分别是20, 50, 100, 200, 300, 500, 1000, 5000时,pi值分别是多少?对于每个N,每次实验算出pi值,重复这个过程20次,并在表中记下均值和方差。
在这里插入图片描述
Figure 1 蒙特卡洛方法求解pi

answer
  • 结果

    (均值保留四位小数,方差保留四位小数)

    SIZEMEANvariance
    203.10000.1660
    503.11200.0524
    1003.19400.0354
    2003.13000.0135
    3003.13200.0079
    5003.14480.0053
    10003.13600.0029
    50003.14700.0005
  • 条形图

    • 均值
      在这里插入图片描述

    • 方差
      在这里插入图片描述

  • 代码

    import numpy as np
    
    
    def is_in(location):
        distance = location[0] ** 2 + location[1] ** 2
        distance = distance ** 0.5
        if distance < 1:
            return True
        else:
            return False
    
    
    sizes = [20, 50, 100, 200, 300, 500, 1000, 5000]
    mean = [0.0] * 8
    var = [0.0] * 8
    
    for num in range(0, 8):
        size = sizes[num]
        result = [0.0] * 20
    
        for time in range(0, 20):
            points = np.random.rand(size, 2)
    
            for one in points:
                if is_in(one):
                    result[time] += 1
            result[time] /= size
            result[time] *= 4
    
        results = np.array(result)
        mean[num] = results.mean()
        var[num] = results.var()
    
    print mean
    print var
    

求简单积分

Exercise 2

We are now trying to integrate the another function by Monte Carlo method:
∫_01▒x3
A simple analytic solution exists here: ∫_(x=0)1▒x3 =1/4. If you compute this integration using Monte Carlo method, what distribution do you use to sample x? How good do you get when N = 5, 10, 20, 30, 40, 50, 60, 70, 80, 100, respectively? For each N, repeat the Monte Carlo process 20 times, and report the mean and variance of the integrate in a table.
我们现在尝试通过蒙特卡洛的方法求解如下的积分:
∫_01▒x3
该积分的求解我们可以直接求解,即有∫_(x=0)1▒x3 =1/4。如果你用蒙特卡洛的方法求解该积分,你认为x可以通过什么分布采样获得?如果采样次数是分别是N = 5, 10, 20, 30, 40, 50, 60, 70, 80, 100,积分结果有多好?对于每个采样次数N,重复蒙特卡洛过程100次,求出均值和方差,然后在表格中记录对应的均值和方差。

answer
  • 结果

    (均值保留六位小数,方差保留七位小数)

    SIZEMEANVARIANCE
    50.2510130.0009399
    100.2493900.0001036
    200.2502020.0000165
    300.2503050.0000052
    400.2500360.0000026
    500.2498970.0000013
    600.2498020.0000008
    700.2500310.0000004
    800.2499720.0000002
    1000.2500150.0000001
  • 条形图

    • 均值
      在这里插入图片描述

    • 方差
      在这里插入图片描述

  • 代码

    import numpy as np
    
    sizes = [5, 10, 20, 30, 40, 50, 60, 70, 80, 100]
    mean = [0.0] * 10
    var = [0.0] * 10
    
    for num in range(0, 10):
    
        size = sizes[num]
        result = [0.0] * 100
    
        for time in range(0, 100):
    
            locations = np.random.rand(size, 1)
    
            for one in range(0, size):
                x = locations[one]/size + one*1.0/size
                result[time] += pow(x, 3)
    
            result[time] /= size
    
        results = np.array(result)
        mean[num] = results.mean()
        var[num] = results.var()
    
    
    print mean
    print var
    

求两重积分

Exercise 3

We are now trying to integrate a more difficult function by Monte Carlo method that may not be analytically computed:

在这里插入图片描述

Can you compute the above integration analytically? If you compute this integration using Monte Carlo method, what distribution do you use to sample (x,y)? How good do you get when the sample sizes are N = 5, 10, 20, 30, 40, 50, 60, 70, 80, 100, 200 respectively? For each N, repeat the Monte Carlo process 100 times, and report the mean and variance of the integrate.
我们现在尝试通过蒙特卡洛的方法求解如下的更复杂的积分:

在这里插入图片描述
你能够通过公式直接求解上述的积分吗?如果你用蒙特卡洛的方法求解该积分,你认为(x, y)可以通过什么分布采样获得?如果点(x, y)的采样次数是分别是N = 10, 20, 30, 40, 50, 60, 70, 80, 100, 200, 500, 积分结果有多好?对于每个采样次数N,重复蒙特卡洛过程100次,求出均值和方差,然后在表格中记录对应的均值和方差。

answer
  • 结果:

    sizemeanvariance
    1011397011186015413
    201049685703306581
    301119174574907015
    401097783102348467
    501188872743787666
    601186912009142994
    701108261862256602
    801184611240587892
    1001139511251562500
    200110962666497079
    500112985282780621
  • 条形图

    • 均值
      在这里插入图片描述

    • 方差
      在这里插入图片描述

  • 代码:

    import numpy as np
    import math
    
    
    def calculate(_x, _y):
        cal_result = []
        for index in range(0, len(_x)):
            temp1 = _y[index] ** 2 * math.exp(-(_y[index] ** 2))
            temp2 = _x[index] ** 4 * math.exp(-(_x[index] ** 2))
            temp3 = _x[index] * math.exp(-(_x[index] ** 2))
            cal_result.append((temp1 + temp2) / temp3)
    
        return cal_result
    
    
    sizes = [10, 20, 30, 40, 50, 60, 70, 80, 100, 200, 500]
    mean = []
    var = []
    floor_space = 2.0 * 2.0
    
    for num in range(0, len(sizes)):
        size = sizes[num]
        result = []
    
        for time in range(0, 100):
    
            # create the random data
            x = np.random.rand(size, 1)
            x *= 2
            x += 2
    
            y = np.random.rand(size, 1)
            y *= 2
            y -= 1
            temp = calculate(x, y)
            ones = np.array(temp)
            one = ones.mean() * floor_space
            result.append(one)
    
        results = np.array(result)
        # print results
        mean.append(results.mean())
        var.append(results.var())
    
    print mean
    print var
    
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值