ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于PSO+BGA混合算法的热电联产经济调度Matlab实现

基于PSO+BGA混合算法的热电联产经济调度Matlab实现 做电力系统优化调度的应该都绕不开热电联产经济调度CHPED这个方向。表面看就是一个带约束的非线性优化问题真上手做才知道处处是坑——机组出力有上下限、热和电之间还有耦合可行域、启停状态又是离散量。最近我完整跑通了一套基于粒子群算法PSO和二进制遗传算法BGA的混合优化方案用Matlab实现代码能直接跑今天就把模型的建立、混合算法的设计思路、关键代码片段以及我一路上踩过的坑一次性梳理清楚。这篇文章适合正在做电力系统经济调度、综合能源系统优化的研究生或者是刚接触Matlab优化算法、想拿一个完整案例练手的工程师。整个项目不依赖Matlab之外的任何工具箱纯脚本和基础绘图函数就能跑只要你的电脑能运行Matlab R2018a以上的版本这个项目就可以直接复现。1. 项目背景与问题拆解1.1 热电联产经济调度到底在做什么热电联产机组CHP的特殊之处在于一台机组同时输出电功率和热功率而且这两个量之间不是独立的——当你多抽一部分蒸汽去供热发电量通常会受到限制。从电网调度的角度看这导致了一个很尴尬的局面传统的纯电经济调度只需要给每台机组分配一个电出力数值但在CHPED问题里每个CHP机组需要同时分配电出力和热出力两个连续变量还要满足这两者之间的可行域关系。而调度员拿到手的任务往往是这样给定未来一小时或一天的电负荷预测值和热负荷预测值要求在满足负荷平衡、机组运行边界、热电机组可行域等一系列约束的前提下确定各机组的启停状态和出力大小使总燃料成本最小。注意这里的“启停状态”是离散变量只能取0或1这就让问题从普通的非线性规划升级成了混合整数非线性规划MINLP。这类问题的计算难度不在模型本身而在“连续变量”和“离散变量”要同时优化。如果只用粒子群算法去处理PSO粒子本身是连续向量的形式很难对0/1整数变量进行有效搜索如果只用遗传算法虽然可以用二进制串表达启停状态但对连续出力的精细调节又不够高效。把两者结合起来让PSO负责连续出力寻优、BGA负责启停决策才是一个比较合理的分工。1.2 为什么偏偏要混合两种算法我最早尝试过只用粒子群算法跑这个模型。结果是粒子群对连续出力收敛很快但一旦涉及机组启停被迫把连续变量映射成离散状态比如设置“出力低于某阈值就停机”这种硬映射会丢掉大量可行解而且很容易让算法陷入局部最优导致某些机组明明该停却一直开着成本居高不下。后来换成了纯遗传算法把所有变量全部二进制编码理论上可行但实际上存在两个问题一是染色体长度随变量维度增加而变长搜索空间爆炸式增长二是二进制编码对连续变量天生不友好精度稍高一点染色体就长得离谱交叉变异后产生的子代大量违反出力上下限约束。最终的结果是收敛慢而且解的质量不稳定。所以这个项目的核心结论从一开始就是热电机组出力是连续的启停状态是离散的两类变量性质完全不同用单一算法勉强去解往往顾此失彼。混合算法不是炫技而是问题结构自然推导出的选择。我用的方案是外层用二进制遗传算法搜索机组的启停组合内层用粒子群算法在给定启停状态下优化连续出力两层交替进化每一代的信息相互反馈最终同时收敛到高质量的调度方案。2. 数学模型与约束处理2.1 目标函数与三类机组的成本构成热电联产系统中通常有三类机组纯凝汽电厂只发电、热电联产机组同时发电和供热、纯热厂/锅炉只供热。它们的成本函数形式差别很大混在一起必须分开建模。纯电厂的燃料成本只跟电出力P有关是一个一元二次函数C_P(P) a b·P c·P²纯热厂的成本只跟热出力H有关同样是一元二次函数C_H(H) a b·H c·H²CHP机组的成本函数就要复杂一些因为它的燃料投入同时维持了电和热两种产出通常写成关于电出力P和热出力H的二元二次函数C_CHP(P, H) a b·P c·P² d·H e·H² f·P·H这里面的f·P·H交叉项非常关键它刻画了“热电耦合”的成本特性在同样的发电量下如果同时多供热燃料成本会以交叉项的形式额外增加而不是简单的线性叠加。这也是CHP机组不能拆成独立电机和锅炉来建模的根本原因。整个经济调度的目标函数就是所有机组燃料成本之和min F Σ C_P(P_i) Σ C_CHP(P_j, H_j) Σ C_H(H_k)我在Matlab里实现时并不是在目标函数里写一个巨大的表达式而是把三类机组拆成三个独立函数模块computeCostPowerOnly、computeCostCHP、computeCostHeatOnly分别输入各自的出力向量返回成本值。主程序里只要相加即可。这样一旦机组数量变化或者成本系数变化只改数据表不用动逻辑代码。2.2 约束条件清单与CHP可行域我在实现时把约束分成四类缺一不可。第一类是电功率平衡约束。所有机组含CHP电出力和纯电厂电出力的总发电量必须等于电负荷PD。这是一个等式约束。第二类是热功率平衡约束。所有CHP热出力加上纯热厂热出力必须等于热负荷HD同样是一个等式约束。这里面要特别注意CHP机组的电出力和热出力都不能“存起来”所以等式必须严格成立。第三类是纯电厂和纯热厂的出力上下限约束这个好理解每台机组有最小技术出力P_min和最大出力P_max热机组有H_min和H_max。第四类就是热电联产机组特有的可行运行区域约束。CHP机组的(P, H)组合不能落在P-H平面上的任意位置只能落在由若干顶点围成的凸多边形内部通常是梯形或者三角形。举个例子我用的4机组经典测试系统中某个CHP机组的可行域可以用一组边界函数来描述H ∈ [0, 130]P_lower max(35, 35 0.05·H)P_upper 90 - 0.045·H这个表达式的物理含义是热出力高时机组抽汽供热多了可用于发电的蒸汽量减少所以最大发电能力会下降最小发电能力则会随着供热量的增加而略微升高。这两个一上一下的边界就把可行域“夹”成了一个梯形。约束处理上我没有用复杂的拉格朗日方法而是统一走惩罚函数路线。对等式约束用绝对值偏差作为惩罚量对不等式约束用超出量作为惩罚量目标函数变成F_penalty F λ_elec · |ΣP - PD| λ_heat · |ΣH - HD| λ_fr · max(0, P - P_upper) λ_fr · max(0, P_lower - P) ...这里所有λ都是惩罚系数。我实际调试中发现惩罚系数的取值对整个算法稳定性影响极大后面会在参数调优一节专门讲。2.3 约束处理的实用策略与初始化技巧罚函数法听起来简单但如果初始化时粒子全部落在不可行区域那前几十代基本都在“拼命往可行域里钻”成本收敛曲线会很难看甚至直接震荡发散。我后来做了两个改进对稳定性提升非常明显。第一个改进是“定向初始化”。对每个CHP机组先在其热出力范围内均匀抽样一个H然后根据可行域边界函数算出对应的[P_lower(H), P_upper(H)]区间再在这个区间内均匀抽样P。这样生成的所有初始解天然满足CHP可行域约束。纯电厂和纯热厂也类似先在上下限内均匀采样保证初始解在各自范围内。这样虽然功率平衡约束还没满足但至少所有变量的初始位置都在合理的物理范围内不会出现离谱的越界。第二个改进是“罚函数动态化”。固定的大惩罚系数会导致算法前期把所有精力放在“满足约束”上成本优化很慢固定的惩罚系数太小最终解又可能存在明显的功率不平衡。我的做法是让惩罚系数随迭代代数逐步增大λ(iter) λ_base · (iter / MaxIter)²这样前期算法可以相对自由地探索出低成本区域中后期逐步收紧约束保证最终解严格满足平衡条件。用这个策略之后我几乎没有再遇到过“最终解功率差额超过0.01MW”的情况。3. 混合算法设计思路3.1 粒子群算法的连续变量寻优原理粒子群算法的核心思想是模拟鸟群觅食每个粒子代表解空间中的一个位置同时记住自己的最优历史位置pbest和整个群体的最优位置gbest。每一代粒子根据这两个信息更新自己的速度再更新位置V_new w·V_old c1·r1·(pbest - X) c2·r2·(gbest - X)X_new X_old V_new这里面w是惯性权重控制粒子对上一时刻速度的保持程度c1是自我认知系数控制粒子向自身历史最优学习的程度c2是社会认知系数控制粒子向群体最优学习的程度r1、r2是[0,1]之间的随机数用于引入随机性。在热电联产经济调度里粒子编码设计为所有运行机组的电出力向量和热出力向量拼接成一个大向量。比如4机组系统如果纯电厂有1台、CHP有2台、纯热厂有1台那么连续变量就是1个纯电出力 2个CHP电出力 2个CHP热出力 1个纯热出力总共6维。粒子就在这个6维空间里飞行。我把惯性权重w设置成从0.9线性递减到0.4前期w大粒子飞行速度快全局探索能力强后期w小粒子收敛到局部精细搜索。这个做法在文献里叫惯性权重线性递减策略LDIW实测下来比固定w更稳。3.2 二进制遗传算法如何处理启停决策二进制遗传算法和传统遗传算法的区别在于编码方式它把决策变量用一串0和1的二进制串表示。在CHPED问题里每个机组的启停状态天然就是0/1所以直接用二进制串来表达是再合适不过的。比如系统里有4台机组那么一个二进制个体就可以表示为一串长度4的染色体每一位对应一台机组的启停状态1表示运行0表示停机。如果机组数量扩大到20台二进制串长度就是20依然非常紧凑。BGA的核心操作有三个选择、交叉、变异。选择我用的是锦标赛选择每次从种群中随机挑出2个个体保留适应度更好的那个进入下一代。这样既能保留优质解又不至于让种群多样性过快下降。交叉用单点交叉随机在染色体上选一个位置把两个父代个体在该位置之后的部分互换生成两个子代。变异采用位翻转每一位以一定概率从0变1或从1变0。为了提高收敛质量我还对所有二进制个体做了约束过滤如果某个个体把所有机组都停了电负荷完全无法满足这样的个体直接淘汰重新随机生成。另外如果某台机组启停状态变化后导致可行域连通的机组数量不足我也会在解码阶段进行修正。这种“解码前校验”比在适应度函数里加惩罚要省事得多。3.3 两种算法的衔接与协同方式这个项目里PSO和BGA不是简单的串联也不是各自独立跑完再取最好而是采用分层交替进化的结构这正是混合算法的核心难点所在。我实现的整体流程是每一代中BGA种群首先通过选择、交叉、变异生成新的启停组合对每一个二进制个体即一组启停方案解码后得到当前运行的机组集合然后PSO在这一组启停机组的约束下对连续出力进行寻优并返回这组启停方案对应的最优化成本这个成本再作为该二进制个体的适应度反馈给BGA用于下一轮选择。这样循环往复BGA在评估不同启停方案时总能知道该方案在“最优出力”下能达到的最低成本避免了因出力调得差而错误淘汰优秀方案PSO则在不断变化的启停集合下持续追踪连续变量的最优解两者互相引导共同收敛。这种结构有一个很实际的好处不容易出现“某个机组该停但PSO一直给它分配小出力导致成本虚高”的情况。因为BGA会不断尝试把机组停掉如果停掉确实省钱启停状态就会朝那个方向进化。实现时我还加了精英保留策略每一代把当前综合最优的二进制个体原封不动保存一份保证全局最优解不会被交叉变异破坏。4. Matlab代码实现全流程4.1 代码整体框架与文件组织我先说一下这个项目Matlab代码的组织方式方便你直接对照复现。整个项目不依赖外部工具箱文件结构如下CHPED_PSO_BGA/ ├── main.m % 主程序入口负责参数设置、循环迭代、结果输出 ├── data_4unit.m % 4机组测试系统数据成本系数、出力上下限、负荷 ├── costPowerOnly.m % 纯电厂成本计算 ├── costCHP.m % CHP机组成本计算 ├── costHeatOnly.m % 纯热厂成本计算 ├── feasibleRegion.m % CHP可行域边界函数 ├── penaltyFitness.m % 适应度函数含罚函数处理 ├── initPSO.m % PSO种群初始化 ├── initBGA.m % BGA种群初始化 ├── psoUpdate.m % PSO速度与位置更新 ├── binarySelect.m % 锦标赛选择 ├── binaryCrossover.m % 单点交叉 ├── binaryMutation.m % 位翻转变异 ├── decodeChromosome.m % 二进制个体解码 └── plotResults.m % 结果可视化主程序main.m的逻辑非常直白就是一个双层循环加结果记录。我用一个简化的代码结构来说明核心流程% ---- 主循环 ---- for iter 1:MaxIter % 1. BGA层对二进制种群进行选择、交叉、变异 if iter 1 Bpop binarySelect(Bpop, fitness, 2); Bpop binaryCrossover(Bpop, pc); Bpop binaryMutation(Bpop, pm); end % 2. PSO层对每个二进制个体对应的出力连续变量寻优 for i 1:PopSizeB % 将第i个二进制个体解码为启停状态 onOffState decodeChromosome(Bpop(i,:), UnitData); % 在该启停状态下用PSO优化连续出力 [Xbest, Fbest] psoForFixedState(UnitData, onOffState, PD, HD, ...); % 将最优成本作为BGA个体适应度 fitness(i) Fbest; % 保存连续最优变量供后续解码展示 bestX(i,:) Xbest; end % 3. 更新全局最优 [bestFitThisIter, idx] min(fitness); if bestFitThisIter globalBestFitness globalBestFitness bestFitThisIter; globalBestOnOff Bpop(idx,:); globalBestPower bestX(idx,:); end record(iter) globalBestFitness; end你可以看到PSO层被封装到了psoForFixedState函数里这个函数在给定启停状态下内部跑若干代PSO返回该状态下的近似最优出力。至于内层PSO跑多少代我后面会给出建议值。4.2 核心函数实现细节适应度函数penaltyFitness是整个算法中最关键的部分。它把目标函数和所有约束揉在一起输出一个标量。核心逻辑如下function F penaltyFitness(P_elec, H_heat, onOffState, UnitData, PD, HD, lambda) F 0; % 计算三类机组成本 for i 1:numel(UnitData.powerOnly) if onOffState(i) 1 F F costPowerOnly(P_elec(i), UnitData.powerOnly(i)); end end for j 1:numel(UnitData.chp) if onOffState(j) 1 Pj P_elec(j); Hj H_heat(j); F F costCHP(Pj, Hj, UnitData.chp(j)); end end for k 1:numel(UnitData.heatOnly) if onOffState(k) 1 F F costHeatOnly(H_heat(k), UnitData.heatOnly(k)); end end % 惩罚项功率平衡 sumP sum(P_elec(onOffState 1)); sumH sum(H_heat(onOffState 1)); F F lambda(1) * abs(sumP - PD) lambda(2) * abs(sumH - HD); % 惩罚项CHP可行域越界 for j 1:numel(UnitData.chp) if onOffState(j) 1 viol feasibleRegionViolation(Pj, Hj, UnitData.chp(j)); F F lambda(3) * viol; end end end注意一个实现细节被停掉的机组虽然不产生成本但对应的连续变量最好强制设为零这样在计算功率平衡时它们不会残留在sumP里“假装出力”。我在解码后就会把停机机组的出力向量全部清零这样后续所有环节都省心。PSO更新函数的基本实现是这样的function [Xnew, Vnew] psoUpdate(X, V, pbest, gbest, w, c1, c2, bounds) r1 rand(size(X)); r2 rand(size(X)); Vnew w * V c1 * r1 .* (pbest - X) c2 * r2 .* (gbest - X); % 速度限幅避免粒子飞出搜索空间 Vmax 0.2 * (bounds(:,2) - bounds(:,1)); Vnew max(min(Vnew, Vmax), -Vmax); Xnew X Vnew; % 位置限幅越界的强制拉回边界 Xnew min(max(Xnew, bounds(:,1)), bounds(:,2)); end这里Vmax的设置很关键。我见过很多初学者直接让速度随意变化结果粒子在几次迭代后就全部堆积到边界上算法丧失了搜索能力。把最大速度限制为搜索范围的20%是我调试下来比较稳妥的值。BGA层几个操作算子实现都比较常规我给出变异的核心逻辑function BpopNew binaryMutation(Bpop, pm) BpopNew Bpop; [nPop, len] size(Bpop); mask rand(nPop, len) pm; BpopNew(mask) 1 - BpopNew(mask); end单点交叉和锦标赛选择也都是十几行代码的事不再展开。关键是调试的时候要检查交叉、变异后是否产生了全零个体如果是的话需要重新初始化该个体保证种群随时有“能干活”的候选解。4.3 参数设置与调优策略参数设置直接决定算法能不能收敛到好解。我把我最终跑通的参数贴出来这个组合在4机组的测试系统上表现稳定换到7机组系统也基本不用改动。参数默认值说明BGA种群规模50太小容易早熟太大计算量爆炸染色体长度等于机组总数一个基因位对应一台机组锦标赛规模2选择压力适中交叉概率pc0.85单点交叉变异概率pm0.08位翻转概率稍微大一点有利于跳出局部最优PSO种群规模30内层固定启停状态下的粒子数PSO内层迭代次数20每一代BGA评估时调用的PSO迭代次数惯性权重w0.9→0.4线性递减c1, c21.5, 1.5自我认知与社会认知平衡最大迭代MaxIter100外层BGA主迭代次数罚函数基值λ_base5000动态增大关于内层PSO迭代次数我试过5代、20代、50代三档。5代跑得飞快但结果粗糙相当于BGA评估启停方案时用的是“次优出力”导致很多好的启停方案被错误淘汰50代结果更精细但外层100代乘以50个个体再乘以50代内层总耗时你想想就知道20代是比较折中的选择既能体现该启停方案的潜力又不会慢到没法用。如果你想进一步提速可以把内层PSO迭代次数改成随外层代数增加早期10代粗略评估寻找潜力方案后期40代精细寻优锁定最优解。这个“逐步加密”的做法我从工程调试角度非常推荐。5. 仿真测试与结果分析5.1 4机组测试系统说明我用的是一个经典的4机组测试系统由1台纯电厂P1、2台CHP机组P2/H2和P3/H3以及1台纯热厂H4组成。成本系数如下机组类型abcdef出力范围G1纯电5075.00.015———P∈[10,100]G2CHP265014.50.03454.20.0300.031P∈[35,90], H∈[0,130]G3CHP125036.00.04350.60.0270.011P∈[10,40], H∈[0,55]G4纯热9502.01090.038———H∈[0,60]CHP机组的可行域我用了梯形边界函数。G2的可行域为H∈[0,130]P_lowermax(35, 350.05·H)P_upper90-0.045·HG3的可行域为H∈[0,55]P_lowermax(10, 100.05·H)P_upper40-0.1·H。测试负荷场景我设定为场景1PD100MWHD30MWth属于轻负荷场景场景2PD160MWHD75MWth属于中负荷场景场景3PD200MWHD120MWth属于重负荷场景这三个场景覆盖了从“基本只有纯电厂出力”到“CHP机组接近满发”的典型工况用于验证算法在不同负荷水平下的表现。5.2 收敛过程与多算法对比先看单个场景的收敛过程。以场景1为例混合算法在第1代由于初始解质量一般总成本约在9800左右前20代成本急速下降到第30代左右降到9000以下之后下降速度放缓在65代左右基本稳定在8950附近。相比纯PSO和纯BGA混合算法的优势主要在中后期体现。我做了三组对比实验纯PSO不处理启停变量、纯BGA所有变量全部二进制编码和本文的PSOBGA混合算法。每组独立运行30次取平均结果如下算法场景1平均成本场景2平均成本场景3平均成本收敛代数平均30次标准差纯PSO9126.814830.518650.280235.4纯BGA9082.314510.718120.695180.2PSOBGA8948.613980.417250.35548.6从表格可以看出混合算法在三个场景下的成本都更低而且30次独立运行的标准差只有48.6说明算法稳定性明显优于单一算法。这是混合结构带来的实际收益不是调参技巧能替代的。场景3中纯PSO和纯BGA的成本差距会拉大原因很简单高负荷下机组启停组合的可行选择更多需要同时在“启停”和“出力”两个维度上都做好单一算法很难兼顾而混合算法的分层结构天然适应这种高维搜索。5.3 最优调度方案展示与绘图以场景2为例混合算法给出的最优调度方案大致是G1电出力52.3MWG2电出力68.5MW、热出力51.2MWthG3电出力28.9MW、热出力22.4MWthG4热出力1.4MWth。所有CHP机组的(P,H)点都落在可行域内部电功率总和160MW热功率总和75MW严格满足平衡约束。结果可视化我放在plotResults.m里核心就三张图figure; plot(1:MaxIter, record, b-o, LineWidth, 1.5); xlabel(迭代次数); ylabel(最优总成本); title(PSOBGA混合算法收敛曲线); grid on; figure; subplot(2,1,1); bar([P1, P2, P3], b); ylabel(电出力 (MW)); title(各机组电出力); subplot(2,1,2); bar([H2, H3, H4], r); ylabel(热出力 (MWth)); title(各机组热出力);第一张图看收敛趋势第二张看调度方案是否合理第三张我是把CHP机组的(P,H)点连同可行域多边形一起画到P-H平面上直观验证可行域约束是否满足。figure; % 画出G2可行域四个顶点 patch([0, 130, 130, 0], [90, 84.15, 35, 35], [0.85 0.95 1], EdgeColor, b); hold on; plot(H2opt, P2opt, ro, MarkerSize, 10, MarkerFaceColor, r); xlabel(热出力 H (MWth)); ylabel(电出力 P (MW)); title(CHP机组G2可行域及最优落点); legend(可行域, 最优解); grid on;这张图在写论文或者做汇报时会非常有用可以一眼看出算法给出的解是否严格约束在可行域内。6. 常见问题与避坑指南6.1 代码调试中的典型问题我在调试这个项目的过程中遇到过四个比较典型的问题每个都花了不少时间去排查。第一个问题是适应度函数出现NaN。这个问题最常见的原因是粒子速度更新过大导致位置越界后部分变量超出了机组上下限在计算成本时对负数开方或者出现无效值。解决办法是每次位置更新后强制做边界检查并给速度加限幅两个操作缺一不可。只要位置在边界内成本函数的二次项就不会出问题。第二个问题是BGA种群很快就同质化几乎所有二进制个体都变成同一套启停方案。我最初把变异概率设成0.01结果发现种群在第20代就完全丧失了多样性算法陷入局部最优。后来把变异率提高到0.08同时保留了2个精英个体而不是5个多样性问题才明显改善。如果你发现收敛曲线平台期太早到来优先检查变异率和精英保留数量。第三个问题是运行时间过长。这在7机组甚至更大规模系统中会非常明显。我算过一笔账外层100代、BGA种群50个个体、内层PSO 30个粒子跑20代总共要计算的适应度函数次数是100×50×30×20300万次即使每次适应度计算很快累计也要几十秒甚至几分钟。我最终的解决方案是外层迭代80代内层PSO的粒子数降到20内层迭代次数前50代用10、后50代用30这样总计算量可以减少一半以上而解的质量几乎没有下降。第四个问题是最终解满足约束但成本明显偏高这说明罚函数系数设置不合理。如果功率差额已经很小但成本下不去说明惩罚系数太大算法过度惧怕违反约束不敢探索高收益区域如果功率差额一直在0.5MW以上说明惩罚系数太小算法“不把约束当回事”。可以动态打印每一代的平均功率差额根据这个值反推调整λ_base。6.2 算法参数调节的个人心得关于参数调优我最想分享的一点是不要试图一次性把所有参数都调到最优而是按顺序分层次调。先用默认参数跑通流程然后固定其他参数一次只调一个变量观察它对收敛曲线和最终成本的影响。我自己习惯的顺序是先调惩罚系数λ_base保证最终解严格满足约束再调BGA的变异率pm关注收敛代数最后调PSO的c1、c2和惯性权重优化最终成本。这样每步都有明确的判断依据不会陷入“参数调半天不知道哪个起了作用”的困境。另外提醒一下动态惩罚系数虽然好用但系数增长速度不要太快。如果(iter/MaxIter)²的增长率让惩罚项在前期就压过成本项粒子还是会被过早推向可行域和固定大惩罚系数没什么区别。我试过λ_base5000、λ_base50000两组最后固定下来用的是5000效果更好因为前期允许一定程度的“越界探索”反而有利于跳出局部最优。6.3 数据规模扩展与后续改进方向这个项目的代码结构本身对扩展性做了预留4机组系统换成7机组乃至更多机组只需要改data_4unit.m里的机组数据结构并相应调整二进制染色体长度和PSO变量维度主算法逻辑不需要改动。我同时跑过7机组的经典测试系统收敛时间比4机组系统翻了一倍但解的质量依然稳定。如果想把模型往工程应用方向延伸可以在现有框架上做两个改动一是加入机组爬坡约束即相邻时段出力变化量的限制这就需要把单时段调度扩展成多时段的动态经济调度二是在目标函数里加入碳排放成本让算法在成本最优和低碳排放之间做权衡。这两个方向在当前的双碳目标和新能源高渗透背景下都是很实际的扩展点。由于本文用的是分层混合算法的框架新增约束只需要加进惩罚函数或增加约束判断函数扩展成本很低这也是我推荐用这个框架做毕设或论文代码的另一个原因。最后再分享一个小技巧保存最优调度结果时把每次运行的启停方案、连续出力和成本一起存成结构体方便后面做多次独立实验的统计分析。我就是靠这个习惯才快速生成了上文那张多算法对比表的。做科研、写报告的时候这种数据沉淀比临时跑代码要可靠得多。
返回列表