GEKKO/IPOPT非线性优化因指数变更致不可行的解决方案咨询
离散时间动态优化模型收敛问题解决方法
问题背景
使用GEKKO与IPOPT(v3.10.2)运行离散时间动态优化模型,代码如下:
from gekko import GEKKO import numpy as np # Simulation time T = 5 #exponent a = 11.3 m = GEKKO(remote = False) #Control variable Tax = m.Array(m.Var, T, value = 100, lb = 0, ub = 100) # State variables H = m.Array( m.SV, T, lb = 1) Z = m.Array(m.Var, T) # Initialization of the state variables m.Equation(H[0] == 10) m.Equation(Z[0] == 5) # Transition equations for t in range(1,T): m.Equation(H[t] == H[t-1] + ( 5 + 5/( (1 +Tax[t])**0.06) )**a ) m.Equation(Z[t] == H[t] - Tax[t]) m.Maximize(m.sum([ 0.97**t * Z[t] for t in range(0,T)]) ) m.options.MAX_ITER = 500 m.solve()
求解器无法收敛,IPOPT返回信息:
EXIT: Converged to a point of local infeasibility. Problem may be infeasible.
An error occured.
The error code is 2
当时间域T减小至3,或指数a减小至3.3时求解器可找到解,但需要运行更长时间域和更高指数的模型,寻求可行解的处理方法。
可行调整方案
优化初始值设置
当前Tax的初始值全设为100,易让模型进入极端区域,导致迭代收敛困难。可尝试设置更合理的初始值,比如线性分布,或用小T模型的最优解初始化大T模型的对应变量:# 用线性分布初始化Tax Tax = m.Array(m.Var, T, value=[i*20 for i in range(T)], lb=0, ub=100)调整变量类型与约束
将状态变量H改为普通Var变量,保留lb=1约束,同时给Z变量添加合理上下限,缩小求解器搜索范围,避免数值异常:H = m.Array(m.Var, T, lb=1, ub=1e10) # 根据实际增长情况调整ub Z = m.Array(m.Var, T, lb=0) # 假设Z不应为负处理高指数项的数值稳定性
指数a=11.3会导致项值急剧膨胀,引发数值问题。可引入辅助变量拆分高指数计算,同时给H设置合理上限:for t in range(1,T): aux = m.Var(lb=5) # 5/(...)>=0,aux最小值为5 m.Equation(aux == 5 + 5/( (1 + Tax[t])**0.06 )) m.Equation(H[t] == H[t-1] + aux**a)调整IPOPT求解器参数
通过调整IPOPT参数提升收敛性:- 增大最大迭代次数:
m.options.MAX_ITER = 1000 - 添加初始扰动:
m.options.IPOPT.initialization_perturbation = 1e-4 - 切换线性求解器:
m.options.IPOPT.linear_solver = 'ma57' - 放宽收敛容差:
m.options.IPOPT.tol = 1e-4
- 增大最大迭代次数:
分阶段优化
先运行低复杂度模型(如T=3、a=3.3)得到最优解,再逐步提升T和a的值,每次用前一次的最优解作为新模型的初始值,逐步逼近目标复杂度的模型。
内容的提问来源于stack exchange,提问作者GaL
相关产品推荐
相关产品推荐

