zoukankan      html  css  js  c++  java
  • 数学模型:4. 随机算法| 蒙特卡罗算法

     随机算法

    1. 蒙特卡罗模拟

    蒙特卡罗(Monte Carlo)方法,又称随机抽样或统计试验方法,是以概率和统计理论方法为基础的一种计算方法
    使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。
    将所求解的问题同一定的概率模型相联系,用电子计算机实现统计模拟或抽样,以获得问题的近似解。

    ① π的计算
    ② 计算积分 y = x**2
    ③ 排队上厕所问题

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    % matplotlib inline
    # π的计算
    
    from matplotlib.patches import Circle
    
    n = 10000
    # 投点次数
    
    r = 1.0           # 半径
    a, b = (0.0, 0.0)   # 圆心
    # 圆的信息
    
    x_min, x_max = a-r, a+r
    y_min, y_max = b-r, b+r
    # 正方形区域边界
    
    x = np.random.uniform(x_min, x_max, n) # 均匀分布
    y = np.random.uniform(y_min, y_max, n)
    # 在正方形区域内随机投点
    # numpy.random.uniform(low,high,size) → 从一个均匀分布[low,high)中随机采样,均匀分布
    
    fig = plt.figure(figsize=(6, 6))
    axes = fig.add_subplot(1, 1, 1)
    plt.plot(x, y, 'ro', markersize = 1)
    plt.axis('equal')
    # 制图
    
    d = np.sqrt((x - a)**2 + (y - b) ** 2)
    res = sum(np.where(d < r, 1, 0))
    # 计算点到圆心的距离
    # 统计落在圆内的点的数目
    
    pi = 4 * res / n
    print(pi)
    
    circle = Circle(xy = (a,b),radius = r, alpha = 0.5 ,color = 'gray')
    axes.add_patch(circle)
    plt.grid(True, linestyle = "--",linewidth = "0.8")
    plt.show()
    # 绘制圆形

    # 计算积分 y = x**2  
    
    n = 10000
    # 投点次数
    
    x_min, x_max = 0.0, 1.0
    y_min, y_max = 0.0, 1.0   
    # 矩形区域边界
    
    x = np.random.uniform(x_min, x_max, n) # 均匀分布
    y = np.random.uniform(y_min, y_max, n)
    # 在矩形区域内随机投点
    
    def f(x):
        return x**2
    # 创建函数 y = x**2
    
    res = sum(np.where(y < f(x), 1, 0))
    # 统计 落在函数 y=x^2图像下方的点的数目
    
    integral = res / n
    print('integral: ', integral)
    # 计算 定积分的近似值
    
    fig = plt.figure(figsize = (6,6)) 
    axes = fig.add_subplot(111) 
    axes.plot(x, y,'ro',markersize = 1)
    plt.axis('equal') 
    # 绘制散点图
    
    xi = np.linspace(0,1,100)
    yi = xi ** 2
    plt.plot(xi,yi,'--k')
    plt.fill_between(xi, yi, 0, color ='gray',alpha=0.5,label='area')  
    plt.grid()
    # 绘制 y = x**2 面积图

    # 厕所排队问题  
    # 1、两场电影结束时间相隔较长,互不影响;
    # 2、每场电影结束之后会有20个人想上厕所;
    # 3、这20个人会在0到10分钟之内全部到达厕所);
    # 4、每个人上厕所时间在1-3分钟之间
    # 首先模拟最简单的情况,也就是厕所只有一个位置,不考虑两人共用的情况则每人必须等上一人出恭完毕方可进行。
    # 分析:对于每个人都有如下几个参数:
    # 到达时间 / 等待时间 / 开始上厕所时间 / 结束时间
    
    arrivingtime = np.random.uniform(0,10,size = 20)
    arrivingtime.sort()
    workingtime = np.random.uniform(1,3,size = 20)
    # np.random.uniform 随机数:均匀分布的样本值
    
    startingtime = [0 for i in range(20)]
    finishtime = [0 for i in range(20)]
    waitingtime = [0 for i in range(20)]
    emptytime = [0 for i in range(20)]
    # 开始时间都是0
    
    #print('arrivingtime
    ',arrivingtime,'
    ')
    #print('workingtime
    ',workingtime,'
    ')
    #print('startingtime
    ',startingtime,'
    ')
    #print('finishtime
    ',finishtime,'
    ')
    #print('waitingtime
    ',waitingtime,'
    ')
    #print('emptytime
    ',emptytime,'
    ')
    print('------')
    
    startingtime[0] = arrivingtime[0]  # 第一个人之前没有人,所以开始时间 = 到达时间
    finishtime[0] = startingtime[0] + workingtime[0]   # 第一个人完成时间 = 开始时间 + “工作”时间
    waitingtime[0] = startingtime[0]-arrivingtime[0]   # 第一个人不用等待
    
    for i in range(1,len(arrivingtime)):
        if finishtime[i-1] > arrivingtime[i]:
            startingtime[i] = finishtime[i-1]
        else:
            startingtime[i] = arrivingtime[i]
            emptytime[i] = arrivingtime[i] - finishtime[i-1]
        finishtime[i] = startingtime[i] + workingtime[i]
        waitingtime[i] = startingtime[i] - arrivingtime[i]
        print('第%d个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
    ' %i,
              arrivingtime[i],
              startingtime[i],
              workingtime[i],
              finishtime[i],
              waitingtime[i],
             '
    ')
    print('arerage waiting time is %f' %np.mean(waitingtime))
    print('------')
    # 判断:如果下一个人在上一个人完成之前到达,则 开始时间 = 上一个人完成时间,
    # 否则 开始时间 = 到达时间,且存在空闲时间 = 到达时间 - 上一个人完成时间
    
    fig = plt.figure(figsize = (6,4))
    plt.plot(waitingtime, '-go')
    plt.grid(True,linestyle='--', color = 'gray',linewidth = '0.8')
    plt.title('蒙特卡罗模拟 - 排队上厕所问题')
    plt.show()
    # 图表绘制

    --->>

    ------
    第1个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     1.47846212718 2.90015955179 2.43550313768 5.33566268947 1.42169742461 
    
    第2个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     1.50766524856 5.33566268947 1.70026811206 7.03593080153 3.82799744091 
    
    第3个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     1.68971606051 7.03593080153 2.55933351317 9.59526431469 5.34621474102 
    
    第4个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     3.22500117584 9.59526431469 2.23730595589 11.8325702706 6.37026313886 
    
    第5个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     3.68624845537 11.8325702706 1.96298225381 13.7955525244 8.14632181522 
    
    第6个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     3.748728758 13.7955525244 1.13434491219 14.9298974366 10.0468237664 
    
    第7个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     3.76353770932 14.9298974366 2.97251793218 17.9024153688 11.1663597273 
    
    第8个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     4.04448060386 17.9024153688 1.52642253332 19.4288379021 13.8579347649 
    
    第9个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     5.15292640194 19.4288379021 2.8327295047 22.2615674068 14.2759115002 
    
    第10个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     6.39798292569 22.2615674068 2.48704326285 24.7486106697 15.8635844811 
    
    第11个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     6.46150544161 24.7486106697 2.75523182998 27.5038424996 18.287105228 
    
    第12个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     6.83020450863 27.5038424996 2.82170691612 30.3255494157 20.673637991 
    
    第13个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     7.54986448877 30.3255494157 1.32813398415 31.6536833999 22.775684927 
    
    第14个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     7.74933683577 31.6536833999 2.01805818046 33.6717415804 23.9043465641 
    
    第15个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     8.42722353547 33.6717415804 1.0300259968 34.7017675772 25.2445180449 
    
    第16个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     8.76080737972 34.7017675772 1.69860652295 36.4003741001 25.9409601974 
    
    第17个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     9.02778847556 36.4003741001 2.19029299704 38.5906670971 27.3725856245 
    
    第18个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     9.0683463525 38.5906670971 1.74875934398 40.3394264411 29.5223207446 
    
    第19个人:到达时间 开始时间 “工作”时间 完成时间 等待时间
     9.51437407844 40.3394264411 1.52156911323 41.8609955544 30.8250523627 
    
    arerage waiting time is 15.743466
    ------

  • 相关阅读:
    关于数据库的alter table操作和索引概念
    mysql_fetch_array()和 mysql_fetch_array()的区别
    left 截取
    学会设置五大类MySQL参数
    MySQL性能优化的最佳20+条经验
    varchar to int error
    2003服务器重启
    缺少注释的结尾标记 '*/'。 '*' 附近有语法错误。
    2003的服务器终端服务器超出最大连接数的解决办法转载
    电脑报警音解读转载
  • 原文地址:https://www.cnblogs.com/shengyang17/p/9656119.html
Copyright © 2011-2022 走看看