Advertisement
phy_bunny

Monte_Carlo_integration_volume_of_n-ball

Mar 25th, 2025
697
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.56 KB | None | 0 0
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from scipy.special import gamma
  4. import time
  5.  
  6. # ========== 计算函数 ==========
  7. def monte_carlo_hypersphere_volume(dim, num_samples):
  8.     """蒙特卡洛体积计算函数"""
  9.     points = np.random.uniform(-1, 1, (num_samples, dim))
  10.     r_squared = np.sum(points**2, axis=1)
  11.     count = np.sum(r_squared <= 1.0)
  12.     return 2**dim * count / num_samples  # 立方体体积 × 内点比例
  13.  
  14. def theoretical_volume(dim):
  15.     """理论体积公式"""
  16.     return (np.pi ** (dim/2)) / gamma(1 + dim/2)
  17.  
  18. # ========== 计算参数 ==========
  19. dims = np.arange(1, 11)   # 1-10维测试(更高维度需要极大样本)
  20. num_samples = 10**6       # 每个维度采样数
  21. mc_volumes = []           # 蒙特卡洛结果容器
  22. true_volumes = []         # 理论值容器
  23. durations = []            # 耗时监测
  24.  
  25. # ========== 执行计算 ==========
  26. print(f"开始执行蒙特卡洛采样(维度 1-10,每维 {num_samples} 样本)")
  27. for d in dims:
  28.     start_time = time.time()
  29.    
  30.     # 计算理论与蒙特卡洛体积
  31.     true_vol = theoretical_volume(d)
  32.     est_vol = monte_carlo_hypersphere_volume(d, num_samples)
  33.    
  34.     # 记录结果
  35.     true_volumes.append(true_vol)
  36.     mc_volumes.append(est_vol)
  37.     durations.append(time.time() - start_time)
  38.    
  39.     print(f"维度 {d:2d} | 理论值: {true_vol:.4f} | 蒙特卡洛: {est_vol:.4f} | 耗时: {durations[-1]:.2f}s")
  40.  
  41. # ========== 绘制结果 ==========
  42. plt.figure(figsize=(10, 6))
  43.  
  44. # 理论值曲线(蓝色实线)
  45. plt.plot(dims, true_volumes, 'b-o', linewidth=2, markersize=8,
  46.          markerfacecolor='white', label='理论值')
  47.  
  48. # 蒙特卡洛结果(红色虚线)
  49. plt.plot(dims, mc_volumes, 'r--s', linewidth=1.5, markersize=7,
  50.          markerfacecolor='white', label='蒙特卡洛估计')
  51.  
  52. # 可视化装饰
  53. plt.title("高维超球体积随维度变化", fontsize=14, pad=20)
  54. plt.xlabel("维度 $d$", fontsize=12)
  55. plt.ylabel("单位超球体积", fontsize=12)
  56. plt.xticks(dims)
  57. plt.yscale('log')  # 对数坐标展示指数衰减
  58. plt.grid(True, which='both', linestyle='--', alpha=0.6)
  59. plt.legend()
  60. plt.tight_layout()
  61.  
  62. # 添加统计数据表
  63. stats_text = (f"蒙特卡洛参数:\n"
  64.              f"- 采样点/维度: {num_samples}\n"
  65.              f"- 总耗时: {sum(durations):.1f}s\n"
  66.              f"- 最大误差: {np.max(np.abs(np.array(mc_volumes)-np.array(true_volumes))/np.array(true_volumes))*100:.1f}%")
  67. plt.gcf().text(0.72, 0.65, stats_text, fontsize=9,
  68.                bbox=dict(facecolor='white', alpha=0.8))
  69.  
  70. plt.show()
  71.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement