You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生成函数曲线下随机点失败问题求助(附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}")

修正说明

  1. 重命名积分区间变量为x_low和x_high,避免和绘图变量冲突。
  2. 根据函数在随机点上的最值确定y的随机范围,保证生成的y点都在函数值域附近。
  3. 保留原始随机点的(x,y)对应关系,不排序,确保每个点的判断基于自身x对应的函数值。
  4. 区分函数正负情况,正确筛选"曲线下方"的点:正数区域取y在0到f(x)之间,负数区域取y在f(x)到0之间。
  5. 新增蒙特卡洛积分计算逻辑,让代码完整实现积分功能。

内容的提问来源于stack exchange,提问作者Utkarsh Basu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:20:28