复制链接
克隆策略
In [12]:
import time
import numpy as np
In [13]:
# 模特卡洛求解积分
def monte_carlo(func, a, b, sample_count):
    """
    args:
        func: 待求积分的函数
        a: 下界
        b: 上界
        sample_count: 抽样数量,越大结果越准确,耗时越多
    """
    # 从 [a, b) 间随机抽样 sample_count 的个数
    x = np.random.uniform(a, b, sample_count)
    # 计算在这些点上的 f(x) 的值
    y = func(x)
    # 计算y的平均值 * (b - a)作为积分的值
    return y.mean() * (b - a)
In [14]:
# 函数 f(x) = x^2 求积分
def f(x):
    return x ** 2
In [15]:
# 试一试
monte_carlo(f, 0, 1, 100)
Out[15]:
0.31655482747549957
In [16]:
def test_monte_carlo(func, a, b):
    """测试一下"""
    
    # 用 scipy 的 integrate 计算一下,作为实际值
    from scipy.integrate import quad
    expected = quad(func, a, b)[0]
    
    for sample_count in [10, 100, 1000, 10000, 100000, 1000000]:
        start_time = time.time()
        actual = monte_carlo(func, a, b, sample_count)
        T.log.info(f"--- 模特卡洛采样 ({sample_count}次)")
        T.log.info(f"实际值: {expected}")
        T.log.info(f"蒙特卡洛估计值: {actual}")
        T.log.info(f"误差(比例): {abs(expected - actual)}({abs((expected - actual) / expected) * 100}%)")
        T.log.info(f"耗时: {time.time() - start_time}s")

test_monte_carlo(f, 0, 1)