簡體   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