Gekko求解动态优化时固定分段线性函数的方法问询
解决Gekko中固定分段线性函数取值的方法
你的问题核心在于将v_max和slope_var定义成了优化变量(Var),求解器会为了满足优化目标调整它们的值。要让分段线性函数的取值像参数一样固定,只需将它们从优化变量改为由位置变量x直接驱动的表达式,具体修改如下:
修改后的代码
import numpy as np from gekko import GEKKO import matplotlib.pyplot as plt min_velocity = 0 max_velocity = 10 max_decel = -1 max_accel = 1 goal_dist = 200 trip_time = 100 # set up PWL functions distances = np.linspace(0,200,10) speed_limits = np.ones(10)*5 speed_limits[5:]=7 slope = np.zeros(10) slope[3:5]=1; slope[7:9]=-1 model = GEKKO(remote=False) model.time = [i for i in range(trip_time)] x = model.Var(value=0.0, lb=0) v = model.Var(value=0.0, lb = min_velocity, ub = max_velocity) a = model.MV(value=0, lb=max_decel ,ub=max_accel) a.STATUS = 1 #define vehicle movement model.Equation(x.dt()==v) model.Equation(v.dt()==a) # 直接用分段线性表达式作为速度约束,无需单独定义v_max变量 model.Equation(v <= model.pwl(x, distances, speed_limits)) # 将slope_var定义为x的分段线性函数(Intermediate变量,非优化变量) slope_var = model.Intermediate(model.pwl(x, distances, slope)) #End state constraints p = np.zeros_like(model.time); p[-1]=1 final = model.Param(p) model.Minimize(1e4*final*(v**2))# vehicle must be fully stopped model.Minimize(1e4*final*((x-goal_dist)**2))# vehicle must arrive at destination #VSPI Objective function obj = model.Intermediate(v * (1.1 * a + 9.81 * slope_var + 0.132) + 0.0003002*pow(v, 3)) model.Obj(obj) # solve model.options.IMODE = 6 model.options.REDUCE = 3 model.options.MAX_ITER=1000 model.solve(disp=False) plt.plot(x.value, model.pwl(x, distances, speed_limits).value, 'b-', label = r'$vmaxvals$') plt.plot(x.value , v.value,'g-',label=r'$vopt$') plt.plot(x.value, a.value, 'c-', label=r'$accel$') plt.plot(x.value, slope_var.value, 'r-', label=r'$slope$') plt.plot(distances, slope, 'mx', label=r'$orig_slope$') plt.plot(distances, speed_limits, 'kx', label=r'$orig_spd_limit$') plt.legend(loc='best') plt.xlabel('Distance Covered') plt.show() print(model.options.APPSTATUS)
关键修改说明
- 移除优化变量定义:删除
v_max = model.Var()和slope_var = model.Var(),因为这两个变量不需要被求解器优化,而是由x的位置直接决定。 - 直接用PWL表达式做约束:将速度约束改为
model.Equation(v <= model.pwl(x, distances, speed_limits)),直接用分段线性函数的结果作为速度上限,避免额外变量引入的自由度。 - 用Intermediate变量存储坡度值:
slope_var = model.Intermediate(model.pwl(x, distances, slope))将坡度定义为x的分段线性函数,Intermediate类型变量是依赖其他变量的表达式,不属于优化变量,求解器只会根据x的当前值计算其取值,不会主动调整。
补充说明
- 确保
distances是单调递增的,这是Gekko分段线性函数的要求,你的代码中已经满足这一点。 - 如果需要强制等式约束(比如某个变量必须严格等于分段线性函数),可以使用
model.pwl(x, y, x_data, y_data, eq=True),其中y是Var类型,但这种场景下用Intermediate变量更高效,无需额外的优化变量。
内容的提问来源于stack exchange,提问作者Salty Spatula
相关产品推荐
相关产品推荐

