配水系统调度使用强化学习
这个例子展示了如何学习的最佳泵配水系统的调度策略利用强化学习(RL)。
配水系统
下面的图显示了一个配水系统。
在这里:
是提供的水量从储水箱。
流出的水量的坦克来满足使用需求。
强化学习的目标代理调度运行的水泵数量最小化系统的能源使用和满足使用需求( )。坦克的动力系统由以下方程。
在这里, 和 。在24小时内的需求作为时间的函数
在哪里 预期的需求和吗 代表了需求的不确定性,这是取样均匀随机分布。
供应的数量是由泵运行, 根据下面的映射。
为了简化问题,电力消耗的定义是水泵运行的数量, 。
下面的函数是这个环境的奖励。避免溢出或排空水箱,添加一个附加的成本如果水高度接近最大值或最低水位, 或 ,分别。
生成需求概要
生成和基于的天数的水需求概要文件,使用generateWaterDemand
函数定义的这个例子。
num_days = 4;%的天数[WaterDemand, T_max] = generateWaterDemand (num_days);
查看需求概要文件。
情节(WaterDemand)
开放和配置模型
打开配电系统仿真软件模型。金宝app
mdl =“watertankscheduling”;open_system (mdl)
除了强化学习代理,一个简单的基线控制器控制律中定义的MATLAB函数块。这个控制器激活一定数量的泵根据水位。
指定初始水高度。
h0 = 3;% m
指定模型参数。
SampleTime = 0.2;H_max = 7;%马克斯槽高度(米)A_tank = 40;%的坦克(m ^ 2)
为RL创建环境接口代理
创建一个环境界面的仿真软件模型,首先定义操作和观察规格,金宝appactInfo
和obsInfo
,分别。代理行为是所选泵的数量。代理观察水的高度,这是作为一个连续时间信号测量。
actInfo = rlFiniteSetSpec ([0, 1, 2, 3]);obsInfo = rlNumericSpec ([1]);
创建环境的接口。
env = rl金宝appSimulinkEnv (mdl mdl +“/ RL代理”、obsInfo actInfo);
指定一个自定义的重置功能,这是定义在这个例子中,随机初始水高度和水的需求。这样做将允许代理被训练在不同初始水位和水需求函数为每个事件。
env。ResetFcn = @(在)localResetFcn(的);
创建DQN代理
DQN代理接近长期奖励,观察和操作,使用一个评论家核反应能量函数表示。创建评论家,首先创建一个深层神经网络。更多信息创建一个深层神经网络价值函数表示,看到的创建政策和价值功能。
%解决随机发生器再现性的种子。rng (0);
创建一个深层神经网络的评论家。对于这个示例,使用一个临时神经网络。使用递归神经网络,集useLSTM
来真正的
。
useLSTM = false;如果useLSTM层= [sequenceInputLayer obsInfo.Dimension (1),“名称”,“状态”,“归一化”,“没有”)fullyConnectedLayer (32,“名称”,“fc_1”)reluLayer (“名称”,“relu_body1”)lstmLayer (32,“名称”,“lstm”)fullyConnectedLayer (32,“名称”,“fc_3”)reluLayer (“名称”,“relu_body3”)fullyConnectedLayer(元素个数(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”)fullyConnectedLayer(元素个数(actInfo.Elements),“名称”,“输出”));结束款= dlnetwork(层);
指定的选项创建一个评论家表示。
criticOpts = rlOptimizerOptions (“LearnRate”,0.001,“GradientThreshold”1);
创建一个评论家使用rlVectorQValueFunction定义深层神经网络和选项。
评论家= rlVectorQValueFunction(款、obsInfo actInfo);
创建DQN代理
创建一个代理,首先指定代理选项。如果您正在使用一个LSTM网络,设置序列长度20.
。
选择= rlDQNAgentOptions (“SampleTime”,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点;opt.CriticOptimizerOptions = criticOpts;
使用定义的选项和评论家表示创建代理。
代理= rlDQNAgent(评论家,选择);
火车代理
培训代理商,首先指定培训选项。对于这个示例,使用以下选项。
运行培训1000集,每集持久
装天花板(T_max / Ts)
时间的步骤。在事件管理器对话框显示培训进展(设置
情节
选项)
培训使用一个指定的选项rlTrainingOptions
对象。
trainOpts = rlTrainingOptions (…“MaxEpisodes”,1000,…“MaxStepsPerEpisode”装天花板(T_max / SampleTime),…“详细”假的,…“阴谋”,“训练进步”,…“StopTrainingCriteria”,“EpisodeCount”,…“StopTrainingValue”,1000,…“ScoreAveragingWindowLength”,100);
当你不要这样做对于这个示例,您可以保存代理在训练过程中。例如,以下选项保存每个代理奖励值大于或等于-42年
。
使用在必要时SaveAgentCriteria trainOpts省代理。SaveAgentCriteria =“EpisodeReward”;trainOpts。SaveAgentValue = -42;
火车代理使用火车
函数。培训这个代理是一个计算密集型过程,需要几个小时才能完成。节省时间在运行这个例子中,加载一个pretrained代理设置doTraining
来假
。训练自己代理,集doTraining
来真正的
。
doTraining = false;如果doTraining%培训代理。%连接块通过手动切换开关块RL代理set_param (mdl +“/手动开关”,“西南”,' 0 ');trainingStats =火车(代理,env, trainOpts);其他的%加载pretrained代理的例子。负载(“金宝appSimulinkWaterDistributionDQN.mat”,“代理”)结束
下面的图显示了培训的进展。
模拟DQN代理
验证培训代理的性能,模拟在水箱的环境。代理模拟更多的信息,请参阅rlSimulationOptions
和sim卡
。
模拟剂性能、连接块通过手动切换开关块RL代理。
set_param (mdl +“/手动开关”,“西南”,' 0 ');
设置步骤的最大数量为每个模拟和仿真的数量。对于本例,30模拟运行。环境重置函数集不同初始水高度和在每个模拟水需求是不同的。
NumSimulations = 30;simOptions = rlSimulationOptions (“MaxSteps”T_max / SampleTime…“NumSimulations”,NumSimulations);
与基线比较代理控制器在相同条件下,重置初始随机环境中使用的种子复位功能。
env.ResetFcn (“重置种子”);
模拟剂对环境。
experienceDQN = sim (env,代理,simOptions);
模拟基线控制器
与基线比较DQN代理控制器,您必须使用相同的仿真模拟基线控制器选项和初始随机种子复位功能。
使基线控制器。
set_param (mdl +“/手动开关”,“西南”,' 1 ');
与基线比较代理控制器在相同条件下,重置环境中使用的随机种子复位功能。
env.ResetFcn (“重置种子”);
模拟对环境基线控制器。
experienceBaseline = sim (env,代理,simOptions);
与基线比较DQN代理控制器
初始化累积奖励结果向量为代理和基线控制器。
resultVectorDQN = 0 (NumSimulations, 1);resultVectorBaseline = 0 (NumSimulations, 1);
计算累积奖励为代理和基线控制器。
为ct = 1: NumSimulations resultVectorDQN (ct) =总和(experienceDQN (ct) .Reward);resultVectorBaseline (ct) =总和(experienceBaseline (ct) .Reward);结束
情节的累积奖励。
情节([resultVectorDQN resultVectorBaseline),“o”甘氨胆酸)组(,“xtick”1:NumSimulations)包含(“模拟数字”)ylabel (“累积奖励”)传说(“DQN”,“基线”,“位置”,“NorthEastOutside”)
累计获得的奖励代理一直约-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 (Demand_mean 1 num_days);需求=需求(:);%添加噪声要求一个= -25;% m ^ 3 /人力资源b = 25;% m ^ 3 /人力资源Demand_noise = a + (b)。*兰德(元素个数(需求),1);WaterDemand = timeseries(需求+ Demand_noise, t);WaterDemand。Name =“水需求”;WaterDemand.TimeInfo。单位=“小时”;结束
重置功能
函数= localResetFcn(中)%使用持久随机种子值来评估代理和基线%控制器在相同条件下。持续的randomSeed如果isempty (randomSeed) randomSeed = 0;结束如果比较字符串(在“重置种子”)randomSeed = 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 > = H_max h0 = 3 * randn;结束黑色=' watertankscheduling /水箱系统/初始水高度”;在= setBlockParameter(黑色,“价值”num2str (h0));结束