Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在随机选择中添加权重曲线_C#_Random_Curve - Fatal编程技术网

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

C# 如何在随机选择中添加权重曲线,c#,random,curve,C#,Random,Curve,我想要一个函数,它返回2个给定值之间的随机数。问题是,我希望它总是“偏好”较低的值而不是较高的值,以某种“曲线”的形式上升 所以,假设我给它100和1000,它可以给我这两个值之间的任何数字。。。然而,它会给我100到200之间的值,远远超过你期望的11.11%,相反,它可能会在30-40%的时间内给出这些值,而最高值可能只在2-4%的时间内给出。关于如何最好地解决这个问题,有什么想法吗 语言是C语言,但可能没那么重要。我建议您使用自己的自定义方式实现随机数生成器。例如,编写一个包装器类,它将创

我想要一个函数,它返回2个给定值之间的随机数。问题是,我希望它总是“偏好”较低的值而不是较高的值,以某种“曲线”的形式上升

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


语言是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);
}