# DRL_algorithm **Repository Path**: fgy-lab/drl_algorithm ## Basic Information - **Project Name**: DRL_algorithm - **Description**: 学习 一些深度强化学习在电力系统优化调度方面 的应用 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-28 - **Last Updated**: 2026-06-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 深度强化学习算法在能源系统最优调度中的性能对比 本代码是论文 *Performance Comparison of Deep RL Algorithms for Energy Systems Optimal Scheduling* 的配套程序,发表于 IEEE PES ISGT EUROPE 2022。 **作者**: Hou Shengren, Edgar Mauricio Salazar, Pedro P. Vergara, Peter Palensky (代尔夫特理工大学) **论文**: [IEEE Xplore](https://ieeexplore.ieee.org/document/9960642) --- ## 摘要 深度强化学习(DRL)算法凭借其数据驱动和无模型的特性,具有应对可再生能源发电带来的不确定性的潜力。为了同时兼顾能源系统的运行成本和技术约束(如发电-负荷功率平衡),DRL 算法在设计奖励函数时必须权衡二者。这种权衡引入了额外的超参数,影响 DRL 算法的性能和提供可行解的能力。本文对 DDPG、TD3、SAC 和 PPO 四种 DRL 算法进行了性能对比,旨在为能源系统最优调度问题提供一个公平的比较基准。结果表明,与数学规划模型相比,DRL 算法即使在未见过的运行场景中也能实时提供高质量的解。然而在峰值负荷较大的情况下,这些算法未能提供可行解,这可能阻碍其实际应用。 --- ## 问题描述 本项目解决一个**微电网的最优调度**问题,包含以下组件: - **3台柴油发电机**:具有二次成本函数、爬坡约束和最小启停时间 - **电池储能系统**:荷电状态(SOC)上下限约束和充放电效率 - **光伏发电**:随机性,基于历史数据驱动 - **电网连接**:允许与外电网进行功率交换 - **电力负荷**:必须实时满足的需求 目标是**最小化总运行成本**(燃油成本 + 购电成本 - 售电收益 + 电池退化成本 + 约束违反惩罚),同时实时维持功率平衡。 ### 状态空间(7维) | 索引 | 变量 | 说明 | |------|------|------| | 0 | `time_step` | 当前小时(0-23) | | 1 | `price` | 当前时段的电价 | | 2 | `soc` | 电池荷电状态(0.2-0.8) | | 3 | `net_load` | 电力需求 - 光伏发电 | | 4 | `dg1_output` | 柴油发电机1当前出力 | | 5 | `dg2_output` | 柴油发电机2当前出力 | | 6 | `dg3_output` | 柴油发电机3当前出力 | ### 动作空间(4维连续,范围 [-1, 1]) | 索引 | 变量 | 说明 | |------|------|------| | 0 | 电池充放电信号 | | 1 | 柴油发电机1出力变化量 | | 2 | 柴油发电机2出力变化量 | | 3 | 柴油发电机3出力变化量 | ### 奖励函数 奖励为负的运行成本(缩放因子 1e-3),包含以下组件: - 柴油发电机燃油成本(二次函数:a×P² + b×P + c) - 电池退化成本 - 电网购电成本和售电收益 - 功率越限惩罚(超出电网交换容量时) --- ## 环境依赖 | 库 | 版本 | |----|------| | Python | 3.8+ | | PyTorch | 1.11.0 | | pandas | 1.1.4 | | numpy | 1.20.1 | | matplotlib | 3.3.4 | | PYOMO | (可选,用于 Gurobi 对比) | | Gurobi | (可选,用于最优基准求解) | | gym | 0.21+ | 安装方式: ```bash pip install torch pandas numpy matplotlib pyomo gurobipy gym ``` --- ## 项目结构 ``` DRL/ ├── README.md # 本文件 ├── README.zh.md # 中文版说明 ├── Parameters.py # 电池和柴油发电机参数 │ ├── random_generator_battery.py # Gym 环境(ESSEnv) │ ├── Constant # 月份天数、最大步数 │ ├── DataManager # 加载和查询光伏/电价/负荷数据 │ ├── DG # 柴油发电机模型 │ ├── Battery # 电池储能模型 │ ├── Grid # 外电网连接 │ └── ESSEnv # 主 Gym 环境类 │ ├── net.py # 神经网络架构 │ ├── Actor # 确定性策略网络(DDPG/TD3) │ ├── ActorSAC # 随机策略网络(SAC) │ ├── ActorPPO # 随机策略网络(PPO) │ ├── Critic # 单 Critic(DDPG) │ ├── CriticTwin # 双 Critic(TD3/SAC) │ └── CriticAdv # 优势函数 Critic(PPO) │ ├── agent.py # 智能体实现 │ ├── AgentBase # 基类 │ ├── AgentDDPG # DDPG 算法 │ ├── AgentTD3 # TD3 算法 │ ├── AgentSAC # SAC 算法 │ └── AgentPPO # PPO 算法 │ ├── tools.py # 工具函数和类 │ ├── optimization_base_result() # Gurobi MILP 最优基准求解器 │ ├── Arguments # 超参数和配置 │ ├── ReplayBuffer # 经验回放缓冲区 │ ├── test_one_episode() # 评估训练好的策略 │ └── get_episode_return() # 计算回合回报 │ ├── DDPG.py # DDPG:训练→测试→绘图→对比 ├── TD3.py # TD3:训练→测试→绘图→对比 ├── SAC.py # SAC:训练→测试→绘图→对比 ├── PPO.py # PPO:训练→测试→绘图→对比 │ ├── plotDRL.py # 绘图和可视化工具 ├── test_gurobi.py # Gurobi 独立测试脚本 │ ├── data/ │ ├── PV.csv # 逐小时光伏发电数据(全年) │ ├── Prices.csv # 逐小时电价数据(全年) │ ├── H4.csv # 分钟级电力消费数据(全年) │ └── constant_and_data_process.py # 数据预处理 │ ├── AgentDDPG/ #(空)保存 DDPG 模型权重 ├── AgentSAC/ #(空)保存 SAC 模型权重 ├── AgentTD3/ #(空)保存 TD3 模型权重 └── __pycache__/ ``` --- ## 算法说明 ### DDPG(深度确定性策略梯度) - **类型**:Off-policy,确定性策略 - **核心特点**:Actor-Critic 框架 + 目标网络 + 经验回放 - **探索方式**:动作添加高斯噪声 - **网络结构**:单 Critic,单 Actor ### TD3(双延迟 DDPG) - **类型**:Off-policy,确定性策略 - **对 DDPG 的改进**: - **裁剪双 Q 学习**:两个 Critic 网络,减少过估计偏差 - **延迟策略更新**:Actor 更新频率低于 Critic - **目标策略平滑**:目标动作添加噪声,起正则化作用 ### SAC(软 Actor-Critic) - **类型**:Off-policy,随机策略(最大熵) - **核心特点**: - 同时最大化奖励和熵(探索与利用兼顾) - 自动温度调节(alpha 参数自适应) - 双 Critic 保证 Q 学习稳定 - 重参数化技巧计算策略梯度 ### PPO(近端策略优化) - **类型**:On-policy,随机策略 - **核心特点**: - 裁剪替代目标函数(信任区域约束) - GAE(广义优势估计)计算优势函数 - Actor 和 Critic 网络分离 - 熵奖励促进探索 --- ## 超参数(`tools.py` 中 Arguments 类定义) | 参数 | 数值 | 说明 | |------|------|------| | `num_episode` | 2000 | 训练回合数 | | `gamma` | 0.995 | 折扣因子 | | `learning_rate` | 2^(-14) ≈ 6e-5 | Adam 学习率 | | `soft_update_tau` | 2^(-8) ≈ 0.005 | 目标网络软更新速率 | | `net_dim` | 256 | 隐藏层维度 | | `batch_size` | 4096 | 小批量大小 | | `repeat_times` | 32 | 每次采样的更新次数 | | `target_step` | 4096 | 每次策略采样的步数 | | `max_memo` | 500,000 | 经验回放缓冲区容量 | | `random_seed_list` | [1234, 2234, 3234, 4234, 5234] | 5个随机种子,保证统计鲁棒性 | --- ## 如何运行 ### 训练模型 ```bash python DDPG.py # 训练 DDPG python TD3.py # 训练 TD3 python SAC.py # 训练 SAC python PPO.py # 训练 PPO(注意:可能存在问题,见下方说明) ``` 每个脚本会依次执行: 1. 使用5个不同的随机种子训练2000个回合 2. 保存训练损失和奖励数据为 `.pkl` 文件 3. 保存训练好的 Actor 网络为 `actor.pth` 4. 运行一个测试回合并保存结果 5. 与 Gurobi 最优解进行对比(需要 Gurobi 许可证) 6. 生成对比图 ### 输出文件 训练完成后,每个算法会在对应目录(`AgentDDPG/` 等)下生成: - `loss_data.pkl` — 训练过程中 Critic/Actor 损失 - `reward_data.pkl` — 回合奖励和约束违反情况 - `actor.pth` — 保存的 Actor 网络权重 - `test_data.pkl` — 单回合测试结果 - `plots/` — 可视化输出 ### 与最优解对比 `tools.py` 中的 `optimization_base_result()` 函数将同一调度问题建模为 **MILP(混合整数线性规划)** 并使用 **Gurobi** 求解,提供理论最优成本作为基准。每次运行结束时输出 `DRL成本 / 最优成本` 的比值。 --- ## 已知问题 - **PPO**:作者反馈上传的 PPO 版本可能无法正常运行,建议优先使用 DDPG、TD3 或 SAC - **数据格式**:CSV 文件使用分号(`;`)作为分隔符,逗号(`,`)作为小数点(欧洲格式) - **Gurobi**:需要 Gurobi 许可证才能运行最优基准对比,无许可证时设置 `args.compare_with_pyomo = False` --- ## 结果与可视化 `plotDRL.py` 脚本可以生成: - 训练奖励曲线 - 成本分解对比(DRL vs Gurobi 最优解) - 发电机调度方案 - 电池 SOC 变化轨迹 - 功率平衡可视化 - 约束违反分析 --- ## 补充说明 - 环境使用欧洲风格 CSV 格式(`,` 为小数点,`;` 为分隔符) - 数据划分:前20天用于训练,每月20日至月末用于测试 - 所有动作归一化到 [-1, 1],在环境内部映射为物理量 - 电池初始 SOC 每回合随机化(均匀分布在 [0.2, 0.8] 之间) --- ## 引用 如果您使用了本代码(或其部分内容),请引用正式发表的论文: ```bibtex @inproceedings{hou2022performance, title={Performance Comparison of Deep RL Algorithms for Energy Systems Optimal Scheduling}, author={Hou, Shengren and Salazar, Edgar Mauricio and Vergara, Pedro P. and Palensky, Peter}, booktitle={2022 IEEE PES Innovative Smart Grid Technologies Conference Europe (ISGT-Europe)}, year={2022}, organization={IEEE} } ``` ## 许可证 本项目基于 MIT 许可证开源 — 详见 [LICENSE](LICENSE) 文件。  --- ## wandb 实验监测说明 项目已经接入 Weights & Biases(wandb)作为可选的实验监测工具。wandb 只负责在线记录和可视化训练过程,原来的本地保存逻辑仍然保留,因此两套方式不会冲突。 ### 是否需要 API Key 不要把 wandb API key 写进代码或 README。首次使用时,在本机命令行执行: ```bash wandb login ``` 或者通过环境变量提供: ```bash set WANDB_API_KEY=your_api_key ``` ### 如何开启 默认情况下 wandb 是关闭的。需要使用时,在 `tools.py` 的 `Arguments` 类中修改: ```python self.use_wandb = True ``` 相关配置项: ```python self.wandb_project = 'DRL-energy-scheduling' self.wandb_entity = None self.wandb_mode = 'online' self.best_unbalance_weight = 1.0 ``` 如果没有安装 wandb,代码会自动跳过 wandb 记录,继续使用本地训练和保存。 ### wandb 记录内容 训练阶段,每个 seed 会创建一个 wandb run,记录: - `train/reward`:当前 episode 的评估奖励 - `train/unbalance`:当前 episode 的功率不平衡指标 - `train/buffer_length`:经验回放池长度 - `loss/critic`:Critic 损失 - `loss/actor`:Actor 损失 - `loss/entropy`:SAC 的熵相关损失 - `best/score`:当前最优模型评分 - `best/episode`:当前最优模型对应的 episode - `best/seed`:当前最优模型对应的随机种子 测试阶段记录: - `test/operation_cost_sum`:测试回合总运行成本 - `test/mean_unbalance`:平均功率不平衡 - `test/max_abs_unbalance`:最大绝对功率不平衡 - `test/final_soc`:测试结束时电池 SOC - `test/cost_ratio_vs_gurobi`:DRL 成本与 Gurobi 最优成本的比值 ### 本地权重保存逻辑 本地保存仍然是主要的离线复现方式。训练完成后,每个算法目录下会保留: - `actor.pth`:兼容旧代码的权重文件 - `actor_last.pth`:最后一次训练结束时的模型 - `actor_best.pth`:训练过程中按评分选出的最好模型 - `loss_data.pkl`:训练损失记录 - `reward_data.pkl`:训练奖励和不平衡记录 - `test_data.pkl`:测试回合详细数据 - `plots/`:本地绘图结果 其中 `actor_best.pth` 的选择标准为: ```python score = reward - best_unbalance_weight * abs(unbalance) ``` 也就是说,模型不仅要奖励高,还要尽量减少功率不平衡。测试阶段会优先加载 `actor_best.pth`;如果该文件不存在,则回退加载 `actor.pth`。 ### 当前接入范围 当前 wandb 已接入: - `DDPG.py` - `TD3.py` - `SAC.py` `PPO.py` 暂未统一接入,因为它目前是相对独立的一套实现,和 `agent.py`、`net.py`、`tools.py` 的复用关系不完全一致。