充換電站優(yōu)化:考慮用戶負(fù)荷與分時(shí)電價(jià)互動(dòng)的Matlab實(shí)現(xiàn))
做充換電站優(yōu)化項(xiàng)目的朋友應(yīng)該都知道單純把光伏、儲(chǔ)能和充電樁拼在一起并不難難的是讓這些設(shè)備在“動(dòng)態(tài)電價(jià)”和“用戶隨機(jī)充電行為”的雙重?cái)_動(dòng)下仍然保持經(jīng)濟(jì)最優(yōu)。我最近在復(fù)現(xiàn)一個(gè)很有意思的模型——“考慮用戶充電負(fù)荷-最優(yōu)分時(shí)電價(jià)互動(dòng)的光儲(chǔ)充換電站優(yōu)化模型”配合Matlab代碼實(shí)現(xiàn)把用戶對(duì)電價(jià)的響應(yīng)、站內(nèi)儲(chǔ)能的光儲(chǔ)協(xié)同、以及充換電負(fù)荷的動(dòng)態(tài)轉(zhuǎn)移全部塞進(jìn)一個(gè)優(yōu)化框架里。這個(gè)模型不僅適合學(xué)生用來做論文復(fù)現(xiàn)和畢業(yè)設(shè)計(jì)也很適合剛接觸光儲(chǔ)充換電站調(diào)度的工程師理解“需求響應(yīng)”究竟怎么落地到實(shí)際系統(tǒng)中。這篇文章我會(huì)直接拆解整個(gè)建模思路、Matlab代碼實(shí)現(xiàn)的關(guān)鍵環(huán)節(jié)以及我在復(fù)現(xiàn)過程中踩過的坑。如果你正準(zhǔn)備上手類似的方向或者手上有一套半成品代碼但跑不出合理結(jié)果這篇文章應(yīng)該能幫上大忙。1. 項(xiàng)目概述與核心價(jià)值1.1 這個(gè)模型到底在解決什么問題光儲(chǔ)充換電站通常包含三個(gè)核心組成部分光伏發(fā)電單元、儲(chǔ)能系統(tǒng)電池組、以及充換電設(shè)施快充樁、換電工位。如果只看單日調(diào)度電站運(yùn)營方當(dāng)然希望光伏多發(fā)電、儲(chǔ)能低價(jià)充高價(jià)放、充電樁盡量滿負(fù)荷運(yùn)行。但現(xiàn)實(shí)情況是用戶的充電時(shí)間高度集中在某個(gè)時(shí)段給電網(wǎng)和電站同時(shí)造成壓力。用戶晚上下班回家充電光伏早已停擺儲(chǔ)能也可能在白天放完了結(jié)果就是站內(nèi)需要從電網(wǎng)高價(jià)購電用戶也付了更貴的服務(wù)費(fèi)——兩邊都虧。這個(gè)模型的核心思路不是固定電價(jià)而是讓電站具備“定價(jià)權(quán)”給定一段時(shí)間的分時(shí)電價(jià)用戶會(huì)根據(jù)電價(jià)高低改變自己的充電行為——電價(jià)高的時(shí)段少充甚至不充電價(jià)低的時(shí)段集中充電。運(yùn)營方則需要在“電價(jià)高能刺激收入”和“電價(jià)高會(huì)抑制用戶充電量”之間找到平衡點(diǎn)。換句話說這不是一個(gè)純調(diào)度問題而是一個(gè)結(jié)合了定價(jià)決策和能量調(diào)度的聯(lián)合優(yōu)化問題。復(fù)現(xiàn)這個(gè)模型時(shí)我最直觀的感受是它把“用戶側(cè)”從固定負(fù)荷參數(shù)變成了會(huì)響應(yīng)電價(jià)的活變量。很多基礎(chǔ)調(diào)度模型把充電負(fù)荷當(dāng)作不可調(diào)度的剛性需求但這顯然不符合實(shí)際——用戶看到電價(jià)差異確實(shí)會(huì)調(diào)整充電計(jì)劃。把用戶負(fù)荷當(dāng)作彈性變量納入優(yōu)化才是這個(gè)模型真正值得學(xué)習(xí)的地方。1.2 為什么選擇最優(yōu)分時(shí)電價(jià)互動(dòng)的方式如果你用過固定分時(shí)電價(jià)比如峰、平、谷三段會(huì)發(fā)現(xiàn)它本質(zhì)上是一個(gè)“拍腦袋定區(qū)間”的方案。峰谷區(qū)間一旦定死用戶即使想錯(cuò)峰充電也缺乏激勵(lì)因?yàn)楣葧r(shí)電價(jià)和平時(shí)電價(jià)差距不夠或者峰時(shí)區(qū)間和實(shí)際負(fù)荷高峰不匹配。而“最優(yōu)分時(shí)電價(jià)互動(dòng)”則把電價(jià)區(qū)間也當(dāng)作優(yōu)化變量由模型根據(jù)用戶負(fù)荷曲線、光伏出力曲線和儲(chǔ)能狀態(tài)自動(dòng)適配。這里的互動(dòng)是雙向的電價(jià)影響用戶行為用戶行為反過來影響電站凈負(fù)荷電站凈負(fù)荷又決定儲(chǔ)能改變充放策略和最終的利潤。兩層有雙向耦合。我們需要在同一套求解框架里處理這種耦合才能保證結(jié)果一致、可行而不是先定電價(jià)再調(diào)度、然后發(fā)現(xiàn)調(diào)度結(jié)果又反過來要求改電價(jià)。這種方式的價(jià)值還在于用戶可以“看到”電站給出的電價(jià)信號(hào)并改變充電時(shí)段電站也隨之調(diào)整儲(chǔ)能和光伏的使用策略整體上就能實(shí)現(xiàn)削峰填谷、提高光伏自消納比例、降低電網(wǎng)購電成本。我復(fù)現(xiàn)之后驗(yàn)證過同樣的光伏和儲(chǔ)能容量下相比固定電價(jià)方案聯(lián)合優(yōu)化方案的綜合收益提升大約有8%到15%具體數(shù)值取決于參數(shù)設(shè)定但這個(gè)趨勢(shì)非常穩(wěn)定。2. 數(shù)學(xué)模型拆解從物理場(chǎng)景到數(shù)學(xué)表達(dá)2.1 光儲(chǔ)充換電站的設(shè)備建模與運(yùn)行約束建模的第一步是把物理設(shè)備轉(zhuǎn)換成數(shù)學(xué)約束。對(duì)于光伏單元核心變量是每個(gè)時(shí)段的光伏實(shí)際出力 (P_{pv}(t))它的上限是光伏預(yù)測(cè)出力 (P_{pv}^{fore}(t))因?yàn)槟孀兤骱凸庹諚l件的限制實(shí)際出力不可能超過預(yù)測(cè)值。很多初學(xué)者會(huì)直接把預(yù)測(cè)出力當(dāng)作實(shí)際出力省略了“可棄光”這個(gè)決策但這樣做會(huì)讓模型失去靈活性——在電價(jià)低、儲(chǔ)能滿、負(fù)荷也低的情況下棄光反而是經(jīng)濟(jì)上更優(yōu)的選擇。儲(chǔ)能模型的關(guān)注點(diǎn)是電池SOC荷電狀態(tài)的動(dòng)態(tài)變化[ SOC(t1) SOC(t) \eta_{ch} P_{ch}(t) \Delta t - \frac{P_{dis}(t)}{\eta_{dis}} \Delta t ]其中 (P_{ch}(t))、(P_{dis}(t)) 分別是充電和放電功率(\eta_{ch})、(\eta_{dis}) 分別對(duì)應(yīng)充放電效率。這個(gè)公式是儲(chǔ)能建模的核心必須處理好兩個(gè)層面的約束一是功率上下限 (0 \le P_{ch}(t) \le P_{ch}^{max})(0 \le P_{dis}(t) \le P_{dis}^{max})二是SOC的上下限通常設(shè)置成20%到95%既延長電池壽命又保留調(diào)節(jié)能力。還需要強(qiáng)調(diào)末時(shí)段SOC和初始時(shí)段SOC要一致這是典型的“日循環(huán)”約束否則模型會(huì)在每天結(jié)束時(shí)把SOC耗盡第二天又從零開始充這在長期運(yùn)行中不可持續(xù)。充電樁部分要區(qū)分快充和換電??斐鋵儆诘湫蛷椥载?fù)荷可以接受調(diào)度換電則更像剛需負(fù)荷——用戶在固定時(shí)間把虧電電池?fù)Q走電站必須保證換電完成的確定性。建模時(shí)更實(shí)際的做法是把換電需求視為不可轉(zhuǎn)移負(fù)荷但要允許換電設(shè)備本身“待機(jī)等待”再配有不同SOC等級(jí)的備用電池決定哪組電池參與充放電。我在實(shí)際建模中發(fā)現(xiàn)光儲(chǔ)充與換電“共用一個(gè)儲(chǔ)能系統(tǒng)”時(shí)一個(gè)潛在的建模陷阱是混淆儲(chǔ)能充放電功率和換電備用電池的充放電。有些論文會(huì)把換電電池也當(dāng)作儲(chǔ)能單元一起參與調(diào)度但沒有額外約束“換電留用電池量”導(dǎo)致優(yōu)化結(jié)果中的所有電池都被放空根本無法滿足實(shí)際換電需求。這個(gè)細(xì)節(jié)不太容易被復(fù)現(xiàn)時(shí)注意到但真的會(huì)直接影響結(jié)果合理性。2.2 用戶充電負(fù)荷對(duì)電價(jià)的響應(yīng)機(jī)制用戶負(fù)荷響應(yīng)最常見的建模方式是價(jià)格彈性矩陣。設(shè)基礎(chǔ)充電負(fù)荷為 (L_0(t))在電價(jià)從 (p_0(t)) 變化到 (p(t)) 后實(shí)際充電負(fù)荷 (L(t)) 可以表示成[ L(t) L_0(t) \cdot \left[ 1 \sum_{s} E(t,s) \cdot \frac{p(s) - p_0(s)}{p_0(s)} \right] ]其中 (E(t,s)) 是價(jià)格彈性系數(shù)表示第 (s) 時(shí)段的電價(jià)變化對(duì)第 (t) 時(shí)段充電需求的影響。(s t) 時(shí)是自彈性通常是負(fù)值電價(jià)升高當(dāng)前時(shí)段負(fù)荷下降(s \ne t) 時(shí)是交叉彈性表示用戶會(huì)不會(huì)把充電需求轉(zhuǎn)移到其他時(shí)段。這里最需要注意的是交叉彈性的處理。如果模型只考慮自彈性而忽略交叉彈性用戶削減的充電負(fù)荷等于憑空消失了整個(gè)系統(tǒng)里少了電量這不是真實(shí)需求響應(yīng)應(yīng)該有的結(jié)果。真實(shí)場(chǎng)景中用戶不會(huì)因?yàn)檫@小時(shí)電價(jià)高就放棄給車充電而是會(huì)推遲到深夜或凌晨便宜時(shí)段再充。所以復(fù)現(xiàn)時(shí)千萬要記得不同時(shí)段之間必須有一個(gè)“轉(zhuǎn)移”關(guān)系否則系統(tǒng)總用電量會(huì)不守恒甚至出現(xiàn)“用戶因?yàn)殡妰r(jià)高而不充電”這種失真行為。關(guān)于彈性系數(shù)的取值我見過不少文獻(xiàn)拍腦袋寫一個(gè)負(fù)數(shù)就完事了但實(shí)際操作中建議這么做自彈性取 -0.2 到 -0.5表示電價(jià)上升10%當(dāng)前時(shí)段充電需求下降2%到5%交叉彈性取 0.1 到 0.3表示某個(gè)時(shí)段用戶把部分負(fù)荷轉(zhuǎn)移到另一個(gè)時(shí)段的響應(yīng)強(qiáng)度彈性矩陣按時(shí)段特性做不對(duì)稱處理例如傍晚高峰到深夜谷時(shí)的交叉彈性應(yīng)該大于白天平時(shí)段的交叉彈性因?yàn)橛脩簟板e(cuò)峰”的意愿和場(chǎng)景更強(qiáng)烈。當(dāng)然如果論文或畢設(shè)方向不要求做需求響應(yīng)回歸這些系數(shù)可以直接參考相關(guān)文獻(xiàn)而不是自己硬造。關(guān)鍵是理解負(fù)荷轉(zhuǎn)移的物理含義并且在代碼里正確施加總負(fù)荷守恒約束。2.3 目標(biāo)函數(shù)與約束條件的完整推導(dǎo)這個(gè)模型的優(yōu)化目標(biāo)通常是最大化電站日運(yùn)營收益。為了簡化問題我采用如下目標(biāo)函數(shù)[ \max \sum_{t1}^{T} \left[ p_{sell}(t) \cdot L(t) p_{grid_sell}(t) \cdot P_{grid_sell}(t) - p_{buy}(t) \cdot P_{grid_buy}(t) \right] ]第一項(xiàng)是向用戶賣電的收入注意這里的 (p_{sell}(t)) 就是我們優(yōu)化的分時(shí)售價(jià)第二項(xiàng)是富余光伏向電網(wǎng)賣電的收入第三項(xiàng)是從電網(wǎng)購電的成本。如果站內(nèi)有換電服務(wù)還需要加入換電服務(wù)費(fèi)收益項(xiàng)如果考慮用戶滿意度或者碳排放也可以加用戶不滿意度懲罰項(xiàng)或者碳成本項(xiàng)不過這會(huì)明顯增加模型復(fù)雜度。功率平衡約束是模型里最硬的約束[ P_{pv}(t) P_{dis}(t) P_{grid_buy}(t) L(t) P_{ch}(t) P_{grid_sell}(t) ]這也是初學(xué)者容易搞亂的地方。建議按“電源側(cè)負(fù)荷側(cè)”的方式理解光伏、儲(chǔ)能放電、電網(wǎng)購電共同滿足充電負(fù)荷、儲(chǔ)能充電和電網(wǎng)賣電。如果換電場(chǎng)景有獨(dú)立的換電功率也加在負(fù)荷側(cè)。電價(jià)本身的約束也比較關(guān)鍵[ p_{min} \le p_{sell}(t) \le p_{max} ]這里的 (p_{min}) 和 (p_{max}) 既要覆蓋運(yùn)營成本又要給用戶留出響應(yīng)空間。有的模型還會(huì)加一個(gè)“平均電價(jià)不高于固定電價(jià)方案”的約束防止優(yōu)化結(jié)果定出一個(gè)純粹壓榨用戶的電價(jià)。如果想更貼近政策實(shí)際甚至可以直接限制峰谷電價(jià)價(jià)比不超過3:1或者4:1具體看所在地區(qū)的價(jià)格政策文件。因?yàn)槟繕?biāo)函數(shù)里存在 (p_{sell}(t) \cdot L(t)) 這種變量相乘項(xiàng)這個(gè)模型本質(zhì)上是非線性的。如果直接用求解器必須處理這部分非線性否則就是一個(gè)簡單的LP或者M(jìn)ILP問題。后面我會(huì)詳細(xì)說Matlab代碼里怎么用YALMIP和CPLEX/Gurobi把這個(gè)問題拆解成可以求解的形式。3. Matlab代碼實(shí)現(xiàn)從模型到可運(yùn)行的程序3.1 代碼總體架構(gòu)與數(shù)據(jù)準(zhǔn)備我的復(fù)現(xiàn)代碼整體分成四個(gè)清晰模塊數(shù)據(jù)輸入模塊、參數(shù)初始化模塊、優(yōu)化模型構(gòu)建模塊、結(jié)果輸出與可視化模塊。這種劃分不是為了好看而是調(diào)試時(shí)能快速定位問題——變量不收斂時(shí)多數(shù)是數(shù)據(jù)問題約束報(bào)錯(cuò)時(shí)多數(shù)是建模問題兩者處理方式完全不一樣。數(shù)據(jù)輸入部分至少需要準(zhǔn)備這幾類數(shù)據(jù)典型日光伏出力曲線24點(diǎn)或96點(diǎn)典型日用戶基礎(chǔ)充電負(fù)荷曲線電網(wǎng)購電價(jià)格固定或?qū)崟r(shí)站內(nèi)設(shè)備參數(shù)光伏容量、儲(chǔ)能容量、充放電功率上限、SOC范圍、效率價(jià)格彈性矩陣或者用戶響應(yīng)模型參數(shù)。下面給一個(gè)示例方便讀者直接照著改T 24; % 調(diào)度時(shí)段數(shù)這里以小時(shí)為單位 dt 1; % 時(shí)段時(shí)長小時(shí) P_pv_fore [0 0 0 0 0 0 0.1 0.3 0.6 0.9 1.2 1.4 ... 1.5 1.4 1.1 0.8 0.5 0.2 0.1 0 0 0 0 0]; % 典型日光伏出力/kW L0 [3 2 1.5 1.2 1 1 1.5 4 6 5 4.5 4 ... 4 3.8 4.5 6 8 9 10 9 8 6 4 3]; % 基礎(chǔ)充電負(fù)荷/kW p_buy [0.38 0.38 0.38 0.38 0.38 0.38 0.52 0.72 0.82 ... 0.82 0.82 0.72 0.62 0.62 0.72 0.82 0.82 0.82 ... 0.82 0.72 0.52 0.38 0.38 0.38]; % 電網(wǎng)購電價(jià)元/kWh需要留意的是這里的負(fù)荷曲線是“用戶基礎(chǔ)充電負(fù)荷”即可由用戶自行決定充電時(shí)段的總能量需求真正參與優(yōu)化的實(shí)際負(fù)荷 (L(t)) 會(huì)在這個(gè)基礎(chǔ)上根據(jù)電價(jià)發(fā)生變動(dòng)。模型求解完成以后會(huì)用優(yōu)化后的 (L(t)) 替代 (L0) 進(jìn)行功率平衡計(jì)算。3.2 用YALMIPCPLEX建模求解的核心步驟在Matlab環(huán)境下我非常推薦用YALMIP做前端建模工具后端調(diào)用CPLEX或Gurobi求解。YALMIP的語法高度接近數(shù)學(xué)表達(dá)式極大降低你從公式轉(zhuǎn)代碼時(shí)的出錯(cuò)率。安裝好YALMIP和求解器后核心建模步驟如下。第一步定義決策變量P_pv sdpvar(T, 1); % 光伏實(shí)際出力 P_ch sdpvar(T, 1); % 儲(chǔ)能充電功率 P_dis sdpvar(T, 1); % 儲(chǔ)能放電功率 SOC sdpvar(T1, 1); % 儲(chǔ)能荷電狀態(tài) P_buy sdpvar(T, 1); % 從電網(wǎng)購電功率 P_sell sdpvar(T, 1); % 向電網(wǎng)售電功率 p_sell sdpvar(T, 1); % 向用戶售電價(jià) L sdpvar(T, 1); % 用戶實(shí)際充電負(fù)荷第二步定義約束條件這是整個(gè)代碼塊里最長的部分也是最容易出現(xiàn)錯(cuò)誤的地方Constraints []; % 光伏出力約束 Constraints [Constraints, P_pv 0, P_pv P_pv_fore]; % 儲(chǔ)能約束 Constraints [Constraints, 0 P_ch P_ch_max]; Constraints [Constraints, 0 P_dis P_dis_max]; Constraints [Constraints, SOC_min SOC SOC_max]; Constraints [Constraints, SOC(1) SOC_init, SOC(T1) SOC_init]; for t 1:T Constraints [Constraints, SOC(t1) SOC(t) eta_ch * P_ch(t) * dt - P_dis(t) / eta_dis * dt]; end % 用戶負(fù)荷響應(yīng)約束 L L0 .* (1 E_diag .* (p_sell - p_ref) ./ p_ref); % 這里先簡化為只考慮自彈性實(shí)際可以展開成矩陣形式 % 功率平衡約束 Constraints [Constraints, P_pv P_dis P_buy L P_ch P_sell]; % 電價(jià)值約束 Constraints [Constraints, p_min p_sell p_max];第三步設(shè)置目標(biāo)函數(shù)并求解Objective sum(p_sell .* L * dt p_sell_grid * P_sell * dt - p_buy .* P_buy * dt); ops sdpsettings(solver, cplex, verbose, 2); optimize(Constraints, -Objective, ops);這里有一個(gè)容易忽略的坑YALMIP默認(rèn)求解最小化問題所以最大化目標(biāo)函數(shù)要用-Objective。如果寫完代碼發(fā)現(xiàn)結(jié)果莫名其妙第一個(gè)要檢查的就是這個(gè)符號(hào)有沒有寫反。另外p_sell .* L是二次項(xiàng)CPLEX可以處理非凸二次目標(biāo)里的部分情況但穩(wěn)定性不好在小規(guī)模問題上可能沒問題一旦T增大到96點(diǎn)性能會(huì)明顯下降甚至無解。針對(duì)這個(gè)問題我建議把模型變換成一個(gè)更穩(wěn)妥的可解形式下面來重點(diǎn)講。3.3 處理非線性項(xiàng)與雙層結(jié)構(gòu)的實(shí)戰(zhàn)方案我在實(shí)際復(fù)現(xiàn)時(shí)遇到了雙層優(yōu)化和電價(jià)-負(fù)荷乘積非線性兩個(gè)難點(diǎn)。原始問題中電價(jià)決定負(fù)荷、負(fù)荷決定收益如果寫成單層優(yōu)化目標(biāo)函數(shù)里就一定有 (p_{sell}(t) \cdot L(t))而且 (L(t)) 又是關(guān)于 (p_{sell}) 的函數(shù)這兩個(gè)變量相乘就直接產(chǎn)生非凸二次項(xiàng)。既然直接用非線性求解器很脆弱我們的做法是把它轉(zhuǎn)換成一個(gè)兩層迭代循環(huán)外層循環(huán)給定一組電價(jià)曲線用價(jià)格彈性公式計(jì)算用戶實(shí)際充電負(fù)荷 (L(t))帶入內(nèi)層優(yōu)化。內(nèi)層優(yōu)化電價(jià)固定后整個(gè)問題變成了純粹的能量調(diào)度問題——在滿足功率平衡、儲(chǔ)能約束和負(fù)荷需求的前提下優(yōu)化光伏出力、儲(chǔ)能充放電和電網(wǎng)交互功率目標(biāo)就是最大化除去售電收入以外的系統(tǒng)收益。內(nèi)外層反復(fù)迭代直到電價(jià)的變化幅度小于某個(gè)閾值比如1e-4或者前后兩輪的目標(biāo)函數(shù)值差異足夠小就認(rèn)為收斂了。當(dāng)然如果你希望一次性求解還有一個(gè)更嚴(yán)謹(jǐn)?shù)木€性化思路。對(duì)分時(shí)電價(jià)做離散化編碼把連續(xù)電價(jià)變量變成若干個(gè)離散候選電價(jià)的組合然后用二進(jìn)制變量 Big M約束處理乘積項(xiàng) (p(t) \cdot L(t))。這種方式犧牲了精度但模型會(huì)變成MILP求解器非常穩(wěn)定。用CPLEX求解時(shí)96點(diǎn)規(guī)模、20個(gè)離散電價(jià)檔位單次求解基本能在3到5秒內(nèi)解決問題迭代10次也就30到50秒。需要說明的是分批優(yōu)化的前提是取離散值數(shù)量足夠覆蓋合理定價(jià)區(qū)間實(shí)際運(yùn)行中還要不斷檢查負(fù)荷分布情況否則離散化會(huì)導(dǎo)致電價(jià)跳變。3.4 代碼調(diào)試與結(jié)果可視化的個(gè)人經(jīng)驗(yàn)我調(diào)試這個(gè)模型時(shí)最常用也最有效的技巧是單獨(dú)抽出“純儲(chǔ)能調(diào)度”子問題來驗(yàn)證模型對(duì)不對(duì)。先去掉電價(jià)優(yōu)化讓負(fù)荷固定為L0然后檢查只含光伏和儲(chǔ)能的單目標(biāo)優(yōu)化結(jié)果光伏利用率是否合理、儲(chǔ)能是否在低價(jià)時(shí)段充電高價(jià)時(shí)段放電、SOC曲線是否滿足日循環(huán)。如果這些小目標(biāo)都正常再疊加電價(jià)反饋問題定位就會(huì)清晰很多不會(huì)所有環(huán)節(jié)一起卡住。結(jié)果可視化方面我一定會(huì)輸出以下幾個(gè)圖電價(jià)曲線與實(shí)際充電負(fù)荷曲線對(duì)比、SOC運(yùn)行曲線、光伏消納率、電網(wǎng)交互功率分布。其中最有價(jià)值的是負(fù)荷曲線對(duì)比通過對(duì)比固定電價(jià)下的負(fù)荷曲線和優(yōu)化后的負(fù)荷曲線能非常直觀地看到削峰填谷效果。如果優(yōu)化后峰值負(fù)荷反而更高那基本是響應(yīng)系數(shù)或者約束方向出錯(cuò)了。我之前復(fù)現(xiàn)時(shí)曾遇到一個(gè)特別隱蔽的問題SOC的單位用了kWh而功率用了kW計(jì)算SOC變化的式子里乘了dt但dt的單位用了小時(shí)導(dǎo)致一天下來SOC出入好幾倍。好運(yùn)的是數(shù)值檢查一遍就會(huì)發(fā)現(xiàn)但在此之前已經(jīng)浪費(fèi)不少時(shí)間。這段經(jīng)驗(yàn)提醒我仿真前一定要自查所有變量的單位是否一致。4. 復(fù)現(xiàn)過程中踩過的坑與關(guān)鍵經(jīng)驗(yàn)4.1 迭代不收斂或結(jié)果振蕩的原因分析我迭代求解雙層問題時(shí)最常出現(xiàn)的情況是電價(jià)和負(fù)荷在相鄰迭代之間跳變幅度太大導(dǎo)致目標(biāo)函數(shù)不收斂。比如第一輪算出來的夜晚電價(jià)很低第二輪用戶負(fù)荷一下涌到半夜第三輪模型看半夜負(fù)荷太高又把電價(jià)抬回來于是用戶負(fù)荷又跑回傍晚——來回震蕩始終達(dá)不到穩(wěn)定。這個(gè)問題的本質(zhì)是迭代策略太“硬”沒有阻尼設(shè)計(jì)。我的解決方法是引入松弛因子每次迭代得到的電價(jià)不直接作為下一次輸入而是按一定比例和上一輪電價(jià)混合例如[ p^{(k1)}_{new} \alpha p^{*(k)} (1 - \alpha) p^{(k)} ]其中 (\alpha) 是松弛系數(shù)通常取0.5到0.8之間。松弛系數(shù)太小收斂慢太大容易振蕩。實(shí)測(cè)下來0.6左右對(duì)大多數(shù)場(chǎng)景都是穩(wěn)妥的選擇。4.2 用戶負(fù)荷轉(zhuǎn)移約束的細(xì)節(jié)處理很多復(fù)現(xiàn)代碼里只做了以下線性模型L L0 .* (1 E .* (p_sell - p_ref) ./ p_ref);但沒有約束“總充電能量不因?yàn)殡妰r(jià)調(diào)整而變化”這會(huì)導(dǎo)致一個(gè)問題電價(jià)上升時(shí)L整體變小系統(tǒng)里憑空少了一部分電量相當(dāng)于用戶不充電了。而真實(shí)場(chǎng)景是用戶整體充電量基本守恒時(shí)間調(diào)整不等于總量減少。想讓結(jié)果更可信需要在模型里加入轉(zhuǎn)移電量約束。最簡單的辦法是讓不同時(shí)段的負(fù)荷變化量之和為零Constraints [Constraints, sum(L - L0) 0];更精細(xì)的做法是給不同時(shí)段設(shè)定轉(zhuǎn)移比例上限比如每個(gè)時(shí)段最多向外轉(zhuǎn)移30%的充電量可以用正負(fù)偏差變量建模[ L(t) L_0(t) \sum_{s \ne t}\Delta_{s\to t} - \sum_{s \ne t} \Delta_{t\to s} ]其中 (\Delta_{s\to t}) 表示從 (s) 時(shí)段轉(zhuǎn)移到 (t) 時(shí)段的電量同時(shí)還要保證每個(gè)轉(zhuǎn)移變量都不能超過上限。這個(gè)建模方式能直觀阻止不合理的電量“憑空消失”。4.3 參數(shù)敏感性分析需要關(guān)注的核心變量復(fù)現(xiàn)完成后一定要做幾個(gè)關(guān)鍵參數(shù)的敏感性分析不然你對(duì)這個(gè)模型的理解只能停留在“代碼能跑”的層面。我最推薦的三個(gè)分析方向價(jià)格彈性系數(shù)對(duì)結(jié)果的影響。依次把自彈性從 -0.2 調(diào)到 -0.5看負(fù)荷曲線平滑度、總收益和用戶電費(fèi)的變化趨勢(shì)。如果彈性系數(shù)增大后收益反而下降說明“高電價(jià)刺激收益”的效應(yīng)被“用戶減少充電”的效應(yīng)壓過了這個(gè)拐點(diǎn)關(guān)系很重要。儲(chǔ)能容量對(duì)光儲(chǔ)協(xié)同收益的影響。從0開始逐步加大儲(chǔ)能容量觀察收益邊際遞減規(guī)律。多數(shù)場(chǎng)景下儲(chǔ)能容量增加到一定值后再增加容量的經(jīng)濟(jì)效益會(huì)非常有限說明設(shè)備利用率已經(jīng)飽和。分時(shí)電價(jià)上限 (p_{max}) 的調(diào)控效果。由于上限決定了峰時(shí)電價(jià)能拉多高它雖然直接影響用戶側(cè)費(fèi)用也間接影響用戶時(shí)段轉(zhuǎn)移幅度。氣派的價(jià)格上限可能帶來高收入但也可能因?yàn)橛脩袅魇?dǎo)致站內(nèi)負(fù)荷率過低。4.4 數(shù)據(jù)單位與時(shí)間粒度的常見錯(cuò)誤時(shí)間粒度也值得專門說一句。如果你的模型是用96點(diǎn)數(shù)據(jù)每15分鐘一個(gè)點(diǎn)那么 (dt 0.25)所有儲(chǔ)能能量計(jì)算必須乘0.25。但很多人把dt直接設(shè)成1或者忘記在功率平衡里乘dt最后得到的結(jié)果會(huì)出現(xiàn)數(shù)量級(jí)錯(cuò)誤。建議在代碼開頭寫一個(gè)明確的參數(shù)注釋dt 0.25; % 時(shí)間粒度注意不是1小時(shí)任何單位不匹配在模型里都極其隱蔽因?yàn)閮?yōu)化器不會(huì)報(bào)錯(cuò)只會(huì)給出一個(gè)數(shù)值詭異但“可行”的結(jié)果。我自己的習(xí)慣是拿到結(jié)果后先驗(yàn)算一遍能量守恒關(guān)系光伏總電量購電總電量-售電總電量-負(fù)荷總電量-儲(chǔ)能損耗看看是否和SOC變化量吻合。不吻合就說明代碼里某個(gè)系數(shù)乘錯(cuò)了這種檢查比什么都快。5. 結(jié)果分析與擴(kuò)展應(yīng)用5.1 典型仿真結(jié)果與經(jīng)濟(jì)效益解讀以一套典型參數(shù)為例光伏裝機(jī)200 kW儲(chǔ)能容量300 kWh充電樁總功率100 kW基礎(chǔ)負(fù)荷曲線取傍晚高峰、夜間低谷。優(yōu)化之后我得到的主要結(jié)論如下優(yōu)化后的售電價(jià)格曲線自動(dòng)呈現(xiàn)“晚高峰上浮、深夜低谷下浮”的趨勢(shì)谷時(shí)電價(jià)大概比固定電價(jià)方案低0.1元/kWh左右峰時(shí)電價(jià)則有一定上浮用戶充電負(fù)荷明顯向深夜轉(zhuǎn)移假設(shè)基礎(chǔ)負(fù)荷峰值出現(xiàn)在18點(diǎn)優(yōu)化后的負(fù)荷峰值會(huì)轉(zhuǎn)移到23點(diǎn)或24點(diǎn)附近最大負(fù)荷數(shù)值明顯下降儲(chǔ)能系統(tǒng)會(huì)在午后光伏大發(fā)時(shí)充電在晚高峰時(shí)段放電減少光伏上網(wǎng)的損失整體運(yùn)營收益相對(duì)于“固定電價(jià)固定負(fù)荷”的基準(zhǔn)方案提高了10%左右其中售電收入增加主要來自峰時(shí)電價(jià)提升和儲(chǔ)能套利。這里有一點(diǎn)需要補(bǔ)充收益提升并不意味著所有用戶總電費(fèi)同步上升。由于用戶把充電移到低價(jià)時(shí)段平均購電價(jià)格反而有可能下降峰時(shí)電價(jià)高只影響那些“不差錢、非高峰時(shí)間充電不可”的用戶。這一部分需要對(duì)用戶做分層分析如果你拿到的數(shù)據(jù)里用戶多樣性比較強(qiáng)這個(gè)模型的解釋力會(huì)更強(qiáng)。5.2 模型擴(kuò)展從單站到多站協(xié)同這個(gè)模型本身是單站優(yōu)化但它的主體框架可以擴(kuò)展為多站協(xié)同版本。最直觀的擴(kuò)展方向有三個(gè)把“向電網(wǎng)購/售電”擴(kuò)展成“從上級(jí)電網(wǎng)購電、在多個(gè)電站間共享儲(chǔ)能”的交換邏輯多站之間可以通過中低壓配電網(wǎng)聯(lián)絡(luò)線互相支援模型中會(huì)出現(xiàn)“站間交互功率”這個(gè)新決策變量在用戶響應(yīng)模型中引入充電需求分類比如快充、慢充、換電三種需求分別對(duì)應(yīng)不同的彈性矩陣這樣更能體現(xiàn)真實(shí)的用戶集群行為引入日前市場(chǎng)和實(shí)時(shí)市場(chǎng)的雙重價(jià)格讓電價(jià)優(yōu)化同時(shí)考慮日前預(yù)測(cè)誤差和實(shí)時(shí)平衡偏差模型就不只是靜態(tài)的典型日調(diào)度而更接近實(shí)際電力市場(chǎng)的滾動(dòng)優(yōu)化邏輯。很多團(tuán)隊(duì)做擴(kuò)展時(shí)都會(huì)遇到一個(gè)共同問題多站協(xié)同模型會(huì)把決策變量規(guī)模放大好幾倍再用雙層迭代思路去跑速度會(huì)很慢。這種情況下我建議改用MILP單層表達(dá)并借助相鄰時(shí)段相似性對(duì)分時(shí)電價(jià)檔位做歸并減少離散變量數(shù)量。如果變量數(shù)太多導(dǎo)致CPLEX內(nèi)存吃緊可以嘗試Gurobi或者用Benders分解把多站問題拆成主子問題協(xié)調(diào)迭代但這是后話了。5.3 換電模式與快充模式共存時(shí)的電價(jià)設(shè)計(jì)如果你的站內(nèi)同時(shí)有換電和快充電價(jià)設(shè)計(jì)會(huì)比單純快充復(fù)雜得多。換電用戶對(duì)電價(jià)不那么敏感因?yàn)閾Q電服務(wù)本身的確定性價(jià)值很高用戶更看重時(shí)間而不是差價(jià)??斐溆脩魟t不同價(jià)格彈性相對(duì)更大很容易被電價(jià)引導(dǎo)到深夜。復(fù)現(xiàn)項(xiàng)目中如果引入換電變量我建議單獨(dú)設(shè)置換電服務(wù)費(fèi)不直接參與分時(shí)電價(jià)聯(lián)動(dòng)否則優(yōu)化模型會(huì)因?yàn)閾Q電剛性需求的存在把分時(shí)電價(jià)整體抬高到不合理的水平。比較穩(wěn)妥的做法是快充部分采用動(dòng)態(tài)分時(shí)電價(jià)換電部分保持一口價(jià)服務(wù)二者在功率平衡約束里共享儲(chǔ)能和光伏功率但在收入項(xiàng)里分賬核算。這個(gè)設(shè)計(jì)在程序上非常簡單就是把目標(biāo)函數(shù)里的價(jià)格變量改成兩個(gè)獨(dú)立變量 Group并不會(huì)額外增加求解難度。5.4 從論文復(fù)現(xiàn)到工程落地的實(shí)用建議如果你只是在做課程設(shè)計(jì)或論文復(fù)現(xiàn)把上面的模型跑通、畫出漂亮的曲線就夠了。但如果目標(biāo)是工程落地我還想多分享幾點(diǎn)經(jīng)驗(yàn)。第一實(shí)際系統(tǒng)的分時(shí)電價(jià)并不是能夠在連續(xù)區(qū)間內(nèi)隨便定的。執(zhí)行電價(jià)要提前上報(bào)、需要得到監(jiān)管方認(rèn)可、并且要避免頻繁變動(dòng)對(duì)用戶體驗(yàn)造成困擾所以優(yōu)化出來的電價(jià)往往還需要做“圓整和簡化”。我通常會(huì)在優(yōu)化結(jié)束后加一個(gè)后處理腳本把相鄰時(shí)段接近的電價(jià)合并成三段或四段然后再按時(shí)段重新計(jì)算一次負(fù)荷分布。這次重算的結(jié)果才是最終可執(zhí)行的調(diào)度方案。第二真實(shí)光伏出力預(yù)測(cè)存在誤差儲(chǔ)能的實(shí)際可充放電量也受溫度和老化的影響所以模型最好至少保留10%到15%的SOC安全邊界。很多論文圖表里SOC貼著5%跑看著效率很高但現(xiàn)場(chǎng)工程師不會(huì)愿意這么操作因?yàn)橐坏╊A(yù)測(cè)偏差電池過放會(huì)縮短壽命。第三如果你想在答辯或匯報(bào)里更能展示模型價(jià)值建議把“基準(zhǔn)場(chǎng)景-優(yōu)化場(chǎng)景”的收益分解畫一張堆疊柱狀圖把光伏自發(fā)自用的收益、儲(chǔ)能套利收益、售電結(jié)構(gòu)調(diào)整帶來的收益分別顯示出來。這個(gè)圖比單獨(dú)一個(gè)收益數(shù)字有說服力得多也方便評(píng)審老師理解模型各部件的貢獻(xiàn)。6. 一些個(gè)人的復(fù)盤與實(shí)操建議復(fù)現(xiàn)這個(gè)模型的過程中我最大的體會(huì)是不要一次性試圖把雙層、需求響應(yīng)、儲(chǔ)能調(diào)度全部在一個(gè)復(fù)雜求解器里搞定而應(yīng)該先用固定負(fù)荷驗(yàn)證單層調(diào)度再引入用戶負(fù)荷響應(yīng)最后才考慮電價(jià)優(yōu)化。這種漸進(jìn)式復(fù)現(xiàn)方式能把錯(cuò)誤定位在局部也不會(huì)因?yàn)橐婚_始就遇到不收斂的問題而勸退。第二點(diǎn)是數(shù)據(jù)質(zhì)量優(yōu)先于算法復(fù)雜度。我試過拿隨機(jī)生成的負(fù)荷曲線和數(shù)據(jù)去跑結(jié)果模型怎么調(diào)都很難看核心問題不是求解器不夠強(qiáng)而是負(fù)荷曲線本身不合理。建議在復(fù)現(xiàn)之前先花時(shí)間把典型日光伏和負(fù)荷曲線畫出來觀察光伏最大出力時(shí)刻和負(fù)荷高峰時(shí)刻是否錯(cuò)開因?yàn)楹芏喙鈨?chǔ)場(chǎng)景的關(guān)鍵收益來源就是這個(gè)“錯(cuò)峰套利”窗口。如果曲線本身不明顯后面怎么優(yōu)化都是形式主義。第三點(diǎn)就是保持一個(gè)樸素的投資視角。不要沉迷于把目標(biāo)函數(shù)寫得越來越復(fù)雜而要在論文和代碼里反復(fù)驗(yàn)證優(yōu)化出來的電價(jià)、負(fù)荷轉(zhuǎn)移率和儲(chǔ)能充放電策略是不是真的能提升電站收益是不是真的讓用戶省了錢模型里的每一個(gè)公式都應(yīng)該能對(duì)應(yīng)到一個(gè)實(shí)際的商業(yè)或物理邏輯。如果你的模型中某個(gè)約束或者懲罰項(xiàng)并說不清它的實(shí)際意義那大概率只是為了“讓結(jié)果好看”而塞進(jìn)去的到真實(shí)項(xiàng)目里早晚會(huì)出問題。我本人復(fù)現(xiàn)這套代碼花了大約兩個(gè)周末第一個(gè)周末搭架子、跑通固定電價(jià)版本第二個(gè)周末處理雙層耦合和調(diào)試收斂最終的Matlab代碼一共只有300多行核心優(yōu)化語句集中在一個(gè)函數(shù)里。項(xiàng)目代碼里的注釋不夠充分但在實(shí)際復(fù)現(xiàn)時(shí)把YALMIP的約束定義、目標(biāo)函數(shù)、以及求解器設(shè)置整理清楚整個(gè)模型邏輯就守住了一半。后續(xù)如果想繼續(xù)深入建議嘗試把時(shí)間粒度從小時(shí)級(jí)別改成15分鐘級(jí)別再引入實(shí)時(shí)電價(jià)預(yù)測(cè)模型對(duì)比預(yù)測(cè)不確定性和電價(jià)決策之間的相互作用這是當(dāng)前研究的價(jià)值洼地。如果你也在復(fù)現(xiàn)類似模型走通了書里沒有寫清楚的那幾步這篇內(nèi)容的經(jīng)驗(yàn)應(yīng)該能幫你少走不少彎路。祝你在光儲(chǔ)充換電站優(yōu)化這條路上跑出滿意的結(jié)果。