繁体   English   中英

Java中具有固定平均值的随机整数数组

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM