【问题标题】:Array of random integers with fixed average in javajava中具有固定平均值的随机整数数组
【发布时间】:2015-07-06 14:23:42
【问题描述】:

我需要创建一个随机整数数组,它们的总和为 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 的随机数。

【问题讨论】:

  • 我不明白你在找什么,请强调你的问题
  • 有随机数范围吗?他们都应该是积极的吗?是否包括零?
  • @RoeyGolzarpoor 抱歉,如果问题解释得不够清楚。哪一部分没看懂?简而言之,我需要生成随机数,它们的总和为 1000 000,它们的平均值(它们的总和除以它们的数量)为 3。
  • @Bohemian,他们应该都是积极的。
  • 如果总和是 1000000,并且平均值必须是 3,那么您的数组必须有 333333 个元素(不精确,但尽可能接近)。

标签: java arrays algorithm random


【解决方案1】:

这在数学上是不可能的:

您正在寻找 n 个值,其总和为 1000000,它们的平均值为 3,即 1000000/n。因为 n 只能取整数值,所以这是不可能的。

【讨论】:

  • 如果我们认为 n 等于 333333,并且除了其中一个是 4 之外,它们都是 3,那么 sum 将是 1000000。 int a = 1000000 / n 在 java 中是 3。
  • 但他们的实际平均值是 3.000003000003。
【解决方案2】:

如果它们被限制为平均值和随机,则它们必须被限制在一个值范围内。 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 的余数为 1/3)时,平均值在数学上是完全 3 是不可能的,但是此代码得到非常接近:

1000000/333334 => 2.999994

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      正如 Göker Gümüş 所说,在数学上不可能让平均值正好是 3,而总和是一百万。

      平均值 = 总和 / 元素数。 这意味着元素数=总和/平均值。

      在这种情况下,它需要 1000000 / 3 = 333333.(3) 个元素。因为你不能有三分之一的元素值为 3 这意味着你的平均值或你的总和需要稍微偏离你的目标才能匹配。 不太显着的差异肯定是平均值,因为它只需要百万分之一单位,即 3.000001 让您能够拥有 333333 个元素的总和为 1000000

      【讨论】:

        【解决方案5】:

        我认为您需要编写一个简单的平均函数,例如:

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

        【讨论】:

        • 您能否在您的答案中添加一个关于其工​​作原理的解释?
        • 是的,每次我们向数组中添加一个新数字时,我们检查平均值是否可以除以 3,如果不是,我们退出 while 循环
        • 将其添加到您的答案中。请更好地解释它。
        【解决方案6】:

        这个问题有很多答案,但假设我们希望我们的随机数最大为 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);
        }
        

        }

        【讨论】:

          猜你喜欢
          • 2014-11-03
          • 2013-03-07
          • 2017-01-23
          • 2013-09-25
          • 1970-01-01
          • 1970-01-01
          • 2011-08-23
          • 1970-01-01
          相关资源
          最近更新 更多