[英]Array of random integers with fixed average in java
我需要创建一个随机整数数组,它们的总和是1000000,这些数字的平均值是3。该数组中的数字可以重复,并且数组的长度可以是任何数字。
我能够找到随机整数的数组,它们的总和是1000000。
ArrayList<Integer> array = new ArrayList<Integer>();
int a = 1000000;
Random rn = new Random();
while (a >= 1)
{
int answer = rn.nextInt(a) + 1;
array.add(answer);
a -= answer;
}
但是,我不知道如何找到平均数为3的随机数。
这在数学上是不可能的:
您正在寻找n个值,其总和为1000000,它们的平均值为3,即1000000 / n。 因为n只能取整数值,所以这是不可能的。
如果将它们限制为平均值和随机数,则必须将它们限制为一个值范围。 范围为1到5(中位数为3)似乎是合理的。 同样合理的是平滑的分布,它给出已知的总计和平均值。
这个简单的代码将完成所有操作:
List<Integer> numbers = new ArrayList<>(333334); // 1000000 / 3
// one instance of 5 must be omitted to make total exactly 1000000
numbers.addAll(Arrays.asList(1, 2, 3, 4));
for (int i = 0; i < 333330; i++)
numbers.add((i % 5) + 1); // add 1,2,3,4,5,1,2,3,4,5,etc
Collections.shuffle(numbers);
// Check sum is correct
numbers.stream().reduce((a,b) -> a + b).ifPresent(System.out::println);
输出:
1000000
请注意,当总数为1000000
时,从数学1000000/3
,平均值不可能精确为 3
(因为1000000/3
的余数为1/3
),但是此代码非常接近:
1000000/333334 => 2.999994
我将遍历列表两次,如果将这两个位置的整数相加并除以2 == 3,则返回,否则,增加整数。
我认为您需要编写一个简单的平均函数,例如:
public double average(ArrayList<Integer> array){
long sum = 0;
int count = 0;
for (Integer item : array){
sum += item;
count++;
}
return sum/count;
}
然后在您的代码中使用它,例如:
ArrayList<Integer> array = new ArrayList<Integer>();
int a = 1000000;
Random rn = new Random();
boolean isDone = true;
while (a >= 1)
{
int answer = rn.nextInt(a) + 1;
array.add(answer);
a -= answer;
if (average(array) % 3 != 0){
isDone = false;
break;
}
}
这个想法是,每次我们向数组添加一个新数字时,我们都会检查平均值是否可以除以3,否则,我们会退出while循环。
为了让我们知道算法是否运行良好,我们需要在最后检查isDone
变量。
更有效的方法是:
ArrayList<Integer> array = new ArrayList<Integer>();
int a = 1000000;
Random rn = new Random();
boolean isDone = true;
long sum = 0;
while (a >= 1)
{
int answer = rn.nextInt(a) + 1;
array.add(answer);
a -= answer;
sum += answer;
if ((sum/array.size()) % 3 != 0){
isDone = false;
break;
}
}
正如GökerGümüş所说,在数学上不可能使平均值精确为3,而总和为100万。
平均值=总和/元素数。 这意味着元素数=总和/平均值。
在这种情况下,它将需要1000000/3 = 333333.(3)个元素。 由于您不能拥有值为3的元素的三分之一,这意味着您的平均值或总和将需要稍微偏离目标才能与之匹配。 不太明显需要的差异肯定是平均值,因为它只需要一个单位的百万分之一,即3.000001,您就能使333333个元素总计为1000000
这个问题有很多答案,但是可以说我们希望随机数最大为10(可以更改)。 我想这会给人满意的答案。
import java.util.Random;
导入java.util.ArrayList;
公共类RandomSumAverage {
public static void main(String[] args) {
Random random = new Random();
ArrayList<Integer> arr = new ArrayList<Integer>();
double sum = 0;
double avg = 0;
int k = 1;
while (sum < 1000000) {
avg = sum / k;
if (avg < 3) {
int element = random.nextInt(10)+1;
sum += element;
arr.add(element);
k++;
} else {
int element = random.nextInt(3)+1;
sum += element;
arr.add(element);
k++;
}
}
System.out.println(arr);
System.out.println(sum);
System.out.println(avg);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.