生成函数曲线下随机点失败问题求助(附Python代码)
问题原因分析及修正方案
核心问题列表
- 变量名冲突:你原本定义的积分下限
a被后续的a=np.linspace(a,b,N)覆盖,导致所有依赖原a的计算全部出错。 - Y轴随机范围错误:生成y随机数时用了x的积分区间
[a,b],但函数f(x)=x/(x²+1)的值域根本不是这个区间。比如当x∈[-2,2]时,f(x)的范围是[-0.5,0.5],用x的区间生成y会导致大部分点不在函数的取值范围内。 - 错误排序破坏对应关系:把x和y分别排序后,原本的随机点(x,y)一一对应关系被完全打乱,
A[i]是原随机x对应的函数值,排序后的xx[i]和A[i]已无对应关系,导致yy[i]<A[i]的判断完全无效。 - 未处理函数正负情况:当f(x)为负数时,"曲线下方"的点应该满足
y > f(x)(负数区域里数值更大的点在曲线下方),直接用yy[i]<A[i]会漏掉这部分区域的点。
修正后的代码
import numpy as np import matplotlib.pyplot as plt N = int(input("Enter the number of points used for integration:")) x_low, x_high = eval(input("Enter the range of integration:")) def f(x): return x/(x**2 + 1) # 生成x方向的随机点 x_rand = np.random.uniform(x_low, x_high, N) # 计算函数在区间的最值,确定y的随机范围 f_vals = f(x_rand) y_min = f_vals.min() y_max = f_vals.max() # 生成y方向的随机点 y_rand = np.random.uniform(y_min, y_max, N) # 筛选曲线下方的点(区分正负情况) below_x = [] below_y = [] for x_val, y_val, f_val in zip(x_rand, y_rand, f_vals): if f_val >= 0: if y_val <= f_val and y_val >= 0: below_x.append(x_val) below_y.append(y_val) else: if y_val >= f_val and y_val <= 0: below_x.append(x_val) below_y.append(y_val) # 绘制函数曲线和筛选后的点 x_plot = np.linspace(x_low, x_high, 1000) plt.plot(x_plot, f(x_plot), color='black', label="given function") plt.grid() plt.scatter(below_x, below_y, s=5, alpha=0.6) plt.legend() plt.show() # 计算蒙特卡洛积分值 total_area = (x_high - x_low) * (y_max - y_min) points_below = len(below_x) integral = total_area * (points_below / N) print(f"蒙特卡洛积分结果:{integral}")
修正说明
- 重命名积分区间变量为
x_low和x_high,避免和绘图变量冲突。 - 根据函数在随机点上的最值确定y的随机范围,保证生成的y点都在函数值域附近。
- 保留原始随机点的(x,y)对应关系,不排序,确保每个点的判断基于自身x对应的函数值。
- 区分函数正负情况,正确筛选"曲线下方"的点:正数区域取y在0到f(x)之间,负数区域取y在f(x)到0之间。
- 新增蒙特卡洛积分计算逻辑,让代码完整实现积分功能。
内容的提问来源于stack exchange,提问作者Utkarsh Basu
相关产品推荐
相关产品推荐

