python-3.x - 使用 GEKKO python 时的负自由度

标签 python-3.x optimization gekko

enter image description here

我正在尝试解决上述优化问题。 我的代码如下。

它有效,但我遇到了负自由度问题。

而且客观值也是负数,这是我没想到的。我期待着积极的一面。

我不明白为什么会发生这种情况,也不知道如何解决这个问题。

有人可以给我一个建议吗?

代码

# Import package
from gekko import GEKKO
import numpy as np

# Define parameters
P_CO = 600                      # $/tonCO
beta_CO2 = 1                    # no unit
P_CO2 = 60                      # $/tonCO2eq
E_ref = 3.1022616               # tonCO2eq/tonCO
E_dir = -1.600570692            # tonCO2eq/tonCO
E_indir_others = 0.3339226804   # tonCO2eq/tonCO
E_indir_elec_cons = 18.46607256 # GJ/tonCO
C1_CAPEX = 285695               # no unit
C2_CAPEX = 188.42               # no unit
C1_FOX = 82282                  # no unit
C2_FOX = 24.094                 # no unit
C1_ROX = 4471.5                 # no unit
C2_ROX = 96.034                 # no unit
C1_UOX = 1983.7                 # no unit
C2_UOX = 249.79                 # no unit
r = 0.08                        # discount rate
N = 10                          # number of scenarios
T = 30                          # total time period
GWP_init = 0.338723235          # 2020 Electricity GWP in EU 27 countries
theta_max = 1600000             # Max capacity

# Function to make GWP_EU matrix (TxN matrix)
def Electricity_GWP(GWP_init, n_years, num_episodes):

    GWP_mean = 0.36258224*np.exp(-0.16395611*np.arange(1, n_years+2)) + 0.03091272
    GWP_mean = GWP_mean.reshape(-1,1)
    GWP_Yearly = np.tile(GWP_mean, num_episodes) 

    noise = np.zeros((n_years+1, num_episodes))
    stdev2050 = GWP_mean[-1] * 0.25 
    stdev = np.arange(0, stdev2050 * (1 + 1/n_years), stdev2050/n_years)

    for i in range(n_years+1):
        noise[i,:] = np.random.normal(0, stdev[i], num_episodes) 

    GWP_forecast = GWP_Yearly + noise 

    return GWP_forecast

GWP_EU = Electricity_GWP(GWP_init, T, N) # (T+1)*N matrix
GWP_EU = GWP_EU[1:,:] # T*N matrix

print(np.shape(GWP_EU))

# Build Gekko model
m = GEKKO(remote=False)
theta = m.Array(m.Var, N, lb=0, ub=theta_max)
demand = np.ones((T,1))
demand[0] = 8031887.589
for k in range(1,11):
    demand[k] = demand[k-1] * 1.026 
for k in range(11,21):
    demand[k] = demand[k-1] * 1.016
for k in range(21,T):
    demand[k] = demand[k-1] * 1.011 
demand = 0.12 * demand
demand = np.tile(demand, N) # T*N matrix

print(np.shape(demand))

obj = m.sum([m.sum([((1/(1+r))**(t+1))*((P_CO*m.min3(demand[t,s], theta[s])) \
            + (beta_CO2*P_CO2*m.min3(demand[t,s], theta[s])*(E_ref-E_dir-E_indir_others-E_indir_elec_cons*GWP_EU[t,s])) \
            - (C1_CAPEX+C2_CAPEX*theta[s]+C1_FOX+C2_FOX*theta[s])-(C1_ROX+C2_ROX*m.min3(demand[t,s], theta[s])+C1_UOX+C2_UOX*m.min3(demand[t,s], theta[s]))) for t in range(T)]) for s in range(N)])
m.Maximize(obj/N)
m.solve() 

输出消息

(30, 10)
(30, 10)
 ----------------------------------------------------------------
 APMonitor, Version 1.0.0
 APMonitor Optimization Suite
 ----------------------------------------------------------------
 
 
 --------- APM Model Size ------------
 Each time step contains
   Objects      :  11
   Constants    :  0
   Variables    :  5121
   Intermediates:  0
   Connections  :  321
   Equations    :  3901
   Residuals    :  3901
 
 Number of state variables:    5121
 Number of total equations: -  3911
 Number of slack variables: -  2400
 ---------------------------------------
 Degrees of freedom       :    -1190
 
 * Warning: DOF <= 0
 ----------------------------------------------
 Steady State Optimization with APOPT Solver
 ----------------------------------------------
Iter:     1 I:  0 Tm:     18.61 NLPi:    5 Dpth:    0 Lvs:    0 Obj: -1.87E+09 Gap:  0.00E+00
 Successful solution
 
 ---------------------------------------------------
 Solver         :  APOPT (v1.0)
 Solution time  :  18.619200000000003 sec
 Objective      :  -1.8677021320161405E+9
 Successful solution
 ---------------------------------------------------

最佳答案

负自由度警告是由于使用 min3() 函数时创建的松弛变量造成的。这只是一个警告,如果所有不等式都有效,那么这可能会导致方程组过度指定(方程多于变量)。如果有成功的解决方案,则可以忽略此警告。

负面目标是因为大多数求解器都需要目标的最小化。 Gekko 自动将 m.Maximize(obj) 转换为 m.Minimize(-obj)。这是一个同等的目标。如果您想报告最大化和积极目标,请在末尾使用以下内容:

print('Objective: ',-m.options.OBJFCNVAL)

关于python-3.x - 使用 GEKKO python 时的负自由度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74162557/

相关文章:

gekko - 为什么在 python GEKKO 中返回索引错误

javascript - 在 Javascript 中执行(整数)操作的最有效方法是什么?

algorithm - 在 Delphi 中快速填充字符串

django - 如何在django中从当前html页面导航到另一个html页面

python - VS Code 找不到 pytest 测试

jquery - 从缓存的选择器遍历 DOM 是否比在 DOM 中查找 ID 元素更快?

python - 使用 GEKKO 移动水平估计和模型预测控制,对测量数据而不是平均测量使用react

python - 在 Python 的 GEKKO 中实现宏观经济模型

python - 在 Pyglet 中有没有办法将 Sprite 带到前台

python - csv读取文件的问题