简介:基于深度强化学习的主动配电网电压控制策略MATLAB源码项目,面向电气、自动化、计算机等专业的毕业设计、课程设计与期末大作业场景,可用于复现智能算法在配电网电压调节中的应用。代码经导师指导并验证运行,适合需要完整可运行项目作为毕设起点或进阶练习的在校学生与开发者。压缩包共4个文件,以MATLAB的m脚本为主,配合一份IEEE33节点标准配电系统xls数据表;其中包含数据初始化、潮流计算(Powerflow)、二阶锥规划(SOCP)等关键模块,覆盖IEEE33节点标准测试系统场景,从数据准备到优化求解链路完整,注释详细,便于理解算法设计思路。资源包仅14KB,轻量便携,可直接导入MATLAB环境调试,也适合作为复现实验、扩展对比算法的基线;目前已有154人学习下载,对于想要快速理解深度强化学习在配电网电压控制中落地思路的读者,是一份高性价比的参考实现。
1. 为什么用深度强化学习解决主动配电网电压控制
配电网从“被动”走向“主动”之后,电压控制从单点定值变成了在线序贯决策问题。分布式光伏、储能和柔性负荷大量接入,潮流方向不再单向,调压手段也从OLTC、电容器组扩展到逆变器无功、储能充放电等多类连续动作。传统最优潮流在已知精确模型前提下能做全局优化,但主动配电网的源荷波动快、量测不完全,模型参数实时获取成本高,线性化模型的误差又会直接反映到电压控制精度上。深度强化学习恰好把电压控制看成马尔可夫决策过程,用神经网络逼近状态到动作的映射,在线学习时不断修正策略,适合光伏出力随机波动场景下的实时电压调节。这个标题下的Matlab源码+详细注释,对两类人最有价值:一是做配电网电压控制研究的学生,需要快速跑通一个端到端的DRL基线;二是工程背景的工程师,想看清状态、动作、奖励函数和训练循环在Matlab里是怎么落地的。文章后面用五章把建模、选型、实现、调参和源码迁移路径讲清楚。
2. 主动配电网电压控制问题的MDP建模与DRL算法选型
2.1 电压控制为什么能建模成马尔可夫决策过程
主动配电网的电压控制本质上是“根据当前断面状态决定下一时刻控制动作”的闭环问题。t时刻的节点电压幅值、负荷功率、光伏出力和储能SOC共同构成状态,电压控制指令是动作,控制后的电压偏移和网损是即时奖励。源荷波动虽然随机,但相邻时刻状态存在时间相关性,满足马尔可夫性质,因此可以用MDP描述。常见做法是把一天24小时划分为96个或288个控制间隔,每个间隔内做一次决策,DRL智能体在一个仿真日内按顺序执行动作、观测回报、推进状态。
相比传统的模型预测控制,DRL不依赖精确的配电网模型做在线滚动优化,而是通过大量离线交互把“源荷场景到最优控制策略”的映射存入网络权重。这个特性让它在模型不完全准确、量测噪声较大的情况下依然能给出合理无功指令。但代价是训练阶段需要大量仿真样本,Matlab里可以用Matpower或者自定义潮流计算函数作为环境,速度比实时物理系统快几个数量级,这是该选题能在科研中落地的前提。
2.2 DDPG / TD3 / SAC的动作空间适配性对比
电压控制的动作包括逆变器无功功率、储能有功/无功、OLTC档位。OLTC档位属于离散动作,逆变器和储能出力是连续动作,同一套DRL框架要同时处理两类动作会引入复杂度。主流做法是先做动作解耦:OLTC档位变化频率低,可以放进慢时间尺度模型单独决策;DRL智能体只负责连续无功和储能出力,这样动作空间维度在几维到十几维之间,适合连续控制算法。
| 算法 | 动作空间 | 策略类型 | 对超参数敏感度 | 推荐场景 |
|---|---|---|---|---|
| DQN | 离散 | 值函数 | 中 | 只有OLTC和分组电容器投切 |
| DDPG | 连续 | 确定性策略 | 高,容易过估计 | 简单配电网,动作维度低 |
| TD3 | 连续 | 确定性策略 + 双Q | 中 | 含逆变器和储能的电压控制 |
| SAC | 连续 | 随机策略 + 最大熵 | 中 | 探索要求高、易陷入局部最优 |
从科研复现角度看,DDPG代码量最小、逻辑直观,作为学习DRL的起点没有问题。但如果要做对比实验或者追求稳定收敛,TD3是更稳妥的选择,它通过双Critic和延迟Actor更新减轻了DDPG的过估计问题。SAC的随机策略在探索阶段表现好,但温度参数需要额外调节,在电力系统连续控制里不是默认首选。 具体选哪个,要看你手里的源码注释深度和算例规模,33节点系统三个算法都能跑,但真正能“高分”的项目通常是DDPG/TD3框架下做了奖励整形和训练稳定性优化。
2.3 状态空间、动作空间与奖励函数的常规设定原则
状态空间的设计决定智能体能“看到”什么。常见状态向量包括:各节点电压幅值标幺值、关键节点注入功率、分布式电源有功出力和无功出力、储能SOC、当前时刻或时段编号(用于区分峰谷)。如果算例里有时序光伏曲线,把当前时间步作为状态分量输入,能帮智能体隐式学习昼夜周期规律。状态量必须做归一化处理,电压归一化到0.9~1.1 p.u.映射到0~1区间,功率按容量基准归一化,SOC本身在0~1内。 归一化没做好,神经网络前几个全连接层的梯度容易爆炸,训练一开始就发散。
动作空间的设定要与配电网实际可控资源对齐。逆变器无功出力通常限制在视在功率约束内,储能的有功输出受到SOC上下限和功率上限双重约束。DRL输出的原始动作是连续值,要经过缩放层或外部约束映射才能变成实际控制量。例如Actor输出tanh激活后值在-1到1之间,乘以无功上限得到实际无功指令,超出设备容量时在环境内部做约束处理。
奖励函数是电压控制项目最容易拉开差距的地方。基础版奖励是电压越限惩罚加网损成本:
penalty_volt = sum((V - 1.05).^2 .* (V > 1.05)) + sum((0.95 - V).^2 .* (V < 0.95)); penalty_loss = Ploss / Pbase; action_penalty = sum((action - action_prev).^2); reward = -(w1 * penalty_volt + w2 * penalty_loss + w3 * action_penalty);代码里V是节点电压幅值向量,Ploss是当前断面网络有功损耗,Pbase是基准功率,action和action_prev是当前与上一时刻的控制动作。三项惩罚的含义分别是:电压越限按平方加权,越严重惩罚越大;网损归一化后参与决策;动作变化量惩罚抑制抖动,避免逆变器无功指令频繁波动。 权重w1通常取 10~50,w2取 0.1~1,w3取 0.01~0.1,先调w1保证电压约束优先满足,再调w2、w3优化经济性和动作平滑性。
需要特别注意的是,奖励信号太稀疏是DRL训练失败的常见原因。如果只在电压越限时给负奖励,大部分时间奖励都是0,智能体无法区分不同动作的好坏。解决办法是把电压偏移的连续量引入奖励,让智能体在电压尚在安全范围内时也能感知到“靠近边界”的趋势。
3. 用Matlab搭建环境接口与Actor-Critic训练主循环
3.1 环境接口设计:把潮流计算封装成标准交互函数
Matlab实现DRL电压控制,第一件事不是搭神经网络,而是把潮流计算封装成稳定的环境接口。常见做法是基于Matpower的runpf函数做潮流求解,自己写一个step(action)函数接收智能体动作,内部更新DG出力、储能功率等参数,重新求解潮流,返回下一时刻状态、奖励和终止标志。封装接口时,要保证每次step只做一次潮流计算,避免在训练循环里重复写潮流求解逻辑。
环境接口核心功能模块一般包括:算例数据加载、状态提取、动作映射、潮流求解、奖励计算、状态更新六个部分。算例数据用Matpower的case33bw或case123结构体,光伏接入节点通过修改bus和gen数据结构实现。动作映射环节是把神经网络的连续输出转换为符合设备约束的控制量,这一步往往在环境内部完成,智能体不感知外部约束,有助于训练稳定性。状态提取函数需要返回时序化数据,例如某个节点电压的历史3个时刻值可以拼进状态向量,让智能体对电压变化趋势有感知。
function [nextObs, reward, done, info] = stepEnv(this, action) % 将DRL原始动作映射到设备控制量 q_dg = this.Qmax .* tanh(action(1:this.nDG)); p_bess = this.PbessMax .* tanh(action(this.nDG+1:end)); % 更新配电网参数并求解潮流 this.mpc.gen(:, 4) = q_dg * this.Sbase; this.mpc.bus(:, 4) = this.Pload * this.loadFactor; result = runpf(this.mpc, this.mpopt); % 提取状态和计算奖励 V = result.bus(:, 8); nextObs = buildObservation(this, V, result); reward = computeReward(this, V, result, action); % 判断仿真是否结束 done = this.t >= this.horizon; info = struct('Vmin', min(V), 'Vmax', max(V)); end这段代码的关键点在于tanh函数把神经网络输出压缩到-1到1区间,再通过Qmax和PbessMax缩放为实际物理量,既保证了动作不越限,又让智能体的输出范围始终稳定。runpf是Matpower的潮流求解入口,mpopt是求解器选项,其中要关闭输出打印,否则训练时命令行会被刷屏。 状态构建函数buildObservation要把电压、功率、时间戳拼成一个列向量,维度在每次调用时保持一致。
3.2 用Deep Learning Toolbox搭建Actor与Critic网络
Matlab实现神经网络有两种常用路径。高级路径是用强化学习工具箱的rlDDPGAgent和rlTD3Agent,它内置了经验回放、目标网络更新和训练循环,十几行代码能跑通训练,省事但不容易改算法细节。通用路径是用Deep Learning Toolbox的dlnetwork手写网络结构和梯度更新,可控性好、能深度定制奖励整形或动作映射逻辑,也是高分项目源码里最常见的做法。
Critic网络输入是状态和动作的拼接向量,输出是Q值估计;Actor网络只接收状态输入,输出动作向量。中间层用fullyConnectedLayer加reluLayer的堆叠结构,隐藏层维度常见为256×128或256×256。Critic网络输出层不需要激活函数,Actor网络输出层用tanhLayer把动作限制在-1到1之间。
% Actor网络:状态 -> 动作 actorNet = [ featureInputLayer(numStates, 'Normalization', 'none', 'Name', 'stateIn') fullyConnectedLayer(256, 'Name', 'actorFC1') reluLayer('Name', 'actorReLU1') fullyConnectedLayer(128, 'Name', 'actorFC2') reluLayer('Name', 'actorReLU2') fullyConnectedLayer(numActions, 'Name', 'actorOut') tanhLayer('Name', 'actorTanh') ]; actor = dlnetwork(actorNet); % Critic网络:状态和动作拼接 -> Q值 criticNet = [ featureInputLayer(numStates + numActions, 'Normalization', 'none', 'Name', 'saIn') fullyConnectedLayer(256, 'Name', 'criticFC1') reluLayer('Name', 'criticReLU1') fullyConnectedLayer(128, 'Name', 'criticFC2') reluLayer('Name', 'criticReLU2') fullyConnectedLayer(1, 'Name', 'criticOut') ]; critic = dlnetwork(criticNet);网络结构参数说明:输入层节点数必须与环境返回的状态维度严格一致,否则训练开始就报维度错误;隐藏层节点数决定网络容量,容量过大容易过拟合到训练场景,容量太小学不到非线性关系。对IEEE 33节点系统,状态维度一般在15~30,两层隐藏层足够拟合Q值函数。 训练过程中如果持续出现NaN梯度,优先检查状态量是否存在Inf或者极端大数值,其次是检查学习率是否过高。
3.3 训练主循环:经验采样、目标网络更新、软更新系数
训练主循环是DRL项目的中枢。每一轮episode对应一个仿真日,从初始断面开始,智能体在每个控制间隔执行动作,环境返回奖励和下一状态,转移数据存入经验池。当经验池样本足够时,从池中随机采样一个小批量数据,分别更新Critic和Actor网络。更新过程中用目标网络计算TD目标,目标网络参数通过软更新从在线网络缓慢复制,这样能避免目标值剧烈波动导致训练不稳定。
for episode = 1:maxEpisodes obs = env.reset(); for t = 1:maxSteps % 探索噪声:训练初期噪声大,后期衰减 noise = exploreNoise * randn(numActions, 1); action = extractdata(predict(actor, dlarray(obs, 'CB'))) + noise; [nextObs, reward, done, ~] = env.step(action); push(buffer, obs, action, reward, nextObs, done); obs = nextObs; if buffer.Size > batchSize && mod(t, 4) == 0 [sBatch, aBatch, rBatch, sNextBatch, dBatch] = sample(buffer, batchSize); % 计算TD目标 aNext = predict(actorTarget, dlarray(sNextBatch, 'CB')); qNext = predict(criticTarget, cat(1, sNextBatch, aNext)); y = rBatch + gamma * (1 - dBatch) .* qNext; % 更新Critic,梯度下降 qPred = predict(critic, cat(1, sBatch, aBatch)); criticLoss = mse(qPred, y); % 更新Actor,最大化Q值 loss = -mean(predict(critic, cat(1, sBatch, predict(actor, dlarray(sBatch, 'CB'))))); end end end代码中exploreNoise是探索噪声标准差,训练前期设为0.2~0.5,中后期衰减到0.02以下,衰减策略可以是线性衰减或指数衰减。batchSize通常取64~256,经验池容量取5万到20万条。gamma是折扣因子,电压控制场景一般取0.95~0.99,越接近1表示越重视长期回报,但这个值过大会让价值估计方差变大。每步更新或者每4步更新一次网络是常见做法,更新频率太高可能导致训练发散,太慢则学习效率低。训练结束后保存Actor网络权重,测试阶段直接把Actor输出作为控制指令,不再叠加探索噪声。
4. 经验回放、目标网络与参数调节的收敛性诊断
4.1 经验回放缓冲区:容量、采样均匀性与优先级
经验回放是DQN以来的核心机制,目的打断样本间的时间相关性,让神经网络更新时假设的独立同分布条件尽量成立。标准做法是均匀随机采样,缓冲区大小由内存和任务复杂度决定。电压控制场景里,状态转移包含连续时序特征,均匀采样会丢失部分时序依赖,但引入比例较高的近期样本,可以部分缓解这个问题。
| 参数 | 推荐范围 | 作用 | 异常表现 |
|---|---|---|---|
| 缓冲区容量 | 5e4 ~ 2e5 | 保存经验样本 | 过小导致样本分布偏窄,过小导致学习震荡 |
| 批次大小 | 64 ~ 256 | 每次梯度更新的样本数 | 过大收敛慢,过小噪声大 |
| 采样比例近期样本 | 20% ~ 40% | 缓解非平稳环境遗忘 | 电压波动快时适当提高 |
| 软更新系数 tau | 0.001 ~ 0.005 | 目标网络跟踪速度 | 过大震荡,过小学习缓慢 |
均匀采样有一个隐藏问题:电压越限样本在正常运行时占比很低,而这些样本恰恰是训练的关键。如果某轮episode光伏出力强、电压越限多,这部分经验对提升策略价值高;均匀采样会把这些稀有样本淹没在大量正常样本中。优先经验回放通过对采样概率按TD误差加权解决这个问题,但实现复杂度和超参数都增加,科研项目中可以先把均匀采样跑通,后续再对比优先回放的提升幅度。
4.2 折扣因子、学习率与探索噪声的联合调节策略
参数调节不是孤立的,折扣因子、学习率和探索噪声三者共同决定训练的收敛轨迹。一个实用的调参顺序是:先固定折扣因子为0.98,探索噪声初始值0.3,将Actor和Critic的学习率分别设为1e-4和1e-3,跑200个episode观察奖励曲线是否上升。如果曲线震荡剧烈,优先调低Critic学习率到3e-4;如果奖励长期不上升,检查探索噪声是否衰减太快,导致智能体过早陷入局部最优。
探索噪声的衰减节奏要匹配训练周期。如果总训练轮数是500个episode,噪声从0.3线性衰减到0.03是常见做法,前100个episode保持较大的噪声促进探索,中间300个episode逐步降低,最后100个episode趋于稳定。 衰减过快会让人想起“过早收敛到次优策略”的现象,表现为测试阶段电压合格率不错但网损偏高;衰减过慢则训练曲线波动大,最终策略不稳定。比较稳妥的做法是用max(0.02, 0.3 * (1 - episode/maxEpisodes))做线性衰减,下限设0.02保证策略仍有最小随机性。
关于这个项目中电压控制策略的调参,最核心的一点是要单独评估Critic网络的损失曲线。Actor损失曲线在很多实现里不直观,Critic的MSE曲线能直接反映价值估计是否收敛。理想情况下Critic损失递减后趋于平稳,训练后期在某个小范围内波动是正常的。如果Critic损失在某一轮突然跳高随后无法回落,通常说明目标值出现了偏差,优先检查目标网络是否更新过快,把tau从0.005调低到0.001可以缓解。
4.3 训练可视化与收敛性判断的三种方法
只盯奖励曲线是不够的,电压控制项目需要结合多个维度判断训练是否真正学到可用的策略。第一个维度是奖励曲线,看趋势不看过拟合;第二个维度是电压合格率,统计每个episode内所有节点电压在0.95~1.05 p.u.范围内的时刻占比;第三个维度是动作平滑度,频繁大幅度动作预示策略不稳定。
% 训练过程中记录电压合格率 voltQual = zeros(maxEpisodes, 1); for ep = 1:maxEpisodes env.reset(); validCount = 0; totalCount = 0; for t = 1:maxSteps V = env.getVoltage(); validCount = validCount + sum(V >= 0.95 & V <= 1.05); totalCount = totalCount + length(V); end voltQual(ep) = validCount / totalCount; end figure; plot(voltQual, 'LineWidth', 1.5); xlabel('Episode'); ylabel('Voltage Qualification Rate'); grid on;这段代码在每个episode结束后统计电压合格率,画出曲线后可以直观看到训练是否在有效提升电压控制能力。如果合格率在某个数值附近长时间停滞且奖励波动大,不是参数问题,而是动作空间或奖励函数设计上有缺陷,需要回到建模层面重新检查。测试阶段禁用探索噪声后,合格率应当比训练曲线更高且相对稳定,这是策略可用的基本判据。
5. 读懂高分项目源码:目录结构、核心函数与工程化改造
5.1 项目源码的常见目录划分与核心函数定位
拿到一个DRL电压控制源码包,第一步不是打开主文件逐行看,而是先建立整体地图。规范的Matlab项目一般包含五个目录:main入口脚本、env环境与潮流计算、agent网络与更新逻辑、train训练循环与可视化、utils数据加载和辅助函数。如果你的源码包里没有清晰目录,优先找到三个核心文件:入口脚本、环境step函数、网络更新函数,其余都是辅助。
DRL_VoltControl/ ├── main.m % 主入口:设置随机种子,加载算例,初始化环境和智能体 ├── env/ │ ├── createEnv.m % 构建环境对象,设置状态/动作维度 │ ├── stepEnv.m % 核心:潮流计算、动作映射、奖励计算 │ └── loadCase.m % 加载IEEE 33/123节点算例,设置DG和储能位置 ├── agent/ │ ├── createActor.m % 定义Actor网络结构 │ ├── createCritic.m % 定义Critic网络结构 │ └── updateAgent.m % 经验采样、梯度计算、参数更新 ├── train/ │ ├── trainLoop.m % 训练主循环 │ └── plotProgress.m % 训练曲线可视化 └── utils/ ├── normalizeState.m % 状态归一化与反归一化 └── saveResults.m % 结果保存与导出目录结构说明:这种模块化设计的好处是环境接口与智能体算法解耦,更换算例时只需改loadCase.m和createEnv.m中的状态动作定义,不需要动网络结构。阅读源码时,先跑通main.m,然后分别单步执行createEnv和stepEnv,理解状态向量的组成和奖励数值的量级,再看updateAgent中的梯度更新是否与理论对应。遇到看不懂的矩阵维度变换,用size()检查每一步输出,比硬读代码效率更高。
5.2 阅读源码时的高频易混淆点与快速验证方法
Matlab的DRL源码有几个特别容易让人困惑的地方。第一是dlarray的数据格式,网络前向传播要求输入是dlarray类型且维度标记为'CB'(通道-批次),普通矩阵直接输入会报类型错误。第二是extractdata的用法,从dlarray中取原始数值,用于拼接或记录日志;如果漏掉这步,数值类型不匹配会造成很多隐性bug。第三是目标网络与在线网络的参数同步,初始化时目标网络要直接复制在线网络参数,不是随机初始化,否则训练初期TD误差巨大。
% 目标网络初始化:复制在线网络参数 actorTarget = actor; criticTarget = critic; % 每步更新后的软更新 actor.State = ... tau * actor.State + (1 - tau) * actorTarget.State;代码说明:Matlab的dlnetwork对象通过State属性保存参数,软更新时用tau混合新旧参数。注意有些源码里用assign函数或者逐层循环更新参数,效果相同但写法繁琐。快速验证目标网络是否更新的方法是训练前打印一层权重,训练10步后再打印同一层权重,数值应当有小幅变化且不是完全不变。如果参数完全不变,说明软更新代码没有执行,梯度更新目标网络参数这条链路是断开的。
5.3 把33节点源码迁移到其他算例的改造路径
拿到一份能跑通的源码后,最常见的需求是换成更大算例或改变分布式电源配置。迁移时按以下顺序操作:先替换算例数据,再检查状态定义,最后验证奖励量级。 常见的改造动作是把case33bw换成case123,此时节点数和支路数变化,状态向量维度要增加,Actor和Critic网络输入层节点数也要同步修改。用文件里的stateIdx或注释里的“状态变量说明”来定位这处改动比逐个搜索数字更高效。DG数量和类型变化时,动作向量的维度和tanh缩放系数要相应修改,同时确认潮流计算中gen矩阵的列位置与新算例一致。Matpower的case结构体版本差异比较大,2017版和2020版的字段命名可能有细微差别,迁移时优先参考源码里自带的基础数据版本。
5.4 源码注释质量判断:从注释看项目完整度
高质量电压控制源码的注释有明确的规律可循,看懂这些规律能帮你判断这个项目值不值得深入读。好的注释一定包含三类信息:变量的物理意义和单位、状态向量的索引与构成、公式与代码的对应关系。例如状态构建函数里应该有“state(1:33)为节点电压幅值标幺值,state(34:36)为光伏有功出力”之类的说明,训练主循环里应该有“这里噪声衰减采用线性策略,公式为 noise = max(noiseMin, noiseInit * (1 - ep / maxEp))”的公式注释。如果注释只在函数头部宏观描述“本函数用于训练”,没有任何变量级别的解释,项目完整度就一般,阅读时要把更多时间花在对照论文推导实现上。
6. 用奖励函数整形提升电压合格率的实用技巧
奖励函数整形是DRL电压控制项目中最容易出效果的部分,不需要改网络结构、不需要动训练算法,只调整奖励的计算方式就能直接影响学习的优先级。基础奖励里电压越限惩罚通常是一个固定权重乘以越限和。改进思路是把“是否越限”改成“越限程度强烈加权”。平方惩罚比线性惩罚对越限更敏感,让智能体在电压接近边界时就感受到压力,而不是等到越限了才收到惩罚信号。
边界软化是第二个有效技巧。把硬性电压约束0.95~1.05改成三个区间,中间安全区奖励为0,接近边界区给予微小负奖励,越限区给予大负奖励,这样智能体学到的动作会更平滑,不会为了规避惩罚而在边界来回跳动。 具体实现时可以用max(V - 1.02, 0)和max(0.98 - V, 0)作为软边界越限指标,配合基础越限指标一起加权。
时域累积惩罚针对的是“间歇性越限”问题。某个节点短时间越限可能因为功率波动,智能体如果只看到瞬时的越限信号,会倾向于频繁调整动作。解决办法是把最近N个时刻的越限状态做指数滑动平均,累计越限程度进入奖励:
persistent violHistory; if isempty(violHistory) violHistory = zeros(1, 3); end violNow = sum(V > 1.05) + sum(V < 0.95); violHistory = [violHistory(2:end), violNow]; violAvg = mean(violHistory); reward = reward - w4 * violAvg;其中w4建议取w1的十分之一左右,作用是让智能体为“持续越限”付出额外代价,避免间歇性振荡的控制行为。这个技巧在实际训练中能明显降低动作抖动频率,电压合格率的收敛曲线更平滑。
动作平滑性奖励是最后一个收尾技巧,在基础奖励中加入动作变化量的软约束,但权重不宜过大,否则智能体会“什么都不做”来最小化动作惩罚。验证奖励整形效果好不好的方法很朴素:固定随机种子和训练轮数,分别跑一版基础奖励和一版整形后的奖励,对比测试集上的电压合格率和动作标准差。合格率提升超过1个百分点、动作标准差下降50%,说明整形有效。如果两种设定下指标几乎没有差异,问题很可能出在训练轮数不够,奖励的差别还没被智能体充分感知到。把整形后的奖励和DDPG原版算法配合,通常经过300~500个episode就能看到清晰的分化。
本文还有配套的精品资源,点击获取