C# 如何在随机选择中添加权重曲线
我想要一个函数,它返回2个给定值之间的随机数。问题是,我希望它总是“偏好”较低的值而不是较高的值,以某种“曲线”的形式上升 所以,假设我给它100和1000,它可以给我这两个值之间的任何数字。。。然而,它会给我100到200之间的值,远远超过你期望的11.11%,相反,它可能会在30-40%的时间内给出这些值,而最高值可能只在2-4%的时间内给出。关于如何最好地解决这个问题,有什么想法吗C# 如何在随机选择中添加权重曲线,c#,random,curve,C#,Random,Curve,我想要一个函数,它返回2个给定值之间的随机数。问题是,我希望它总是“偏好”较低的值而不是较高的值,以某种“曲线”的形式上升 所以,假设我给它100和1000,它可以给我这两个值之间的任何数字。。。然而,它会给我100到200之间的值,远远超过你期望的11.11%,相反,它可能会在30-40%的时间内给出这些值,而最高值可能只在2-4%的时间内给出。关于如何最好地解决这个问题,有什么想法吗 语言是C语言,但可能没那么重要。我建议您使用自己的自定义方式实现随机数生成器。例如,编写一个包装器类,它将创
语言是C语言,但可能没那么重要。我建议您使用自己的自定义方式实现随机数生成器。例如,编写一个包装器类,它将创建一个介于1-100之间的随机数,如果它介于1-40之间,它将返回介于100-200之间的随机数,依此类推,这样,您就可以将自己的优先级设置添加到数字生成中。如果值在41-100之间,它将返回一个介于201-1000之间的数字。我想说的是,使用y=ab^x创建一条指数曲线,这将在两个输入数字之间创建一条曲线,然后获得一个介于0和1之间的随机数,以获得沿曲线x轴的标准化位置并返回y值。您可以将随机数平方,这会将数字加权到范围的底部:
public double GetWeightedRandom(int min, int max)
{
Random random = new Random();
double randomZeroToOne = random.NextDouble();
double weightedRandom = randomZeroToOne * randomZeroToOne * (max - min) + min;
return weightedRandom;
}
在我对100到1000的测试中,平均值是400而不是550。然后,如果您希望数字的权重更大,则可以将其分成立方体。加权随机数可能就是您想要的,在这种情况下,一个很好的想象方式是,想象一个具有重复元素的列表,其中权重更高
var elements = new[]{1,1,2,2,3,3,10,11,12,13};
var rnd = elements[rnd.Next(0,elements.length-1)];
从上面可以看出,rnd等于1
、2
或3
的几率是10
、11
、12
或13
的两倍
您可以使用函数生成相同的列表,该函数采用平面列表和相关权重:
public List<int> GenerateWeighedList(int[] list, float[] weight) {
var weighedList = new List<int>();
// Loop over weights
for (var i = 0; i < weight.Length; i++) {
var multiples = weight[i] * 100;
// Loop over the list of items
for (var j = 0; j < multiples; j++) {
weighedList.push(list[i]);
}
}
return weighedList;
};
weightedList
然后可用于从指定权重的所需集合生成加权随机数我将分两步完成。第一步是决定你的电话号码是否应该降低。第二步是返回相应范围内的随机数
public int RandomWeighted(int min, int max, int cap, int percent)
{
Random rand = new Random();
bool isInCap = rand.Next(0, 101) < percent;
return isInCap? rand.Next(min, cap) : rand.Next(cap, max);
}
公共整数随机加权(整数最小值、整数最大值、整数上限、整数百分比)
{
Random rand=新的Random();
bool-isInCap=rand.Next(0,101)<百分比;
返回isInCap?下一个随机数(最小,上限):下一个随机数(上限,最大);
}
并像这样使用:intnum=RandomWeighted(100100020050)代码>
这将在50%的时间内为您提供100-200次,在其他50%的时间内为您提供200-1000次。randomZeroToOne*randomZeroToOne
部分也可以替换为Math.Pow(randomZeroToOne,x)
,以实现更精细的控制。使用大于1的x
来支持较小的值。x
越大,值越小。
public int RandomWeighted(int min, int max, int cap, int percent)
{
Random rand = new Random();
bool isInCap = rand.Next(0, 101) < percent;
return isInCap? rand.Next(min, cap) : rand.Next(cap, max);
}