生成总和一定的随机整数列,总和为固定值,并且限制每个数的最大值

一、生成总和一定随机数列

 总和为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话修改一下就行了)

如有错误,欢迎指出~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值