繁体   English   中英

Python Gekko 中目标函数的约束

[英]Constraint on objective function in Python Gekko

有没有办法将目标函数限制在 Python Gekko 的范围内? 我正在研究一个商业渔业超过 10 年的经营经济学的示例优化问题 可调参数是鱼的生产速度(收获率)。 目标函数是 10 年期间的运营利润。 数学上的优化问题是:

渔业经济优化

解决方案和Python Gekko代码是:

钓鱼优化结果

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt

# create GEKKO model
m = GEKKO()

# time points
n=501
m.time = np.linspace(0,10,n)

# constants
E = 1
c = 17.5
r = 0.71
k = 80.5
U_max = 20

# fishing rate
u = m.MV(value=1,lb=0,ub=1)
u.STATUS = 1
u.DCOST = 0

# fish population
x = m.Var(value=70)

# fish population balance
m.Equation(x.dt() == r*x*(1-x/k)-u*U_max)

# objective (profit)
J = m.Var(value=0)
# final objective
Jf = m.FV()
Jf.STATUS = 1
m.Connection(Jf,J,pos2='end')
m.Equation(J.dt() == (E-c/x)*u*U_max)
# maximize profit
m.Maximize(Jf)

# options
m.options.IMODE = 6  # optimal control
m.options.NODES = 3  # collocation nodes
m.options.SOLVER = 3 # solver (IPOPT)

# solve optimization problem
m.solve()

# print profit
print('Optimal Profit: ' + str(Jf.value[0]))

# plot results
plt.figure(1)
plt.subplot(2,1,1)
plt.plot(m.time,J.value,'r--',label='profit')
plt.plot(m.time[-1],Jf.value[0],'ro',markersize=10,\
         label='final profit = '+str(Jf.value[0]))
plt.plot(m.time,x.value,'b-',label='fish population')
plt.ylabel('Value')
plt.legend()
plt.subplot(2,1,2)
plt.plot(m.time,u.value,'k.-',label='fishing rate')
plt.ylabel('Rate')
plt.xlabel('Time (yr)')
plt.legend()
plt.show()

我在化学制造中的观察结果之一是,优化有时会导致非直观的解决方案,因为优化器 (IPOPT) 会将过程带到绝对极限,以实现甚至多出几美元的盈利能力。 有没有办法限制目标函数(在这种情况下是利润),以便业务保持可行,但优化器不会提供推动设备(或在这种情况下的鱼类种群)极限的解决方案。

您可以通过添加上限来设置目标的限制,例如:

Jf = m.FV(ub=100)  # final objective

这将上限ub100 尽管您可以这样做,但您可能不想对目标施加限制的原因有很多。 一是如果优化器无法达到该限制,这可能会导致不可行的解决方案。 另一个原因是,您可能仍然无法实现“直观的解决方案”,或者在某些时期内不会将您的设备(例如渔船或化学制造厂)推向极限。 正如 Tim 在评论中提到的,更好的方法是对您可以控制的事物(例如钓鱼率)施加限制。 您可能会发现一些有用的参数是移动抑制因子DCOST 、最大移动DMAX和钓鱼速率COST 也许在一年内提高到全捕捞率然后在 5 年以上下降到 40% 是不合理的。 建立捕捞船队可能还会产生相关成本,而这些成本不会反映在您当前的解决方案中。

您还可以将目标设置为某些目标值之间的软约束,然后让其他目标(例如最大化鱼类种群)作为决定盈利能力上限和下限目标的驱动力。

# objective (profit)
J = m.CV(value=0)
J.SPHI = 100; J.WSPHI = 1000
J.SPLO = 80;  J.WSPLO = 1000
m.options.CV_WGT_START = n-1 # start at n-1
J.STATUS = 1

m.Maximize(x) # maximize fish population

这提供了介于 80 到 100 之间的利润限制的解决方案,但也最大化了鱼类种群。

钓鱼人口

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt

# create GEKKO model
m = GEKKO()

# time points
n=501
m.time = np.linspace(0,10,n)

# constants
E = 1
c = 17.5
r = 0.71
k = 80.5
U_max = 20

# fishing rate
u = m.MV(value=1,lb=0,ub=1)
u.STATUS = 1
u.DCOST = 0

# fish population
x = m.Var(value=70)

# fish population balance
m.Equation(x.dt() == r*x*(1-x/k)-u*U_max)

# objective (profit)
J = m.CV(value=0)
J.SPHI = 100; J.WSPHI = 1000
J.SPLO = 80;  J.WSPLO = 1000
m.options.CV_WGT_START = n-1 # start at n-1
J.STATUS = 1

m.Maximize(x) # maximize fish population

m.Equation(J.dt() == (E-c/x)*u*U_max)

# options
m.options.IMODE = 6  # optimal control
m.options.NODES = 3  # collocation nodes
m.options.SOLVER = 3 # solver (IPOPT)

# solve optimization problem
m.solve()

# print profit
print('Optimal Profit: ' + str(J.value[-1]))

# plot results
plt.figure(1)
plt.subplot(2,1,1)
plt.plot([0,10],[100,100],'k:',label='target profit range')
plt.plot([0,10],[80,80],'k:')
plt.plot(m.time,J.value,'r--',label='profit')
plt.plot(m.time[-1],J.value[-1],'ro',markersize=10,\
         label='final profit = '+str(J.value[-1]))
plt.plot(m.time,x.value,'b-',label='fish population')
plt.ylabel('Value')
plt.legend()
plt.subplot(2,1,2)
plt.plot(m.time,u.value,'k.-',label='fishing rate')
plt.ylabel('Rate')
plt.xlabel('Time (yr)')
plt.legend()
plt.show()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM