經(jīng)濟(jì)調(diào)度實(shí)戰(zhàn)解析)
最近有好幾個(gè)做電力系統(tǒng)方向的朋友跟我聊起同一個(gè)話題碳排放交易機(jī)制到底怎么揉進(jìn)優(yōu)化調(diào)度模型里而且要求還特別具體——要用分布式ADMM來(lái)解。這個(gè)方向確實(shí)是目前論文和工程落地的一個(gè)交叉熱點(diǎn)一方面雙碳目標(biāo)下碳約束成了調(diào)度的硬命題另一方面集中式優(yōu)化在大規(guī)模多區(qū)域電網(wǎng)里越來(lái)越吃力加上分布式ADMM天然適合多利益主體、多控制中心的架構(gòu)兩者疊在一起就成了很自然的選項(xiàng)。我自己完整復(fù)現(xiàn)過(guò)一個(gè)基于分布式ADMM、考慮碳排放交易的電力系統(tǒng)經(jīng)濟(jì)調(diào)度算例從模型搭建、算法推導(dǎo)到MATLAB編碼踩了不少坑也攢了一些比較實(shí)用的經(jīng)驗(yàn)。這篇文章就把整個(gè)思路、建模過(guò)程、代碼架構(gòu)和排錯(cuò)心得一次性講清楚適合正在做相關(guān)課題的學(xué)生、剛接觸分布式優(yōu)化的工程師或者想在自己的調(diào)度系統(tǒng)里加碳約束的開(kāi)發(fā)者參考。不保證寫(xiě)得絕對(duì)學(xué)術(shù)嚴(yán)謹(jǐn)?shù)WC是從實(shí)操角度能直接抄作業(yè)的那種。1. 為什么這個(gè)方向值得做分布式ADMM與碳排放交易的組合邏輯1.1 集中式調(diào)度的問(wèn)題出在哪傳統(tǒng)電力系統(tǒng)經(jīng)濟(jì)調(diào)度以集中式為主調(diào)度中心收集全網(wǎng)機(jī)組參數(shù)、負(fù)荷預(yù)測(cè)、網(wǎng)絡(luò)拓?fù)浣y(tǒng)一求解一個(gè)全局優(yōu)化問(wèn)題。這種方式在電網(wǎng)規(guī)??煽?、信息完全公開(kāi)的前提下很有效但放到現(xiàn)在的場(chǎng)景下就有點(diǎn)吃力了。首先是計(jì)算量的問(wèn)題。多區(qū)域互聯(lián)電網(wǎng)模型規(guī)模大、約束多全網(wǎng)集中建模后優(yōu)化問(wèn)題的變量維度和約束數(shù)量都會(huì)暴漲單次求解時(shí)間會(huì)變得非常難看。尤其調(diào)度周期從小時(shí)級(jí)擴(kuò)展到分鐘級(jí)滾動(dòng)優(yōu)化之后集中式算法在計(jì)算速度上很難滿(mǎn)足實(shí)時(shí)性需求。更重要的是隱私與協(xié)調(diào)的矛盾?,F(xiàn)代電網(wǎng)往往是多主體協(xié)同架構(gòu)不同區(qū)域的電網(wǎng)由不同控制中心管理新能源場(chǎng)站、儲(chǔ)能運(yùn)營(yíng)商、售電公司各有各的商業(yè)數(shù)據(jù)。機(jī)組成本曲線、負(fù)荷預(yù)測(cè)、可調(diào)容量這些信息沒(méi)有哪一方愿意當(dāng)作公開(kāi)數(shù)據(jù)交給一個(gè)中心化的調(diào)度平臺(tái)。集中式調(diào)度要求所有參與者上交核心私有信息這在工程上并不現(xiàn)實(shí)。還有一個(gè)容易被忽略的問(wèn)題集中式方案的單點(diǎn)故障風(fēng)險(xiǎn)。一旦調(diào)度中心出問(wèn)題整個(gè)優(yōu)化調(diào)度鏈條就癱瘓了。分布式架構(gòu)天然規(guī)避了這一點(diǎn)各區(qū)域可以獨(dú)立運(yùn)行、按需通信。所以分布式優(yōu)化不是“為了分布式而分布式”而是確實(shí)有多區(qū)域協(xié)調(diào)、數(shù)據(jù)隱私保護(hù)、高可靠性的現(xiàn)實(shí)需求。1.2 ADMM的分布式思路ADMM全稱(chēng)是交替方向乘子法它的核心思想是“分解-協(xié)調(diào)”。把一個(gè)大的全局優(yōu)化問(wèn)題拆成若干個(gè)可以獨(dú)立求解的子問(wèn)題子問(wèn)題各自求解后交換少量邊界信息通過(guò)迭代逐步逼近全局最優(yōu)解。我用一個(gè)很生活化的例子說(shuō)明ADMM的原理。假設(shè)三個(gè)朋友一起做飯一個(gè)人負(fù)責(zé)洗菜、一個(gè)人負(fù)責(zé)炒菜、一個(gè)人負(fù)責(zé)擺盤(pán)但廚房只有一個(gè)灶臺(tái)、一個(gè)水池。如果各自完全獨(dú)立干活會(huì)因?yàn)橘Y源沖突亂成一團(tuán)如果所有事都集中到一個(gè)人身上安排其他人的靈活度又沒(méi)了。ADMM的思路是大家各自干各自的活但每隔一段時(shí)間對(duì)一下表——你什么時(shí)候用灶臺(tái)、我什么時(shí)候用水池通過(guò)反復(fù)協(xié)調(diào)最終形成一套大家都能接受的安排而且整體效率接近集中統(tǒng)籌的結(jié)果。在電力系統(tǒng)調(diào)度里這個(gè)“對(duì)表”的過(guò)程就是各區(qū)域之間交換聯(lián)絡(luò)線功率或邊界節(jié)點(diǎn)相角信息每次迭代都向全局一致性目標(biāo)靠攏一點(diǎn)。ADMM最優(yōu)秀的地方在于第一它不要求目標(biāo)函數(shù)嚴(yán)格凸很多實(shí)際中的非光滑項(xiàng)比如機(jī)組啟停的0-1變量帶來(lái)的非凸性、碳排放配額的階躍約束也能在框架里較好地處理第二收斂性理論相對(duì)成熟在溫和條件下可以證明收斂到全局最優(yōu)或局部最優(yōu)第三實(shí)現(xiàn)簡(jiǎn)單只需要在現(xiàn)有優(yōu)化求解器外面包一層迭代循環(huán)即可不需要專(zhuān)門(mén)開(kāi)發(fā)新的求解內(nèi)核。1.3 碳排放交易怎么落進(jìn)優(yōu)化調(diào)度模型碳排放交易機(jī)制的底層邏輯是用市場(chǎng)手段給碳排放定價(jià)。在碳市場(chǎng)中政府給排放主體發(fā)放碳排放配額如果實(shí)際排放低于配額可以把剩余配額賣(mài)出獲利如果實(shí)際排放超過(guò)配額就必須從市場(chǎng)上購(gòu)買(mǎi)配額否則面臨高額罰款。把這種機(jī)制引入優(yōu)化調(diào)度后碳排放就不再只是一個(gè)環(huán)保指標(biāo)而是變成了直接影響調(diào)度決策的經(jīng)濟(jì)信號(hào)。具體來(lái)說(shuō)優(yōu)化目標(biāo)需要在傳統(tǒng)的發(fā)電成本之外加上碳交易成本讓機(jī)組在出力分配時(shí)自動(dòng)權(quán)衡“多發(fā)一度電掙的錢(qián)”和“多發(fā)一度電對(duì)應(yīng)的碳成本”。這個(gè)模型設(shè)計(jì)里有幾個(gè)關(guān)鍵問(wèn)題要處理初始配額怎么給一般有免費(fèi)分配法和有償分配法學(xué)術(shù)計(jì)算里常用免費(fèi)分配法基于機(jī)組歷史排放水平或出力的基準(zhǔn)線乘以一個(gè)比例系數(shù)。碳價(jià)如何設(shè)定碳交易成本可以設(shè)置為一個(gè)常數(shù)也可以設(shè)計(jì)成階梯函數(shù)——碳排放量超過(guò)一定閾值后單位碳價(jià)跳升這樣更貼近真實(shí)碳市場(chǎng)中的價(jià)格波動(dòng)。碳約束是軟約束還是硬約束如果碳配額不足必須購(gòu)買(mǎi)那碳交易成本是目標(biāo)函數(shù)里的一項(xiàng)如果允許直接限排放量那就是一個(gè)不等式約束。更常見(jiàn)的處理是把兩者結(jié)合起來(lái)既能購(gòu)買(mǎi)配額也允許一定程度超排但超排要付出更高代價(jià)。從我實(shí)際復(fù)現(xiàn)的經(jīng)驗(yàn)看把碳交易成本寫(xiě)成目標(biāo)函數(shù)里的一項(xiàng)用碳價(jià)乘以?xún)襞欧帕繉?shí)際排放減配額是最容易實(shí)現(xiàn)且結(jié)果最直觀的做法。2. 模型構(gòu)建與數(shù)學(xué)表述從目標(biāo)函數(shù)到分布式約束2.1 目標(biāo)函數(shù)拆解我算例用的是標(biāo)準(zhǔn)經(jīng)濟(jì)調(diào)度模型加上碳交易項(xiàng)。先看整體目標(biāo)函數(shù)每個(gè)區(qū)域獨(dú)立寫(xiě)自己的目標(biāo)最后通過(guò)耦合約束串起來(lái)。目標(biāo)函數(shù)由三部分組成機(jī)組發(fā)電成本、碳交易成本、棄電懲罰可選。發(fā)電成本我用二次函數(shù)擬合成本曲線對(duì)機(jī)組$i$在時(shí)段$t$的出力和啟停狀態(tài)進(jìn)行建模。這里要說(shuō)明的是很多論文用線性化成本函數(shù)簡(jiǎn)化計(jì)算但實(shí)際機(jī)組成本曲線更接近凸二次函數(shù)。ADMM對(duì)凸二次目標(biāo)函數(shù)收斂性很好沒(méi)必要主動(dòng)簡(jiǎn)化掉。碳交易成本分兩塊。一塊是實(shí)際碳排放量超過(guò)免費(fèi)配額時(shí)需要花真金白銀購(gòu)買(mǎi)配額的成本另一塊是碳排放量低于配額時(shí)賣(mài)出剩余配額獲取的收益。兩者符號(hào)相反本質(zhì)都是凈排放量與碳價(jià)的乘積。再補(bǔ)一個(gè)棄電懲罰項(xiàng)。新能源滲透率較高的算例里如果不給棄風(fēng)棄光設(shè)懲罰模型會(huì)為了降低發(fā)電成本極端壓縮火電出力導(dǎo)致部分節(jié)點(diǎn)電壓越限或備用不足等問(wèn)題。加一個(gè)線性的棄電懲罰系數(shù)數(shù)值上取略高于煤電邊際成本的值讓模型在棄風(fēng)和降碳之間自然權(quán)衡。這樣每個(gè)區(qū)域的子問(wèn)題目標(biāo)函數(shù)就清楚了區(qū)域內(nèi)所有機(jī)組發(fā)電成本 碳交易成本 棄電懲罰最小化。2.2 約束體系要覆蓋哪些內(nèi)容約束條件是整個(gè)模型的骨架缺一個(gè)約束、松一個(gè)約束都可能讓結(jié)果完全跑偏。對(duì)于一個(gè)區(qū)域$k$內(nèi)的優(yōu)化子問(wèn)題我至少考慮了以下約束第一類(lèi)是功率平衡約束。區(qū)域內(nèi)所有機(jī)組出力、新能源出力、其他區(qū)域流入功率之和必須等于本區(qū)域負(fù)荷需求。這個(gè)約束在每個(gè)調(diào)度時(shí)段都成立。用拉格朗日乘子配上ADMM框架里的邊界變量這塊約束是各區(qū)域內(nèi)部自行滿(mǎn)足的不需要跨區(qū)域協(xié)調(diào)。第二類(lèi)是機(jī)組出力上下限約束。常規(guī)火電機(jī)組有技術(shù)出力上下限新能源機(jī)組出力上限由預(yù)測(cè)功率決定下限為0。對(duì)儲(chǔ)能設(shè)備還要加充放電功率上下限和SOC荷電狀態(tài)約束如果算例里含儲(chǔ)能的話。第三類(lèi)是機(jī)組爬坡約束。相鄰時(shí)段出力的變化量不能超過(guò)爬坡速率限制。這個(gè)約束是時(shí)間維度上的耦合在分布式分解時(shí)要把時(shí)間變量保留在同一個(gè)區(qū)域的優(yōu)化問(wèn)題內(nèi)部避免把一個(gè)區(qū)域的跨時(shí)段約束切碎了。第四類(lèi)是網(wǎng)絡(luò)傳輸約束。各區(qū)域之間的聯(lián)絡(luò)線傳輸功率必須在額定限額之內(nèi)。這是最典型的跨區(qū)域耦合約束也是ADMM分解時(shí)要重點(diǎn)處理的邊界約束。具體做法是把聯(lián)絡(luò)線功率復(fù)制成兩份分別由區(qū)域$i$和區(qū)域$j$的決策變量表示然后強(qiáng)制這兩份相等。第五類(lèi)是碳排放約束或配額約束。模型采用“配額上限 市場(chǎng)購(gòu)買(mǎi)”機(jī)制實(shí)際排放量減去配額后如果為正需要購(gòu)買(mǎi)等量配額為負(fù)則可以出售均按碳價(jià)結(jié)算。這里我得提醒一個(gè)容易踩的坑約束的松弛方式會(huì)顯著影響結(jié)果解釋。比如負(fù)荷平衡約束如果只寫(xiě)成等式約束模型會(huì)嚴(yán)格滿(mǎn)足但如果求解器數(shù)值精度不夠可能在某些迭代輪次出現(xiàn)微小的功率不平衡。實(shí)際操作中一般允許一個(gè)很小的容差比如10^-4避免ADMM迭代后期因?yàn)閿?shù)值抖動(dòng)來(lái)回震蕩不收斂。2.3 碳交易模型具體怎么量化碳交易部分的量化我按以下方式處理先算每臺(tái)機(jī)組在出力$P$下的碳排放量用單位出力的碳排放強(qiáng)度乘以出力并累加。碳排放強(qiáng)度和機(jī)組類(lèi)型強(qiáng)相關(guān)燃煤機(jī)組約0.8-1.0 tCO2/MWh燃?xì)鈾C(jī)組約0.4-0.5 tCO2/MWh新能源幾乎為0。算例里我分別設(shè)置了不同機(jī)型的碳排放強(qiáng)度系數(shù)。再確定免費(fèi)配額。免費(fèi)配額按兩種基準(zhǔn)一是按機(jī)組歷史平均出力乘以基準(zhǔn)排放強(qiáng)度二是按總配額在機(jī)組之間按容量比例分?jǐn)偂N矣昧税礆v史出力的方式這樣更容易體現(xiàn)“出力越高的機(jī)組拿到的配額越多但實(shí)際排放可能更高”的現(xiàn)實(shí)邏輯。碳價(jià)設(shè)為常量還是動(dòng)態(tài)量會(huì)直接影響模型行為。常量碳價(jià)實(shí)現(xiàn)簡(jiǎn)單算出來(lái)的結(jié)果更穩(wěn)定動(dòng)態(tài)碳價(jià)比如超過(guò)配額閾值后碳價(jià)上浮更貼近市場(chǎng)實(shí)際情況但增加了目標(biāo)函數(shù)的非凸性ADMM收斂速度會(huì)受影響。我的建議是先做常量碳價(jià)版本跑通之后再擴(kuò)展動(dòng)態(tài)碳價(jià)。凈排放量 實(shí)際排放 - 免費(fèi)配額。若為正碳交易成本為正買(mǎi)配額若為負(fù)碳交易成本為負(fù)賣(mài)配額收益進(jìn)目標(biāo)函數(shù)。這個(gè)設(shè)計(jì)讓模型在約束收緊時(shí)會(huì)自動(dòng)調(diào)低高碳機(jī)組出力提高低碳機(jī)組和新能源出力比例效果立竿見(jiàn)影。3. 分布式ADMM的求解流程與收斂機(jī)制3.1 問(wèn)題分解區(qū)域自治 邊界協(xié)調(diào)ADMM第一步是問(wèn)題分解。把全局調(diào)度問(wèn)題建模為各區(qū)域子問(wèn)題加耦合約束的形式。每個(gè)區(qū)域$k$維護(hù)自己的決策變量$x_k$包括區(qū)域內(nèi)各機(jī)組出力、新能源出力、儲(chǔ)能充放電功率等。耦合約束特指聯(lián)絡(luò)線功率一致性約束區(qū)域$i$流入?yún)^(qū)域$j$的功率等于區(qū)域$j$從區(qū)域$i$接收到的功率。注意這里有個(gè)選擇是把耦合約束的功率變量直接復(fù)制成兩個(gè)區(qū)域的變量然后強(qiáng)制相等還是用一個(gè)公共變量統(tǒng)一表示聯(lián)絡(luò)線潮流。后者在物理上更直觀但會(huì)把不同區(qū)域的變量綁得過(guò)緊削弱分布式特性。所以我采用前者——復(fù)制變量加一致性約束這也是ADMM論文里最標(biāo)準(zhǔn)的處理方式。這樣分解之后每個(gè)區(qū)域內(nèi)部可以獨(dú)立求解一個(gè)帶邊界變量副本的優(yōu)化子問(wèn)題。區(qū)域之間唯一需要交換的信息就是邊界變量的取值和對(duì)偶變量乘子不涉及任何區(qū)域內(nèi)部的成本曲線、機(jī)組參數(shù)或負(fù)荷數(shù)據(jù)。隱私保護(hù)的訴求就滿(mǎn)足了。3.2 迭代更新預(yù)測(cè)-修正-協(xié)調(diào)三步走ADMM迭代核心是三步和預(yù)測(cè)控制里的模型預(yù)測(cè) 反饋校正節(jié)奏很像第一步所有區(qū)域并行求解各自的子問(wèn)題目標(biāo)函數(shù)里除了本區(qū)域發(fā)電成本和碳交易成本之外再加一個(gè)增廣拉格朗日罰項(xiàng)。這個(gè)罰項(xiàng)包含了與相鄰區(qū)域交換的邊界變量偏差以及上次迭代的對(duì)偶乘子作用是引導(dǎo)本區(qū)域在追求個(gè)體最優(yōu)的同時(shí)兼顧整體協(xié)調(diào)。第二步獲取各區(qū)域更新后的邊界變量匯總到協(xié)調(diào)層可以是某一區(qū)域擔(dān)任協(xié)調(diào)者也可以是虛擬的協(xié)調(diào)中心更新對(duì)偶乘子。乘子更新的物理意義是如果區(qū)域A發(fā)送的功率和區(qū)域B接收的功率不一致就按偏差大小調(diào)整對(duì)偶乘子相當(dāng)于給A、B雙方都施加一個(gè)“糾偏力”。第三步檢查收斂條件。計(jì)算原始?xì)埐钸吔缱兞科畹姆稊?shù)和對(duì)偶?xì)埐钕噜弮纱蔚吔缱兞孔兓康姆稊?shù)兩者都小于閾值時(shí)停止迭代。這里有個(gè)實(shí)現(xiàn)細(xì)節(jié)值得強(qiáng)調(diào)區(qū)域子問(wèn)題并行求解時(shí)理論上各區(qū)域之間不需要通信真正需要通信的只有邊界變量和對(duì)偶乘子。所以代碼里不需要復(fù)雜的分布式通信框架用MATLAB的parfor循環(huán)或者直接for循環(huán)按順序求解各區(qū)域子問(wèn)題即可迭代層面做串行協(xié)調(diào)。如果想模擬真正的并行效果就改用parallel computing toolbox的spmd或parfeval。3.3 收斂判據(jù)和罰參數(shù)選擇的門(mén)道ADMM收斂判據(jù)和罰參數(shù)$\rho$的選擇直接決定代碼能不能在合理時(shí)間內(nèi)跑完。收斂判據(jù)我用的是雙殘差標(biāo)準(zhǔn)。閾值設(shè)置很關(guān)鍵設(shè)太松結(jié)果質(zhì)量差設(shè)太緊則會(huì)迭代幾百次出不來(lái)。實(shí)踐中我一般設(shè)原始?xì)埐铋撝?e-4對(duì)偶?xì)埐铋撝?e-4。如果算例規(guī)模大或者參數(shù)復(fù)雜度高放寬到1e-3也沒(méi)有太大問(wèn)題。罰參數(shù)$\rho$的選擇是ADMM最玄學(xué)的部分。$\rho$過(guò)小原始?xì)埐钕陆德龑?duì)偶乘子提供的糾偏力弱整體收斂速度慢$\rho$過(guò)大雖然原始?xì)埐羁焖傧陆档珜?duì)偶乘子更新容易震蕩導(dǎo)致對(duì)偶?xì)埐钜恢苯挡幌聛?lái)甚至在某些非凸場(chǎng)景下直接發(fā)散。我的經(jīng)驗(yàn)是從$\rho 0.1$起步觀察前20輪迭代的殘差變化曲線。如果原始?xì)埐钕陆颠^(guò)于平緩就把$\rho$提升一個(gè)量級(jí)如果原始?xì)埐羁焖傧陆档胶苄〉珜?duì)偶?xì)埐罘磸?fù)震蕩就降低$\rho$。這個(gè)調(diào)參過(guò)程就像是調(diào)水龍頭的冷熱開(kāi)關(guān)找到一個(gè)讓兩邊殘差均衡同步下降的點(diǎn)。更精細(xì)的做法是采用自適應(yīng)懲罰參數(shù)在迭代過(guò)程中根據(jù)原始?xì)埐詈蛯?duì)偶?xì)埐畹谋戎祫?dòng)態(tài)調(diào)整。原始?xì)埐钸^(guò)大于對(duì)偶?xì)埐顣r(shí)增大$\rho$反之減小$\rho$。這個(gè)改進(jìn)能明顯加快收斂特別是在參數(shù)初始值選取不夠理想的情況下。我有一次從固定$\rho$轉(zhuǎn)到自適應(yīng)$\rho$后迭代次數(shù)從200多輪直接降到60輪以?xún)?nèi)。4. MATLAB實(shí)現(xiàn)要點(diǎn)以IEEE 30節(jié)點(diǎn)算例復(fù)現(xiàn)為例4.1 算例選擇和數(shù)據(jù)準(zhǔn)備算例我用的是IEEE 30節(jié)點(diǎn)系統(tǒng)這個(gè)系統(tǒng)規(guī)模適中做分布式算法驗(yàn)證非常合適。將系統(tǒng)按區(qū)域邊界劃分為5個(gè)子區(qū)域每個(gè)區(qū)域包含本地機(jī)組、本地負(fù)荷和與相鄰區(qū)域的聯(lián)絡(luò)線邊界節(jié)點(diǎn)。數(shù)據(jù)準(zhǔn)備階段第一件事是整理機(jī)組數(shù)據(jù)。母線編號(hào)、機(jī)組類(lèi)型、成本系數(shù)、出力上下限、爬坡速率、碳排放強(qiáng)度。這里我建議把數(shù)據(jù)寫(xiě)成結(jié)構(gòu)體數(shù)組或MAT文件統(tǒng)一讀入不要散落在多個(gè)腳本里后期改參數(shù)會(huì)方便很多。第二件事是定義區(qū)域歸屬矩陣。哪個(gè)節(jié)點(diǎn)屬于哪個(gè)區(qū)域、哪條線路是區(qū)域間聯(lián)絡(luò)線這個(gè)是分布式模型的核心數(shù)據(jù)。我建議寫(xiě)一個(gè)區(qū)域劃分的配置函數(shù)輸入節(jié)點(diǎn)編號(hào)和線路編號(hào)輸出區(qū)域歸屬向量和聯(lián)絡(luò)線列表。這一步可以用可視化工具先畫(huà)一遍系統(tǒng)拓?fù)浯_認(rèn)區(qū)域劃分合理再寫(xiě)進(jìn)代碼。第三件事是負(fù)荷數(shù)據(jù)和新能源出力數(shù)據(jù)。負(fù)荷數(shù)據(jù)可以直接用IEEE標(biāo)準(zhǔn)節(jié)點(diǎn)數(shù)據(jù)也可以按典型日負(fù)荷曲線自行構(gòu)造新能源出力用一組帶波動(dòng)性的歸一化出力數(shù)據(jù)。我的建議是設(shè)計(jì)一個(gè)統(tǒng)一的setup_case.m腳本返回一個(gè)包含所有數(shù)據(jù)的結(jié)構(gòu)體。這個(gè)腳本相當(dāng)于整個(gè)項(xiàng)目的“數(shù)據(jù)裝配車(chē)間”改動(dòng)算例時(shí)只需要?jiǎng)舆@個(gè)腳本。4.2 代碼模塊結(jié)構(gòu)分區(qū)明確迭代清晰MATLAB工程項(xiàng)目最忌諱寫(xiě)成一個(gè)超長(zhǎng)腳本。我的代碼結(jié)構(gòu)是這樣的main.m主入口負(fù)責(zé)讀取數(shù)據(jù)、初始化參數(shù)、調(diào)用迭代循環(huán)、輸出結(jié)果。setup_case.m算例數(shù)據(jù)裝配返回結(jié)構(gòu)和各類(lèi)參數(shù)。init_admm.m初始化ADMM相關(guān)參數(shù)罰參數(shù)、收斂閾值、最大迭代次數(shù)、對(duì)偶變量初值。solve_region.m求解單個(gè)區(qū)域的子問(wèn)題輸入本區(qū)域數(shù)據(jù)、邊界變量當(dāng)前值、對(duì)偶乘子輸出本區(qū)域最優(yōu)決策。update_consensus.m更新邊界一致性變量和對(duì)偶乘子。check_convergence.m計(jì)算原始?xì)埐睢?duì)偶?xì)埐?、判斷是否收斂。plot_results.m結(jié)果可視化畫(huà)機(jī)組出力、碳交易量、迭代收斂曲線。這個(gè)結(jié)構(gòu)的好處是每個(gè)模塊可以單獨(dú)測(cè)試。我先測(cè)試單個(gè)區(qū)域子問(wèn)題能不能在給定邊界條件下正常求解再測(cè)試兩個(gè)區(qū)域互聯(lián)的場(chǎng)景最后擴(kuò)展到5個(gè)區(qū)域。逐層遞進(jìn)出問(wèn)題時(shí)定位非常快。區(qū)域子問(wèn)題的求解我用的是MATLAB的quadprog或fmincon。如果模型是凸二次規(guī)劃加線性約束quadprog足夠高效如果加了非線性約束或非凸項(xiàng)就得用fmincon。aaa更省事的做法是用YALMIP工具箱建模代碼可讀性更高算小規(guī)模算例時(shí)性能損失可忽略。我在復(fù)現(xiàn)時(shí)首選YALMIP因?yàn)樗V庇^便于快速修改約束條件。4.3 關(guān)鍵代碼片段ADMM迭代骨架下面這段是我主循環(huán)里的核心邏輯做了必要的簡(jiǎn)化但保持了完整結(jié)構(gòu)。% main.m 主循環(huán)骨架 for iter 1 : max_iter % 1. 各區(qū)域并行/串行求解子問(wèn)題 for k 1 : n_region x_region{k} solve_region(k, x_boundary_prev, lambda_prev, params); end % 2. 收集邊界變量更新一致性變量取相鄰區(qū)域邊界變量均值或協(xié)調(diào)值 x_boundary_curr update_boundary(x_region, adjacency_matrix, params); % 3. 更新對(duì)偶乘子 lambda_curr lambda_prev params.rho * (x_boundary_curr - x_boundary_reference); % 4. 計(jì)算殘差 residual_prim norm(x_boundary_curr - x_boundary_prev, inf); residual_dual params.rho * norm(x_boundary_curr - x_boundary_prev_inner, inf); % 5. 自適應(yīng)調(diào)整罰參數(shù) if residual_prim 10 * residual_dual params.rho params.rho * 2; elseif residual_dual 10 * residual_prim params.rho params.rho / 2; end % 6. 收斂判斷 if residual_prim params.tol residual_dual params.tol break; end end實(shí)際編碼中需要注意幾個(gè)細(xì)節(jié)邊界變量的一致性處理不是簡(jiǎn)單地取平均值。更標(biāo)準(zhǔn)的做法是引入一個(gè)參考變量更新時(shí)讓所有相關(guān)區(qū)域的邊界變量向其靠攏參考變量本身取各區(qū)域邊界變量的均值然后逐區(qū)域更新對(duì)偶變量并回傳。對(duì)偶乘子lambda的維度必須與邊界變量一致形狀不對(duì)會(huì)在矩陣運(yùn)算時(shí)報(bào)錯(cuò)這種錯(cuò)誤很隱蔽建議在初始化后立即打印維度核對(duì)一遍。自適應(yīng)$\rho$調(diào)整雖然好用但有一個(gè)坑$\rho$如果加得太大子問(wèn)題目標(biāo)函數(shù)中的罰項(xiàng)會(huì)主導(dǎo)目標(biāo)導(dǎo)致區(qū)域內(nèi)部約束被稀釋。所以要對(duì)$\rho$設(shè)上下限比如限制在[0.01, 100]區(qū)間內(nèi)避免參數(shù)漂移失去意義。4.4 性能調(diào)優(yōu)和經(jīng)驗(yàn)心得實(shí)踐中我發(fā)現(xiàn)幾個(gè)直接影響計(jì)算效率的點(diǎn)整理出來(lái)供參考。第一個(gè)是區(qū)域子問(wèn)題求解器的選擇。quadprog在MATLAB里對(duì)付凸二次規(guī)劃很快但它不支持二次約束。如果你的模型加了線路潮流二次約束或者新能源出力的二次約束還是要回到fmincon。fmincon用內(nèi)點(diǎn)法在小規(guī)模問(wèn)題上足夠穩(wěn)但要做好初始值選擇否則容易進(jìn)入局部解。第二個(gè)是稀疏矩陣的使用。電力系統(tǒng)的鄰接矩陣、節(jié)點(diǎn)導(dǎo)納矩陣天然稀疏在寫(xiě)代碼時(shí)用稀疏存儲(chǔ)大規(guī)模算例下內(nèi)存和計(jì)算速度差距非常大。我這部分吃了虧最初用全矩陣存儲(chǔ)5區(qū)域30節(jié)點(diǎn)還不覺(jué)得擴(kuò)展到100節(jié)點(diǎn)后明顯吃力。改成稀疏存儲(chǔ)后速度提升了一個(gè)量級(jí)。第三個(gè)是初始化的技巧。我習(xí)慣用各區(qū)域內(nèi)部的純經(jīng)濟(jì)調(diào)度結(jié)果作為邊界變量的初值也就是先不考慮跨區(qū)域耦合各自獨(dú)立跑一遍區(qū)域內(nèi)經(jīng)濟(jì)調(diào)度用這個(gè)結(jié)果去初始化邊界變量和對(duì)偶變量。這樣初始解已經(jīng)在可行域附近迭代初期殘差就不會(huì)太大。相比全零初始化大概能少迭代20到30輪。第四個(gè)是分階段驗(yàn)證的策略。第一次跑通別直接上完整模型先把碳交易從目標(biāo)函數(shù)里去掉只做常規(guī)經(jīng)濟(jì)調(diào)度確認(rèn)ADMM框架本身沒(méi)問(wèn)題然后加入碳交易成本項(xiàng)和集中式求解結(jié)果對(duì)比確認(rèn)分布式解和集中式解一致最后再擴(kuò)展場(chǎng)景、調(diào)參數(shù)。我的實(shí)際體會(huì)是這種“先框架、后業(yè)務(wù)”的遞進(jìn)調(diào)試方式能讓問(wèn)題定位時(shí)間縮短一半以上。5. 常見(jiàn)問(wèn)題與排錯(cuò)實(shí)錄5.1 迭代不收斂殘差一直震蕩這是ADMM跑出來(lái)的最經(jīng)典問(wèn)題。殘差曲線如果呈現(xiàn)周期性震蕩最常見(jiàn)的原因是罰參數(shù)$\rho$取值不當(dāng)。我調(diào)試時(shí)遇到過(guò)$\rho0.01$時(shí)原始?xì)埐钇椒€(wěn)下降但對(duì)偶?xì)埐顜缀醪粍?dòng)一直跑到300輪還是達(dá)不到閾值把$\rho$調(diào)到1之后兩個(gè)殘差都在40輪左右降到閾值以下。另一個(gè)原因是邊界變量參考變量更新得太頻繁。如果每輪迭代都直接用當(dāng)前各區(qū)域邊界變量均值覆蓋參考變量某些情況下會(huì)引起連鎖震蕩。我改用“帶慣性”的更新方式參考變量 0.7新均值 0.3舊參考值相當(dāng)于給協(xié)調(diào)層加了阻尼曲線立刻平穩(wěn)了很多。5.2 分布式結(jié)果和集中式結(jié)果差異過(guò)大很多論文要求分布式ADMM結(jié)果逼近集中式最優(yōu)解實(shí)際跑下來(lái)可能差距不小。我先排查是不是模型分解時(shí)遺漏了約束。比如某些區(qū)域間的傳輸容量約束如果沒(méi)有轉(zhuǎn)成邊界一致性約束分布式模型和集中式模型的可行域就不一致結(jié)果自然對(duì)不上。還有一個(gè)常見(jiàn)原因是子問(wèn)題求解精度設(shè)置過(guò)高或過(guò)低。fmincon的OptimalityTolerance設(shè)成1e-8雖然能保證子問(wèn)題高精度但會(huì)顯著拖慢單次求解速度設(shè)置成1e-3又可能讓子問(wèn)題解過(guò)于粗糙迭代后期每次邊界變量更新都比較小殘差下降緩慢。我最后折中取了OptimalityTolerance1e-6又給子問(wèn)題加了最大迭代次數(shù)限制整體收斂速度和結(jié)果質(zhì)量都比較理想。5.3 碳價(jià)參數(shù)敏感性太高結(jié)果時(shí)好時(shí)壞碳交易成本在目標(biāo)函數(shù)中所占比例如果過(guò)低模型基本不會(huì)主動(dòng)調(diào)整機(jī)組出力碳排放量幾乎不變碳價(jià)如果過(guò)高碳交易成本又會(huì)蓋過(guò)發(fā)電成本模型可能過(guò)度壓制火電出力導(dǎo)致系統(tǒng)總成本暴增甚至無(wú)解。這里需要敏感性分析。我對(duì)碳價(jià)做了從10元/噸到500元/噸的掃描橫坐標(biāo)碳價(jià)、縱坐標(biāo)系統(tǒng)總成本和總排放量畫(huà)出一條曲線??梢郧宄吹教純r(jià)在50元/噸以?xún)?nèi)時(shí)市場(chǎng)規(guī)模很溫和超過(guò)100元/噸后排放下降明顯加速。這個(gè)表格在論文里作為分析是很好的素材。5.4 MATLAB代碼層面的坑和避坑MATLAB有幾個(gè)具體的坑值得提醒。變量覆蓋MATLAB對(duì)變量名大小寫(xiě)不敏感l(wèi)ambda和Lambda是同一個(gè)變量。我在代碼里同時(shí)用了lambda做對(duì)偶乘子、Lambda做線路導(dǎo)納矩陣結(jié)果跑出來(lái)的結(jié)果全是錯(cuò)的排查了兩天才發(fā)現(xiàn)這個(gè)低級(jí)問(wèn)題。建議代碼里的變量名區(qū)分度盡量大lambda就叫l(wèi)ambda_dualLambda就叫admit_matrix。parfor使用限制如果區(qū)域子問(wèn)題求解用parfor并行注意子問(wèn)題里不能有全局變量和隨機(jī)數(shù)。IEE30節(jié)點(diǎn)的5區(qū)域并行跑速度提升接近4倍但我也遇到過(guò)一次某個(gè)worker崩潰導(dǎo)致整個(gè)循環(huán)報(bào)錯(cuò)的情況。穩(wěn)妥的辦法是設(shè)置好parpool的容錯(cuò)機(jī)制或者干脆先用串行跑通再改并行。內(nèi)存泄漏每次調(diào)用fmincon或者quadprog時(shí)如果頻繁創(chuàng)建大結(jié)構(gòu)體數(shù)組且不清除迭代上百輪后內(nèi)存會(huì)越來(lái)越大。迭代循環(huán)里盡量復(fù)用結(jié)構(gòu)體變量不再使用就用clear及時(shí)清掉。5.5 結(jié)果可視化角度結(jié)果的可視化不只是為了好看更是排錯(cuò)的必要手段。我強(qiáng)烈建議在調(diào)試階段就畫(huà)三張圖迭代收斂曲線、各區(qū)域聯(lián)絡(luò)線功率交換圖、機(jī)組出力與碳排量對(duì)比圖。迭代收斂曲線是最直接的排錯(cuò)工具一眼可以看出殘差是單調(diào)下降還是震蕩。區(qū)域間交換功率圖可以驗(yàn)證模型邏輯是否正確——比如兩個(gè)區(qū)域之間如果有聯(lián)絡(luò)線功率交換這張圖上應(yīng)該能看到方向一致的功率流向如果出現(xiàn)區(qū)域間功率來(lái)回倒灌基本說(shuō)明邊界約束或方向定義有問(wèn)題。最后一張圖可以直觀反映碳交易機(jī)制是否生效高碳排放機(jī)組出力是否有所下調(diào)低碳機(jī)組出力是否上升配額買(mǎi)賣(mài)量是否合理。6. 排錯(cuò)之后的復(fù)盤(pán)幾個(gè)可以繼續(xù)擴(kuò)展的方向基本模型跑通之后我個(gè)人覺(jué)得這個(gè)骨架的擴(kuò)展空間非常大做課題或者工程落地都能在此基礎(chǔ)上疊加很多內(nèi)容。一個(gè)是把碳交易從常數(shù)碳價(jià)擴(kuò)展為實(shí)時(shí)波動(dòng)的碳價(jià)模型。真實(shí)碳市場(chǎng)價(jià)格波動(dòng)有很強(qiáng)的時(shí)變特性調(diào)度模型可以把碳價(jià)當(dāng)作外生隨機(jī)變量引入場(chǎng)景生成方法或者兩階段隨機(jī)優(yōu)化框架讓調(diào)度決策在碳價(jià)不確定條件下依然有可靠的期望收益。另一個(gè)是考慮需求側(cè)響應(yīng)和儲(chǔ)能。當(dāng)前模型主要聚焦供給側(cè)出力和碳配額分配沒(méi)有涉及負(fù)荷側(cè)的柔性調(diào)度。加上可中斷負(fù)荷、電動(dòng)汽車(chē)充放電管理可以在不增加太多碳排放的前提下提升系統(tǒng)靈活性這也是目前調(diào)度領(lǐng)域的熱點(diǎn)。再一個(gè)就是多時(shí)段耦合類(lèi)約束的分布式處理。我前面提到爬坡約束和儲(chǔ)能SOC約束是跨時(shí)段約束在區(qū)域內(nèi)部處理起來(lái)相對(duì)容易。但如果要做全局多維度的分布式協(xié)調(diào)就需要引入時(shí)間維度上的耦合變量復(fù)制與一致性約束算法復(fù)雜度和通信量也會(huì)增加。這些擴(kuò)展方向都是在現(xiàn)有ADMM框架上做增量變化邏輯鏈條是完整的。我自己已經(jīng)驗(yàn)證過(guò)在模型里加儲(chǔ)能后的效果系統(tǒng)總成本下降約3%碳排放量下降約6%同時(shí)區(qū)域間功率交換的峰谷差顯著緩解。這樣的擴(kuò)展結(jié)果比單純報(bào)一個(gè)收斂曲線更有說(shuō)服力。如果你也在做類(lèi)似的方向建議先把本文的模型框架跑通吃透再按自己的場(chǎng)景去擴(kuò)展。有一個(gè)穩(wěn)定可靠的基礎(chǔ)實(shí)現(xiàn)比你一開(kāi)始就上復(fù)雜模型高效得多。我踩過(guò)的這些坑尤其是罰參數(shù)調(diào)優(yōu)、邊界變量初始化、碳價(jià)敏感性分析那幾步希望能夠幫你節(jié)省一些調(diào)Debug的時(shí)間。