简体   繁体   English

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

[英]Array of random integers with fixed average in java

I need to create an array of random integers which a sum of them is 1000000 and an average of these numbers is 3. The numbers in the array could be duplicated and the length of the array could be any number. 我需要创建一个随机整数数组,它们的总和是1000000,这些数字的平均值是3。该数组中的数字可以重复,并且数组的长度可以是任何数字。

I am able to find the array of random integers which the sum of them is 1000000. 我能够找到随机整数的数组,它们的总和是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;
    }

However, I don't know how to find the random numbers with average of 3. 但是,我不知道如何找到平均数为3的随机数。

that's mathematically not possible: 这在数学上是不可能的:

you are looking for n values, sum of which makes 1000000, and the average of them is 3, which is 1000000/n. 您正在寻找n个值,其总和为1000000,它们的平均值为3,即1000000 / n。 since n can only take integer values it is not possible. 因为n只能取整数值,所以这是不可能的。

If they are constrained to an average and random, they must be constrained to a value range. 如果将它们限制为平均值和随机数,则必须将它们限制为一个值范围。 A range of 1 to 5 (median is 3) seems reasonable. 范围为1到5(中位数为3)似乎是合理的。 Also reasonable is a smooth distribution, which gives a known total and average. 同样合理的是平滑的分布,它给出已知的总计和平均值。

This simple code will do all that: 这个简单的代码将完成所有操作:

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);

Output: 输出:

1000000

Note that it is mathematically impossible for the average to be exactly 3 when the total is 1000000 (because 1000000/3 has a remainder of 1/3 ), however this code gets pretty close: 请注意,当总数为1000000时,从数学1000000/3 ,平均值不可能精确为 3 (因为1000000/3的余数为1/3 ),但是此代码非常接近:

1000000/333334 => 2.999994

我将遍历列表两次,如果将这两个位置的整数相加并除以2 == 3,则返回,否则,增加整数。

I think that you need to write a simple average function like: 我认为您需要编写一个简单的平均函数,例如:

public double average(ArrayList<Integer> array){

    long sum = 0;
    int count = 0;
    for (Integer item : array){
        sum += item;
        count++;
    }
    return sum/count;
}

Then use it in your code like: 然后在您的代码中使用它,例如:

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;
    }
}

The idea is each time we adding a new number to the array, we checking that the average can be divide with 3, if not, we getting out of the while loop. 这个想法是,每次我们向数组添加一个新数字时,我们都会检查平均值是否可以除以3,否则,我们会退出while循环。

To let us know if the algorithm went well, we need to check isDone variable at the end. 为了让我们知道算法是否运行良好,我们需要在最后检查isDone变量。

And the more efficient way is: 更有效的方法是:

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;
    }
}

As Göker Gümüş said it is mathematically impossible to have the average be exactly 3 and the sum be a million. 正如GökerGümüş所说,在数学上不可能使平均值精确为3,而总和为100万。

The average = sum / number of elements. 平均值=总和/元素数。 This means that number of elements = sum / average. 这意味着元素数=总和/平均值。

In this case it would need 1000000 / 3 = 333333.(3) elements. 在这种情况下,它将需要1000000/3 = 333333.(3)个元素。 Since you can't have a third of an element with value 3 it means your average or your sum will need to be slightly off your target for it to match up. 由于您不能拥有值为3的元素的三分之一,这意味着您的平均值或总和将需要稍微偏离目标才能与之匹配。 The less notable needed difference would definitely be the average as it would only need to be a millionth of a unit off, ie 3.000001 for you to be able to have 333333 elements summing to 1000000 不太明显需要的差异肯定是平均值,因为它只需要一个单位的百万分之一,即3.000001,您就能使333333个元素总计为1000000

there are many answers to this question but lets say we want our random number to be 10 max (which we can change). 这个问题有很多答案,但是可以说我们希望随机数最大为10(可以更改)。 I guess this would give a satisfactory answer. 我想这会给人满意的答案。

import java.util.Random;

import java.util.ArrayList; 导入java.util.ArrayList;

public class RandomSumAverage { 公共类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