[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
- [Algorithm]随机抖动整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 拆分整数
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 整数拆分
- 随机拆分红包
- [Algorithm]随机发牌
- 整数按和拆分
- 怎么实现类似"今日头条"app
- 35. Search Insert Position
- 36. Valid Sudoku
- 37. Sudoku Solver
- 38. Count and Say
- [Algorithm]随机抖动整数拆分
- 爬虫配置必备:JQuery|querySelector|Cheerio DOM节点选择干货集
- 源码编译Asterisk系统环境要求
- 九度OJ-1176-
- 九度OJ-1201-二叉排序树
- fetch_array()与fetch_assoc()的用法
- ssh学习整理笔记
- 将博客搬至CSDN
- 大网站常用清除float浮动的方法