Python Gekko如何实现时间与路径双目标同步优化
问题核心原因
你当前的问题并不是Gekko只读取最后一个目标函数,Gekko会自动将所有m.Minimize()/m.Obj()定义的目标项求和,作为整体单目标优化。你观察到的“仅最后一个目标生效”的现象,本质是不同目标项的权重量级不匹配,导致权重小的目标对整体优化结果的影响可忽略。
你现在的目标项包含三类:x方向终点偏差惩罚、y方向终点偏差惩罚、总时间最小化,前两项的惩罚系数是1e4,总时间项的权重是1,权重差了4个数量级,优化时会优先满足路径偏差最小的要求,时间目标的作用被覆盖。
解决方案
方案1:加权和法(快速实现多目标偏好调节)
给不同目标设置可调权重,通过调整权重比值得到不同偏好的优化结果,遍历权重即可得到帕累托最优解集。
修改后的目标函数部分示例:
# 目标函数参数可根据需求调整权重比 w_path = 1e4 # 路径偏差惩罚权重 w_time = 10 # 时间优化权重,可调整该值平衡两个目标的优先级 m.Minimize(w_path * (x * final - pathx) ** 2) # x方向终点偏差惩罚 m.Minimize(w_path * (pathy - y * final) ** 2) # y方向终点偏差惩罚 m.Minimize(w_time * tf) # 总时间最小化,添加权重平衡量级
如果需要得到完整帕累托前沿,可循环遍历w_time的不同取值,每次求解后保存对应的路径偏差和总时间结果即可。
方案2:ε约束法(严格约束其中一个目标的上限)
如果需要明确约束某一个目标的阈值,可将其中一个目标转为约束条件,仅优化另一个目标:
比如要求路径偏差不超过100,优化最短时间,可添加如下约束,删掉原路径偏差的目标项即可:
# 路径偏差转为约束,偏差不超过100 m.Equation((x * final - pathx)**2 + (y * final - pathy)**2 <= 100**2) # 仅保留时间作为优化目标 m.Minimize(tf)
可运行完整代码
你提供的代码还缺少numpy导入、求解调用、结果输出的部分,补全后可直接运行:
import numpy as np import matplotlib.pyplot as plt from gekko import GEKKO # Gekko model m = GEKKO(remote=False) # Time points nt = 501 tm = np.linspace(0, 1, nt) m.time = tm # Variables g = m.Const(value=9.80665) V = m.Const(value=200) # velocity Xi = m.Var(value=0, lb=-2*np.pi, ub=2*np.pi) # Heading angle x = m.Var(value=0, lb=-100000, ub=100000) # x position y = m.Var(value=0, lb=-100000, ub=100000) # y position pathx = m.Const(value=70000) # intended distance in x direction pathy = m.Const(value=20000) # intended distance in y direction p = np.zeros(nt) # final time=1 p[-1] = 1.0 final = m.Param(value=p) m.options.MAX_ITER = 1000000 # iteration number # Optimize Final Time tf = m.FV(value=1.0, lb=0.0001, ub=1000.0) tf.STATUS = 1 # Controlled parameters Mu = m.MV(value=0, lb=-1, ub=1) # solver controls bank angle Mu.STATUS = 1 Mu.DCOST = 1e-3 # Equations m.Equation(x.dt() == tf * (V * (m.cos(Xi)))) m.Equation(y.dt() == tf * (V * (m.sin(Xi)))) m.Equation(Xi.dt() == tf * (g * m.tan(Mu)) / V ) # 加权和法目标函数 w_path = 1e4 w_time = 10 m.Minimize(w_path * (x * final - pathx) ** 2) m.Minimize(w_path * (pathy - y * final) ** 2) m.Minimize(w_time * tf) # 求解 m.solve(disp=True) # 结果输出 print(f"最优总时间: {tf.value[0]}") print(f"终点x坐标: {x.value[-1]}, 目标x: {pathx.value}") print(f"终点y坐标: {y.value[-1]}, 目标y: {pathy.value}") # 路径绘图 plt.figure(figsize=(8,4)) plt.plot(x.value, y.value) plt.scatter(pathx.value, pathy.value, c='red', label='目标终点') plt.xlabel('x坐标') plt.ylabel('y坐标') plt.legend() plt.show()
内容的提问来源于stack exchange,提问作者bernberni
相关产品推荐
相关产品推荐

