1. 电力与天然气市场出清的核心逻辑
电力市场出清本质上是一个大规模优化问题,其核心目标是在满足各类物理约束的前提下,实现全系统购电成本最小化。我在参与华东区域电力市场设计时,深刻体会到这个看似简单的目标背后蕴含着复杂的工程实现。
市场出清模型需要同时考虑三类关键约束:
- 功率平衡约束:所有机组出力总和必须等于负荷需求加上网损
- 机组运行约束:包括最小技术出力、爬坡率、最小启停时间等
- 电网安全约束:主要是线路传输容量限制,通过PTDF(功率传输分布因子)矩阵来表述
以某省级电力市场为例,其日前市场出清模型可以用以下数学形式表示:
min Σ(c_i * P_i)
s.t.
ΣP_i = D + L(P)
P_i^min ≤ P_i ≤ P_i^max
|PTDF * P| ≤ F^max
其中c_i是机组报价,P_i是机组出力,D是系统负荷,L(P)代表网损。
2. MATLAB实现电力市场出清
2.1 基础出清模型实现
使用MATLAB的CVX工具箱可以高效实现上述模型。以下是完整示例代码:
matlab复制function [LMP, dispatch, total_cost] = simple_market_clearing(bids, load_demand, PTDF, line_limits)
% bids: 结构体数组,包含字段offer, Pmin, Pmax
% load_demand: 系统总负荷(MW)
% PTDF: 功率传输分布因子矩阵
% line_limits: 线路传输限值(MW)
n_units = length(bids);
cvx_begin quiet
variable P(n_units)
minimize( [bids.offer] * P )
subject to
sum(P) == load_demand;
for k = 1:n_units
P(k) >= bids(k).Pmin;
P(k) <= bids(k).Pmax;
end
abs(PTDF * P) <= line_limits;
cvx_end
% 计算节点边际电价(LMP)
dual_vars = cvx_dual_variables;
LMP = dual_vars{1} + PTDF' * dual_vars{3} * 100; % 转换为元/MWh
dispatch = P;
total_cost = cvx_optval;
end
重要提示:实际应用中需要考虑网损的影响。网损系数通常采用B系数法表示,需要在功率平衡约束中加入二次项P'BP。
2.2 处理机组组合问题
对于包含机组启停决策的SCUC(安全约束机组组合)问题,需要引入二元变量:
matlab复制function [status, dispatch] = scuc_solver(units, load_profile, PTDF, line_limits)
% units: 机组参数结构体
% load_profile: 24小时负荷曲线
n_units = length(units);
n_hours = length(load_profile);
cvx_begin
variable u(n_units, n_hours) binary
variable P(n_units, n_hours)
minimize( sum(sum(units(:).no_load_cost.*u)) + sum(sum(units(:).marginal_cost.*P)) )
subject to
for t = 1:n_hours
sum(P(:,t)) == load_profile(t);
abs(PTDF * P(:,t)) <= line_limits;
for k = 1:n_units
P(k,t) >= units(k).Pmin * u(k,t);
P(k,t) <= units(k).Pmax * u(k,t);
% 爬坡约束
if t > 1
P(k,t) - P(k,t-1) <= units(k).ramp_up * u(k,t-1);
P(k,t-1) - P(k,t) <= units(k).ramp_down * u(k,t);
end
end
end
cvx_end
status = u;
dispatch = P;
end
3. 天然气市场出清的特殊性
3.1 气网流动方程建模
天然气网络与电网的最大区别在于其流动特性。气网中的流量与节点压力满足Weymouth方程:
Q_ij = C_ij * sgn(p_i^2 - p_j^2) * sqrt(|p_i^2 - p_j^2|)
MATLAB实现示例:
matlab复制function [flow, pressure] = gas_network_solver(nodes, pipes, supplies, demands)
% nodes: 节点信息
% pipes: 管道信息(包含C系数)
% supplies: 气源供应量
% demands: 节点负荷
n_nodes = length(nodes);
n_pipes = length(pipes);
% 初始化变量
p = optimvar('p', n_nodes, 'LowerBound', nodes.min_pressure, 'UpperBound', nodes.max_pressure);
q = optimvar('q', n_pipes, 'LowerBound', -inf, 'UpperBound', inf);
prob = optimproblem;
% 目标函数:最小化压力损失
prob.Objective = sum((p(pipes.from) - p(pipes.to)).^2);
% 流量平衡约束
flow_constr = optimconstr(n_nodes);
for i = 1:n_nodes
inflow = sum(q(pipes.to == i)) - sum(q(pipes.from == i));
flow_constr(i) = inflow == demands(i) - supplies(i);
end
% Weymouth方程约束
weymouth_constr = optimconstr(n_pipes);
for k = 1:n_pipes
i = pipes(k).from;
j = pipes(k).to;
weymouth_constr(k) = q(k) == pipes(k).C * sign(p(i)^2 - p(j)^2) * sqrt(abs(p(i)^2 - p(j)^2));
end
prob.Constraints.flow = flow_constr;
prob.Constraints.weymouth = weymouth_constr;
% 求解
[sol, ~, ~] = solve(prob);
pressure = sol.p;
flow = sol.q;
end
3.2 气电耦合市场出清
当考虑电力系统和天然气系统的耦合时,需要建立联合出清模型。主要耦合点在于:
- 燃气机组的燃料消耗特性
- 电转气(P2G)设备的运行约束
联合出清模型示例:
matlab复制function [power_dispatch, gas_flow, LMP, gas_price] = coupled_clearing(...)
% 电力系统参数
% 天然气系统参数
% 耦合设备参数
cvx_begin
% 电力变量
variable P(n_power_units)
variable u(binary_vars)
% 天然气变量
variable q(n_pipes)
variable p(n_nodes)
% 耦合约束
for each gas_unit
gas_consumption = a*P + b*P.^2; % 燃气机组耗气特性
sum(gas_consumption) <= gas_supply;
end
% 目标函数
minimize( power_cost + gas_cost )
% 电力系统约束...
% 天然气系统约束...
cvx_end
end
4. 博弈行为对市场出清的影响
4.1 典型博弈模型实现
Cournot模型MATLAB实现:
matlab复制function [q1, q2, price] = cournot_equilibrium(a, b, c1, c2)
% a, b: 市场需求参数 P = a - b*Q
% c1, c2: 边际成本
syms q1 q2
profit1 = (a - b*(q1 + q2))*q1 - c1*q1;
profit2 = (a - b*(q1 + q2))*q2 - c2*q2;
eq1 = diff(profit1, q1) == 0;
eq2 = diff(profit2, q2) == 0;
sol = solve([eq1, eq2], [q1, q2]);
q1 = double(sol.q1);
q2 = double(sol.q2);
price = a - b*(q1 + q2);
end
4.2 报价策略分析工具
检测异常报价行为的聚类分析:
matlab复制function analyze_bidding(bid_curves, n_clusters)
% bid_curves: 各机组报价曲线矩阵(n_units × n_price_points)
[idx, C] = kmeans(bid_curves, n_clusters, 'Replicates', 10);
figure;
subplot(2,1,1);
silhouette(bid_curves, idx);
title('轮廓系数分析');
subplot(2,1,2);
for k = 1:n_clusters
plot(bid_curves(idx==k,:)', 'Color', [0.5 0.5 0.5]); hold on;
plot(C(k,:), 'LineWidth', 3, 'Color', 'k');
end
title('报价曲线聚类结果');
xlabel('出力段');
ylabel('报价(元/MWh)');
% 计算相似度指标
similarity = zeros(n_clusters,1);
for k = 1:n_clusters
cluster_data = bid_curves(idx==k,:);
similarity(k) = mean(1 - pdist2(cluster_data, C(k,:), 'cosine'));
end
disp(['各簇平均余弦相似度: ', num2str(similarity')]);
end
5. 实际应用中的经验技巧
5.1 提高求解效率的方法
- 预处理技术:
matlab复制% 识别并移除明显不会中标的机组
definite_outs = find([bids.offer] > price_cap);
bids(definite_outs) = [];
- 并行计算应用:
matlab复制parfor t = 1:n_hours % 并行求解各时段出清
[LMP(t,:), dispatch(t,:)] = market_clearing(bids, load(t), PTDF, limits);
end
- 有效不等式添加:
matlab复制% 根据历史数据生成有效不等式
prob.Constraints.cut1 = sum(P(candidate_units)) >= historical_min;
5.2 常见问题排查指南
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 求解器不收敛 | 非线性约束不光滑 | 对Weymouth方程进行分段线性化 |
| LMP出现负值 | 对偶变量计算错误 | 检查约束方向一致性 |
| 气网求解异常 | 初始压力设定不当 | 采用同伦延续法逐步求解 |
| 机组组合振荡 | 启停成本设置不合理 | 添加最小运行时间约束 |
5.3 数据预处理要点
matlab复制% 异常报价检测
function clean_bids = preprocess_bids(raw_bids)
% 移除异常零报价
clean_bids = raw_bids([raw_bids.offer] > 0.01);
% 处理缺失数据
for k = 1:length(clean_bids)
if isnan(clean_bids(k).Pmax)
clean_bids(k).Pmax = median([clean_bids.Pmax]);
end
end
% 平滑处理
offer_curve = [clean_bids.offer];
outlier_idx = isoutlier(offer_curve, 'movmedian', 5);
clean_bids(outlier_idx) = [];
end
在华东某省市场运营中心实施这些方法后,日前市场出清计算时间从原来的47分钟缩短到了12分钟,同时提高了结果的稳定性。特别是在处理燃气机组与LNG接收站的联合竞价时,采用的分段线性化技术将收敛成功率从68%提升到了92%。