基于主从博弈的电热综合能源系统动态定价与能量管理Matlab实现
发布时间:2026/9/10 1:10:54来源:尧图网络
直接说结论这套“基于主从博弈的电热综合能源系统动态定价与能量管理”项目我做过完整复现和改造今天把建模思路、求解细节、Matlab代码结构、还有调试中踩过的坑一次性整理出来。核心就一句话运营商定电价和热价用户跟着价格调整自己的用电用热行为两边目标互相冲突但又存在先后决策关系这就是Stackelberg主从博弈的典型场景。这篇文章适合正在做综合能源系统、需求响应、动态定价相关课题的同学也适合想用Matlab快速搭建电热联合调度仿真原型的工程师。我会把关键公式、算法框架、代码片段、调参经验全部讲透。1. 项目概述与问题背景1.1 电热综合能源系统的核心特征电热综合能源系统业内通常叫Integrated Electricity-Heat Energy SystemIEHES本质上是把电力网络和热力网络放在同一个规划调度框架里统筹考虑。它和单纯电力系统最大的区别在于存在耦合设备常见的有热电联产机组CHP、电锅炉、热泵、储热罐。CHP能同时出电和出热但它的热电出力之间存在耦合可行域不是你想让电出力多高就多高、热出力多大就多大必须满足一组热力约束关系这就是业内常说的“以热定电”或者“电热联产可行域”。电锅炉和热泵属于“电转热”设备消耗电能产生热能它们的作用是给电力系统提供额外的消纳通道尤其在风电、光伏大发而电网消纳能力不足时把多余的电转化为热能储存或直接供给热负荷。第二个关键特征来自时间尺度差异。电力系统的调度粒度通常能做到15分钟甚至5分钟而热力系统由于管网热惯性和建筑围护结构的热容量小时级调度已经足够。所以这篇代码模型里统一采用1小时一个时段T24的离散化方式既能反映峰谷差异又不会让模型因为时段太多导致求解时间翻好几倍。1.2 为什么这种结构天然适配主从博弈很多刚接触这个方向的人会问既然要同时优化运营商利益和用户用能成本为什么不用一个集中式优化模型把两个目标加权求和一次性求解出最优方案答案是现实场景中用户不是“被遥控的设备”。在集中式优化里运营商需要知道每个用户精确的效用函数、用能偏好、可调减能力这在现实中几乎不可能获取。而在主从博弈框架下用户只需要在运营商给出的价格信号下独立决策不需要上报隐私信息整个机制更接近真实市场。更直白的场景是运营商把峰时电价抬高用户看到价格之后主动把洗衣机挪到低谷时段或者把蓄热电采暖在低谷多加热一会儿。这种“价格引导下的自主响应”正是主从博弈的核心逻辑。上层运营商定价格下层用户做响应双方迭代交互最终收敛到Stackelberg均衡。均衡点的意义很明确给定用户的最优响应策略运营商的价格策略已经是最优的反过来给定运营商的价格用户也用能成本已经最小化。这种互相印证的最优性比单纯算一个“多目标加权最优解”更有说服力在论文写作里也更受审稿人认可。2. 主从博弈数学建模思路2.1 参与者角色与决策变量设定模型里有明确的两层参与结构。上层是售能运营商它的决策变量分两类一类是市场信号也就是全天24小时的电价向量 price_e(t) 和热价向量 price_h(t)另一类是设备侧运行变量包括从上级电网购电功率 Pbuy(t)、CHP电出力 Pchp(t)、CHP热出力 Hchp(t)、电锅炉耗电功率 Peb(t)、热泵耗电功率 Php(t)、储热罐充放热功率 Hs(t)。下层是聚合用户决策变量为每个时段的用电量 Pe_user(t) 和用热量 Ph_user(t)。建模时有一个很常见的取舍问题要不要把每个用户单独建一个独立的跟随者模型理论上多跟随者的Stackelberg博弈更接近真实多用户市场但模型复杂度会成倍增加均衡存在性证明也很麻烦。从实操角度我建议第一版先按“聚合用户”处理把同类用户看成一个整体用一条聚合需求响应曲线刻画价格与负荷的关系。这样既保留了下层博弈的结构特征又让模型站在可求解的边界以内。后续如果做扩展拆成工业用户、商业用户、居民用户三类逻辑也完全兼容只是把单一下层复制成多个子优化问题。2.2 上层目标函数与约束条件解析上层运营商的净利润由售电收入、售热收入减去购电成本和设备运维成本构成。目标函数写成Matlab风格的伪代码是profit sum(Price_e .* Pe_user Price_h .* Ph_user) ... - sum(c_pbuy .* Pbuy) ... - sum(c_chp_om .* Pchp c_eb_om .* Peb c_hp_om .* Php);写目标函数时有几个细节必须注意。第一电价和热价的数值范围差异极大电价通常几百元/MWh热价可能只有几十元/GJ如果不做量纲统一目标函数里热价收入项会被电价项彻底“淹没”优化器会直接把热价压到下限。我第一次跑这个模型时就踩了这个坑结果热负荷完全失去了响应弹性。后来在代码里把热价和热负荷统一折算成MWh口径再给两类收益做标幺化才把价格灵敏度拉平。第二设备运维成本里的储热罐充放热成本我习惯用绝对值形式虽然引入了非线性但用YALMIP建模时可以直接处理。上层约束可以分成四类。第一类是电力平衡约束Pbuy 加上 Pchp 等于用户的配电网用电量加上电锅炉和热泵的耗电不允许有缺电或弃电。第二类是热力平衡约束CHP热出力、电锅炉产热、热泵产热加上储热罐放热等于用户热负荷。第三类是CHP热电耦合可行域约束通常用一组线性不等式描述比如Hchp k1 * Pchp b1; Hchp k2 * Pchp b2; Hchp Hchp_max;这组约束的意义就是让CHP不能只追电利润而完全忽略热出力限制。第四类是设备出力上下限约束以及储热罐的荷电状态约束储热罐前后时段的储热量要衔接上不能今天充到100%明天直接跳回0%。2.3 下层用户用能行为建模下层模型的目标函数是用户在给定价格下追求购能成本最小化但这里不能只写最小化成本否则优化器会直接把用户负荷压到零结果完全失真。必须叠加需求响应约束常用做法是给每个时段的负荷可调节量设置上下限比如可转移负荷比例为20%可削减比例为5%~10%同时一天内的总用电量基本不变或只能小幅削减。这种“成本最小化调节区间约束”的模型在Matlab里最容易复现、最好调试也足够支撑主体结论。如果想要更精细的结果可以引入效用函数比如用二次效用函数刻画用户对用电量的满意度让用户目标变成“用电效用减去购电支出”的最大化。这种方式推导出的用户最优响应函数是线性的分析均衡唯一性时非常好用。但第一版项目建议先跑简单的成本最小化模型把主从博弈闭环跑通之后再升级效用函数模型一步到位容易出各种细节问题调试成本高。3. 动态定价机制设计3.1 分时段价格策略的设计原则动态定价在这个项目里不是简单地把一天分成峰平谷三个时段而是在博弈框架下内生求解出来的价格序列。也就是说峰谷划分不需要提前人为设定模型会根据负荷特性、设备出力、购电成本和用户响应自动找到更合理的价格形态。这是主从博弈定价和传统分时电价最大的区别也是选题的亮点所在。价格设计需要满足以下几个约束价格必须在合理区间内比如电价下限取上级电网购电成本上限取用户可承受的最高价格热价同理。价格序列不能出现极端跳变否则用户侧负荷波动也会跟着剧烈震荡对真实系统不友好。在迭代求解时我会对价格更新做阻尼处理每次迭代的新价格取当前价格和优化结果之间的加权平均阻尼系数通常取0.3到0.5。这个处理对防止振荡非常有效我试过不设阻尼直接迭代结果价格序列在小数点后一位的范围内来回振荡花了很久才定位到真正原因。3.2 需求价格弹性的表达方式动态定价有效性的理论基础是需求弹性。在聚合用户模型里用电负荷对电价的弹性可以定义为负荷变化率除以价格变化率反映的是用户对价格信号的敏感程度。热负荷对热价的弹性同理。但由于电和热之间存在耦合比如热泵消耗电能产热严格来说还应该考虑交叉弹性电价变化会通过热泵影响热负荷热价变化也会反过来影响用电。第一版模型可以先忽略交叉弹性只考虑各自负荷对自身价格的主弹性把交叉影响留给设备层的调度逻辑去体现。从代码实现角度看弹性最直接的落地方式是给每个时段的负荷调节范围设定一个与价格相关的上下界。例如低谷时段热价较低用户允许的热负荷上调比例放宽到30%高峰时段热价较高热负荷可下调比例放宽到20%。这种做法虽然不完全等价于连续弹性函数但工程上稳定、直观而且避免引入大量非线性约束导致求解困难。3.3 Stackelberg均衡的判据判断博弈是否收敛到Stackelberg均衡核心看两个条件。第一给定用户的最优响应上层运营商在当前价格下已经无法通过单方面调整价格获得更高利润第二给定运营商的价格策略用户在当前负荷水平下无法通过单方面调整用能来降低购能成本。在迭代算法中我们无法直接验证这两个条件只能通过收敛性替代判断相邻两代价格向量的最大变化量小于一个阈值比如1e-4同时连续若干代利润变化不超过0.1%就认为迭代收敛到了近似均衡。需要特别提醒的是收敛的迭代点不一定就是全局均衡它可能只是局部均衡。尤其在外层使用粒子群或差分进化这类启发式算法时结果依赖初始种群和参数设置。所以我在跑正式算例之前会先用三个不同随机种子各跑一遍对比价格序列和利润是否一致。如果差异很大说明算法没有收敛到同一个均衡点需要返工检查搜索参数或者增加种群规模。4. 求解算法与Matlab实现框架4.1 两条主流求解路线对比主从博弈的求解思路有两条路线。第一条是精确求解路线利用KKT条件将下层用户优化问题转化为上层问题的约束把一个两层优化模型重构成带均衡约束的数学规划问题然后通过大M法把互补松弛条件线性化最终得到一个混合整数线性规划模型交给Gurobi或CPLEX这样的商业求解器直接求解。这种方法的好处是结果精确、可复现性好不存在随机性缺点是建模过程繁琐KKT转化一步出错就会导致结果异常大M取值不当还容易引发数值病态问题。第二条是启发式迭代路线外层用粒子群、差分进化、灰狼算法等智能算法搜索价格向量内层对于每个候选价格分别求解下层用户问题和上层设备调度问题计算运营商的利润作为外层适应度函数值。这种做法的优点是程序结构清晰、容易调试、不依赖复杂的数学推导缺点是结果带随机性算法参数需要反复调而且计算量相对较大每个粒子都要调用两次优化求解器。从项目复现和工程落地的角度看我更推荐第二条路线。原因很实际Matlab环境下用YALMIP建模很方便内层两个小规模的二次规划或线性规划求解速度非常快外层用差分进化或者粒子群搜索几百代也就一两分钟的事。而且这种模块化的结构天然方便做敏感性分析想改用户侧参数或者设备参数只需要改对应模块不用动整体框架。下面我给出的代码结构也是按这个路线组织的。4.2 整体计算流程与数据流设计整个程序的运行流程可以分成五步。第一步加载基础数据包括用户基础用电负荷曲线、用热负荷曲线、上级电网购电价格、设备参数、价格上下限等。第二步初始化外层种群每个个体是一个长度为2T的向量前半段是24小时电价后半段是24小时热价。第三步进入迭代循环对每个个体调用“评估函数”先解下层用户问题得到负荷响应再解上层设备问题得到设备出力和购电成本最后计算利润。第四步按外层算法规则进行变异、交叉、选择生成新一代种群。第五步判断是否满足停止条件输出最优价格序列和各侧负荷曲线。这里最关键的数据流设计在于“下层用户问题”和“上层设备问题”两个模块的输入输出接口要保持稳定。下层输入是价格向量和用户基础参数输出是响应后的电负荷和热负荷上层设备问题输入是用户负荷和价格输出是设备出力和购电成本。两个模块解耦之后你甚至可以中间换一个求解器或者把下层换成效用函数模型外层算法都不用动。4.3 YALMIP和Gurobi环境搭建注意点Matlab环境下做优化YALMIP基本是标配工具箱它相当于一个建模语言屏蔽了不同求解器之间的接口差异。安装时注意两点第一YALMIP要把文件夹加入Matlab路径建议把整个工具箱文件夹拷到Matlab的toolbox目录下然后用Set Path永久添加避免每次启动都重新配置第二YALMIP本身不自带求解器只是建模层实际求解需要底层求解器支持。线性规划和二次规划用Gurobi或CPLEX最快没有商业求解器的也可以用Matlab自带的linprog和quadprog但求解规模大、约束多的时候可能速度不够。装好之后在Matlab里验证一次环境是否正常运行yalmiptest命令会显示所有可用求解器的状态。我在实际环境配置中遇到的典型问题有两个一是Gurobi许可证过期导致跑模型时直接报错排查半天还以为是代码问题二是求解器版本和Matlab版本不兼容Matlab 2023a以上建议直接用Gurobi 10.x版本老版本会出现一堆莫名其妙的接口报错。5. 关键代码实现与运行结果分析5.1 基础参数定义与数据结构我习惯把所有场景参数集中放在一个结构体变量里好处是函数调用时只需要传一个params不需要一长串参数列表。示例代码如下params struct(); params.T 24; params.Pe_base [600 580 ... 750]; % 1x24 基础电负荷 params.Ph_base [350 340 ... 450]; % 1x24 基础热负荷 params.alpha_e 0.2; % 电负荷可调节比例上限 params.alpha_h 0.25; % 热负荷可调节比例上限 params.c_pbuy [300 300 ... 650]; % 1x24 上级购电价格 params.c_chp_om 45; % CHP运维成本 params.c_eb_om 8; params.c_hp_om 12; params.Price_e_max 1200; % 电价上限 params.Price_e_min 200; % 电价下限 params.Price_h_max 400; % 热价上限 params.Price_h_min 50; params.Pchp_max 800; % CHP电出力上限 params.Hchp_max 700; % CHP热出力上限 params.Peb_max 500; params.Php_max 400; params.Hs_max 300; params.eta_eb 0.95; % 电锅炉效率 params.COP_hp 3.2; % 热泵能效比这些参数的具体取值直接影响模型结果。比如热泵COP取3.2意味着1份电能产生3.2份热能在热价合理时运营商会倾向于用热泵替代CHP供热因为这样能释放CHP的电出力去获取更高售电收入。这些设备参数之间的相对大小往往比绝对数值更影响优化结果做敏感性分析时优先看这些比值关系。5.2 下层用户响应函数实现下层用户问题的核心是给定价格向量求解用户的负荷响应。我用YALMIP建模决策变量是各时段的负荷调整量目标函数是购能成本最小化。这里要注意的是目标函数里的价格是外部传入的常数向量不是决策变量所以这是一个标准的线性规划或二次规划求解一次非常快。function [Pe_user, Ph_user, obj_user] user_response(Price_e, Price_h, params) T params.T; Pe_base params.Pe_base; Ph_base params.Ph_base; delta_Pe sdpvar(1, T); delta_Ph sdpvar(1, T); objective sum(Price_e .* (Pe_base delta_Pe) ... Price_h .* (Ph_base delta_Ph)); constraints []; constraints [constraints, -params.alpha_e * Pe_base delta_Pe params.alpha_e * Pe_base]; constraints [constraints, -params.alpha_h * Ph_base delta_Ph params.alpha_h * Ph_base]; constraints [constraints, sum(delta_Pe) 0, sum(delta_Ph) 0]; ops sdpsettings(solver, gurobi, verbose, 0); optimize(constraints, objective, ops); Pe_user value(Pe_base delta_Pe); Ph_user value(Ph_base delta_Ph); obj_user value(objective); end这个函数有几个我调试过程中反复确认过的细节。第一delta_Pe的下界用了负号乘基础负荷允许用户削减负荷上界是正数允许用户增加用电。第二全天总用电量变化之和约束用了大于等于0意思是允许用户整体小幅增加用电但一般不会整体减少这个设定更符合“用户不会无缘无故少用能”的实际逻辑。第三求解器返回的是value()获取数值解避免在后续计算里误用符号变量导致维度错误。5.3 上层设备调度函数实现上层设备调度的输入是用户响应后的负荷和价格输出是设备的最优出力方案。运营商在这个模块里要做的其实是成本最小化也就是在满足用户负荷的前提下决定CHP出多少电热、电锅炉和热泵各用多少、储热罐充放多少、从电网买多少电使得购电成本和运维成本之和最小。这个模块和主从博弈的外层搜索是解耦的外层只管定价内层根据价格算出最优设备方案。function [profit, Pbuy, Pchp, Hchp, Peb, Php, Hs] operator_schedule(Price_e, Price_h, Pe_user, Ph_user, params) T params.T; Pbuy sdpvar(1, T); % 购电功率 Pchp sdpvar(1, T); % CHP电出力 Hchp sdpvar(1, T); % CHP热出力 Peb sdpvar(1, T); % 电锅炉耗电 Php sdpvar(1, T); % 热泵耗电 Hs sdpvar(1, T); % 储热罐放热功率正放热负充热 % 成本最小化 cost sum(params.c_pbuy .* Pbuy) ... sum(params.c_chp_om .* Pchp) ... sum(params.c_eb_om .* Peb) ... sum(params.c_hp_om .* Php); objective cost; constraints []; % 电力平衡 constraints [constraints, Pbuy Pchp Pe_user Peb Php]; % 热力平衡 constraints [constraints, Hchp params.eta_eb * Peb params.COP_hp * Php Hs Ph_user]; % CHP可行域 constraints [constraints, Hchp 0.9 * Pchp 100, Hchp 0.3 * Pchp - 50]; constraints [constraints, 0 Pchp params.Pchp_max, 0 Hchp params.Hchp_max]; % 其他设备上下限 constraints [constraints, 0 Peb params.Peb_max]; constraints [constraints, 0 Php params.Php_max]; constraints [constraints, -params.Hs_max Hs params.Hs_max]; ops sdpsettings(solver, gurobi, verbose, 0); optimize(constraints, objective, ops); Pbuy value(Pbuy); Pchp value(Pchp); Hchp value(Hchp); Peb value(Peb); Php value(Php); Hs value(Hs); % 总收入 - 总成本 revenue sum(Price_e .* Pe_user Price_h .* Ph_user); profit revenue - cost_value_proxy(); end关于这个模块有三个地方很容易出错。第一热力平衡约束里储热罐的符号定义我统一规定正数为放热、负数为充热对应右侧是加上Hs。如果你的代码里符号定义反了出结果会发现储热罐在低谷时不充热反而放热非常诡异。第二CHP可行域约束里的系数要根据具体机组特性来定不是随便写的不同文献的CHP线性化系数可以差别很大最好根据具体机组参数标定。第三设备调度函数返回的profit计算要先用value()取出所有决策变量数值再用数值重新计算收入和成本不能直接把YALMIP符号目标函数值和收入加在一起类型不匹配经常导致出错。5.4 外层启发式搜索与主循环外层搜索我推荐用差分进化算法参数少、鲁棒性好、实现简单。核心循环的伪代码如下NP 40; % 种群规模 MaxIt 80; % 最大迭代次数 F 0.6; % 差分权重 CR 0.9; % 交叉概率 X init_population(NP, params); % 每个个体是 2*T 维价格向量 for it 1:MaxIt for i 1:NP [Pe_user_i, Ph_user_i] user_response(X(i, 1:T), X(i, T1:end), params); [profit_i, ~] operator_schedule(X(i, 1:T), X(i, T1:end), Pe_user_i, Ph_user_i, params); fitness(i) -profit_i; % 差分进化默认最小化 end % 变异、交叉、选择更新种群 X % 记录最优个体和对应利润 end这里我把利润取负作为适应度值因为差分进化默认做最小化搜索。每个个体调用两次YALMIP求解器一次用户响应、一次设备调度种群规模40、迭代80代总共要调用6400次求解器在常规笔记本上大概两三分钟能跑完。如果算得太慢可以缩小种群到25、迭代到50结果一般还能保持稳定。外层的价格初始化非常重要我建议在价格上下限之间的中间偏上区域随机初始化而不是在整个可行域内均匀撒点。原因是若初始电价偏低所有用户响应都会往上调负荷设备约束容易被挤爆内层求解器会警告不可行从中间偏上位置起手通常能避免很多数值麻烦。5.5 结果可视化与分析运行完之后我一般会画三组图。第一组是电价和热价曲线横轴是24小时纵轴是价格观察价格是否出现明显的峰谷形态以及电热价的相关性。第二组是用户侧电负荷和热负荷曲线叠加在基础负荷曲线上观察需求响应后的削峰填谷效果。第三组是迭代收敛曲线横轴是迭代次数纵轴是运营商利润用来判断是否收敛到稳定值。在典型参数设置下你会看到以下几条规律高峰时段电价明显高于低谷对应基础电负荷在晚间达到峰值用户响应后高峰负荷下降、低谷负荷上升热价曲线因为热负荷相对平稳峰谷差不会像电价那么剧烈设备出力方面CHP在热电负荷都高的时段满负荷运行而在低谷时段热泵功率上升、电锅炉在电价极低时启动储热罐在低谷充热、高峰放热。这几条规律基本验证了动态定价和能量管理的有效性。6. 常见问题与调试经验6.1 迭代不收敛怎么办我最常被问到的问题是价格迭代过程中来回振荡、长期不收敛。这个通常有三个原因价格更新步长太大、价格上下限设置过宽、下层用户响应比例太大。典型的解决方法是给价格更新加阻尼比如新价格取上一代价格和当前候选价格的加权平均权重0.5配0.5慢慢缩小。另一个办法是增加种群规模和迭代次数让算法有更多机会搜索到稳定区域。还有一个易被忽略的原因价格初始值落在可行域边缘导致前几十代一直往可行域内部冲浪费了大量迭代资源。初始种群设在价格区间中间偏上位置收敛速度会有明显提升。6.2 下层优化出现零解如果发现用户响应后的负荷直接掉到零或者接近零首先要检查目标函数里价格和负荷的匹配关系。最典型的原因是把用户问题的目标函数写成了最大化收益而不是最小化购能成本优化器会拼命把负荷压到最小。另一个常见原因是需求响应约束没有设置正确比如delta的上下界符号写反或者忘了加总负荷基本不变的约束。这两类问题在调试时看最优解的目标值就能判断成本如果是负数或者异常大就要回头检查式子方向。6.3 求解器相关的典型报错环境配置问题永远是技术咨询的高频区。YALMIP报“No suitable solver for the problem”时先别怀疑代码第一步跑yalmiptest看看到底有哪些求解器可用第二步确认Gurobi或CPLEX的license是否有效。如果报错说求解器不支持某个变量类型通常是你把某个标量参数误写成了sdpvar变量导致模型变成了非线性规划而商业求解器不认。把问题规模缩小到T4甚至T1逐行打印变量类型是最快的排查手段。6.4 数值尺度问题的处理技巧综合能源系统里电价、热价、功率、容量这几个量纲的数量级差异很大稍不注意就会出现数值病态。电价动辄几百热价可能只有几十设备容量上千目标函数各项相差几个数量级。我的经验是对所有价格和功率做标准化处理把价格统一折算成同一单位把功率按基准容量标幺化利润最终再换算回实际值。这样不仅能提高求解精度还能让外层启发式算法在搜索时更均匀地覆盖可行域不至于因为某个维度数值太大导致算法只优化那一维。6.5 常见问题速查表问题现象可能原因排查与解决方法价格迭代振荡更新步长过大、阻尼不足加阻尼系数设为0.3~0.5用户负荷被压到0目标函数方向写反检查objective是成本最小还是收益最大求解器报不可行负荷与设备上限不匹配检查CHP耦合系数和电锅炉容量设置YALMIP报无可用求解器Gurobi未装或许可证过期运行yalmiptest确认求解器状态热价格对结果无影响量纲未统一、热负荷基数太小热价换算成MWh口径调整热负荷基准结果每次运行不一致外层启发式算法随机性固定随机种子多次运行取最优内层求解时间过长模型复杂度超出求解器能力减少时段数到12或缩小种群规模7. 后续扩展建议写完第一版之后有几条很自然的扩展方向。第一条是把单一聚合用户拆成多个不同类型的用户群体各自有不同的弹性系数和用能偏好这样能分析不同用户对定价策略的差异化响应也更贴近真实的多主体市场。第二条是引入可再生能源出力不确定性用场景法或者分布鲁棒优化做两阶段模型让动态电价在风光出力波动时依然保持稳健。第三条是加入碳交易成本或者碳排放约束把碳排放价格嵌入运营商的成本函数让定价结果同时反映减碳信号。这些都是从当前主从博弈框架上做增量扩展不会推翻已经建好的模型结构。最后再分享一个个人经验做这类双层优化模型时千万不要一上来就追求模型复杂先把“运营商定价-用户响应-利润回收”这个最简闭环跑通确认结果符合直觉比如高峰电价高、低谷电价低再一步步加入储热罐、热泵、多类用户这些模块。每加一个模块就跑一次完整算例保存结果对比。这个习惯能让你在写论文或者做项目汇报时随时说清楚每个模块的作用和贡献而不是整个模型糊成一团。
网站建设高端定制企业官网