具體問題是Applied Energy期刊文章《Combined heating and cooling networks with waste heat recovery based on energy hub concept 》中的能源樞紐問題(該問題是多目標問題,這裏主要是復現這篇文章)
from gurobipy import *
import random
import numpy as np
try:
# 天然氣鍋爐的轉換率(天然氣->熱負荷)
eta_fh_b = 0.85
# 熱泵的轉換率(電->熱負荷;(eta_eh_hp-1)爲電->冷負荷)
eta_eh_hp = 6
# 製冷機組的轉換率(電->冷負荷)
eta_eh_ch = 4
# 電鍋爐的轉換率(電->熱負荷)
eta_eh_eh = 0.95
# 熱泵的價格(熱泵的容量,每1kw需要的錢)
phi_hp = 230
# 電的價格(每一度(1kwh)需要的錢)
phi_e = 0.0327
# 天然氣的價格(每m³的天然氣價格,產生一度電的天然氣的價格)
phi_f = 0.016123
# 電排放二氧化碳的比例(每度電排放的二氧化碳量)
lambda_e = 0.02072
# 天然氣排放二氧化碳的比例(產生一度電的天然氣排放的二氧化碳量)
lambda_f = 0.17644
# 熱負荷函數的振幅
A_h = 50000
# 冷負荷函數的振幅
A_c = 50000
# 同時刻 # 5000(Lc >> Lh) 800(Lh >> Lc)
# t = 1 # 默認第一個時刻
# 一年的總時刻
tau = 8760
# 熱負荷函數
# Lh = A_h + A_h * np.sin(2 * np.pi * t / tau + np.pi / 2) # 默認負荷
# 冷負荷函數
# Lc = A_c + A_c * np.sin(2 * np.pi * t / tau - np.pi / 2) # 默認負荷
# print(Lh, Lc)
# tt = np.sin(2*np.pi*t/tau - np.pi/2)
# 用戶標準電負荷
Le = 10000
# 電熱的最大容量
q_eh_max = 5133
run_cost = ((1 + 0.05) ** 10 - 1) / (0.05 * (1 + 0.05) ** 10)
# N = 2
random.seed(1) # 設置隨機種子
# 產生隨機 Tmatrix 和 Cmatrix
# phi_e = {(i+1, j+1): 0.0327 for i in range(N) for j in range(4) if j == 0}
# phi_f = {(i+1+N, j+1+N): 0.02072 for i in range(N) for j in range(N)}
# 第一個目標成本目標的係數矩陣
Coeff_obj1 = {}
Coeff_obj2 = {}
Lh = []
Lc = []
for t in range(tau):
for j in range(4):
# pe_eh
if j == 0:
Coeff_obj1[(t, j)] = phi_e * run_cost
Coeff_obj2[(t, j)] = lambda_e
# pe_hp
if j == 1:
Coeff_obj1[(t, j)] = phi_e * run_cost
Coeff_obj2[(t, j)] = lambda_e
# pe_ch
if j == 2:
Coeff_obj1[(t, j)] = phi_e * run_cost
Coeff_obj2[(t, j)] = lambda_e
# pf
if j == 3:
Coeff_obj1[(t, j)] = phi_f * run_cost
Coeff_obj2[(t, j)] = lambda_f
# Lc self.Lc = Individual.A_c + Individual.A_c * np.sin(2 * np.pi * self.t / Individual.tau - np.pi / 2)
lc = A_c + A_c * np.sin(2 * np.pi * t / tau - np.pi / 2)
Lc.append(lc)
lh = A_h + A_h * np.sin(2 * np.pi * t / tau + np.pi / 2)
Lh.append(lh)
print(Coeff_obj1)
# 定義 model
m = Model('hub')
# 添加變量 Tmatrix.keys()個變量, 默認係數是0
x = m.addVars(Coeff_obj1.keys(), vtype=GRB.CONTINUOUS, name='x')
qhp_size = m.addVar(obj=phi_hp, vtype=GRB.CONTINUOUS, name='qhp_size')
# print(x)
# 添加約束
# 熱負荷等式約束
m.addConstrs((x[t, 3] * eta_fh_b + x[t, 0] * eta_eh_eh + x[t, 1] * eta_eh_hp == Lh[t] for t in range(tau)), 'C1')
# 冷負荷等式約束
m.addConstrs((x[t, 2] * eta_eh_ch + x[t, 1] * (eta_eh_hp-1) == Lc[t] for t in range(tau)), 'C2')
# 有熱泵的約束
m.addConstrs((eta_eh_eh * x[t, 0] <= q_eh_max for t in range(tau)), 'C3')
# 電鍋爐的約束
m.addConstrs(((eta_eh_hp - 1) * x[t, 1] <= qhp_size for t in range(tau)), 'C4')
# # 設置多目標 權重 聚合方式
# m.setObjectiveN(x.prod(Coeff_obj1) + qhp_size * phi_hp + run_cost * phi_e * Le, index=0, weight=0.5, name='obj1')
# m.setObjectiveN(x.prod(Coeff_obj2) + lambda_e * Le, index=1, weight=0.5, name='obj2')
# 設置多目標 優先級 在滿足第一個目標最優的前提下,第二個目標最優
m.setObjectiveN(x.prod(Coeff_obj1) + qhp_size * phi_hp + run_cost * phi_e * Le, index=0, priority=1, abstol=0, reltol=0, name='obj1')
m.setObjectiveN(x.prod(Coeff_obj2) + lambda_e * Le, index=1, priority=2, abstol=100, reltol=0, name='obj2')
# 設置logFile的名稱
m.setParam(GRB.Param.LogFile, 'MultiAssignmentLog.log')
# print('writing......')
# m.write('hub.lp')
# 啓動求解
m.optimize()
# print(x)
# 獲得求解結果
for t in range(tau):
print('pe_eh:', x[t, 0])
print('pe_hp:', x[t, 1])
print('pe_ch:', x[t, 2])
print('p_f:', x[t, 3])
print('Lh:', Lh[t])
print('Lc:', Lc[t])
print('qhp_size:', qhp_size)
for i in range(2):
m.setParam(GRB.Param.ObjNumber, i)
print('Obj%d = ' % (i+1), m.ObjNVal)
# print('writing......')
# m.write('hub.lp')
except GurobiError:
print('Error reported')