使用Brent法在Python中优化含未知变量函数遇报错求助
代码错误分析与修复
核心问题
- 变量未定义+目标函数格式错误:
eq_tau_c_i里直接调用expectation(y, A, P)时,y根本没定义;而且scipy.optimize.root_scalar的brentq方法要求传入只接受单个自变量的函数,不能直接传计算好的数值结果。 - 逻辑与需求公式不匹配:原
expectation函数算的是sum(max((A-y)%P, 0)),但你要的是满足Exp(max(x_i-y)) = c的y,既缺了指数运算,逻辑也和需求对不上。 - 维度处理有隐患:
y.reshape((-1,1))没考虑y是标量的情况,容易触发维度不兼容的错误。
修正后的代码
情况1:完全匹配需求公式Exp(max(x_i-y)) = c
import numpy as np from scipy import optimize def expectation(y, A): # 计算每个样本的max(x_i - y),再做指数运算 max_diff = np.max(A - y, axis=1) return np.exp(max_diff) def eq_tau_c_i(A, c): # 构造brentq要求的单变量目标函数:f(y) = exp(max(x_i - y)) - c def target_func(y): return expectation(y, A) - c # brentq要求区间两端点函数值异号,需确保[0,2.0]符合要求,可根据实际调整 root_result = optimize.root_scalar(target_func, method='brentq', bracket=[0, 2.0]) return root_result.x
情况2:保留原代码中的模P运算逻辑
如果你的实际需求是带模运算的Exp(max((x_i-y)%P)) = c,则调整如下:
import numpy as np from scipy import optimize def expectation(y, A, P): # 处理y的维度,兼容标量输入 y_arr = np.asarray(y).reshape((-1, 1)) subtraction = A - y_arr result = subtraction % P max_result = np.max(result, axis=1) return np.exp(max_result) # 补上指数运算,匹配需求公式 def eq_tau_c_i(A, P, c): def target_func(y): return expectation(y, A, P) - c # 需确认bracket区间内函数值两端异号,否则brentq会报错 root_result = optimize.root_scalar(target_func, method='brentq', bracket=[0, 2.0]) return root_result.x
关键注意事项
brentq算法要求bracket指定的区间内,目标函数在两端点的取值符号相反,否则会抛出求解失败的错误,需根据你的数据调整区间范围。- 若
A是一维数组,可去掉reshape操作,简化维度处理逻辑。 - 原代码中
expectation的sum操作是多余的,若你确实需要求和后再指数化,可将np.exp(max_result)改为np.exp(np.sum(max_result, axis=1)),但需和你的需求公式对应。
内容的提问来源于stack exchange,提问作者Laurentien Diepenhorst
相关产品推荐
相关产品推荐

