1. 项目概述:电力市场中的旋转备用与市场出清
在电力系统运行中,旋转备用(Spinning Reserve)是指那些已经同步接入电网、能够随时响应调度指令的备用发电容量。作为电力辅助服务市场的核心产品之一,旋转备用对于维持电网频率稳定、应对突发机组故障或负荷波动具有关键作用。主辅助服务市场出清模型正是用于确定这些备用容量的最优分配方案和市场价格的经济学模型。
我最近用Matlab实现了一个考虑旋转备用的市场出清模型,这个模型基于安全约束机组组合(SCUC)框架,能够同时优化电能和备用容量的分配。与传统仅考虑电能市场的模型不同,这个实现需要处理更复杂的约束条件,包括:
- 机组爬坡率限制
- 备用容量与发电出力的耦合关系
- 系统旋转备用总量要求
- 网络传输安全约束
提示:旋转备用容量通常占系统总负荷的2%-10%,具体比例取决于电网规模和可靠性要求。在建模时需要特别注意备用容量与机组实际出力之间的关系——一台额定容量为100MW的机组,若当前出力为80MW,则其可提供的旋转备用上限为20MW。
2. 模型理论基础与数学表达
2.1 目标函数构建
市场出清模型的核心是一个双层优化问题。上层目标是最小化系统总运行成本,包括:
math复制\min \sum_{t=1}^{T}\sum_{i=1}^{N}[C_i(P_{i,t}) + C_i^{SR}(R_{i,t}^{SR})]
其中:
P_{i,t}:机组i在时段t的电能出力R_{i,t}^{SR}:机组i在时段t提供的旋转备用C_i(·):发电成本函数(通常为二次函数)C_i^{SR}(·):备用容量报价函数
在Matlab中,我们使用quadprog或intlinprog等优化工具箱函数来求解这个混合整数二次规划问题。对于大型系统,也可以考虑调用Gurobi或CPLEX等第三方求解器。
2.2 关键约束条件
2.2.1 功率平衡约束
math复制\sum_{i=1}^{N} P_{i,t} = D_t, \quad \forall t
其中D_t为时段t的系统总负荷。在代码实现中,这表现为线性等式约束:
matlab复制Aeq_power = [ones(1,N), zeros(1,N*T)]; % 电能平衡
beq_power = D(t);
2.2.2 旋转备用需求约束
math复制\sum_{i=1}^{N} R_{i,t}^{SR} \geq R_t^{req}, \quad \forall t
其中R_t^{req}为时段t的系统旋转备用需求总量。在Matlab中表示为:
matlab复制A_reserve = [zeros(1,N), ones(1,N)]; % 备用总量
b_reserve = R_req(t);
2.2.3 机组运行约束
包括出力上下限、爬坡率限制以及备用容量可行性:
matlab复制% 机组出力上下限
lb = [P_min'; zeros(N,1)];
ub = [P_max'; R_max'];
% 爬坡率约束
A_ramp = [eye(N)-lag1(eye(N)), zeros(N)];
b_ramp_up = ramp_up_limit;
b_ramp_down = ramp_down_limit;
% 备用可行性(出力+备用≤容量)
A_cap = [eye(N), eye(N)];
b_cap = P_max';
3. Matlab实现详解
3.1 数据准备与参数设置
首先需要准备以下输入数据:
matlab复制% 机组参数 [容量(MW) 最小出力(MW) 爬坡率(MW/h) 电能报价($/MWh) 备用报价($/MW)]
units = [
200 50 100 45 8;
150 30 80 50 10;
100 20 60 60 12;
];
% 系统负荷与备用需求(24小时)
load_profile = [550 600 650 700 750 800 850 900 950 1000 1050 1100...
1150 1100 1050 1000 950 900 850 800 750 700 650 600];
reserve_req = 0.1 * load_profile; % 备用需求=10%负荷
T = 24; % 时段数
N = size(units,1); % 机组数
3.2 优化模型构建
使用quadprog求解器构建完整模型:
matlab复制% 构造成本函数矩阵H和f
H = zeros(2*N*T);
f = zeros(2*N*T,1);
for i = 1:N
a = units(i,4); b = units(i,5);
for t = 1:T
idx_p = (t-1)*2*N + i;
idx_r = (t-1)*2*N + N + i;
H(idx_p,idx_p) = 2*a; % 二次成本系数
f(idx_p) = 0; % 线性成本系数(假设已包含在二次项)
f(idx_r) = b; % 备用容量报价
end
end
% 构造约束条件
Aeq = []; beq = []; A = []; b = [];
for t = 1:T
% 电能平衡约束
Aeq_t = zeros(1,2*N*T);
Aeq_t((t-1)*2*N + (1:N)) = 1;
Aeq = [Aeq; Aeq_t];
beq = [beq; load_profile(t)];
% 备用需求约束
A_t = zeros(1,2*N*T);
A_t((t-1)*2*N + N + (1:N)) = -1; % 注意符号方向
A = [A; A_t];
b = [b; -reserve_req(t)];
% 机组容量约束
for i = 1:N
A_cap = zeros(1,2*N*T);
A_cap((t-1)*2*N + [i, N+i]) = [1 1];
A = [A; A_cap];
b = [b; units(i,1)];
end
% 爬坡率约束(t>1时)
if t > 1
for i = 1:N
A_ramp_up = zeros(1,2*N*T);
A_ramp_up((t-2)*2*N + i) = -1;
A_ramp_up((t-1)*2*N + i) = 1;
A = [A; A_ramp_up];
b = [b; units(i,3)];
A_ramp_down = zeros(1,2*N*T);
A_ramp_down((t-2)*2*N + i) = 1;
A_ramp_down((t-1)*2*N + i) = -1;
A = [A; A_ramp_down];
b = [b; units(i,3)];
end
end
end
% 出力下限约束
lb = repmat([units(:,2); zeros(N,1)], T, 1);
ub = repmat([units(:,1); units(:,1)], T, 1);
% 求解优化问题
options = optimoptions('quadprog','Algorithm','interior-point-convex');
[x, fval] = quadprog(H,f,A,b,Aeq,beq,lb,ub,[],options);
3.3 结果解析与可视化
提取并展示优化结果:
matlab复制% 提取各机组出力和备用分配
P = reshape(x(1:N*T), N, T)';
R = reshape(x(N*T+1:end), N, T)';
% 计算边际价格
lambda_power = -Aeq'\H*x; % 电能边际价格
lambda_reserve = -A'\H*x; % 备用边际价格
% 绘制结果
figure;
subplot(3,1,1);
bar(P, 'stacked');
title('机组出力分配');
ylabel('MW');
subplot(3,1,2);
bar(R, 'stacked');
title('旋转备用分配');
ylabel('MW');
subplot(3,1,3);
plot(1:T, lambda_power, 'b-o', 1:T, lambda_reserve, 'r--*');
legend('电能价格','备用价格');
title('市场出清价格');
xlabel('时段');
ylabel('$/MWh');
4. 关键问题与解决方案
4.1 机组组合整数变量处理
实际SCUC问题需要处理机组的启停状态(0-1变量),这会使问题变为混合整数规划。在Matlab中可以采用以下方法:
matlab复制% 引入二进制变量表示机组状态
intcon = 1:N*T; % 整数变量索引
x0 = zeros(2*N*T,1); % 初始解
% 修改上下界
lb(intcon) = 0;
ub(intcon) = 1;
% 使用intlinprog求解
[x, fval] = intlinprog(f,intcon,A,b,Aeq,beq,lb,ub,x0,options);
注意:对于大规模系统,直接求解MIP可能非常耗时。可以考虑:
- 使用优先级列表法(Priority List)预筛选机组组合
- 采用Benders分解等算法将问题分解
- 调用专业求解器如Gurobi的MATLAB接口
4.2 网络约束处理
基本模型忽略了输电网络约束。要加入直流潮流约束,需要:
- 构建节点-机组关联矩阵和PTDF矩阵
- 添加线路功率限制约束:
matlab复制% PTDF: L×N矩阵,表示各机组对线路潮流的分布因子
for l = 1:L
A_line = zeros(1,2*N*T);
for t = 1:T
A_line((t-1)*2*N + (1:N)) = PTDF(l,:);
end
A = [A; A_line; -A_line];
b = [b; line_limits(l); line_limits(l)];
end
4.3 求解效率优化
对于实际规模的系统(如100+机组,24+时段),直接构建完整模型可能导致内存问题。可以采用:
- 稀疏矩阵存储约束矩阵
matlab复制A = sparse(A); Aeq = sparse(Aeq);
- 并行计算各时段的子问题
- 使用问题特定的预处理技术减少变量数
5. 扩展应用与进阶方向
5.1 考虑可再生能源不确定性
通过场景法或鲁棒优化处理风电/光伏的预测误差:
matlab复制% 场景法示例
num_scenarios = 10;
scenario_prob = ones(num_scenarios,1)/num_scenarios;
for s = 1:num_scenarios
% 生成风电出力场景
wind_scenario = forecast_wind + randn(size(forecast_wind))*forecast_error;
% 添加场景相关约束
% ...
end
5.2 联合能量-备用市场出清
更复杂的市场设计可以考虑备用容量的机会成本:
matlab复制% 在目标函数中加入备用机会成本项
for i = 1:N
f( (t-1)*2*N + N + i ) = units(i,5) + opportunity_cost(i,t);
end
5.3 机器学习辅助决策
使用历史数据训练模型预测最优备用需求:
matlab复制% 使用神经网络预测备用需求
net = fitnet([10 10]);
net = train(net, historical_inputs, optimal_reserves);
predicted_reserve = net(current_conditions);
6. 实际应用中的注意事项
-
数据质量验证:
- 机组参数(特别是爬坡率)需要现场测试数据校准
- 备用报价应反映真实机会成本,避免市场操纵
-
计算时间管理:
- 实时市场出清通常需要在5-15分钟内完成
- 对超时情况准备备用规则(如延长时段或简化模型)
-
结果合理性检查:
matlab复制% 检查各时段备用是否满足需求 assert(all(sum(R,2) >= reserve_req'), '备用需求未满足'); % 检查机组是否在可行域内运行 assert(all(all(P >= units(:,2)')) && all(all(P <= units(:,1)')), '机组越限'); -
市场力监测:
- 设置报价上限或市场力缓解机制
- 监控关键机组的边际价格贡献
这个Matlab实现为研究电力市场出清问题提供了灵活的平台。根据具体应用场景,可以进一步扩展模型复杂度或集成到更大的能源管理系统框架中。对于实际市场运营,还需要考虑更多的工程细节和市场规则,但核心的建模思路和方法保持一致。
