[Algorithm]随机抖动整数拆分

来源:互联网 发布:vscode 代码片段 编辑:程序博客网 时间:2024/05/17 06:27

测试效果:
当number=101、size=6、wave=3时,可得到如下效果:

  • 17、19、16、18、13、18
  • 18、15、18、14、19、17

可看到生成的随机数在16上下浮动,幅度不超过3,且总和为101。

源码如下:

using System.Collections.Generic;using UnityEngine;using Random = UnityEngine.Random;namespace XM.Tool{    public class MathCalc    {        /// <summary>        /// 随机抖动整数拆分        /// </summary>        /// <param name="number">需要分割的整数</param>        /// <param name="size">份数</param>        /// <param name="wave">抖动半径</param>        /// <returns></returns>        public static int[] RandomSegmentation(int number, int size, int wave)        {            int midNumber = number / size - wave;//抖动分界线            //check            if (midNumber < 0)            {                return null;            }            int wavex2 = wave * 2;            int[] numbers = new int[size];            int valueCnt = number % size + size * wave;//需要随机分配的值            int tmpRand;            int tmpMin;            int tmpMax;            int tmpDelta;            for (int i = 0; i < size; i++)            {                //随机一个值                tmpRand = Random.Range(0, wavex2 + 1);                numbers[i] = tmpRand;                //总量减少                valueCnt -= tmpRand;            }            //分配剩余总量            if (valueCnt != 0)            {                if (valueCnt > 0)                {//分配剩余总量                    //需要增加的值的范围                    tmpMin = 0;                    tmpMax = wavex2 - 1;                    //增量                    tmpDelta = 1;                }                else                {//分配多了,需要减少                    //需要减少的值的范围                    tmpMin = 1;                    tmpMax = wavex2;                    //增量                    tmpDelta = -1;                }                //递归随机分配                FindNumberToRandomSet(numbers, tmpMin, tmpMax, ref valueCnt, tmpDelta);            }            if (midNumber != 0)            {                for (int i = 0; i < size; i++)                {                    numbers[i] += midNumber;                }            }            return numbers;        }        /// <summary>        /// 用于随机填充数组        /// </summary>        /// <param name="numbers">需要填充的数组</param>        /// <param name="min">需要填充的最小值</param>        /// <param name="max">需要填充的最大值</param>        /// <param name="valueCnt">可用填充值</param>        /// <param name="delta">填充步长,1或-1</param>        /// <param name="useIndexLst">不填</param>        /// <returns></returns>        protected static bool FindNumberToRandomSet(int[] numbers, int min, int max, ref int valueCnt, int delta, List<int> useIndexLst = null/*don`t need set*/)        {            //当可用值为0时,即分配完成,结束递归            if (valueCnt == 0)            {//over                return true;            }            if (useIndexLst == null)            {//init                useIndexLst = new List<int>();                //获取符合要求的元素下标                for (int i = 0; i < numbers.Length; i++)                {                    if (numbers[i] >= min && numbers[i] <= max)                    {                        useIndexLst.Add(i);                    }                }            }            Debug.Assert(useIndexLst.Count != 0, "useIndexLst.Count is 0 !!!!!!");            int randUseIndex = Random.Range(0, useIndexLst.Count);//随机一个需要修改的元素下标            int index = useIndexLst[randUseIndex];//得到下标            useIndexLst.RemoveAt(randUseIndex);//移除下标            //修改值            numbers[index] += delta;            //总量减少            valueCnt -= delta;            if (numbers[index] >= min && numbers[index] <= max)            {//判断该元素是否可以继续修改,可以的话将下标存入列表                useIndexLst.Add(index);            }            //递归            return FindNumberToRandomSet(numbers, min, max, ref valueCnt, delta, useIndexLst);        }    }}

如果有什么更好的整数拆分算法,望留言。

这里写图片描述

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 快两岁的宝宝不爱吃饭怎么办 宝宝断奶后不愿意喝奶粉怎么办 宝宝断奶了不愿意喝奶怎么办? 宝宝断奶不愿意喝奶粉怎么办 宝宝断奶不愿意喝牛奶怎么办? 四个月宝宝断奶不吃奶粉怎么办 2岁不开口说话怎么办 八个月宝宝断奶不吃奶粉怎么办 宝宝断奶不喝奶粉怎么办 周岁 给娘家东西婆家看见怎么办 自己娘家妈总说婆家人坏话怎么办 娘家婆家老公都没有依靠怎么办? 2岁宝宝断奶粉怎么办 2岁宝宝夜奶频繁怎么办 宝宝15个月还在吃夜奶怎么办 宝宝两岁四个月还吃母乳怎么办 宝宝睡前老是找奶吃怎么办 宝宝戒奶晚上哭怎么办 宝宝戒奶半夜哭怎么办 吸习惯母乳不吸奶嘴怎么办 八个月宝宝奶睡怎么办 宝宝要吸着奶睡怎么办 戒母乳胸胀的疼怎么办 断奶孩子晚上哭的厉害怎么办 喜欢咬指甲的人怎么办? 成年了还咬指甲怎么办 戒奶乳房有硬块怎么办 戒奶七天有硬块怎么办 两岁宝宝喘气粗怎么办 两岁宝宝断不了奶怎么办 两岁宝宝不愿意喝奶粉怎么办 吃母乳不愿意吃奶粉怎么办 母乳宝宝不愿意喝奶粉怎么办 宝宝断母乳不喝奶粉怎么办 9个月宝宝不会爬怎么办 孩子五年级学习成绩差该怎么办 孩子临近中考学习成绩很差该怎么办 初中生成绩不好家长该怎么办 成绩差该怎么办贴吧 宝宝只会匍匐爬怎么办 一年级的孩子数学不好怎么办