Gekko优化求解报错error 2、-13提示无可行解问题咨询
Gekko求解报Error 2/Error -13无可行解问题修复
问题根因
两个报错本质都是约束冲突、参数设置错误导致求解器找不到合法可行域,代码里有三个核心问题:
- 待拟合参数边界设置完全错误:你给
a、b两个需要优化的参数设置的上下界均为-4000.0,相当于直接把两个参数固定死在-4000,优化器完全没有调整参数的空间,无论用哪个形式的方程,这个离谱的固定参数值都会直接导致约束冲突,不可能找到可行解。 - 变量缺少合理初始值放大数值问题:
y_predict仅设置了1e-4的下界,没有匹配测量值设置初始猜测,求解器默认初始值如果靠近0,很容易触发对数计算的定义域错误,或者迭代发散。 - 等价方程的数值稳定性存在差异:数学上完全等价的两个方程,数值求解时的稳定性不一样:
- 对数形式
m.log(y_predict) == a + b * m.log(x)要求迭代全程y_predict严格大于0,只要某一步迭代步长过大让y_predict跳到0或负数,就会触发非法计算,返回error -13(求解过程异常终止) - 指数形式
y_predict == m.exp(a + b * m.log(x))不存在对数定义域问题,但如果参数边界完全不合理,会因为约束和目标无法同时满足返回error 2(无可行解)
修复方案
- 把
a、b的上下界改成合理范围,绝对不能把上下界设为同一个值锁死参数,幂函数拟合场景下参数取[-10,10]的区间完全足够覆盖数据分布 - 给
y_predict设置和测量值匹配的初始值,避免迭代初始点不合理触发计算错误 - 优先使用指数形式的方程,数值稳定性更好,不会碰到对数定义域报错
- 调试阶段可以打开求解器诊断级别,快速定位约束冲突点
修正后可运行代码
import numpy as np from gekko import GEKKO # 原始数据集 xm = np.array([0.122, 0.276, 0.303, 0.356, 0.384, 0.444, 0.662 , 0.779, 0.867, 0.964 ,1.09, 1.17, 1.3, 1.33 ,1.41]) ym = np.array([0.00515, 0.00297, 0.00271, 0.00249, 0.00228, 0.00216, 0.0016, 0.00139, 0.0013, 0.00116, 0.00105, 0.00101, 0.000888, 0.000904, 0.000854]) # 初始化模型 m = GEKKO(remote=False) # 给待拟合参数设置合理边界 a = m.FV(lb=-10.0, ub=10.0) b = m.FV(lb=-10.0, ub=10.0) x = m.Param(value=xm) y_measure = m.Param(value=ym) # 给预测值设置下界+匹配测量值的初始值,避免迭代异常 y_predict = m.Var(lb=1e-6, value=ym) # 打开参数优化开关 a.status = 1 b.status = 1 # 选用数值稳定性更好的指数形式方程 m.Equation(y_predict == m.exp(a + b * m.log(x))) # 目标:最小化归一化平方误差 m.Minimize(((y_predict-y_measure)/y_measure)**2) # 设置为回归求解模式 m.options.IMODE = 2 # 调试时可打开诊断信息 # m.options.DIAGLEVEL = 2 # 求解 m.solve() # 输出结果 print('Final SSE Objective: ' + str(m.options.objfcnval)) print('Solution') print('a = ' + str(a.value[0])) print('b = ' + str(b.value[0]))
修正后代码可以正常收敛,拟合结果和数据分布匹配,不会再出现无可行解、求解异常终止的报错。如果后续要切换为对数形式的方程,需要适当收紧y_predict的下界,同时给a、b设置合理初始值,避免迭代过程中出现非正值导致对数计算失败。
内容的提问来源于stack exchange,提问作者Mam
相关产品推荐
相关产品推荐

