如何将加权曲线添加到随机选择中

How to add weighting curve to random selection

我想要一个 returns 两个给定值之间的随机数的函数。问题是,我希望它总是 "prefer" 较低的值超过较高的值,以某种 "curve".

的方式上升

所以,假设我给它数字 100 和 1000,它可以给我这两个值之间的任何数字...但是它给我的 100 到 200 远远超过你期望的 11.11%,相反,它可能会在大约 30-40% 的时间内给出这些值,而最高值可能只在 2-4% 的时间内给出。关于如何最好地解决这个问题有什么想法吗?

语言是 C#,但可能并不重要。

那么我建议您使用自己的自定义方式来实现随机数生成器。例如,编写一个包装器 class,它将创建一个 1-100 之间的随机数,如果它落在 1-40 之间,它会返回 100-200 之间的随机数,依此类推,因此您基本上添加了自己的集合优先考虑您的号码生成。如果该值介于 41 - 100 之间,它将返回一个介于 201 - 1000 之间的数字。你喜欢哪种方式

我会说使用 y=ab^x 创建指数曲线,这将在两个输入数字之间创建一条您想要的曲线,然后获取 0 和 1 之间的随机数以获得标准化位置曲线的 x 轴和 return 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,23的几率是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;
};

所以上面的列表可以用

生成
var input = new[]{1,2,3,10,11,12,13};
var weight = new[]{0.2,0.2,0.2,0.1,0.1,0.1,0.1};
var weightedList = GenerateWeighedList(input,weight);

weightedList 然后可用于从指定权重的所需集合中生成加权随机数

我会分两步完成。第一步 - 是确定您的号码是否应该降低。第二步return一个对应范围内的随机数

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);
}

并像这样使用它:int num = RandomWeighted(100, 1000, 200, 50); 这会给你 100 - 200 在 50% 的时间和 200 - 1000 在其他 50%