/**
* 将数值随机分成N份,数字较均匀,采用先算平均值,再在平均值基础上增减
* @param num 基数
* @param n 份数
* @param scale 波动范围
* @return
*/
public static int[] randDivide(int num, int n, int scale){
if(n < 1){
n = 1;
}
int[] data = new int[n];
if(num <= n){
Arrays.fill(data, 1);
return data;
}
//先平均分配
int avg = num/n;
Arrays.fill(data, avg);
//不能整除的情况
int last = num - avg*(n-1);
data[n-1] = last;
//波动范围,不超过平均数
if(scale < 1 || scale > avg){
scale = avg;
}
//红包算法
Random random = new Random();
for(int i = 0; i < n; ++i){
int add = random.nextInt(scale);
data[i] = data[i] - add;
int idx = (i+1)%n;
data[idx] = data[idx] + add;
}
return data;
}
数字波动较大
/**
* 将数值随机分成N份,数字变化较大,采用平均值倍数波动
* @param num 基数
* @param n 份数
* @param times 波动倍率
* @param used 倍率波动使用次数
* @return
*/
public static int[] randDivide1(int num, int n, int times, int used){
if(n < 1){
n = 1;
}
int[] data = new int[n];
//不够分配直接返回
if(num <= n){
Arrays.fill(data, 1);
return data;
}
Random random = new Random();
for(int i = 0; i < n; ++i){
//剩余个数
int left = n-i;
//限制大倍率使用次数
if(i >= used){
times = 2;
}
//大倍率自动衰减
if(times > left){
times = left;
}
//平均值波动倍数
int avg = num/left;
int max = avg * times;
int min = avg / times;
//最大值不能超过,保证剩下的数据够分配
if(max > num - left){
max = num - left;
}
int range = max - min;
int randed;
if(range < 1){
randed = min;
}else{
randed = max - random.nextInt(range);
}
data[i] = randed;
num -= randed;
}
//打乱顺序
for(int i=0; i<n; ++i){
int idx = random.nextInt(n);
if(i == idx){
continue;
}
int temp = data[i];
data[i] = data[idx];
data[idx] = temp;
}
return data;
}