主要内容

使用强化学习的配水系统调度

这个例子展示了如何使用强化学习(RL)来学习配水系统的最优泵调度策略。

配水系统

下图显示了配水系统。

在这里:

  • Q 供给 是从蓄水池中供给水箱的水量。

  • Q 需求 为满足使用需要而从水箱中流出的水量。

强化学习代理的目标是调度运行的泵的数量,以最小化系统的能源使用并满足使用需求( H > 0 ).储罐系统的动力学由以下方程式控制。

A. dh dt = Q 供给 ( T ) - Q 需求 ( T )

在这里, A. = 40 M 2. H 最大值 = 7. M . 24小时内的需求是时间的函数,如下所示:

Q 需求 ( T ) = μ ( T ) + η ( T )

在哪里 μ ( T ) 是预期的需求和需求 η ( T ) 表示从均匀随机分布中采样的需求不确定性。

供应量由运行的泵数量决定, A. { 0 , 1. , 2. , 3. } 根据下面的映射。

Q 供给 ( T ) = Q ( A. ) = { 0 A. = 0 164 A. = 1. 279 A. = 2. 344 A. = 3. 厘米 H

为了简化问题,将功耗定义为运行的泵数量, A. .

下面的函数是对这种环境的奖励。为了避免溢出或清空水箱,如果水的高度接近最大或最小水位,将增加额外的成本, H 最大值 H 最小值 ,分别。

R ( H , A. ) = - 10 ( H ( H 最大值 - 0 . 1. ) ) - 10 ( H 0 . 1. ) - A.

生成需求概要

要根据所考虑的天数生成和分析需水量概况,请使用generateWaterDemand函数的定义。

num_days = 4;%天数[需水量,T_max]=发电需水量(num_天);

查看需求配置文件。

情节(WaterDemand)

图中包含一个轴对象。标题为“时间序列图:需水量”的坐标轴对象包含一个线型对象。

打开并配置模型

打开配电系统Simulink模型。万博1manbetx

mdl =“watertankscheduling”;开放式系统(mdl)

除了强化学习代理,在控制律MATLAB函数块中定义了一个简单的基线控制器。这个控制器根据水位激活一定数量的泵。

指定初始水位。

h0=3;% m

指定模型参数。

SampleTime = 0.2;H_max = 7;最大油箱高度(m)A_tank = 40;%水箱面积(m^2)

创建RL代理的环境接口

要为Simulink模型创建一个环境接口,首先定义动作和观察规范,万博1manbetxactInfoobsInfo,分别。所选的药剂作用是泵的数量。代理观测是作为连续时间信号测量的水位。

actInfo = rlFiniteSetSpec ([0, 1, 2, 3]);obsInfo = rlNumericSpec ([1]);

创建环境接口。

env = rl万博1manbetxSimulinkEnv (mdl mdl +“/ RL代理”,obsInfo,actInfo);

指定一个自定义的重置函数(在本例的最后定义),它将随机化初始水位和需水量。这样做可以让代理在不同的初始水位和每一集的水需求函数上接受训练。

env.ResetFcn=@(in)localResetFcn(in);

创建DQN代理

DQN代理使用批评家Q值函数表示,在给定观察和行动的情况下,近似长期奖励。要创建批评家,首先创建一个深度神经网络。有关创建深度神经网络值函数表示的更多信息,请参见创建策略和价值功能表示.

%修复随机发生器种子的再现性。rng (0);

为评论家创建一个深度神经网络。对于本例,使用非递归神经网络。要使用递归神经网络,请设置useLSTM真正的.

useLSTM=false;如果useLSTM layers = [sequenceInputLayer(obsInfo.Dimension(1)),“姓名”,“国家”,“正常化”,“没有”)完全连接层(32,“姓名”,“fc_1”)雷卢耶(“姓名”,“relu_body1”) lstmLayer (32,“姓名”,“lstm”)完全连接层(32,“姓名”,“fc_3”)雷卢耶(“姓名”,“relu_body3”) fullyConnectedLayer(元素个数(actInfo.Elements),“姓名”,“输出”)];其他的[featureInputLayer(obsInfo.Dimension(1)),“姓名”,“国家”,“正常化”,“没有”)完全连接层(32,“姓名”,“fc_1”)雷卢耶(“姓名”,“relu_body1”)完全连接层(32,“姓名”,“fc_2”)雷卢耶(“姓名”,“relu_body2”)完全连接层(32,“姓名”,“fc_3”)雷卢耶(“姓名”,“relu_body3”) fullyConnectedLayer(元素个数(actInfo.Elements),“姓名”,“输出”)];终止

指定用于创建评论家表示的选项。

criticOpts=rlRepresentationOptions(“LearnRate”, 0.001,“梯度阈值”,1);

使用定义的深度神经网络和选项创建批评家表示。

评论家= rlQValueRepresentation (layerGraph(层),obsInfo, actInfo,...“观察”,{“国家”},批判者);

创建DQN代理

要创建代理,首先指定代理选项。如果使用的是LSTM网络,则将序列长度设置为20..

选择= rlDQNAgentOptions (“SampleTime”,采样时间);如果useLSTM opt.SequenceLength = 20;其他的opt.SequenceLength = 1;终止opt.DiscountFactor = 0.995;opt.ExperienceBufferLength = 1 e6;opt.EpsilonGreedyExploration.EpsilonDecay = 1 e-5;opt.EpsilonGreedyExploration.EpsilonMin = .02点;

使用定义的选项和批评家表示创建代理。

代理=rlDQNAgent(批评家,opt);

列车员

要培训代理,首先指定培训选项。对于本示例,请使用以下选项。

  • 进行1000集的训练,每集持续时间为装天花板(T_max / Ts)时间步长。

  • 在“插曲管理器”对话框中显示培训进度(设置情节选项)

指定使用RL培训选项对象。

培训选项=RL培训选项(...“MaxEpisodes”, 1000,...“MaxStepsPerEpisode”装天花板(T_max / SampleTime),...“详细”假的,...“情节”,“训练进步”,...“停止培训标准”,“EpisodeCount”,...“停止训练值”, 1000,...“ScoreAveragingWindowLength”, 100);

虽然在本例中不需要这样做,但您可以在培训过程中保存代理。例如,以下选项将保存每个奖励值大于或等于的代理-42年.

如有必要,使用SaveAgentCriteria保存代理培训。SaveAgentCriteria='eposodereward';trainOpts.SaveAgentValue=-42;

训练代理人使用火车函数。训练这个代理是一个计算密集型的过程,需要几个小时才能完成。为了节省运行此示例的时间,请通过设置加载预先训练过的代理溺爱错误的.要亲自培训特工,请设置溺爱真正的.

doTraining = false;如果溺爱培训代理商。trainingStats =火车(代理,env, trainOpts);其他的%加载示例的预训练代理。负载(“万博1manbetxSimulinkWaterDistributionDQN.mat”,“代理”)终止

下图显示了培训进度。

模拟DQN代理

为了验证训练后的agent的性能,将其模拟在水箱环境中。有关代理模拟的更多信息,请参见rlSimulationOptions模拟.

为了模拟代理性能,通过拨动手动开关块连接RL代理块。

设置参数(mdl+“/手动开关”,“西南”,'0');

设置每个模拟的最大步骤数和模拟的数量。对于本例,运行30个模拟。环境复位函数设置了不同的初始高度,每次模拟的需水量也不同。

NumSimulations = 30;simOptions = rlSimulationOptions (“MaxSteps”T_max / SampleTime...“NumSimulations”, NumSimulations);

要在相同条件下将代理与基线控制器进行比较,请重置环境重置功能中使用的初始随机种子。

env。ResetFcn (“重置种子”);

根据环境模拟代理。

experienceDQN = sim (env,代理,simOptions);

模拟基线控制器

要将DQN代理与基线控制器进行比较,必须使用相同的模拟选项和初始的重置函数随机种子来模拟基线控制器。

启用基线控制器。

设置参数(mdl+“/手动开关”,“西南”,'1');

要在相同条件下将代理与基线控制器进行比较,请重置环境重置功能中使用的随机种子。

env。ResetFcn (“重置种子”);

根据环境模拟基线控制器。

体验基线=sim(环境、代理、simOptions);

比较DQN代理与基线控制器

初始化代理和基线控制器的累积奖励结果向量。

resultVectorDQN=0(数值模拟,1);resultVectorBaseline=0(数值模拟,1);

计算代理和基线控制器的累计奖励。

对于ct = 1: numsimulate resultectordqn (ct) = sum(experiedqn (ct).Reward);resultVectorBaseline (ct) =总和(experienceBaseline (ct) .Reward);终止

绘制累积奖励。

情节([resultVectorDQN resultVectorBaseline),“o”)set(gca,“xtick”1: NumSimulations)包含(“模拟数字”) ylabel (“累积奖励”)传说(“DQN”,“基线”,“位置”,“东北外”)

图中包含一个轴对象。轴对象包含两个类型为line的对象。这些对象表示DQN, Baseline。

代理人获得的累积报酬始终在-40左右。这个值远远大于基线控制器获得的平均奖励。因此,DQN代理在节能方面始终优于基线控制器。

局部函数

需水量函数

作用[WaterDemand,T_max] = generateWaterDemand(num_days) t = 0:(num_days*24)-1;%的人力资源T_max = t(结束);Demand_mean = [28, 28, 28, 45, 55, 110, 280, 450, 310, 170, 160, 145, 130,...150, 165, 155, 170, 265, 360, 240, 120, 83, 45, 28]';% m ^ 3 /人力资源需求=repmat(需求平均值,1,天数);需求=需求(:);%增加需求一个= -25;% m ^ 3 /人力资源b=25;% m ^ 3 /人力资源/ /要求噪声= a + (b-a).*rand(numel(Demand),1);WaterDemand = timeseries(Demand + Demand_noise,t);WaterDemand。Name =“水需求”;终止

重置功能

作用= localResetFcn(中)%使用持久随机种子值来评估代理和基线%控制器在相同条件下。持久的randomSeed如果isempty(randomSeed) randomSeed = 0;终止如果比较字符串(在“重置种子”) randomSeed = 0;回来终止randomSeed = randomSeed + 1;rng (randomSeed)%随机化水需求。num_days=4;H_max=7;[需水量,~]=发电需水量(num_days);分配(“基地”,“WaterDemand”,需水量)%随机初始高度。h0=3*randn;虽然h0 <= 0 || h0 | h0终止黑色=“水箱调度/水箱系统/初始水位”;in=参数(in,blk,“价值”,num2str(h0));终止