化的微網(wǎng)多電源容量配置Matlab實(shí)現(xiàn))
做微網(wǎng)容量配置的同仁應(yīng)該都有體會風(fēng)光出力一波動、負(fù)荷一變臉之前算好的配置可能立馬就不夠看了。我早先做這類項(xiàng)目時用的還是確定性優(yōu)化加多個典型日場景結(jié)果每次評審都被追問一句“極端場景你考慮了沒有”。后來轉(zhuǎn)用兩階段魯棒優(yōu)化來做微網(wǎng)多電源容量配置把不確定性問題從“事后補(bǔ)丁”變成了“事前兜底”整個項(xiàng)目的說服力提升了一個檔次。這篇博客就把我在Matlab里的完整實(shí)現(xiàn)思路、建模細(xì)節(jié)、求解流程和踩過的坑一次性說清楚想直接復(fù)現(xiàn)的按章節(jié)走就行。1. 核心思路為什么容量配置要用兩階段魯棒優(yōu)化1.1 容量配置問題到底在解決什么微網(wǎng)里的“多電源”一般不是指發(fā)電機(jī)品類多而是指可控與不可控電源的組合。常見配置包括光伏、風(fēng)電這類不可控可再生電源柴油機(jī)或微型燃?xì)廨啓C(jī)這類可控發(fā)電單元再加上儲能系統(tǒng)常規(guī)負(fù)荷里還往往帶一定比例的可中斷負(fù)荷。容量配置要做的事就是在這些候選電源類型和數(shù)量都給定的前提下把每種電源的安裝容量選出來使得整體方案在全壽命周期內(nèi)既滿足供電可靠性又讓綜合費(fèi)用盡量低。這個決策里有個天然的層次矛盾——容量投資是一次性的大額支出而系統(tǒng)運(yùn)行成本是日積月累的支出。如果只考慮投資成本配得越少越省錢但運(yùn)行階段可能天天買高價(jià)電如果只考慮運(yùn)行成本配得越足越穩(wěn)但投資回收期會拉得很難看。容量配置問題本質(zhì)上就是要把這兩個階段的目標(biāo)捏在一起做聯(lián)合優(yōu)化。傳統(tǒng)做法是把典型日場景固定下來比如春季、夏季、大負(fù)荷日、小負(fù)荷日各挑幾天讓優(yōu)化模型在這幾個場景下做運(yùn)行模擬再把運(yùn)行費(fèi)用折算進(jìn)目標(biāo)函數(shù)。這種方法的弱點(diǎn)很明顯所選的典型日終究只是歷史數(shù)據(jù)的抽樣萬一未來出現(xiàn)比歷史更惡劣的連續(xù)陰雨天、風(fēng)速長時間偏小、或者負(fù)荷尖峰疊加新能源低谷的情況按這套容量配置出來的微網(wǎng)可能直接撐不住。兩階段魯棒優(yōu)化把不確定性直接納入到了模型結(jié)構(gòu)里。它不再問“這些給定場景下能不能跑通”而是問“在允許的不確定性范圍內(nèi)最惡劣的場景下系統(tǒng)能不能扛得住、運(yùn)行費(fèi)用最多是多少”。這個視角的轉(zhuǎn)變讓結(jié)果對邊界條件天然保守恰好適合容量配置這種要管五年十年的大決策。1.2 為什么用“兩階段”結(jié)構(gòu)表達(dá)這個問題把數(shù)學(xué)模型攤開看容量配置有兩個層次的動作需要優(yōu)化第一階段這里在知道不確定參數(shù)可能的取值范圍、但不知道具體出力的前提下決定各電源的裝機(jī)容量。第二階段運(yùn)行層在容量給定、不確定參數(shù)的具體取值被揭示后做實(shí)時經(jīng)濟(jì)調(diào)度也就是在各機(jī)組出力、儲能充放電之間找到成本最低的運(yùn)行方案。這兩個階段時間尺度不同信息結(jié)構(gòu)也不同。第一階段是“看分布做決策”第二階段是“看實(shí)現(xiàn)做響應(yīng)”。兩階段魯棒優(yōu)化的目標(biāo)函數(shù)就是先求第一階段的投資成本再加上第二階段在最壞不確定場景下的最小運(yùn)行成本。寫成數(shù)學(xué)語言就是典型的“min-max-min”結(jié)構(gòu)外層min對應(yīng)容量決策中間max對應(yīng)不確定性集合里挑最壞場景內(nèi)層min對應(yīng)運(yùn)行調(diào)度優(yōu)化。這里的核心難點(diǎn)在于中間層的max不是隨便挑一個場景而是要對整個不確定性集合求最大。如果直接把三種不確定變量風(fēng)電、光伏、負(fù)荷的所有組合都枚舉一遍計(jì)算量是指數(shù)級的在容量配置這種中等規(guī)模問題上根本跑不動。后面要講的列與約束生成算法CCG就是專門用來對付這個難題的它不枚舉所有場景而是讓“壞場景”在迭代中自己浮出水面。1.3 與隨機(jī)規(guī)劃、信息間隙決策理論的對比取舍做微網(wǎng)規(guī)劃的同行還會遇到隨機(jī)規(guī)劃和信息間隙決策理論IGDT等備選方案。簡單說下我的取舍理由隨機(jī)規(guī)劃需要預(yù)設(shè)不確定參數(shù)的概率分布且理論上要有足夠多的場景保證收斂。工程里風(fēng)光出力的精確分布往往很難拿到即便拿歷史數(shù)據(jù)擬合尾部風(fēng)險(xiǎn)也常被低估。計(jì)算量同樣不小。信息間隙決策理論它在給定“偏差幅度”下最大化系統(tǒng)對偏差的承受能力不需要分布思路很簡潔但對非線性約束的處理比較麻煩而且它的魯棒性度量方式偏向“最大可承受偏差”和工程上關(guān)心“最壞情況下的費(fèi)用”表述不太一致。兩階段魯棒優(yōu)化只需要不確定量落在某個有界集合內(nèi)即可不要求精確概率求解結(jié)果直接給出最壞情況下的運(yùn)行成本上界。這種“以集合代替分布”的做法在數(shù)據(jù)有限場景下非常實(shí)用。所以最終選兩階段魯棒優(yōu)化不是因?yàn)樗呒壎且驗(yàn)樗汀叭萘颗渲眯枰5?、?shù)據(jù)又不夠精細(xì)”這一工程需求最匹配。2. 建模細(xì)節(jié)目標(biāo)函數(shù)、約束與不確定性集合的構(gòu)建2.1 目標(biāo)函數(shù)的分層設(shè)計(jì)模型的目標(biāo)函數(shù)分兩層寫第一層是投資成本其中p代表電源類型索引涵蓋光伏pv、風(fēng)電wt、柴油機(jī)de、儲能es等c_p是單位容量投資成本N_p是安裝容量r是折現(xiàn)率L是規(guī)劃年限。這樣可以把一次性投資折算成等年值和年運(yùn)行成本放在同一個時間尺度上比較。第二層是在所有可能的風(fēng)光出力和負(fù)荷波動下取運(yùn)行成本最大的那個場景然后對應(yīng)該最惡劣場景求經(jīng)濟(jì)調(diào)度的最小運(yùn)行成本是燃料成本由柴油機(jī)出力和燃油單價(jià)決定是向上級電網(wǎng)購電時支付的購電成本有時還要把切負(fù)荷懲罰加進(jìn)去表示在極端場景下不得已切除一部分負(fù)荷的代價(jià)如果配置了儲能還可以考慮儲能循環(huán)老化折算成的運(yùn)行維護(hù)成本。兩者合起來就是整個兩階段魯棒優(yōu)化模型的函數(shù)主體這里要注意一個容易被忽略的點(diǎn)運(yùn)行成本內(nèi)部求的是min但它的外層又被max包住。也就是說調(diào)度員在給定容量下總會盡力把運(yùn)行成本壓到最低但大自然不確定性會挑一個讓這個最低成本最高的場景來“為難”你。這種對抗式邏輯正是魯棒優(yōu)化的靈魂。2.2 約束條件的幾大核心族建模時約束數(shù)量看著多核心其實(shí)就幾個族規(guī)劃階段和運(yùn)行階段分開列。規(guī)劃階段的核心約束是容量上界與安裝數(shù)量約束。每種電源的總安裝容量不能超過該場地或預(yù)算對應(yīng)的上限比如屋頂光伏受可用面積限制風(fēng)機(jī)受占地面積和噪聲限制。這條約束在Math中表達(dá)為運(yùn)行階段的約束是最多的主要包括功率平衡約束任意時刻所有電源出力、儲能放電、購電功率的總和等于負(fù)荷加儲能充電功率。求解中這個約束要帶平衡變量處理否則在極端場景下可能因?yàn)楣β薀o法平衡而彈出“infeasible”。儲能動態(tài)約束包括充電功率上限、放電功率上限、荷電狀態(tài)SOC上下限、以及SOC的時間遞推關(guān)系這里充放電效率、分別參與兩個方向的能量轉(zhuǎn)換同時還要避免同一個時刻既充電又放電的邏輯錯誤。實(shí)踐中最常見的做法是引入充電狀態(tài)和放電狀態(tài)的0-1變量來互斥否則連續(xù)變量求解器很容易給出“邊充邊放”這種物理上無意義但數(shù)學(xué)上似乎可行的解??煽仉娫闯隽团榔录s束柴油機(jī)的出力有上下限單位時間內(nèi)增減出力還受爬坡率限制。容量配置階段如果不加爬坡約束運(yùn)行成本會被樂觀估計(jì)配置結(jié)果會偏向多裝柴油機(jī)、少裝儲能。我在實(shí)際項(xiàng)目里吃過這個虧建議大家從建模第一天就把爬坡約束放進(jìn)去。棄風(fēng)棄光約束為了給魯棒優(yōu)化留出可行性余地可再生能源出力可以適度削減但削減量要控制在某個比例以內(nèi)比如不得高于預(yù)測出力的5%。這條約束也叫“可再生能源利用率下限”它的存在避免了魯棒解為了“抗最壞場景”而過度配置儲能、同時又在正常場景拼命棄風(fēng)棄光這種自相矛盾的結(jié)果。2.3 不確定性集合的取舍與數(shù)學(xué)表達(dá)兩階段魯棒優(yōu)化里不確定性集合的選擇直接決定求解難度和結(jié)果保守度。常用的有盒式不確定集每個不確定參數(shù)獨(dú)立地在區(qū)間內(nèi)波動數(shù)學(xué)上最簡單但所有參數(shù)同時取極端值的概率極低做出來會過于保守。多面體不確定集在盒式基礎(chǔ)上加一個“總偏差預(yù)算”要求所有不確定參數(shù)偏離預(yù)測值的總量不能超過某個閾值。它把獨(dú)立極端情況限制住了保守度低不少數(shù)學(xué)上依然保持線性結(jié)構(gòu)。橢球不確定集用橢球描述相關(guān)性數(shù)學(xué)上更精細(xì)但會把模型變成二階錐規(guī)劃求解器要求和計(jì)算時間都上一個臺階。工程上最常用的還是多面體不確定集。以光伏為例可以寫成負(fù)荷的寫法類似只是把、換成和。這里的一組0-1變量和一組連續(xù)變量會并存0-1變量決定波動方向連續(xù)變量決定波動幅度。預(yù)算參數(shù)直接控制保守程度——設(shè)得越大允許同時波動的變量越多結(jié)果越保守設(shè)得越小解的魯棒性越弱。從實(shí)操來看我通常建議先把設(shè)為0跑一版確定性模型作為費(fèi)用下限再把設(shè)為極端值跑一版最保守模型作為費(fèi)用上限。中間取若干檔位做靈敏度分析能畫出“保守度-成本”曲線這個曲線在項(xiàng)目評審時非常有用比單給一個“最優(yōu)解”有說服力得多。3. 兩階段魯棒求解CCG算法的原理與實(shí)現(xiàn)路徑3.1 “min-max-min”三層結(jié)構(gòu)到底在算什么剛才提到模型整體是“min-max-min”結(jié)構(gòu)很多人第一次看到會覺得有點(diǎn)繞。我用一個通俗的類比拆開講第一層min容量決策你作為微網(wǎng)規(guī)劃師現(xiàn)在要拍板裝多少光伏、多少風(fēng)機(jī)、多少儲能。決策完設(shè)備錢就花出去了。中間層max自然選擇你不知道未來光照、風(fēng)速、負(fù)荷到底會怎樣但你清楚它們會落在某個波動范圍內(nèi)。大自然這時候“站了出來”替你挑了一個讓你運(yùn)行成本最高的組合。內(nèi)層min調(diào)度響應(yīng)面對這個已經(jīng)發(fā)生的“壞場景”微網(wǎng)的運(yùn)行調(diào)度系統(tǒng)會立刻做出最優(yōu)響應(yīng)——柴油機(jī)多出力、儲能放電、或者切掉一部分負(fù)荷盡量把這一天的運(yùn)行費(fèi)壓到最低。如果把這個邏輯寫成一句話就是在你最擔(dān)心的世界里做最經(jīng)濟(jì)的應(yīng)對。容量配置決策能不能扛住這個“最擔(dān)心的世界”就是魯棒優(yōu)化給出的答案。3.2 CCG算法主流程詳解CCGColumn and Constraint Generation列與約束生成是目前求解兩階段魯棒優(yōu)化最主流的精確算法之一它的核心思路不是枚舉所有場景而是“讓極端場景在迭代中自己長出來”每一輪只往主問題里加一個最惡劣場景對應(yīng)的約束。算法寫成偽碼很清晰初始化設(shè)置下界為負(fù)無窮上界為正無窮設(shè)定一個初始的“壞場景”通常取不確定參數(shù)的名義值即預(yù)測值設(shè)定收斂閾值比如0.01。求解主問題MP主問題里包含第一階段容量決策變量、第二階段運(yùn)行變量以及所有已經(jīng)識別出來的惡劣場景約束。解出來得到容量配置和當(dāng)前下界。固定容量配置求解子問題SP子問題是一個“給定容量、找最壞場景、算最小運(yùn)行成本”的優(yōu)化問題解出來得到當(dāng)前最壞場景和對應(yīng)的運(yùn)行成本再疊加投資成本得到當(dāng)前上界。收斂判斷如果上界和下界的相對誤差小于閾值停止迭代把當(dāng)前容量配置作為最終結(jié)果輸出。如果沒收斂把子問題解出來的這個最壞場景對應(yīng)的運(yùn)行變量和約束以新列的形式加入到主問題中返回步驟2繼續(xù)迭代。這個流程里最微妙的點(diǎn)在第5步——每輪迭代不是簡單改個參數(shù)而是往主問題里新增一組完整約束包含該場景下的功率平衡、儲能動態(tài)、機(jī)組出力等讓主問題規(guī)模逐輪增大但每一輪都會更接近“所有極端場景都被考慮”的收斂狀態(tài)。3.3 子問題的對偶轉(zhuǎn)化與KKT條件處理子問題本身是一個內(nèi)嵌max的min問題不能直接用現(xiàn)成的商業(yè)求解器求解。解決這個問題的兩種主流途徑是強(qiáng)對偶轉(zhuǎn)化利用線性規(guī)劃的對偶理論把內(nèi)層的min問題替換為它的對偶max問題這樣整個子問題就變成一個單層的max問題外層找壞場景、內(nèi)層變成了對偶max合起來是max-max直接合并成一個max問題。這個方法的前提是內(nèi)層模型是線性且可行的強(qiáng)對偶定理保證二者最優(yōu)值相等。KKT條件轉(zhuǎn)化把內(nèi)層min問題的最優(yōu)性條件KKT條件作為約束加入外層問題中這樣也把雙層問題壓成了單層。但KKT條件里的互補(bǔ)松弛條件會引入非線性項(xiàng)需要借助大M法線性化。從我的使用經(jīng)驗(yàn)看只要模型保持線性優(yōu)先用強(qiáng)對偶轉(zhuǎn)化它實(shí)現(xiàn)簡單、對求解器友好。只有在模型里不得不加入非線性因素、強(qiáng)對偶無法直接套用的場景下才考慮KKT路線。這里有一個工程細(xì)節(jié)提醒做對偶轉(zhuǎn)化時內(nèi)層min問題里的“運(yùn)行成本”目標(biāo)函數(shù)寫多了哪個二次項(xiàng)或絕對值項(xiàng)對偶形式就會變得很難處理。比如儲能充放電損耗如果是按“功率平方”建模那內(nèi)層就不是LP強(qiáng)對偶就不能直接用了。前期的模型線性化工作直接影響后面能不能順利套用CCG。3.4 外逼近與CCG的差異性對比做魯棒優(yōu)化的文獻(xiàn)里還有一類叫“外逼近”outer approximation的算法容易和CCG混淆。我的理解是外逼近法在迭代中用一階近似約束逼近子問題的最優(yōu)值函數(shù)它對凸問題的效果很好但對離散變量的處理比較弱CCG則通過直接添加第二階段的變量和約束來逼近它不需要最優(yōu)值函數(shù)的光滑性假設(shè)對混合整數(shù)問題更友好。容量配置問題里儲能充放電狀態(tài)是0-1變量柴油機(jī)啟停也可能引入整數(shù)變量這些離散量的存在會讓外逼近的處理變得很啰嗦而CCG天然不怕。所以我最終在Matlab里落地的是CCG下面所有代碼也都圍繞這個算法展開。4. Matlab實(shí)操代碼框架、求解器配置與關(guān)鍵實(shí)現(xiàn)4.1 求解環(huán)境與依賴說明我在Windows環(huán)境下的Matlab R2022b上完成實(shí)現(xiàn)調(diào)用的是YALMIP工具箱加CPLEX求解器。如果你們手頭沒有CPLEX用Gurobi也可以代碼的頂層結(jié)構(gòu)完全不用動只需要把YALMIP的solver設(shè)置那一行改掉。有一點(diǎn)務(wù)必確認(rèn)CCG里的主問題和子問題都涉及混合整數(shù)規(guī)劃不要用Matlab自帶的linprog或intlinprog去硬扛那個規(guī)模和速度在迭代求解下會很痛苦。工程上至少要用CPLEX、Gurobi或MOSEK這類商業(yè)求解器。4.2 模型參數(shù)與典型場景準(zhǔn)備實(shí)現(xiàn)的第一步是把以下參數(shù)準(zhǔn)備好電源候選集合每種電源的單位投資成本、壽命、最大允許安裝容量單位運(yùn)行成本柴油燃料單價(jià)、單位購電電價(jià)、切負(fù)荷懲罰單價(jià)不確定量預(yù)測值典型日24小時的光伏出力標(biāo)幺值、風(fēng)電出力標(biāo)幺值、負(fù)荷標(biāo)幺值序列不確定性集合參數(shù)波動幅度的上下界、預(yù)算參數(shù)、以及可切負(fù)荷比例儲能參數(shù)容量單價(jià)、功率上限、SOC上下限、充放電效率、初始SOC調(diào)度約束參數(shù)柴油機(jī)出力上下限、爬坡率、最小運(yùn)行時間。所有時序數(shù)據(jù)都按小時分辨率建模典型日的數(shù)量可以取3到4個。如果只做示例可以先用一個典型日跑通代碼再擴(kuò)展到多典型日。4.3 主問題的YALMIP建模框架這里給出一個精簡但完整的主問題建??蚣荜P(guān)鍵模塊分了四塊決策變量聲明、投資成本目標(biāo)、運(yùn)行約束塊、以及CCG迭代用的場景約束塊。% 決策變量第一階段 N_pv sdpvar(1,1); % 光伏安裝容量 N_wt sdpvar(1,1); % 風(fēng)電安裝容量 N_de sdpvar(1,1); % 柴油機(jī)安裝容量 N_es sdpvar(1,1); % 儲能安裝容量 % 決策變量第二階段在當(dāng)前場景集合下 P_pv sdpvar(T,1); % 光伏實(shí)際出力 P_wt sdpvar(T,1); % 風(fēng)電實(shí)際出力 P_de sdpvar(T,1); % 柴油機(jī)出力 P_ch sdpvar(T,1); % 儲能充電功率 P_dis sdpvar(T,1); % 儲能放電功率 SOC sdpvar(T1,1); % 儲能荷電狀態(tài) P_buy sdpvar(T,1); % 購電功率 P_cut sdpvar(T,1); % 切負(fù)荷功率 u_ch binvar(T,1); % 充電狀態(tài)標(biāo)記 u_dis binvar(T,1); % 放電狀態(tài)標(biāo)記 % 目標(biāo)函數(shù)投資等年值 運(yùn)行成本運(yùn)行成本是從屬部分 inv_cost (c_pv*N_pv c_wt*N_wt c_de*N_de c_es*N_es) * crf; obj inv_cost (1/sce_num) * sum(oper_cost); % 多場景取平均CCG里場景逐輪新增這段代碼里crf是把一次性投資折算成年值的等額分付資本回收系數(shù)。它的計(jì)算是也就是通過折現(xiàn)率r和壽命年限L把全部投資折算成每年等額支付。這是個非常常用的財(cái)務(wù)轉(zhuǎn)換系數(shù)不要漏掉它否則投資成本和年運(yùn)行成本不在同一時間軸上模型結(jié)果會系統(tǒng)性偏向多裝儲能。另外主問題里的場景塊不是一次性寫全的而是在CCG迭代過程中不斷追加。因此我在建模時采用了一個場景計(jì)數(shù)的循環(huán)每輪迭代把新場景的約束用“追加約束”的方式加進(jìn)YALMIP的約束列表中。4.4 子問題的強(qiáng)對偶轉(zhuǎn)化與YALMIP實(shí)現(xiàn)子問題的數(shù)學(xué)形式是“給定N先max挑場景再min算調(diào)度成本”。對內(nèi)層min做對偶轉(zhuǎn)化后整個子問題變成一個max問題可以直接用YALMIP建模求解。核心實(shí)現(xiàn)思路是先把內(nèi)層min問題寫成標(biāo)準(zhǔn)LP形式提取出其對偶變量把內(nèi)層min的約束轉(zhuǎn)成對偶可行域約束目標(biāo)函數(shù)改為外層不確定變量驅(qū)動的目標(biāo)部分加對偶目標(biāo)部分注意最后要加上對偶問題中的常數(shù)項(xiàng)也就是固定容量參數(shù)對應(yīng)的那一塊。在我的代碼里子問題被封裝成一個獨(dú)立的函數(shù)輸入是當(dāng)前容量配置輸出是最壞場景下的運(yùn)行成本、對應(yīng)的最壞場景參數(shù)以及當(dāng)前上界。這里有個很關(guān)鍵的對偶實(shí)現(xiàn)細(xì)節(jié)% 內(nèi)層min問題示意 % min c*x d*u % s.t. A*x B*u b % x 0, u是有界不確定變量 % 對偶后目標(biāo)為 max b*lambda - (B*u)*lambda % 對偶可行域 A*lambda c % lambda 0 % 原運(yùn)行變量x被消去只剩對偶變量lambda和外層不確定變量u用YALMIP寫子問題時不需要手工推導(dǎo)出所有的對偶表達(dá)式可以借助YALMIP的dualize命令來自動處理線性規(guī)劃的對偶。這一點(diǎn)對新手尤其友好能大幅減少手工推導(dǎo)出錯的可能。但要注意dualize只適用于連續(xù)線性規(guī)劃如果內(nèi)層有0-1變量就得先把整數(shù)變量作為“給定參數(shù)”剝離出去或者改用KKT路線。4.5 CCG迭代主循環(huán)的代碼骨架主循環(huán)邏輯寫出來非常短但就是這段短代碼扛起了整個迭代UB inf; LB -inf; tol 1e-3; nominal_u get_nominal_scenario(); % 名義場景作為初始壞場景 while abs(UB - LB) / abs(LB) tol % 1. 把當(dāng)前最壞場景加入主問題的場景列表 mp build_mp(k, nominal_u, worst_u_set); optimize(mp, obj_mp, sdpsettings(solver,cplex,verbose,0)); LB value(obj_mp); N_now get_capacity(value([N_pv,N_wt,N_de,N_es])); % 2. 固定容量解子問題找新的最壞場景 [sp_obj, worst_u_new] solve_sp(N_now); UB value(inv_cost) sp_obj; % 3. 收斂判斷 if abs(UB - LB)/abs(LB) tol break; end worst_u_set [worst_u_set; worst_u_new]; % 新場景入列 end初次接觸這段流程的讀者會發(fā)現(xiàn)主問題每輪都要重新求解一次而新增的約束越來越多求解時間會隨迭代輪數(shù)增長。這是正?,F(xiàn)象不代表程序?qū)憠牧恕奈业膶?shí)踐看一般迭代十輪以內(nèi)就能收斂到相對誤差1%以內(nèi)總耗時在幾分鐘量級工程上完全能接受。4.6 結(jié)果可視化的常見處理算法跑完后建議把以下幾張圖和表整理出來各類電源的容量配置柱狀圖直觀對比投資占比最壞場景下的24小時功率平衡曲線包括光伏、風(fēng)電、柴油機(jī)、儲能、購電和負(fù)荷曲線確認(rèn)功率平衡約束確實(shí)被滿足“保守度-成本”曲線橫軸是某個不確定參數(shù)的預(yù)算值縱軸是最優(yōu)年化總成本這是評審時最有說服力的單張圖儲能SOC曲線檢查是否在允許范圍內(nèi)波動并確認(rèn)沒有出現(xiàn)無意義的邊充邊放行為。計(jì)算完成后還可以順手算一個關(guān)鍵指標(biāo)——最壞場景下的運(yùn)行成本相對確定性模型運(yùn)行成本的增量。這個增量就是“魯棒溢價(jià)”它告訴決策者為了對抗不確定性系統(tǒng)每年要多付出多少運(yùn)行成本。有時候這個溢價(jià)算出來并不高但能讓方案在極端天氣里不趴窩這筆賬就非常劃算。5. 常見問題與排查技巧實(shí)錄5.1 CCG迭代不收斂或收斂速度極慢現(xiàn)象迭代了二三十輪UB和LB之差始終降不下來。排查思路先懷疑不確定性集合的預(yù)算參數(shù)是否設(shè)置得過大導(dǎo)致最壞場景過于極端每次新場景都讓主問題的容量決策大幅跳變再檢查子問題的壞場景搜索是否正確可以打印每輪找到的最壞場景看是否在幾個極端點(diǎn)之間反復(fù)橫跳。最有效的加速手段就是“多場景并行初始化”。我一般會先把每個不確定參數(shù)單獨(dú)取極端值比如光伏全低、風(fēng)電全高、負(fù)荷全高的排列組合作為初始場景一次性塞進(jìn)主問題的場景集里。這樣前兩輪迭代就能把保守度拉到位后面幾輪只是微調(diào)收斂速度能提升一倍以上。另一個加速技巧是給主問題加“正則化”約束比如限制相鄰兩輪容量配置的總變動幅度不超過某個閾值。這本質(zhì)上改變了問題的收斂路徑但不會影響最終收斂點(diǎn)。對大型實(shí)例這種技巧幾乎必用。5.2 子問題出現(xiàn)infeasible提示這個是我調(diào)試早期代碼時遇到最多的問題。原因通常是給定某組容量N后最壞場景下的功率平衡約束根本無法滿足比如切負(fù)荷上限設(shè)置太小或者儲能容量設(shè)得太低導(dǎo)致備用完全不足。處理方式有三種調(diào)整可切負(fù)荷比例上限比如從5%放寬到10%增大儲能的功率上限或容量上下限把外購電力的購電上限從固定值改成可變上限并接入本地配電網(wǎng)的容量約束。還有一個更穩(wěn)妥的做法是在子問題里加入“松弛變量”目標(biāo)函數(shù)對松弛變量給予極高懲罰系數(shù)。這樣即使某個極端場景下不平衡量不為零子問題也能給出一個帶懲罰費(fèi)用的解CCG主流程不會中斷。最后再檢查最優(yōu)解中松弛變量的值如果很大說明該容量配置確實(shí)不可行需要在主問題中強(qiáng)制增加容量。5.3 對偶轉(zhuǎn)化結(jié)果與原始問題不一致這種情況最隱蔽排查難度也最大我遇到過兩次最后發(fā)現(xiàn)都是建模里的符號問題。例如原問題中的不等式方向?qū)懛崔D(zhuǎn)對偶時對偶變量非負(fù)條件就反了。另一個高頻錯誤是把等式約束誤寫成了不等式約束對偶后出現(xiàn)自由度丟失解出來的“最壞場景”根本不在原問題允許范圍內(nèi)。我的排查方法是不要只相信對偶推導(dǎo)結(jié)果先用一個小規(guī)模實(shí)例固定一組容量值直接枚舉所有可能的不確定場景組合把真實(shí)的最壞運(yùn)行成本算出來同時用對偶轉(zhuǎn)化的子問題求一遍二者比對。數(shù)值一致說明對偶過程沒問題如果不一致縮小模型規(guī)模逐步二分定位出錯約束直到找出符號或系數(shù)寫錯的位置。5.4 求解器頻繁報(bào)數(shù)值問題YALMIP里經(jīng)常遇到的警告是“big-M too large”或“numerical issues”。這類問題的根源往往是儲能SOC約束或充放電互斥約束里用了過大或過小的大M參數(shù)。我的經(jīng)驗(yàn)法則是大M取該約束涉及變量取值范圍的10倍即可。比如SOC范圍是0到1大M取10就足夠不用為了“保險(xiǎn)”取到10000。另外模型里不同約束之間存在數(shù)量級差異時比如投資成本是百萬級SOC是0到1最好對參數(shù)和變量做歸一化處理比如把所有功率和容量都用標(biāo)幺值表示。歸一化后數(shù)值穩(wěn)定性明顯改善CPLEX的迭代步長也正常很多。5.5 常見問題速查表問題現(xiàn)象主要原因建議處理迭代多輪不收斂預(yù)算參數(shù)過大或場景初始集合太弱減小預(yù)算值用極端組合做初始場景UB低于LB對偶推導(dǎo)錯誤或子問題遺漏約束用小規(guī)模暴力枚舉驗(yàn)證對偶正確性子問題infeasible容量不足導(dǎo)致最壞場景無法平衡引入松弛變量設(shè)置切負(fù)荷上限主問題規(guī)模過大求解緩慢場景數(shù)量累積過多定期清理冗余場景重新構(gòu)造子集儲能出現(xiàn)邊充邊放缺0-1互斥約束或M參數(shù)不當(dāng)加入互斥二進(jìn)制變量規(guī)范化大M結(jié)果為全裝儲能或全裝柴油機(jī)目標(biāo)函數(shù)量綱不一致或缺少約束檢查等年值轉(zhuǎn)換確認(rèn)運(yùn)行約束完整6. 實(shí)操體會與補(bǔ)充建議寫到這分享幾個我從多個項(xiàng)目里沉淀下來的體會希望能幫大家少走彎路。第一點(diǎn)不要一上來就追求最嚴(yán)苛的保守度。容量配置的最終目的是讓微網(wǎng)在真實(shí)場景下運(yùn)行經(jīng)濟(jì)、可靠而不是在數(shù)學(xué)意義上“永遠(yuǎn)不敗”。把預(yù)算參數(shù)從松到緊多調(diào)幾檔畫一張成本和魯棒性的權(quán)衡曲線再定方案這是我做項(xiàng)目時最常用也讓各方都認(rèn)可的操作。評審專家喜歡這張曲線比冗長的公式推導(dǎo)更有說服力。第二點(diǎn)兩階段魯棒優(yōu)化的計(jì)算結(jié)果最好再配一輪蒙特卡洛仿真來校核。具體做法是把優(yōu)化得到的容量配置固定住隨機(jī)生成幾千組可能的風(fēng)光負(fù)荷序列模擬運(yùn)行并統(tǒng)計(jì)切負(fù)荷率和平均運(yùn)行成本。如果蒙特卡洛測試中極少出現(xiàn)切負(fù)荷說明預(yù)算參數(shù)設(shè)保守了可以適當(dāng)放松如果切負(fù)荷頻繁說明魯棒程度不夠需要調(diào)大預(yù)算參數(shù)。這種“優(yōu)化仿真”雙驗(yàn)證模式是我目前最推薦的做法能有效防止魯棒模型在“工程直覺”和“數(shù)學(xué)最優(yōu)”之間跑偏。第三點(diǎn)代碼一定要模塊化。主問題構(gòu)建、子問題求解、參數(shù)定義、結(jié)果后處理分開寫成多個函數(shù)。原因不只是維護(hù)方便更重要是CCG迭代時要反復(fù)調(diào)用子問題求解函數(shù)如果每個子問題都是單獨(dú)一個腳本文件調(diào)試時改一處變量名整個項(xiàng)目就全亂了。模塊化之后換一組新參數(shù)測新案例只需要改參數(shù)腳本求解核心根本不動。第四點(diǎn)規(guī)模放大時優(yōu)先考慮場景削減和約束篩選。如果微網(wǎng)節(jié)點(diǎn)多、電源類型多、時間分辨率細(xì)CCG的主問題規(guī)模會膨脹得很快。此時可以先按典型日聚類初步壓縮數(shù)據(jù)從根源減少場景數(shù)量還能在迭代過程中定期檢查已有場景約束中有沒有冗余約束——如果連續(xù)多輪迭代某個約束的松弛變量始終為零就可以把它從主問題中臨時移除以節(jié)省內(nèi)存和求解時間。最后想說的是兩階段魯棒優(yōu)化在微網(wǎng)容量配置里的價(jià)值不是它比傳統(tǒng)方法算得快、算得準(zhǔn)而是它逼著你把“最壞情況”拿出來擺在桌面上公開討論。做電力系統(tǒng)規(guī)劃最怕的就是方案只在正常工況下漂亮一到特殊天氣就捉襟見肘。魯棒優(yōu)化至少讓所有參與決策的人都知道這個方案最差會差到什么程度。如果你的微網(wǎng)項(xiàng)目將來可能面對比較嚴(yán)苛的并網(wǎng)考核或者極端天氣考驗(yàn)花點(diǎn)時間把兩階段魯棒這套工具用起來大概率不會讓你后悔。