""" 光伏出力优化模块 该模块通过调整光伏出力曲线的系数,在给定的系统参数条件下 最小化与电网交换的电量,提高系统的自平衡能力。 作者: iFlow CLI 创建日期: 2025-12-26 """ import numpy as np from typing import List, Dict, Tuple, Optional from dataclasses import dataclass from storage_optimization import SystemParameters, optimize_storage_capacity, calculate_energy_balance @dataclass class SolarOptimizationResult: """光伏优化结果类""" optimal_solar_coefficient: float # 最优光伏系数 original_solar_output: List[float] # 原始光伏出力曲线 optimized_solar_output: List[float] # 优化后光伏出力曲线 min_grid_exchange: float # 最小电网交换电量 grid_purchase: float # 购电量 grid_feed_in: float # 上网电量 storage_result: Dict # 储能优化结果 optimization_history: List[Dict] # 优化历史记录 def calculate_grid_exchange_metric( solar_output: List[float], wind_output: List[float], thermal_output: List[float], load_demand: List[float], params: SystemParameters ) -> Dict[str, float]: """ 计算电网交换电量指标 Args: solar_output: 光伏出力曲线 (MW) wind_output: 风电出力曲线 (MW) thermal_output: 火电出力曲线 (MW) load_demand: 负荷曲线 (MW) params: 系统参数配置 Returns: 包含电网交换指标的字典 """ # 计算最优储能容量 storage_result = optimize_storage_capacity( solar_output, wind_output, thermal_output, load_demand, params ) # 计算电网交换电量 grid_feed_in = storage_result['grid_feed_in'] # 分离购电和上网电量 total_purchase = sum(-x for x in grid_feed_in if x < 0) # 购电量(正值) total_feed_in = sum(x for x in grid_feed_in if x > 0) # 上网电量(正值) # 计算总交换电量(购电 + 上网) total_exchange = total_purchase + total_feed_in return { 'total_exchange': total_exchange, 'grid_purchase': total_purchase, 'grid_feed_in': total_feed_in, 'storage_capacity': storage_result['required_storage_capacity'], 'storage_result': storage_result } def optimize_solar_output( original_solar_output: List[float], wind_output: List[float], thermal_output: List[float], load_demand: List[float], params: SystemParameters, coefficient_range: Tuple[float, float] = (0.1, 2.0), tolerance: float = 0.01, max_iterations: int = 50 ) -> SolarOptimizationResult: """ 优化光伏出力系数以最小化电网交换电量 Args: original_solar_output: 原始光伏出力曲线 (MW) wind_output: 风电出力曲线 (MW) thermal_output: 火电出力曲线 (MW) load_demand: 负荷曲线 (MW) params: 系统参数配置 coefficient_range: 光伏系数搜索范围 (最小值, 最大值) tolerance: 收敛容差 max_iterations: 最大迭代次数 Returns: 光伏优化结果 """ print("开始光伏出力优化...") # 初始化优化历史 optimization_history = [] # 使用黄金分割法进行一维优化 phi = (1 + np.sqrt(5)) / 2 # 黄金比例 resphi = 2 - phi a, b = coefficient_range c = b - resphi * (b - a) d = a + resphi * (b - a) # 计算初始点的目标函数值 fc = calculate_grid_exchange_metric( [x * c for x in original_solar_output], wind_output, thermal_output, load_demand, params ) fd = calculate_grid_exchange_metric( [x * d for x in original_solar_output], wind_output, thermal_output, load_demand, params ) # 记录初始点 optimization_history.append({ 'coefficient': c, 'total_exchange': fc['total_exchange'], 'grid_purchase': fc['grid_purchase'], 'grid_feed_in': fc['grid_feed_in'], 'storage_capacity': fc['storage_capacity'] }) optimization_history.append({ 'coefficient': d, 'total_exchange': fd['total_exchange'], 'grid_purchase': fd['grid_purchase'], 'grid_feed_in': fd['grid_feed_in'], 'storage_capacity': fd['storage_capacity'] }) # 黄金分割搜索 for iteration in range(max_iterations): if abs(fc['total_exchange'] - fd['total_exchange']) < tolerance: break if fc['total_exchange'] < fd['total_exchange']: b = d d = c fd = fc c = b - resphi * (b - a) fc = calculate_grid_exchange_metric( [x * c for x in original_solar_output], wind_output, thermal_output, load_demand, params ) optimization_history.append({ 'coefficient': c, 'total_exchange': fc['total_exchange'], 'grid_purchase': fc['grid_purchase'], 'grid_feed_in': fc['grid_feed_in'], 'storage_capacity': fc['storage_capacity'] }) else: a = c c = d fc = fd d = a + resphi * (b - a) fd = calculate_grid_exchange_metric( [x * d for x in original_solar_output], wind_output, thermal_output, load_demand, params ) optimization_history.append({ 'coefficient': d, 'total_exchange': fd['total_exchange'], 'grid_purchase': fd['grid_purchase'], 'grid_feed_in': fd['grid_feed_in'], 'storage_capacity': fd['storage_capacity'] }) # 确定最优系数 if fc['total_exchange'] < fd['total_exchange']: optimal_coefficient = c best_result = fc else: optimal_coefficient = d best_result = fd # 生成优化后的光伏出力曲线 optimized_solar_output = [x * optimal_coefficient for x in original_solar_output] # 重新计算完整的最优储能配置 final_storage_result = optimize_storage_capacity( optimized_solar_output, wind_output, thermal_output, load_demand, params ) print(f"优化完成!最优光伏系数: {optimal_coefficient:.3f}") print(f"最小电网交换电量: {best_result['total_exchange']:.2f} MWh") return SolarOptimizationResult( optimal_solar_coefficient=optimal_coefficient, original_solar_output=original_solar_output, optimized_solar_output=optimized_solar_output, min_grid_exchange=best_result['total_exchange'], grid_purchase=best_result['grid_purchase'], grid_feed_in=best_result['grid_feed_in'], storage_result=final_storage_result, optimization_history=optimization_history ) def export_optimization_results(result: SolarOptimizationResult, filename: str = None): """ 导出光伏优化结果到Excel文件 Args: result: 光伏优化结果 filename: 输出文件名,如果为None则自动生成 """ import pandas as pd from datetime import datetime if filename is None: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"solar_optimization_results_{timestamp}.xlsx" print(f"正在导出光伏优化结果到Excel文件: {filename}") hours = list(range(1, len(result.original_solar_output) + 1)) # 创建主要数据DataFrame data_df = pd.DataFrame({ '小时': hours, '原始光伏出力(MW)': result.original_solar_output, '优化后光伏出力(MW)': result.optimized_solar_output, '出力变化(MW)': [result.optimized_solar_output[i] - result.original_solar_output[i] for i in range(len(result.original_solar_output))], '变化比例(%)': [(result.optimized_solar_output[i] / result.original_solar_output[i] - 1) * 100 if result.original_solar_output[i] > 0 else 0 for i in range(len(result.original_solar_output))] }) # 创建优化结果摘要DataFrame summary_df = pd.DataFrame({ '指标': [ '最优光伏系数', '最小电网交换电量', '购电量', '上网电量', '所需储能容量', '优化后弃风率', '优化后弃光率', '优化后上网电量比例' ], '数值': [ f"{result.optimal_solar_coefficient:.3f}", f"{result.min_grid_exchange:.2f} MWh", f"{result.grid_purchase:.2f} MWh", f"{result.grid_feed_in:.2f} MWh", f"{result.storage_result['required_storage_capacity']:.2f} MWh", f"{result.storage_result['total_curtailment_wind_ratio']:.3f}", f"{result.storage_result['total_curtailment_solar_ratio']:.3f}", f"{result.storage_result['total_grid_feed_in_ratio']:.3f}" ] }) # 创建优化历史DataFrame history_df = pd.DataFrame(result.optimization_history) history_df.columns = ['光伏系数', '电网交换电量(MWh)', '购电量(MWh)', '上网电量(MWh)', '储能容量(MWh)'] # 写入Excel文件 with pd.ExcelWriter(filename, engine='openpyxl') as writer: # 写入主要数据 data_df.to_excel(writer, sheet_name='出力曲线对比', index=False) # 写入优化结果摘要 summary_df.to_excel(writer, sheet_name='优化结果摘要', index=False) # 写入优化历史 history_df.to_excel(writer, sheet_name='优化历史', index=False) # 创建说明工作表 description_df = pd.DataFrame({ '项目': [ '文件说明', '生成时间', '优化目标', '优化方法', '数据长度', '注意事项' ], '内容': [ '光伏出力优化结果 - 通过调整光伏系数最小化电网交换电量', datetime.now().strftime("%Y-%m-%d %H:%M:%S"), '最小化与电网交换的总电量(购电 + 上网)', '黄金分割一维优化算法', f"{len(result.original_solar_output)} 小时", '优化结果在给定的系统参数约束下得出' ] }) description_df.to_excel(writer, sheet_name='说明', index=False) print(f"光伏优化结果已成功导出到: {filename}") return filename def main(): """主函数,提供示例使用""" # 示例数据 original_solar_output = [0.0] * 6 + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0] + [0.0] * 6 wind_output = [2.0, 3.0, 4.0, 3.0, 2.0, 1.0] * 4 thermal_output = [5.0] * 24 load_demand = [3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 18.0, 16.0, 14.0, 12.0, 10.0, 8.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 2.0] # 系统参数 params = SystemParameters( max_curtailment_wind=0.1, max_curtailment_solar=0.1, max_grid_ratio=0.2, storage_efficiency=0.9, discharge_rate=1.0, charge_rate=1.0, rated_thermal_capacity=100.0, rated_solar_capacity=100.0, rated_wind_capacity=100.0, available_thermal_energy=2400.0, available_solar_energy=600.0, available_wind_energy=1200.0 ) # 执行光伏优化 result = optimize_solar_output( original_solar_output, wind_output, thermal_output, load_demand, params ) # 打印结果 print("\n=== 光伏出力优化结果 ===") print(f"最优光伏系数: {result.optimal_solar_coefficient:.3f}") print(f"最小电网交换电量: {result.min_grid_exchange:.2f} MWh") print(f"其中购电量: {result.grid_purchase:.2f} MWh") print(f"其中上网电量: {result.grid_feed_in:.2f} MWh") print(f"所需储能容量: {result.storage_result['required_storage_capacity']:.2f} MWh") print(f"优化后弃风率: {result.storage_result['total_curtailment_wind_ratio']:.3f}") print(f"优化后弃光率: {result.storage_result['total_curtailment_solar_ratio']:.3f}") print(f"优化后上网电量比例: {result.storage_result['total_grid_feed_in_ratio']:.3f}") # 导出结果 export_optimization_results(result) return result if __name__ == "__main__": main()