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

时间:2015-07-06 13:44:25

标签: c# random curve

我想要一个在两个给定值之间返回一个随机数的函数。问题是,我希望它始终"更喜欢"较高值的较低值,以某种曲线"上升。

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

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

5 个答案:

答案 0 :(得分:3)

您可以对随机数进行平方,这会将数字加权到范围的底部:

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.如果你希望它更加加权到底部,你可以将数字立方体化。

答案 1 :(得分:0)

我建议您使用自己的自定义方式实现随机数生成器。例如,编写一个包装类,它将创建一个介于1到100之间的随机数,如果它介于1-40之间,它会返回100到200之间的随机数,或者等等,那么你基本上可以将自己的优先级集添加到你的数字生成。如果该值介于41 - 100之间,则会返回201 - 1000之间的数字。这是您喜欢的方式

答案 2 :(得分:0)

我想说使用y = ab ^ x创建一个指数曲线,这将在两个输入数字之间创建一条曲线,然后获得一个0到1之间的随机数,以获得沿x的标准化位置曲线的轴并返回y值。

答案 3 :(得分:0)

加权随机可能是你想要的,一个很好的想象方法是想一个重量较高的重复元素列表

var elements = new[]{1,1,2,2,3,3,10,11,12,13};
var rnd = elements[rnd.Next(0,elements.length-1)];

从上面可以看出,rnd等于123的可能性是1011,{ {1}}或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); 从指定权重的所需集合中生成加权随机数

答案 4 :(得分:0)

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

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); 这将给你50%的100 - 200和其他50%的200 - 1000