优化器接口¶
Pockit 把最优控制模型转录为稀疏非线性规划(NLP),目前提供 Ipopt 和 SciPy trust-constr 接口。
细网格和大型约束模型通常更适合 Ipopt。SciPy 不需要额外的本地 Ipopt 库,适合中小问题和诊断。无论选择哪个求解器,都不能替代合理的尺度、一致的约束和可行性较好的初值。
单阶段调用¶
若系统只有一个阶段且没有静态参数,传入和返回的都是单个 Variable:
from pockit.optimizer import ipopt
solution, info = ipopt.solve(
system,
guess,
optimizer_options={"tol": 1e-8, "max_iter": 1000},
)
if info["status"] not in (0, 1):
status_message = info["status_msg"]
if isinstance(status_message, bytes):
status_message = status_message.decode()
raise RuntimeError(status_message)
SciPy 的调用形式相同,但选项名称和结果对象不同:
from pockit.optimizer import scipy
solution, result = scipy.solve(
system,
guess,
optimizer_options={"maxiter": 1000},
)
if not result.success:
raise RuntimeError(result.message)
多阶段调用¶
依次传入各阶段初值,最后传入静态参数初值;结果保持相同布局:
[solution_0, solution_1, static], info = ipopt.solve(
system,
[guess_0, guess_1, static_guess],
optimizer_options={"tol": 1e-8, "max_iter": 1500},
)
静态参数常用于共享事件时刻和边界状态,因此列表最后一项属于系统级参数,并不是另一个阶段。
Ipopt 线性求解器¶
Ipopt 每次迭代都要求解来自 Karush-Kuhn-Tucker 条件的稀疏线性方程组。该系统可能不定,也可能条件数较差,因此稀疏线性求解器会影响稳健性和速度。只有当前 Ipopt 构建包含对应求解器时,才能通过选项选择它:
参数详见 Ipopt 选项参考。发表结果时应记录所有非默认求解器选项。