主要内容

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

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

配水系统

下图显示了一个配水系统。

这里:

  • 供应 是从储层供应到水箱的水量。

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

强化学习agent的目标是调度水泵运行数量,使系统能量消耗最小化,同时满足使用需求( h > 0 ).储罐系统的动力学由下列方程控制。

一个 dh dt 供应 t - 需求 t

这里, 一个 40 2 h 马克斯 7 .24小时内的需求是时间的函数

需求 t μ t + η t

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

供给量由运行泵的数量决定, 一个 0 1 2 3. 根据下面的映射。

供应 t 一个 0 一个 0 164. 一个 1 279. 一个 2 344. 一个 3. 厘米 h

为了简化问题,功率消耗被定义为运行的泵的数量, 一个

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

r h 一个 - 10. h h 马克斯 - 0 1 - 10. h ≤. 0 1 - 一个

生成需求概况

要根据所考虑的天数来生成和生成水需求剖面,请使用生成沃特德姆和函数的定义。

num_days = 4;%天数[WaterDemand, T_max] = generateWaterDemand (num_days);

查看需求配置文件。

情节(WaterDemand)

图包含轴对象。具有标题时间序列图的轴对象:水需求包含类型线的对象。

开放和配置模型

打开配电系统的Simulink模型。金宝app

mdl =“watertankscheduling”;open_system (mdl)

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

指定初始水位。

h0 = 3;%M.

指定模型参数。

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

为RL代理创建环境界面

要为Simulink模型创建环境界面,首先定义操作和观察规范,金宝appActinfo.obsInfo,分别。所选的药剂作用是泵的数量。代理观测是作为连续时间信号测量的水位。

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

创建环境接口。

Env = Rl金宝appsimulinkenV(MDL,MDL +“/ rl代理人”、obsInfo actInfo);

指定自定义重置功能,该函数在此示例结束时定义,可随机化初始水高和需水需求。这样做允许代理接受不同初始水位和每集的水需求函数培训。

env。ResetFcn = @(在)localResetFcn(的);

创建DQN代理

DQN代理使用批判q值函数表示来逼近给定的观察和行动的长期回报。要创建批评家,首先要创建一个深度神经网络。有关创建深度神经网络值函数表示的更多信息,请参见创建策略和值函数表示

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

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

useLSTM = false;如果USELSTM图层= [sequentInputlayer(ObsInfo.dimension(1),“名称”“状态”“归一化”“没有”) fullyConnectedLayer (32,“名称”“fc_1”) reluLayer (“名称”“relu_body1”) lstmLayer (32,“名称”“lstm”) fullyConnectedLayer (32,“名称”“fc_3”) reluLayer (“名称”“relu_body3”)全连接列(Numel(Actinfo.Elements),“名称”“输出”));其他的图层= [featureInputLayer(ObsInfo.dimension(1),“名称”“状态”“归一化”“没有”) fullyConnectedLayer (32,“名称”“fc_1”) reluLayer (“名称”“relu_body1”) fullyConnectedLayer (32,“名称”“fc_2”) reluLayer (“名称”“relu_body2”) fullyConnectedLayer (32,“名称”“fc_3”) reluLayer (“名称”“relu_body3”)全连接列(Numel(Actinfo.Elements),“名称”“输出”));结束

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

criticOpts = rlRepresentationOptions (“LearnRate”,0.001,“GradientThreshold”1);

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

评论家= rlqvaluerepresentation(图层图(图层),obsinfo,Actinfo,......'观察',{“状态”}, criticOpts);

创建DQN代理

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

opt = rldqnagentoptions('采样时间', SampleTime);如果USELSTM opt.Sequencelength = 20;其他的opt.sequencelength = 1;结束opt.discountfactor = 0.995;opt.ExperienceBufferLength = 1E6;opt.epsilongredyexpliation.epsilondecay = 1e-5;opt.epsilongredyexpliation.epsilonmin = .02;

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

代理= rlDQNAgent(评论家,选择);

火车代理

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

  • 跑步训练1000集,每集持续装天花板(T_max / Ts)时间的步骤。

  • 在Episode Manager对话框中显示培训进度(设置绘图选项)

指定用于培训的选项rlTrainingOptions目的。

trainOpts = rlTrainingOptions (......“MaxEpisodes”,1000,......“MaxStepsPerEpisode”,ceil(t_max / sampletime),......'verbose'假的,......“阴谋”'培训 - 进步'......“StopTrainingCriteria”'episodecount'......“StopTrainingValue”,1000,......“ScoreAveragingWindowLength”, 100);

虽然您未为此示例执行此操作时,您可以在培训过程中保存代理。例如,以下选项保存每个代理,奖励值大于或等于-42年

如果需要的话,使用SaveAgentCriteria保存代理。SaveAgentCriteria =“EpisodeReward”;trainOpts。SaveAgentValue = -42;

训练代理人使用火车功能。培训此代理是一个计算密集型进程,需要几个小时才能完成。要在运行此示例的同时节省时间,请通过设置加载预制代理doTraining.自己训练代理人,设置doTraining真正的

dotraining = false;如果doTraining%训练代理人。TrainingStats =火车(代理商,ENV,训练);其他的%加载预磨料的代理。加载(“金宝appSimulinkWaterDistributionDQN.mat”'代理人'结束

下图显示了培训进度。

模拟DQN代理

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

要模拟代理性能,请通过切换手动交换机块来连接RL代理块。

set_param (mdl +“/手动开关”“西南”' 0 ');

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

numsimulations = 30;simoptions = rlsimulationoptions(“MaxSteps”,t_max / sampletime,......'numsimulations',numsimulations;

为了将agent与基线控制器在相同条件下进行比较,对环境重置函数中使用的初始随机种子进行重置。

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

根据环境模拟代理。

经验丰富的qn = sim(env,代理,simoptions);

模拟基线控制器

要将DQN代理与基线控制器进行比较,必须使用相同的模拟选项和复位功能的初始随机种子模拟基线控制器。

启用基线控制器。

set_param (mdl +“/手动开关”“西南”' 1 ');

为了将agent与基线控制器在相同条件下进行比较,对环境复位函数中使用的随机种子进行复位。

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

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

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

比较DQN Agent与基线控制器

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

resultVectorDQN = 0 (num道模拟,1);resultVectorBaseline = 0 (NumSimulations, 1);

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

ct = 1:numsimulations结果vectordqn(ct)= sum(经验丰富的qn(ct).reward);结果vectorbaseline(ct)= sum(经验绑定(ct).reward);结束

绘制累积奖励。

绘图([ResultVectordQn结果vectorbaseline],“o”甘氨胆酸)组(,'xtick',1:numsimulations)xlabel(“模拟号码”) ylabel (“累积奖励”) 传奇(“DQN”“基线”'地点'“NorthEastOutside”

图包含轴对象。轴对象包含2个类型的物体。这些对象代表DQN,基线。

代理商获得的累计奖励始终如一。该值远大于基线控制器获得的平均奖励。因此,DQN Agent在节能方面始终如一地优于基线控制器。

本地函数

水需求函数

函数[waterdemand,t_max] =生成海拉德姆(num_days)t = 0 :( num_days * 24)-1;%小时t_max = t(结束);需求_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 / hr需求= repmat (Demand_mean 1 num_days);需求=需求(:);给需求增加噪音a = -25;%m ^ 3 / hrb = 25;%m ^ 3 / hrDESTRENT_NOISE = A +(B-A)。*兰特(NUMER(需求),1);WaterDemand = TimeSeries(需求+需求_Noise,T);waterdemand.name =“水需求”结束

重置功能

函数在= localresetfcn(in)%使用持久随机种子值来评估代理和基线%控制器在相同的条件下。持续的随机如果isempty(随机)随机= 0;结束如果Strcmp(在,“重置种子”)随机= 0;返回结束randomSeed = randomSeed + 1;rng (randomSeed)%随机用水需求。num_days = 4;H_max = 7;[WaterDemand ~] = generateWaterDemand (num_days);assignin (“基地”“WaterDemand”WaterDemand)%随机化初始高度。h0 = 3 * randn;h0 <= 0 || h0 | h0结束黑色='Watertankscheding /水箱系统/初始水高';在= setBlockParameter(黑色,“价值”num2str (h0));结束