1. 风光出力场景生成与削减概述
在电力系统规划与运行中,风光发电出力具有显著的随机性和波动性。准确模拟这些不确定性因素,并通过合理的场景削减技术降低计算复杂度,是电力系统优化决策的关键基础。本文将详细介绍从场景生成到削减的全流程实现方法。
提示:场景生成与削减技术不仅适用于风光出力模拟,也可应用于负荷预测、电价波动等各类不确定性分析场景。
2. 场景生成方法详解
2.1 蒙特卡洛模拟实现
蒙特卡洛模拟通过随机抽样来模拟不确定性,其核心步骤包括:
-
确定输入变量概率分布:
- 光伏出力:主要受光照强度(正态分布)和温度(威布尔分布)影响
- 风电出力:主要受风速(威布尔分布)和风向(均匀分布)影响
-
建立出力计算模型:
python复制# 光伏出力计算模型示例 def pv_output_model(illumination, temp): # 标准测试条件(STC)下的参数 P_stc = 250 # W G_stc = 1000 # W/m² temp_coeff = -0.0045 # %/℃ # 简单线性模型 P = P_stc * (illumination/G_stc) * (1 + temp_coeff*(temp - 25)) return max(0, P) # 出力不为负 -
大规模随机抽样:
python复制# 生成10000个场景的示例 n_scenarios = 10000 illumination = np.random.normal(1000, 150, n_scenarios) # 光照强度 temperature = np.random.normal(25, 5, n_scenarios) # 温度 pv_scenarios = [pv_output_model(i,t) for i,t in zip(illumination,temperature)]
注意事项:蒙特卡洛模拟需要足够大的样本量才能保证精度,通常建议至少10000次抽样。
2.2 拉丁超立方抽样改进
拉丁超立方抽样(LHS)通过分层抽样提高效率:
-
抽样空间划分:
- 将每个输入变量的累积概率分布划分为N个等间隔区间
- 在每个区间内随机抽取一个样本点
-
Python实现示例:
python复制from pyDOE import lhs # 3个输入变量(光照、温度、风速) n_vars = 3 samples = lhs(n_vars, samples=500) # 转换为实际物理量 illumination = norm.ppf(samples[:,0], loc=1000, scale=150) temperature = norm.ppf(samples[:,1], loc=25, scale=5) wind_speed = weibull_min.ppf(samples[:,2], c=2, scale=6) -
与传统蒙特卡洛对比:
方法 样本效率 计算复杂度 收敛速度 蒙特卡洛 低 O(n) 慢(1/√n) LHS 高 O(n) 快(1/n)
3. 场景削减技术实现
3.1 快速前推削减法
-
算法流程:
- 计算所有场景间的距离矩阵
- 迭代合并最近场景对,直到达到目标数量
- 更新剩余场景概率为合并场景概率之和
-
距离度量改进:
python复制def wasserstein_distance(scenario1, scenario2): """考虑时序特征的Wasserstein距离""" from scipy.stats import wasserstein_distance return wasserstein_distance(scenario1, scenario2) def pattern_distance(s1, s2): """考虑形状相似性的DTW距离""" from dtaidistance import dtw return dtw.distance(s1, s2) -
完整实现代码:
python复制def fast_forward_reduction(scenarios, target_num, distance_metric='euclidean'): n = len(scenarios) prob = np.ones(n)/n # 初始等概率 while n > target_num: # 计算距离矩阵 dist_mat = np.zeros((n,n)) for i in range(n): for j in range(i+1,n): if distance_metric == 'euclidean': dist_mat[i,j] = np.linalg.norm(scenarios[i]-scenarios[j]) elif distance_metric == 'wasserstein': dist_mat[i,j] = wasserstein_distance(scenarios[i],scenarios[j]) else: dist_mat[i,j] = pattern_distance(scenarios[i],scenarios[j]) # 找到最近场景对 min_dist = np.min(dist_mat[dist_mat>0]) i, j = np.where(dist_mat == min_dist) i, j = i[0], j[0] # 合并场景 new_scenario = (prob[i]*scenarios[i] + prob[j]*scenarios[j])/(prob[i]+prob[j]) scenarios[i] = new_scenario prob[i] += prob[j] # 删除被合并场景 scenarios.pop(j) prob = np.delete(prob, j) n -= 1 return scenarios, prob
3.2 同步回代削减法
-
核心改进点:
- 考虑场景间的统计依赖性
- 保留概率密度函数的矩信息
-
关键实现步骤:
python复制def synchronous_backward_reduction(scenarios, target_num): n = len(scenarios) prob = np.ones(n)/n selected = set(range(n)) while n > target_num: # 计算各场景的矩贡献 moment_contrib = np.zeros(n) mean = np.average(scenarios, weights=prob, axis=0) for k in selected: diff = scenarios[k] - mean moment_contrib[k] = prob[k] * np.sum(diff**2) # 找到贡献最小的场景 to_remove = np.argmin(moment_contrib) selected.remove(to_remove) n -= 1 # 调整剩余场景概率 total_prob = sum(prob[list(selected)]) for k in selected: prob[k] /= total_prob return [scenarios[i] for i in selected], prob[list(selected)] -
方法对比分析:
特性 快速前推法 同步回代法 计算效率 O(n²) O(n³) 保留特性 局部相似性 全局统计特性 适用场景 大规模场景 高精度要求
4. 负荷场景集成方法
4.1 多变量联合建模
-
Copula理论应用:
python复制from copulae import GaussianCopula # 建立风光荷联合分布 data = np.column_stack([pv_scaled, wind_scaled, load_scaled]) copula = GaussianCopula(dim=3) copula.fit(data) # 生成联合场景 uniform_samples = copula.random(1000) pv_scenes = norm.ppf(uniform_samples[:,0], pv_mean, pv_std) wind_scenes = weibull_min.ppf(uniform_samples[:,1], c=2, scale=6) load_scenes = norm.ppf(uniform_samples[:,2], load_mean, load_std) -
时序相关性建模:
python复制from statsmodels.tsa.arima.model import ARIMA # 对残差序列建立ARIMA模型 model = ARIMA(load_daily_diff, order=(2,0,1)) results = model.fit() # 场景生成 n_steps = 24 # 24小时场景 for _ in range(n_scenarios): resid = results.simulate(n_steps) scenario = base_load + np.cumsum(resid) load_scenarios.append(scenario)
4.2 实际应用案例
某省级电网的典型参数设置:
python复制# 风光参数
pv_capacity = 1000 # MW
wind_capacity = 1500 # MW
load_peak = 8000 # MW
# 场景生成配置
n_initial = 5000 # 初始场景数
n_final = 20 # 削减后场景数
time_horizon = 24 # 24小时场景
# 生成完整场景集
full_scenarios = generate_joint_scenarios(
pv_capacity, wind_capacity, load_peak,
n_initial, time_horizon
)
# 场景削减
reduced_scenarios, probs = synchronous_backward_reduction(
full_scenarios, n_final
)
5. 工程实践要点
5.1 参数校准建议
-
风光特性参数:
- 光伏:面板倾角、方位角、效率衰减系数
- 风电:轮毂高度、功率曲线、空气密度修正
-
统计检验方法:
python复制from scipy.stats import kstest # 检验场景分布与历史数据的一致性 historical = load_historical_data() generated = generate_scenarios() stat, p = kstest(historical, generated) print(f"KS检验p值:{p:.3f}") # p>0.05表示通过检验
5.2 常见问题排查
-
场景代表性不足:
- 现象:优化结果波动大
- 解决:增加初始场景数,或改用LHS抽样
-
削减后场景失真:
- 现象:极端场景丢失
- 解决:采用重要性抽样,保留低概率高影响场景
-
计算时间过长:
- 优化:使用稀疏距离矩阵计算
python复制from scipy.spatial.distance import pdist, squareform dist_mat = squareform(pdist(scenarios, 'euclidean'))
5.3 高级技巧分享
-
自适应场景生成:
python复制def adaptive_sampling(initial_scenarios, n_add): # 识别概率密度低的区域 kde = KernelDensity(kernel='gaussian', bandwidth=0.2).fit(initial_scenarios) scores = kde.score_samples(initial_scenarios) low_prob_indices = np.argsort(scores)[:n_add] # 在稀疏区域生成新场景 new_scenarios = [] for idx in low_prob_indices: perturbed = initial_scenarios[idx] + np.random.normal(0, 0.1) new_scenarios.append(perturbed) return np.vstack([initial_scenarios, new_scenarios]) -
并行计算加速:
python复制from joblib import Parallel, delayed def parallel_distance(scenarios): n = len(scenarios) return Parallel(n_jobs=4)( delayed(np.linalg.norm)(scenarios[i]-scenarios[j]) for i in range(n) for j in range(i+1,n) )
在实际项目中,我们通常会根据具体电网特性调整参数。例如对于高渗透率光伏电网,需要特别关注日出日落时段的出力爬坡特性;对于风电主导系统,则需重点模拟风速的时空相关性特征。