我想要一个在两个给定值之间返回一个随机数的函数。问题是,我希望它始终"更喜欢"较高值的较低值,以某种曲线"上升。
所以,比方说我给它数字100和1000,它可以给我这两个值之间的任何数字......但是它会给我100到200远远超过你期望它的11.11%,相反它可能会在30-40%的时间内给出这些值,而最高值可能只有2-4%的时间给出。关于如何最好地解决这个问题的任何想法?
语言是C#,但可能并不重要。
答案 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等于1
,2
或3
的可能性是10
,11
,{ {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