如何用SciPy优化带范围约束的多自变量无解析关系函数?
解决17维无解析关系函数的带边界优化问题
你的核心问题是当前使用的scipy.optimize.fmin不支持边界约束,导致算法在无限空间内搜索,无法收敛。以下是具体的解决方案:
1. 准备边界约束条件
将给定的自变量最小/最大值配对为scipy优化器支持的边界格式,每个自变量对应一个(最小值, 最大值)元组:
from scipy.optimize import minimize minimum_values = [4.03, 15.03, 15.06, 20.02, 90.03, 75.0, 12.01, 12.03, 23.04, 24.01, 21.0, 35.09, 24.01, 21.08, 18.03, 30.04, 66.01] maximum_values = [11.98, 21.99, 22.99, 29.99, 99.99, 83.0, 21.98, 21.96, 33.0, 29.98, 26.98, 42.94, 30.0, 26.99, 25.92, 42.76, 81.95] # 生成边界列表,每个元素为(下限, 上限)元组 bounds = list(zip(minimum_values, maximum_values))
2. 使用支持边界的优化器
由于你的目标函数无解析关系(无法推导梯度),推荐选用无需梯度的优化算法,比如Nelder-Mead或Powell,通过minimize函数实现:
完整代码示例
x_initial = [10, 20, 20, 25, 95, 80, 20, 20, 30, 27, 25, 40, 25, 25, 20, 35, 70] # 定义目标函数(最大化效率等价于最小化负效率值) def objective(x): return -polynom_regression(data, x) # 执行带边界的优化,选择Nelder-Mead算法(无梯度需求) result = minimize( objective, x_initial, method='Nelder-Mead', bounds=bounds, callback=cb, # 可选:设置终止条件,避免无限迭代 options={'maxiter': 1000, 'fatol': 1e-6} ) # 输出结果 print("最优几何参数:", result.x) print("最优效率值:", -result.fun)
3. 替代方案:使用fmin_l_bfgs_b
如果需要更快的收敛速度,可选用fmin_l_bfgs_b,通过approx_grad=True启用数值梯度计算:
from scipy.optimize import fmin_l_bfgs_b result = fmin_l_bfgs_b( objective, x_initial, bounds=bounds, callback=cb, approx_grad=True ) print("最优参数:", result[0]) print("最优效率值:", -result[1])
关键注意点
- 不要继续使用
fmin,它不支持边界约束,无法限制搜索范围。 - 针对无解析函数,优先选择无梯度算法(如Nelder-Mead),避免因梯度缺失导致的报错。
- 通过
options参数设置迭代次数、精度阈值等,可进一步控制优化过程的终止时机。
内容的提问来源于stack exchange,提问作者Iaroslav_Che
相关产品推荐
相关产品推荐

