簡體   English   中英

如何使用滾動原理修復 Gekko 優化中的“找不到解決方案”錯誤

[英]How to fix "Solution Not Found" Error in Gekko Optimization with rolling principle

我的計划是優化家用電池的充電和放電,以最大限度地減少年底的電力成本。 在這種情況下,還有一個 PV,這意味着有時您向電網注入電力並收到錢。 家里的用電量每15分鍾測量一次,所以我1天有96個測量點。 我想優化電池的充電和放電 2 天,以便第 1 天考慮到第 2 天的使用情況。 我寫了一個 controller,它讀取數據並每次給出 2 天的輸入值以進行優化。 按照滾動原則,它會轉到接下來的 2 天,依此類推。 下面你可以看到我的 controller 的代碼。

from gekko import GEKKO
from simulationModel2_2d_1 import getSimulation2
from exportModel2 import exportToExcelModel2
import numpy as np
#import matplotlib.pyplot as plt
import pandas as pd
import time
import math

# ------------------------ Import and read input data ------------------------

file = r'Data Sim 2.xlsx'

data = pd.read_excel(file, sheet_name='Input', na_values='NaN')

dataRead = pd.DataFrame(data, columns= ['Timestep','Verbruik woning (kWh)','Netto afname (kWh)','Prijs afname (€/kWh)',
                                            'Prijs injectie (€/kWh)','Capaciteit batterij (kW)',
                                            'Capaciteit batterij (kWh)','Rendement (%)',
                                            'Verbruikersprofiel','Capaciteit PV (kWp)','Aantal dagen'])

timestep = dataRead['Timestep'].to_numpy()                                 
usage_home = dataRead['Verbruik woning (kWh)'].to_numpy()
net_offtake = dataRead['Netto afname (kWh)'].to_numpy()
price_offtake = dataRead['Prijs afname (€/kWh)'].to_numpy()
price_injection = dataRead['Prijs injectie (€/kWh)'].to_numpy()
cap_batt_kW = dataRead['Capaciteit batterij (kW)'].iloc[0]              
cap_batt_kWh = dataRead['Capaciteit batterij (kWh)'].iloc[0]
efficiency = dataRead['Rendement (%)'].iloc[0]
usersprofile = dataRead['Verbruikersprofiel'].iloc[0]
days = dataRead['Aantal dagen'].iloc[0]
pv = dataRead['Capaciteit PV (kWp)'].iloc[0]

# ------------- Optimization model & Rolling principle (2 days) --------------

# Initialise model
m = GEKKO()

# Output data
ts = []
charging = []                       # Amount to charge/decharge batterij
e_batt = []                         # Amount of energy in the battery
usage_net = []                      # Usage after home, battery and pv
p_paid = []                         # Price paid for energy of 15min

# Energy in battery to pass
energy = 0

# Iterate each day for one year
for d in range(int(days)-1):
    d1_timestep = []
    d1_net_offtake = []
    d1_price_offtake = []
    d1_price_injection = []
    d2_timestep = []
    d2_net_offtake = []
    d2_price_offtake = []
    d2_price_injection = []
    
    # Iterate timesteps
    for i in range(96):
        d1_timestep.append(timestep[d*96+i])
        d2_timestep.append(timestep[d*96+i+96])
        
        d1_net_offtake.append(net_offtake[d*96+i])
        d2_net_offtake.append(net_offtake[d*96+i+96])
        
        d1_price_offtake.append(price_offtake[d*96+i])
        d2_price_offtake.append(price_offtake[d*96+i+96])
        
        d1_price_injection.append(price_injection[d*96+i])
        d2_price_injection.append(price_injection[d*96+i+96])
    
    # Input data simulation of 2 days
    ts_temp = np.concatenate((d1_timestep, d2_timestep))
    net_offtake_temp = np.concatenate((d1_net_offtake, d2_net_offtake))
    price_offtake_temp = np.concatenate((d1_price_offtake, d2_price_offtake))
    price_injection_temp = np.concatenate((d1_price_injection, d2_price_injection))
    if(d == 7):
        print(ts_temp)
        print(energy)
    # Simulatie uitvoeren
    charging_temp, e_batt_temp, usage_net_temp, p_paid_temp, energy_temp = getSimulation2(ts_temp, net_offtake_temp, price_offtake_temp, price_injection_temp,                                                                                     cap_batt_kW, cap_batt_kWh, efficiency, energy, pv)
    
    # Take over output first day, unless last 2 days
    energy = energy_temp
    if(d == (days-2)):
        for t in range(1,len(ts_temp)):
            ts.append(ts_temp[t])
            charging.append(charging_temp[t])
            e_batt.append(e_batt_temp[t])
            usage_net.append(usage_net_temp[t])
            p_paid.append(p_paid_temp[t])
    elif(d == 0):
        for t in range(int(len(ts_temp)/2)+1):
            ts.append(ts_temp[t])
            charging.append(charging_temp[t])
            e_batt.append(e_batt_temp[t])
            usage_net.append(usage_net_temp[t])
            p_paid.append(p_paid_temp[t])
    else:
        for t in range(1,int(len(ts_temp)/2)+1):
            ts.append(ts_temp[t])
            charging.append(charging_temp[t])
            e_batt.append(e_batt_temp[t])
            usage_net.append(usage_net_temp[t])
            p_paid.append(p_paid_temp[t])
            
    print('Simulation day '+str(d+1)+' complete.')
    
# ------------------------ Export output data to Excel -----------------------

a = exportToExcelModel2(ts, usage_home, net_offtake, price_offtake, price_injection, charging, e_batt, usage_net, p_paid, cap_batt_kW, cap_batt_kWh, efficiency, usersprofile, pv)
print(a)

Gekko 的優化發生在以下代碼中:

from gekko import GEKKO

def getSimulation2(timestep, net_offtake, price_offtake, price_injection, 
                   cap_batt_kW, cap_batt_kWh, efficiency, start_energy, pv):
    
    # ---------------------------- Optimization model ----------------------------
       
    # Initialise model
    m = GEKKO(remote = False)
    
    # Global options
    m.options.SOLVER = 1
    m.options.IMODE  = 6
    
    # Constants
    speed_charging = cap_batt_kW/4
    m.time = timestep
        
    max_cap_batt = m.Const(value = cap_batt_kWh)
    min_cap_batt = m.Const(value = 0)
    max_charge = m.Const(value = speed_charging)                                    # max battery can charge in 15min
    max_decharge = m.Const(value = -speed_charging)                                 # max battery can decharge in 15min
    
    # Parameters
    usage_home = m.Param(net_offtake)
    price_offtake = m.Param(price_offtake)
    price_injection = m.Param(price_injection)
    
    # Variables
    e_batt = m.Var(value=start_energy, lb = min_cap_batt, ub = max_cap_batt)  # energy in battery
    price_paid = m.Var()                                              # price paid each 15min
    charging = m.Var(lb = max_decharge, ub = max_charge)              # amount charge/decharge each 15min
    usage_net = m.Var(lb=min_cap_batt)
    
    # Equations
    m.Equation(e_batt==(m.integral(charging)+start_energy)*efficiency)
    m.Equation(-charging <= e_batt)
    m.Equation(usage_net==usage_home + charging)
    price = m.Intermediate(m.if2(usage_net*1e6, price_injection, price_offtake))
    price_paid = m.Intermediate(usage_net * price / 100)
    
    # Objective 
    m.Minimize(price_paid)
    
    # Solve problem
    m.options.COLDSTART=2
    m.solve()
    
    m.options.TIME_SHIFT=0
    m.options.COLDSTART=0
    m.solve()
          
    # Energy to pass
    energy_left = e_batt[95]
    
    #m.cleanup()
    
    return charging, e_batt, usage_net, price_paid, energy_left

您需要輸入的數據可以在這個 Excel 文檔中找到: https://docs.google.com/spreadsheets/d/1S40Ut9-eN_PrftPCNPoWl8WDDQtu54f0/edit?usp=sharing&ouid=104786612700360067470&rtpof=true&rtpof=true

使用此代碼,它總是在第 17 天以“找不到解決方案”錯誤結束。 我已經嘗試將默認迭代限制擴展到 500,但它沒有用。 我也嘗試過其他求解器,但也沒有改善。 通過使用 COLDSTART 預求解,它已經達到了第 17 天,如果沒有它,它會在第 8 天結束。

我解決了我的優化單獨結束的日子,然后總是使用相同的代碼立即找到解決方案。 有人可以向我解釋一下並找到解決方案嗎? 提前致謝!

這對於故障排除來說有點大,但這里有一些可能有幫助的一般想法。 正如您所說,這假設 model 在第 1-2 天、第 3-4 天和第 5-6 天等問題上解決得很好。並且這些結果通過了檢查(也就是基本的 model 按您所說的那樣工作)。

然后在第 17 天左右(顯然)有些不對勁。需要注意和嘗試的一些事情:

  • 在第16-17天啟動model,看看它是否獨立運行
  • 收集你的結果,你 go 並做一個時間序列 plot 的關鍵變量,也許其中之一是一個明顯的壞趨勢,導致不可行......也許e_batt變量正在緩慢下降,因為沒有足夠的光伏能源可用並在第 17 天達到最低
  • 從根本上改變變量的上限/下限以測試它們以查看它們是否可能涉及不可行性(假設有一個)
  • 制作一個不同的(假的)數據集,其中解決方案是確定的並且有點明顯......所有常量或您知道的模式都會產生一些已知結果並測試 model 輸出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM