1.代码
using System;
using System.Collections.Generic;
using Unity.MLAgents.Inference.Utils;
using Random = System.Random;
namespace Unity.MLAgents
{
/// <summary>
/// Takes a list of floats that encode a sampling distribution and returns the sampling function.
/// </summary>
internal static class SamplerFactory
{
/// <summary>
/// 创建一个产生指定范围内均匀分布随机数的采样函数。
/// </summary>
public static Func<float> CreateUniformSampler(float min, float max, int seed)
{
Random distr = new Random(seed);
return () => min + (float)distr.NextDouble() * (max - min);
}
/// <summary>
/// 创建一个产生指定均值和标准差的高斯分布随机数的采样函数。
/// </summary>
public static Func<float> CreateGaussianSampler(float mean, float stddev, int seed)
{
RandomNormal distr = new RandomNormal(seed, mean, stddev);
return () => (float)distr.NextDouble();
}
/// <summary>
/// 创建一个从多个区间均匀分布中进行采样的采样函数。
/// </summary>
public static Func<float> CreateMultiRangeUniformSampler(IList<float> intervals, int seed)
{
// 随机数生成器
Random distr = new Random(seed);
// 将要用于归一化区间函数的总和
float sumIntervalSizes = 0;
// 区间数量
int numIntervals = (intervals.Count / 2);
// 存储区间长度的数组
float[] intervalSizes = new float[numIntervals];
// 存储均匀分布函数的列表
IList<Func<float>> intervalFuncs = new Func<float>[numIntervals];
// 收集所有区间并将它们存储为均匀分布函数
// 收集所有区间的长度
for (int i = 0; i < numIntervals; i++)
{
var min = intervals[2 * i];
var max = intervals[2 * i + 1];
var intervalSize = max - min;
sumIntervalSizes += intervalSize;
intervalSizes[i] = intervalSize;
intervalFuncs[i] = () => min + (float)distr.NextDouble() * intervalSize;
}
// 归一化区间长度
for (int i = 0; i < numIntervals; i++)
{
intervalSizes[i] = intervalSizes[i] / sumIntervalSizes;
}
// 为区间构建累积分布函数
for (int i = 1; i < numIntervals; i++)
{
intervalSizes[i] += intervalSizes[i - 1];
}
Multinomial intervalDistr = new Multinomial(seed + 1);
float MultiRange()
{
int sampledInterval = intervalDistr.Sample(intervalSizes);
return intervalFuncs[sampledInterval].Invoke();
}
return MultiRange;
}
}
}
这段代码定义了一个静态类 SamplerFactory
,其中包含了三个静态方法,分别用于生成不同类型的采样函数。具体来说:
①CreateUniformSampler(float min, float max, int seed)
方法用于生成一个均匀分布采样函数,其输入参数为采样区间的下界 min
,上界 max
,以及随机数生成器的种子 seed
。该方法返回一个委托,调用该委托即可获得一个采样值,其值域在区间 [min, max]
内均匀分布。
②CreateGaussianSampler(float mean, float stddev, int seed)
方法用于生成一个正态分布采样函数,其输入参数为正态分布的均值 mean
,标准差 stddev
,以及随机数生成器的种子 seed
。该方法返回一个委托,调用该委托即可获得一个采样值,其值域服从以 mean
为均值、stddev
为标准差的正态分布。
③CreateMultiRangeUniformSampler(IList<float> intervals, int seed)
方法用于生成一个多区间均匀分布采样函数,其输入参数为采样区间的下界和上界组成的列表 intervals
,以及随机数生成器的种子 seed
。该方法返回一个委托,调用该委托即可获得一个采样值,其值域在多个区间内均匀分布。例如,当 intervals
为 [1,2,4,5]
时,该采样函数会在区间 [1,2]
和 [4,5]
之间等概率地采样一个值。
这些采样函数在强化学习等领域中非常常用,用于生成随机的行为或状态,以增加智能体的探索能力。