简体   繁体   中英

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.

I am able to find the array of random integers which the sum of them is 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.

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. since n can only take integer values it is not possible.

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. 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/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.

To let us know if the algorithm went well, we need to check isDone variable at the end.

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.

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. 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. 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

there are many answers to this question but lets say we want our random number to be 10 max (which we can change). I guess this would give a satisfactory answer.

import java.util.Random;

import java.util.ArrayList;

public class 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);
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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