粒子群算法的含碳捕集微網(wǎng)多時(shí)間尺度低碳經(jīng)濟(jì)調(diào)度Matlab實(shí)現(xiàn))
1. 拆解題目這三個(gè)名詞為什么必須放在一起談拿到“基于改進(jìn)粒子群算法的含碳捕集微網(wǎng)多時(shí)間尺度低碳經(jīng)濟(jì)調(diào)度Matlab代碼實(shí)現(xiàn)”這個(gè)題目我第一反應(yīng)不是去找PSO改進(jìn)的論文而是先想清楚一個(gè)問(wèn)題為什么這道題要同時(shí)用“碳捕集”“多時(shí)間尺度”“改進(jìn)粒子群”三樣?xùn)|西。說(shuō)實(shí)話這幾年微網(wǎng)經(jīng)濟(jì)調(diào)度的代碼我復(fù)現(xiàn)了不少但純風(fēng)光儲(chǔ)那種模型目標(biāo)函數(shù)線性、約束清晰用Matlab自帶的linprog甚至intlinprog就能解得非常干凈根本不需要粒子群。這個(gè)題目不一樣它的難處在于碳捕集裝置引入了強(qiáng)非線性項(xiàng)時(shí)間尺度上又有日前、日內(nèi)、實(shí)時(shí)三層滾動(dòng)決策這兩件事疊加之后傳統(tǒng)數(shù)學(xué)規(guī)劃工具的建模成本很高于是改進(jìn)粒子群才成了合理選擇。這個(gè)題目的價(jià)值也正在這里它不是在考你能不能把某個(gè)算法背下來(lái)而是考你能不能把物理模型、時(shí)間維度、智能算法三條線擰成一股繩。適合的人群也很明確——正在做微網(wǎng)低碳調(diào)度方向的研究生、需要完成課程設(shè)計(jì)或畢業(yè)設(shè)計(jì)復(fù)現(xiàn)的人、以及想搞清楚“粒子群算法在復(fù)雜約束下到底怎么落地”的Matlab使用者。我下面要講的是把這套方案從零到能跑通、再到結(jié)果可信的完整經(jīng)驗(yàn)沒(méi)有藏私。1.1 碳捕集裝置加入之后微網(wǎng)的電平衡被打破了很多初學(xué)者會(huì)把碳捕集簡(jiǎn)單理解成“給燃?xì)廨啓C(jī)戴個(gè)口罩排碳乘個(gè)系數(shù)”但仿真模型里不能這么干。碳捕集裝置運(yùn)行時(shí)有兩個(gè)物理過(guò)程必須建模一是從煙氣中分離二氧化碳這個(gè)過(guò)程通常需要再生能耗折合成電耗一般在0.3到0.5 MWh/tCO2左右具體數(shù)值取決于吸收劑和工藝參數(shù)二是捕集到的CO2可以被壓縮、儲(chǔ)存甚至外售這部分收益會(huì)影響目標(biāo)函數(shù)。所以在系統(tǒng)能流里碳捕集裝置既是“減碳設(shè)備”又是“耗電設(shè)備”它會(huì)打破原來(lái)的功率平衡。我習(xí)慣用一組式子來(lái)描述這個(gè)環(huán)節(jié)。設(shè)燃?xì)廨啓C(jī)出力為P_gt其單位發(fā)電碳排放系數(shù)為e_g單位tCO2/MWh則總碳排放量為E_gt e_g * P_gt。捕集系統(tǒng)捕集到的CO2量為M_cap eta_cap * lambda_c * E_gt其中eta_cap是捕集效率lambda_c是煙氣分流比也就是實(shí)際進(jìn)入捕集系統(tǒng)的煙氣比例。捕集過(guò)程消耗的電功率P_ccs k_ccs * M_capk_ccs是單位捕集量對(duì)應(yīng)的電耗。這樣一來(lái)微網(wǎng)功率平衡就變成了P_pv P_wt P_gt P_dis P_buy P_load P_ch P_sell P_ccs注意P_ccs出現(xiàn)在負(fù)荷側(cè)很多第一次建模的人會(huì)漏掉它結(jié)果碳捕集率越高系統(tǒng)反而不平衡仿真直接崩。捕集能耗這件事不僅是技術(shù)細(xì)節(jié)它的存在還會(huì)讓目標(biāo)函數(shù)出現(xiàn)一個(gè)隱性的“拐點(diǎn)”——碳價(jià)高時(shí)系統(tǒng)想多捕集但捕集消耗的電力又可能來(lái)自外部購(gòu)電或燃?xì)廨啓C(jī)增發(fā)而這個(gè)增發(fā)又產(chǎn)生新的碳排放形成一種“治理排放反而制造排放”的耦合效應(yīng)處理不好整個(gè)優(yōu)化就白做了。1.2 多時(shí)間尺度不是把96個(gè)時(shí)段算一遍而是三層遞進(jìn)修正我見(jiàn)過(guò)太多復(fù)現(xiàn)代碼把“多時(shí)間尺度”簡(jiǎn)單理解成“把一天分成96個(gè)時(shí)段調(diào)度模型需要同時(shí)優(yōu)化96個(gè)時(shí)步的決策變量”嚴(yán)格說(shuō)那只是“多時(shí)段”不是“多時(shí)間尺度”。真正做多時(shí)間尺度調(diào)度核心邏輯是遞進(jìn)修正日前階段以1小時(shí)為步長(zhǎng)基于預(yù)測(cè)數(shù)據(jù)確定機(jī)組啟停狀態(tài)、碳捕集裝置的大致投運(yùn)策略、儲(chǔ)能系統(tǒng)各時(shí)段的目標(biāo)SOC范圍日內(nèi)階段以15分鐘為步長(zhǎng)滾動(dòng)優(yōu)化利用更新的光伏和風(fēng)電預(yù)測(cè)值在日前計(jì)劃的基礎(chǔ)上修正燃?xì)廨啓C(jī)出力和儲(chǔ)能出力實(shí)時(shí)階段則以更短的時(shí)間間隔處理AGC和一次調(diào)頻把分鐘級(jí)功率偏差壓掉。這套結(jié)構(gòu)在Matlab代碼里如何體現(xiàn)是后文要重點(diǎn)講的但這里先把思路理清日前優(yōu)化輸出的不是“最終答案”而是“邊界條件”。比如日內(nèi)優(yōu)化啟動(dòng)時(shí)儲(chǔ)能的初始SOC應(yīng)當(dāng)讀日前最后一刻的SOC值燃?xì)廨啓C(jī)的啟停狀態(tài)應(yīng)當(dāng)繼承日前結(jié)果碳捕集裝置的儲(chǔ)液罐液位也是日前的終值。很多代碼失敗是因?yàn)閮蓪又g沒(méi)有信息傳遞各自獨(dú)立優(yōu)化結(jié)果日前說(shuō)燃?xì)廨啓C(jī)早晨滿發(fā)、日內(nèi)又說(shuō)停機(jī)互相矛盾整個(gè)調(diào)度計(jì)劃完全不能用。時(shí)間尺度的劃分也沒(méi)有絕對(duì)答案。我做過(guò)的算例里常見(jiàn)的配置是日前1小時(shí)、日內(nèi)15分鐘實(shí)時(shí)5分鐘或1分鐘。日內(nèi)滾動(dòng)優(yōu)化的窗口長(zhǎng)度可以是4小時(shí)或6小時(shí)不必每次都優(yōu)化全天否則計(jì)算量太大、預(yù)測(cè)誤差修正的意義也沒(méi)了。你可以在代碼里把這些參數(shù)都做成全局變量方便不同算例之間切換這也是后續(xù)調(diào)參的基礎(chǔ)。1.3 目標(biāo)函數(shù)里“碳”怎么定價(jià)低碳和經(jīng)濟(jì)會(huì)不會(huì)打架低碳經(jīng)濟(jì)調(diào)度的“經(jīng)濟(jì)”兩字重點(diǎn)體現(xiàn)在目標(biāo)函數(shù)的結(jié)構(gòu)上。我用的目標(biāo)函數(shù)包含六部分燃?xì)廨啓C(jī)燃料成本、機(jī)組運(yùn)維成本、從主網(wǎng)購(gòu)電成本、向主網(wǎng)售電收益、碳排放成本、以及捕集CO2外售帶來(lái)的收益。寫(xiě)成公式就是min F sum(F_fuel(t)) sum(F_om(t)) sum(C_buy(t)P_buy(t)) - sum(C_sell(t)P_sell(t)) sum(C_co2E_net(t)) - sum(C_co2_saleM_cap(t))其中E_net是系統(tǒng)凈碳排放量等于總排放減去捕集量再減去碳配額。這里有一個(gè)很關(guān)鍵的設(shè)計(jì)選擇碳排放成本到底是只算微網(wǎng)內(nèi)部的燃?xì)廨啓C(jī)排放還是要把外部購(gòu)電折算的間接排放也算進(jìn)來(lái)。兩種做法的結(jié)果差別很大。我的建議是采用后者即購(gòu)電時(shí)按照主網(wǎng)平均碳排放因子折算間接排放。因?yàn)槿绻凰銉?nèi)部排放系統(tǒng)可能會(huì)毫無(wú)顧忌地從主網(wǎng)購(gòu)電把碳排放“外包”這既不低碳也不符合實(shí)際碳責(zé)任核算的邏輯。碳價(jià)的設(shè)定直接影響捕集率和系統(tǒng)成本之間的關(guān)系。碳價(jià)低的時(shí)候捕集裝置能耗帶來(lái)的成本高于碳減排收益系統(tǒng)傾向于少捕集甚至不捕集碳價(jià)高的時(shí)候系統(tǒng)會(huì)提高分流比但如果碳價(jià)繼續(xù)升高到某個(gè)閾值捕集能耗會(huì)迫使燃?xì)廨啓C(jī)多發(fā)電總成本反而上升。這種非單調(diào)關(guān)系是改進(jìn)粒子群算法最容易卡住的地方也是驗(yàn)證算法全局搜索能力的好場(chǎng)景。1.4 約束條件里哪些必須顯式處理哪些適合交給罰函數(shù)微網(wǎng)調(diào)度模型里的約束分為幾類一是等式約束包括功率平衡、儲(chǔ)能SOC遞推關(guān)系二是不等式約束包括機(jī)組出力上下限、爬坡速率、儲(chǔ)能充放電功率和容量、購(gòu)售電上限、碳捕集裝置運(yùn)行的煙氣分流比上下限等三是時(shí)間耦合約束比如儲(chǔ)能SOC的連續(xù)性、碳捕集儲(chǔ)液罐液位跨時(shí)段銜接。在粒子群算法里等式約束和不等式約束的處理策略要分開(kāi)。不等式約束直接用“越界裁剪”處理——粒子更新后的變量如果超過(guò)上限就取上限、低于下限就取下限這是最省事、也最有效的做法。等式約束不能簡(jiǎn)單裁剪否則一修變量、二壞平衡。我的做法是設(shè)計(jì)一個(gè)“功率平衡修正算子”先讓粒子自由更新再檢查功率不平衡量然后按照“優(yōu)先調(diào)儲(chǔ)能、其次調(diào)購(gòu)電、最后調(diào)燃?xì)廨啓C(jī)”的優(yōu)先級(jí)把不平衡量修正掉。這個(gè)算子是整套代碼能穩(wěn)定跑起來(lái)的關(guān)鍵后面我會(huì)給出具體寫(xiě)法。對(duì)于碳排放相關(guān)的約束比如總排放限額我傾向于保留為罰函數(shù)項(xiàng)罰系數(shù)設(shè)置成碳價(jià)的兩到三倍即可。原因是這類約束本質(zhì)上不是硬約束罰函數(shù)形式反而更貼近碳交易機(jī)制中“超排要花錢(qián)買配額”的邏輯。需要注意的是罰系數(shù)不能太大太大會(huì)讓目標(biāo)函數(shù)表面變得凹凸不平粒子群在這種地形上極易早熟。2. 標(biāo)準(zhǔn)粒子群算法跑這個(gè)模型的“三宗罪”以及我改了什么說(shuō)實(shí)話標(biāo)準(zhǔn)粒子群并不是不能跑這個(gè)模型十次里面總能跑出幾次還行但工程上沒(méi)法用——你交差的時(shí)候不能跟導(dǎo)師說(shuō)“這次運(yùn)氣好收斂了”。我總結(jié)標(biāo)準(zhǔn)PSO在這個(gè)場(chǎng)景下的三個(gè)典型癥狀早熟收斂、等式約束被大量破壞、局部搜索精度差。這三個(gè)癥狀不是獨(dú)立出現(xiàn)的它們會(huì)互相放大。種群快速聚攏到某個(gè)局部最優(yōu)那個(gè)局部解又因?yàn)榱P函數(shù)的作用而恰好是一個(gè)“看似可行、實(shí)則虛假”的高成本解之后就再也跳不出來(lái)。2.1 癥狀一迭代到一半整個(gè)種群就“凝固”了標(biāo)準(zhǔn)PSO里粒子的速度更新公式是v wv c1r1*(pbest - x) c2r2(gbest - x)其中w是慣性權(quán)重c1和c2是學(xué)習(xí)因子。問(wèn)題就出在這個(gè)w上如果固定下來(lái)后期粒子飛向全局最優(yōu)的速度太快種群多樣性迅速歸零大家擠在同一個(gè)點(diǎn)附近做微小擾動(dòng)算法就“凝固”了。尤其是碳價(jià)這種參數(shù)會(huì)讓目標(biāo)函數(shù)出現(xiàn)多個(gè)局部谷底gbest一旦落進(jìn)一個(gè)比較平的谷底整個(gè)種群根本意識(shí)不到山的另一邊還有更深的谷。我的第一個(gè)改進(jìn)是用混沌序列做種群初始化然后在迭代過(guò)程中采用非線性遞減的自適應(yīng)慣性權(quán)重?;煦绯跏蓟肔ogistic映射x(n1) 4x(n)(1-x(n))生成0到1之間的序列再映射到?jīng)Q策變量上下限。它和隨機(jī)初始化的差別在于隨機(jī)數(shù)在有限樣本量下經(jīng)常扎堆覆蓋不均勻而混沌序列雖有“偽隨機(jī)”的外表遍歷性卻好得多決策變量在搜索空間里能鋪得比較開(kāi)。慣性權(quán)重方面我用的是指數(shù)衰減形式公式是w w_min (w_max - w_min) * exp(-beta * iter / max_iter)beta取2到4w_max取0.9w_min取0.4。相比線性遞減指數(shù)衰減在前期保留更多全局搜索能力后期又能更快轉(zhuǎn)入局部精細(xì)搜索和PSO的收斂特性更匹配。2.2 癥狀二等式約束總被打破罰函數(shù)調(diào)到懷疑人生粒子在更新時(shí)P_gt、P_buy、P_dis這些變量是各自獨(dú)立的它們相加之后幾乎不可能恰好滿足功率平衡等式。于是很多代碼里只能靠罰函數(shù)硬拉罰系數(shù)大了目標(biāo)函數(shù)曲面變得崎嶇不平小了呢解又不可行。我用的方案是前文提到的“修正算子”它的邏輯順序是先檢查所有不等式約束做越界裁剪然后計(jì)算功率偏差deltaP優(yōu)先調(diào)整儲(chǔ)能出力因?yàn)閮?chǔ)能的調(diào)節(jié)速度最快且沒(méi)有爬坡限制如果儲(chǔ)能到邊界還不夠再調(diào)整購(gòu)電量和售電量最后才微調(diào)燃?xì)廨啓C(jī)出力使其滿足爬坡約束。這樣處理之后九成以上的粒子在進(jìn)入目標(biāo)函數(shù)評(píng)價(jià)之前就已經(jīng)是可行解了罰函數(shù)只需要兜住碳排放限額這類弱約束。這里分享一個(gè)我踩過(guò)的教訓(xùn)修正算子的順序不能亂。一開(kāi)始我把燃?xì)廨啓C(jī)放在最優(yōu)先調(diào)節(jié)的位置結(jié)果燃?xì)廨啓C(jī)出力被反復(fù)拉來(lái)拉去經(jīng)常觸發(fā)爬坡約束修完功率平衡又破壞了爬坡需要再修一遍循環(huán)好多次都不收斂。后來(lái)改成“儲(chǔ)能優(yōu)先、購(gòu)電其次、燃?xì)廨啓C(jī)最后”的順序迭代一次就能修完速度和穩(wěn)定性都明顯改善。順序的本質(zhì)是“優(yōu)先使用靈活性最好、代價(jià)最低的調(diào)節(jié)資源”。2.3 癥狀三陷入局部最優(yōu)之后微調(diào)已經(jīng)救不回來(lái)即使有了混沌初始化和自適應(yīng)權(quán)重PSO在中后期仍然可能被某個(gè)局部最優(yōu)困住只是概率降低了而已。為了進(jìn)一步擺脫這種情況我引入了模擬退火機(jī)制對(duì)全局最優(yōu)解做精英擾動(dòng)。具體做法是每迭代一定代數(shù)后在當(dāng)前gbest附近生成一個(gè)鄰域候選解gbest_temp它等于gbest加上一個(gè)高斯擾動(dòng)項(xiàng)sigma*randn(size(gbest))sigma隨迭代次數(shù)遞減。然后按Metropolis準(zhǔn)則決定是否接受這個(gè)擾動(dòng)如果擾動(dòng)后的解更好就直接替換gbest如果更差就以一定概率接受概率和溫度相關(guān)、隨著迭代推進(jìn)逐漸降低。這個(gè)改進(jìn)的原理不難理解PSO的優(yōu)勢(shì)是收斂快、群體協(xié)作能力強(qiáng)但粒子一旦聚攏局部搜索的精細(xì)度不夠模擬退火的優(yōu)勢(shì)恰恰是在溫度較高時(shí)允許“向壞處走”從而有機(jī)會(huì)翻越局部的“山頭”。兩者結(jié)合以后改進(jìn)后的粒子群在前期依靠混沌初始化探索全局、中期依靠自適應(yīng)權(quán)重平衡搜索、后期依靠模擬退火跳出局部整體穩(wěn)定性比標(biāo)準(zhǔn)PSO高一個(gè)量級(jí)。我跑的典型算例里標(biāo)準(zhǔn)PSO連續(xù)五次運(yùn)行會(huì)有三四個(gè)不同結(jié)果改進(jìn)之后十次運(yùn)行基本能收斂到同一個(gè)范圍內(nèi)。2.4 我的改進(jìn)框架總覽和參數(shù)推薦我把整個(gè)改進(jìn)方案總結(jié)成下面這張表方便你對(duì)照著改代碼改進(jìn)點(diǎn)標(biāo)準(zhǔn)PSO做法我的做法主要作用種群初始化均勻隨機(jī)Logistic混沌映射提升初始解覆蓋均勻性慣性權(quán)重固定0.7指數(shù)自適應(yīng)衰減0.9→0.4前期強(qiáng)全局、后期強(qiáng)局部學(xué)習(xí)因子c1c22c1遞減、c2遞增前期重個(gè)體探索、后期重群體收斂等式約束罰函數(shù)修正算子裁剪保證粒子可行、降低罰函數(shù)壓力局部搜索無(wú)模擬退火精英擾動(dòng)輔助跳出局部最優(yōu)參數(shù)方面種群規(guī)模建議取60到100。這個(gè)模型的決策變量維度按日內(nèi)滾動(dòng)16個(gè)時(shí)段算大概在80到120維左右種群規(guī)模取變量維數(shù)的0.8到1倍比較合適。最大迭代次數(shù)取300到500代如果加入停滯判斷比如連續(xù)30代gbest變化小于1e-6就提前終止實(shí)際運(yùn)行代數(shù)通常會(huì)比上限少很多。學(xué)習(xí)因子的初值和終值我用的是c1從2.5遞減到0.5、c2從0.5遞增到2.5效果比恒定2更好。這些參數(shù)不是拍腦袋決定的是通過(guò)一個(gè)簡(jiǎn)單算例做網(wǎng)格掃描之后選出來(lái)的具體怎么驗(yàn)證我放在第四部分講。3. Matlab代碼結(jié)構(gòu)怎么把一個(gè)帶碳捕集的調(diào)度模型裝進(jìn)PSO框架有人問(wèn)過(guò)我Matlab代碼實(shí)現(xiàn)這種調(diào)度模型最難的是什么我覺(jué)得不是算法本身而是把數(shù)學(xué)模型“翻譯”成代碼時(shí)保持結(jié)構(gòu)清晰。如果所有邏輯全寫(xiě)在main腳本里一開(kāi)始跑得通換一組參數(shù)或者改一個(gè)約束就亂套了。所以我的第一建議是先設(shè)計(jì)好文件目錄讓數(shù)據(jù)、模型、算法、結(jié)果各司其職。3.1 主程序文件劃分與責(zé)任邊界我的代碼目錄大概是這樣的main.m是整個(gè)程序的入口負(fù)責(zé)加載數(shù)據(jù)、設(shè)置參數(shù)、調(diào)用優(yōu)化器、輸出結(jié)果data_input.m里是所有場(chǎng)景參數(shù)包括24小時(shí)負(fù)荷預(yù)測(cè)曲線、光伏和風(fēng)電出力預(yù)測(cè)、設(shè)備參數(shù)表、碳價(jià)、預(yù)測(cè)誤差等model_cost.m計(jì)算目標(biāo)函數(shù)值model_constraints.m負(fù)責(zé)越界裁剪和功率平衡修正pso_improved.m是改進(jìn)粒子群主體decode_solution.m實(shí)現(xiàn)從粒子位置到調(diào)度決策變量的映射。另外還有一個(gè)multi_timescale.m專門(mén)處理三層時(shí)間尺度的狀態(tài)傳遞關(guān)系。這樣拆的好處是每一層的修改都不會(huì)波及其他部分。比如你要把PSO換成遺傳算法或差分進(jìn)化只需要替換pso_improved.m目標(biāo)和約束函數(shù)完全不用動(dòng)你要調(diào)整碳捕集參數(shù)只需要改data_input.m里的這張表算法流程不受影響。對(duì)于需要做大量對(duì)比實(shí)驗(yàn)的論文場(chǎng)景這種結(jié)構(gòu)能省下來(lái)至少一半的重復(fù)工作時(shí)間。main.m的流程大概是這樣幾行邏輯先調(diào)用data_input.m讀入?yún)?shù)然后調(diào)用multi_timescale.m里面的日前優(yōu)化函數(shù)得到日前計(jì)劃再把日前計(jì)劃的關(guān)鍵狀態(tài)量機(jī)組啟停、SOC終值、儲(chǔ)液罐液位傳給日內(nèi)優(yōu)化函數(shù)日內(nèi)優(yōu)化滾動(dòng)完成后輸出最終的調(diào)度方案和各項(xiàng)成本指標(biāo)。整個(gè)過(guò)程不需要復(fù)雜的數(shù)據(jù)結(jié)構(gòu)用結(jié)構(gòu)體struct組織中間結(jié)果就夠了。3.2 粒子編碼與解碼這是所有映射邏輯的核心粒子編碼方式直接決定搜索空間的形狀。我的做法是把每個(gè)時(shí)段的決策變量拼接成一個(gè)連續(xù)的實(shí)數(shù)向量決策變量包括燃?xì)廨啓C(jī)出力P_gt、購(gòu)電功率P_buy、售電功率P_sell、儲(chǔ)能放電功率P_dis、儲(chǔ)能充電功率P_ch、碳捕集煙氣分流比lambda_c。如果日內(nèi)滾動(dòng)窗口是16個(gè)時(shí)段那么一個(gè)粒子的維度就是6乘以16等于96維。這里的P_buy和P_sell同時(shí)存在沒(méi)有意義正常經(jīng)濟(jì)調(diào)度下不會(huì)出現(xiàn)又買又賣的怪異狀態(tài)但粒子在搜索過(guò)程中完全可能同時(shí)給出兩個(gè)很大的值所以約束修正算子中要把“同時(shí)購(gòu)售電”的情況處理成只保留其中一項(xiàng)規(guī)則是優(yōu)先保留價(jià)格方案中更有利的那一項(xiàng)。解碼過(guò)程就是把粒子向量按時(shí)段切開(kāi)送到model_constraints.m里進(jìn)行裁剪和修正得到一組滿足所有約束的實(shí)際調(diào)度方案再送到model_cost.m去計(jì)算適應(yīng)度。需要注意粒子更新之后必須先解碼、再計(jì)算適應(yīng)度不能直接拿原始粒子算否則罰函數(shù)會(huì)主導(dǎo)整個(gè)搜索過(guò)程算法行為的解釋性就很差了。下面是我在decode_solution.m中處理功率平衡修正的核心邏輯用Matlab代碼可以這樣寫(xiě)function x fixPowerBalance(x, param) % x為粒子解碼后的決策變量結(jié)構(gòu)體 % 第一優(yōu)先級(jí)修正儲(chǔ)能出力 deltaP x.Pload x.Pch x.Psell x.Pccs - ... (x.Ppv x.Pwt x.Pgt x.Pdis x.Pbuy); adjP min(max(deltaP, -param.PdisMax), param.PchMax); if deltaP 0 x.Pdis x.Pdis min(deltaP, param.PdisMax); else x.Pch x.Pch min(-deltaP, param.PchMax); end % 剩余不平衡量交給購(gòu)電和燃?xì)廨啓C(jī)按比例分?jǐn)?end這段邏輯里最容易被忽略的是P_ccs必須由碳捕集模型函數(shù)先算出來(lái)不能等功率平衡修正之后才補(bǔ)算因?yàn)镻_ccs和P_gt是強(qiáng)耦合關(guān)系——燃?xì)廨啓C(jī)出力改變碳排放量改變捕集能耗也改變。所以在解碼順序上要先由P_gt算E_gt和M_cap再算P_ccs最后才做功率平衡。順序反了結(jié)果一定是錯(cuò)的。3.3 日前與日內(nèi)兩層調(diào)度在代碼里的狀態(tài)傳遞多時(shí)間尺度調(diào)度在代碼里最大的工作量不是把每個(gè)時(shí)段的優(yōu)化做對(duì)而是把日前的狀態(tài)精確傳給日內(nèi)。我定義了一個(gè)全局結(jié)構(gòu)體schedule_state包含soc_init、soc_end、gt_status、storage_level這四個(gè)字段。日前優(yōu)化結(jié)束后把最后一個(gè)時(shí)段的SOC值存進(jìn)schedule_state.soc_init日內(nèi)優(yōu)化函數(shù)啟動(dòng)時(shí)直接讀取這個(gè)字段作為第一個(gè)時(shí)段的儲(chǔ)能起始狀態(tài)。同樣的邏輯適用于碳捕集裝置的儲(chǔ)液罐。碳捕集系統(tǒng)的CO2儲(chǔ)存罐容量有限捕集可以發(fā)生在某個(gè)時(shí)段但CO2的交易和外售可能發(fā)生在另一個(gè)時(shí)段這相當(dāng)于一種“碳量平移”。在日前優(yōu)化里儲(chǔ)液罐的液位是一個(gè)時(shí)段耦合的狀態(tài)變量在日內(nèi)優(yōu)化里它同樣需要繼承日前的末值。沒(méi)有這種狀態(tài)傳遞日內(nèi)滾動(dòng)只能做“近視”決策儲(chǔ)液罐會(huì)頻繁沖到上限或放空調(diào)度結(jié)果完全沒(méi)有實(shí)際意義。為了讓日內(nèi)結(jié)果不要偏離日前計(jì)劃太遠(yuǎn)我還在日內(nèi)目標(biāo)函數(shù)里加了一個(gè)軟約束項(xiàng)懲罰日內(nèi)實(shí)際SOC相對(duì)日前計(jì)劃SOC的偏差懲罰系數(shù)取1到3元/MWh效果很好跑出來(lái)的調(diào)度曲線既跟隨了最新預(yù)測(cè)信息又不至于和日前“完全脫節(jié)”。3.4 目標(biāo)函數(shù)和約束函數(shù)怎么寫(xiě)得又穩(wěn)又快PSO每代要評(píng)價(jià)幾十上百次目標(biāo)函數(shù)如果目標(biāo)函數(shù)里用循環(huán)遍歷96個(gè)時(shí)段一次評(píng)價(jià)可能要幾百毫秒一百代跑下來(lái)就是幾十分鐘非常吃力。我的建議是充分利用Matlab矩陣運(yùn)算把所有的時(shí)序計(jì)算寫(xiě)成向量形式。比如功率平衡可以寫(xiě)成電矩陣相加再用一條sum語(yǔ)句歸并碳排放成本用點(diǎn)乘實(shí)現(xiàn)避免任何for循環(huán)。另外強(qiáng)烈建議把設(shè)備的參數(shù)讀取放到參數(shù)結(jié)構(gòu)體里傳遞而不是每次在目標(biāo)函數(shù)內(nèi)部重新load或定義。這樣不僅能減少重復(fù)計(jì)算而且調(diào)整參數(shù)時(shí)只需要改一個(gè)地方。尤其在目標(biāo)函數(shù)里要訪問(wèn)多個(gè)外界變量時(shí)用結(jié)構(gòu)體比用全局變量干凈得多也不容易在多層函數(shù)調(diào)用時(shí)發(fā)生命名沖突。我見(jiàn)過(guò)有人用global變量傳數(shù)據(jù)結(jié)果哪天忘了初始化程序跑出“猴子調(diào)度”排查了一整天才發(fā)現(xiàn)是global變量在某個(gè)子函數(shù)里被意外覆蓋。這種問(wèn)題在復(fù)雜程序里非常難查結(jié)構(gòu)體參數(shù)傳遞能直接避免。4. 仿真設(shè)計(jì)怎么驗(yàn)證你的“改進(jìn)”是真的改進(jìn)代碼能跑出漂亮的曲線不代表結(jié)果可信。仿真的價(jià)值在于能回答三個(gè)問(wèn)題改進(jìn)粒子群算法比標(biāo)準(zhǔn)PSO好在哪、碳捕集裝置起了多大作用、多時(shí)間尺度調(diào)度相比單尺度能省多少錢(qián)。這三個(gè)問(wèn)題對(duì)應(yīng)著三組對(duì)比實(shí)驗(yàn)缺一不可。4.1 對(duì)照組怎么設(shè)置才算科學(xué)我把仿真實(shí)驗(yàn)分成四組。第一組是“基礎(chǔ)經(jīng)濟(jì)調(diào)度”不安裝碳捕集裝置只做日前單時(shí)間尺度優(yōu)化這是基準(zhǔn)場(chǎng)景第二組是“固定捕集率”碳捕集裝置以固定的50%分流比運(yùn)行時(shí)間尺度仍是日前單層第三組是“可變捕集率”分流比作為決策變量實(shí)時(shí)優(yōu)化時(shí)間尺度仍舊日前單層第四組是完整方案可變捕集率加上日前、日內(nèi)兩層滾動(dòng)調(diào)度。四組實(shí)驗(yàn)都用同一套負(fù)荷、光伏、風(fēng)電預(yù)測(cè)數(shù)據(jù)和設(shè)備參數(shù)只改變模型結(jié)構(gòu)這樣才能清晰分離開(kāi)每種改進(jìn)帶來(lái)的收益。對(duì)照組設(shè)計(jì)里有個(gè)容易翻車的細(xì)節(jié)碳捕集裝置的固定捕集率不能拍腦袋取50%。我建議先跑一次可變捕集率的完整模型看它優(yōu)化的平均分流比大概落在什么范圍再把這個(gè)均值作為固定捕集率場(chǎng)景的輸入。否則固定捕集率設(shè)置在極不合理的位置結(jié)果與實(shí)際應(yīng)用場(chǎng)景脫節(jié)審稿人和答辯評(píng)委一眼就能指出問(wèn)題。4.2 收斂曲線怎么解讀曲線形態(tài)會(huì)說(shuō)話改進(jìn)算法效果如何最直觀的是看收斂曲線。改進(jìn)后的粒子群在典型算例里通常表現(xiàn)出三個(gè)特征一是前50代下降速度明顯快于標(biāo)準(zhǔn)PSO這得益于混沌初始化讓初始解質(zhì)量整體更高二是中段曲線可能出現(xiàn)“階梯式下降”這不是算法故障而是模擬退火擾動(dòng)恰好發(fā)現(xiàn)了一個(gè)新的更優(yōu)區(qū)域gbest跳變帶來(lái)的正?,F(xiàn)象三是終點(diǎn)值更穩(wěn)定連續(xù)運(yùn)行多次結(jié)果接近。我習(xí)慣把標(biāo)準(zhǔn)PSO和改進(jìn)PSO各跑10次記錄每次的最優(yōu)值和收斂代數(shù)再統(tǒng)計(jì)均值和標(biāo)準(zhǔn)差。標(biāo)準(zhǔn)差這個(gè)指標(biāo)很關(guān)鍵它反映算法的魯棒性。標(biāo)準(zhǔn)PSO在這個(gè)模型上十次結(jié)果的標(biāo)準(zhǔn)差通常很大有些算例甚至相差百分之十幾改進(jìn)后一般能控制在百分之三以內(nèi)。如果你復(fù)現(xiàn)的代碼連續(xù)運(yùn)行結(jié)果波動(dòng)很小說(shuō)明算法實(shí)現(xiàn)是健康的如果波動(dòng)特別大要先檢查是不是種群初始化部分出了問(wèn)題或者罰系數(shù)設(shè)置不當(dāng)。4.3 碳價(jià)敏感性實(shí)驗(yàn)實(shí)驗(yàn)結(jié)果和物理直覺(jué)要對(duì)得上碳價(jià)敏感性是這套代碼最值得深挖的場(chǎng)景。我通常取碳價(jià)從50元/噸逐漸增加到300元/噸步長(zhǎng)25或50元/噸逐次求解完整模型記錄最優(yōu)分流比、總碳排放量、總運(yùn)行成本。合理的實(shí)驗(yàn)結(jié)果應(yīng)該有這些趨勢(shì)碳價(jià)升高系統(tǒng)煙氣分流比上升、凈碳排放量下降總成本則不是單調(diào)的它先隨碳價(jià)上升而增加但碳價(jià)高到某個(gè)值之后捕集CO2外售收益開(kāi)始抵消成本曲線可能持平甚至微微下降。有一次我跑出來(lái)的結(jié)果里碳價(jià)300元/噸時(shí)系統(tǒng)捕集率標(biāo)到了95%碳排放幾乎為零看起來(lái)很“低碳”但仔細(xì)一查捕集能耗導(dǎo)致購(gòu)電量急劇增加相當(dāng)于把排放轉(zhuǎn)移到主網(wǎng)去了。檢查過(guò)后發(fā)現(xiàn)是模型里沒(méi)有約束儲(chǔ)液罐容量捕集系統(tǒng)在全天各時(shí)段都拼命工作實(shí)際上儲(chǔ)液罐早就滿了。遇到這類結(jié)果一定要回到物理模型檢查約束而不是迷信數(shù)值結(jié)果。現(xiàn)在我的模型里都加了M_cap eta_cap * E_gt和儲(chǔ)液罐容量約束就再也不會(huì)出現(xiàn)這種過(guò)度捕集的笑話了。4.4 多時(shí)間尺度滾動(dòng)帶來(lái)的效益怎么算多時(shí)間尺度調(diào)度的收益來(lái)源是日內(nèi)滾動(dòng)優(yōu)化可以用更新后的預(yù)測(cè)數(shù)據(jù)修正日前計(jì)劃的偏差。為了衡量這個(gè)收益我設(shè)計(jì)了一個(gè)“預(yù)測(cè)偏差回放”實(shí)驗(yàn)用真實(shí)曲線與日前預(yù)測(cè)之間的誤差模擬日內(nèi)優(yōu)化時(shí)的預(yù)測(cè)修正對(duì)比“只用日前計(jì)劃執(zhí)行到底”和“日前加日內(nèi)滾動(dòng)執(zhí)行”兩種方案的實(shí)際運(yùn)行成本。結(jié)果通常顯示考慮預(yù)測(cè)誤差后滾動(dòng)優(yōu)化能在燃料成本和購(gòu)電成本上節(jié)省5%到12%具體數(shù)值取決于預(yù)測(cè)誤差幅值。這個(gè)實(shí)驗(yàn)還要注意一個(gè)細(xì)節(jié)日內(nèi)滾動(dòng)優(yōu)化的預(yù)測(cè)數(shù)據(jù)不能直接拿真實(shí)曲線用否則屬于“開(kāi)卷考試”高估了滾動(dòng)優(yōu)化的能力。正確做法是給日內(nèi)預(yù)測(cè)人為加上一個(gè)比日前預(yù)測(cè)小一些的隨機(jī)誤差比如日前預(yù)測(cè)誤差標(biāo)準(zhǔn)差設(shè)為10%日內(nèi)設(shè)為4%再對(duì)多個(gè)隨機(jī)場(chǎng)景求平均。這樣才能真實(shí)反映滾動(dòng)信息質(zhì)量提升帶來(lái)的調(diào)度優(yōu)勢(shì)。5. 復(fù)現(xiàn)這套代碼的排坑實(shí)錄五個(gè)我踩過(guò)但你不用踩的坑這套方案我前前后后迭代了很多版每次踩坑都花了不少時(shí)間。下面這些坑都有共性提出來(lái)給你排掉是這篇內(nèi)容里我最想讓你帶走的部分。5.1 坑一粒子維度太高迭代幾百代都不收斂我第一次直接把全天96時(shí)段的所有變量全部塞進(jìn)一個(gè)粒子維度瞬間到了300以上。改進(jìn)粒子群在這個(gè)維度上跑三百代結(jié)果還是很差原因很簡(jiǎn)單搜索空間的體積隨維度指數(shù)增長(zhǎng)粒子數(shù)量根本覆蓋不過(guò)來(lái)。我的解決辦法是把外層日前調(diào)度放到日內(nèi)時(shí)按需降維具體來(lái)講日前階段用1小時(shí)步長(zhǎng)的24時(shí)段方案做粗粒度優(yōu)化日內(nèi)階段只在一個(gè)4到6小時(shí)的滾動(dòng)窗口里用15分鐘步長(zhǎng)精細(xì)優(yōu)化窗口內(nèi)的決策變量維度控制在40到100維粒子群在這個(gè)規(guī)模下表現(xiàn)就很穩(wěn)定。如果你確實(shí)需要全天96時(shí)段的決策可以先用K-means聚類把典型日負(fù)荷曲線壓縮成幾個(gè)代表性時(shí)段求解再還原到96時(shí)段的基準(zhǔn)網(wǎng)格上評(píng)估成本精度損失通??梢钥刂圃诎俜种詢?nèi)。5.2 坑二SOC漂移導(dǎo)致日內(nèi)結(jié)果完全不可用SOC漂移是最隱蔽的坑之一。日內(nèi)滾動(dòng)優(yōu)化時(shí)如果只盯著當(dāng)前窗口儲(chǔ)能系統(tǒng)會(huì)被當(dāng)前時(shí)段的電價(jià)和負(fù)荷“牽著走”一個(gè)窗口內(nèi)把SOC放得很低下個(gè)窗口又從很低的位置開(kāi)始算最終滾動(dòng)到一天結(jié)束SOC和日前計(jì)劃的預(yù)期值差了十萬(wàn)八千里。我前面的軟約束懲罰項(xiàng)就是專門(mén)治這個(gè)的日內(nèi)目標(biāo)函數(shù)里加入一個(gè)SOC偏差懲罰項(xiàng)讓日內(nèi)優(yōu)化在“跟隨最新預(yù)測(cè)”和“尊重日前計(jì)劃”之間取得平衡。懲罰系數(shù)取大了日內(nèi)滾動(dòng)就失去意義取小了SOC漂移依然嚴(yán)重我在調(diào)試時(shí)用1、2、3、5元/MWh做了一組對(duì)比2元效果最均衡但這個(gè)系數(shù)還是要根據(jù)你算例里的單位電價(jià)做scale調(diào)整。5.3 坑三Matlab矩陣運(yùn)算寫(xiě)成循環(huán)目標(biāo)函數(shù)一次評(píng)價(jià)要兩秒這是Performance層面的教訓(xùn)。最初版本的model_cost.m用了一串for循環(huán)遍歷每個(gè)時(shí)段算功率平衡、燃料成本、碳排放成本一次評(píng)價(jià)要1.5秒種群100個(gè)粒子、迭代300代單次運(yùn)行需要12個(gè)小時(shí)以上。后來(lái)我把所有時(shí)段計(jì)算向量化用矩陣點(diǎn)乘、sum、cumsum這些函數(shù)重寫(xiě)了目標(biāo)函數(shù)單次評(píng)價(jià)降到0.05秒運(yùn)行時(shí)間縮短到半小時(shí)以內(nèi)。對(duì)于這類調(diào)度代碼向量化不是錦上添花而是必須做。如果你在評(píng)價(jià)函數(shù)里看到“先算A、循環(huán)里再算B、B依賴A”這種結(jié)構(gòu)優(yōu)先想能不能用cumsum和濾波器來(lái)替代循環(huán)遞推儲(chǔ)能SOC正是一個(gè)典型的遞推關(guān)系它可以直接用cumsum寫(xiě)成向量形式。5.4 坑四結(jié)果出現(xiàn)“碳排放為負(fù)”被質(zhì)疑造假這個(gè)問(wèn)題我在前面提了一句但它值得單獨(dú)拿出來(lái)說(shuō)。碳價(jià)較高時(shí)改進(jìn)粒子群在搜索中會(huì)發(fā)現(xiàn)“瘋狂捕集”似乎能帶來(lái)很大的碳收益如果模型里沒(méi)有M_cap的上限約束或者沒(méi)有把捕集量與排放量耦合起來(lái)優(yōu)化結(jié)果會(huì)出現(xiàn)捕集量大于總排放量系統(tǒng)的凈碳排放變成負(fù)數(shù)。這在物理上是不可實(shí)現(xiàn)的。解決辦法是在解碼函數(shù)里加一條硬邏輯先計(jì)算E_gt再計(jì)算M_cap_max eta_cap * E_gt剪裁分流比讓它不超過(guò)M_cap_max對(duì)應(yīng)的上限。加了這條之后凈碳排放永遠(yuǎn)大于等于零邏輯上站得住腳答辯時(shí)也不會(huì)被抓到把柄。5.5 坑五復(fù)現(xiàn)結(jié)果驗(yàn)證不足被導(dǎo)師或?qū)徃迦俗穯?wèn)“憑什么信你”代碼可信度的驗(yàn)證我總結(jié)了兩個(gè)便宜好用的方法。第一個(gè)是退化對(duì)比把碳價(jià)設(shè)為零、碳捕集分流比下限設(shè)為零模型退化成普通微網(wǎng)經(jīng)濟(jì)調(diào)度此時(shí)用Matlab里的linprog求解線性規(guī)劃做對(duì)比兩者結(jié)果應(yīng)該高度一致。只要粒子群結(jié)果和線性規(guī)劃結(jié)果對(duì)得上說(shuō)明優(yōu)化框架和解碼邏輯沒(méi)問(wèn)題。第二個(gè)是簡(jiǎn)化場(chǎng)景解析驗(yàn)證把系統(tǒng)縮到兩個(gè)時(shí)段、一臺(tái)機(jī)組、一個(gè)儲(chǔ)能目標(biāo)函數(shù)可以用手算或符號(hào)計(jì)算得到解析最優(yōu)解再用粒子群跑一遍看它是否找到同一個(gè)解。這兩個(gè)驗(yàn)證做完基本上整個(gè)代碼的可信度就有了堅(jiān)實(shí)的地基后續(xù)再談算法改進(jìn)才有意義。最后分享一點(diǎn)個(gè)人體會(huì)。這套代碼真正跑通之后我最大的收獲不是“會(huì)了粒子群”而是明白了智能算法落地時(shí)最核心的功夫在約束處理和模型可靠性上。粒子群的改進(jìn)本質(zhì)上是把搜索能力和問(wèn)題結(jié)構(gòu)匹配起來(lái)匹配得越好算法發(fā)揮越穩(wěn)。如果你現(xiàn)在正在復(fù)現(xiàn)類似題目我建議你先跑通一個(gè)最簡(jiǎn)單的小規(guī)模退化版本把功率平衡修正算子和狀態(tài)傳遞邏輯調(diào)通再逐步加入碳捕集、再加入多時(shí)間尺度滾動(dòng)。一次加一個(gè)變量出了問(wèn)題也能馬上定位。這樣雖然前期慢一點(diǎn)但后面的調(diào)試成本會(huì)小很多整個(gè)項(xiàng)目反而更快交付。