一、生成总和一定随机数列
总和为sum,数列长度为count
这个比较简单,先生成count-1个随机在[0,Sum+1)之间的整数列,然后将数列排序,数列头部和尾部分别添加0和sum,最后取前一项减去后一项作为随机数列的值即可。例如:
生成总和为10,数量为3的随机数列,先生成在[0,11)之间生成2个数如:8,2,排序后为2,8,最后头部插0尾部插10,成为0,2,8,10,取两项差为值得到结果:2,6,2。
public static int[] CreatNums(int sum, int count)
{
Random random = new Random();
List<int> result = new List<int>();
result.Add(0);
for (int i = 0; i < count - 1; i++)
{
result.Add(random.Next(0, sum+1));
}
result.Add(sum);
//正负数都要的话,不排序就行
result.Sort();
for (int i = 0; i < result.Count - 1; i++)
{
result[i] = result[i + 1] - result[i];
}
result.RemoveAt(result.Count - 1);
return result.ToArray();
}
二、总和一定随机数列,但限制每个数的最大值
跟上文一样,但是由于最大值限制,每次生成随机数时就不能简单在[0,max]之间生成了。如果生成小了,会导致为了保证总和一定,最后一个数会超过最大值,因此需要对生成上下限进行限定,代码如下:
public static int[] CreatNums(int sum, int count, int max)
{
int[] res = new int[count];
for (int i = 0; i < count - 1; i++)
{
int floor = (sum - max * (count - i - 1));
if (floor < 0) { floor = 0; }
int ceiling = sum < max ? sum : max;
int v = Random.Range(floor, ceiling + 1);
res[i] = v;
sum -= v;
}
res[^1] = sum;
return res;
}
为了保证输入的正确性,我们需要在计算之前就判断参数是否可行,因此扩展后代码如下:
public static int[] CreatNums(int sum, int count, int max)
{
//判断是否可能
if (count * max < sum)
{
max = (int)Mathf.Ceil((float)sum / count);
}
int[] res = new int[count];
for (int i = 0; i < count - 1; i++)
{
int floor = (sum - max * (count - i - 1));
if (floor < 0) { floor = 0; }
int ceiling = sum < max ? sum : max;
int v = Random.Range(floor, ceiling + 1);
res[i] = v;
sum -= v;
}
res[^1] = sum;
return res;
}
(Random是unity中API的,如需使用System的Random话修改一下就行了)
如有错误,欢迎指出~
5万+






