【问题标题】:Generate random values with fixed sum in C++ [closed]在 C++ 中生成具有固定总和的随机值 [关闭]
【发布时间】:2014-07-25 10:26:54
【问题描述】:

我在网上看到了很多关于这个问题的答案,但是你能相信我吗?我仍然没有得到这个问题的解决方案。我有一个值数组。这个数组的大小是“n”。我也有定义的值“总和”。我想要的是生成“n”个随机值,使得它们的总和等于“总和”,最好是均匀分布的,否则(例如)第一个随机数等于“总和”,其余的等于零不是很好。我需要两种算法来完成这项任务。一个带有正整数,一个带有正浮点数。提前非常感谢!

【问题讨论】:

  • 你的意思是你希望n值的每个可能组合被选择为均匀分布?
  • 您没有得到解决方案怎么办? (如果您在问题中包含解决方案也会有所帮助。)
  • 您希望 n 值总和为 sum,但如果它们不是均匀分布的,那……有点好,但不理想?这真的是你的要求吗?
  • 约瑟夫,是的,我想这就是我的意思。关键是……假设 sum = 10 和 n = 4。好的随机值例如是 3,3,3,1。如果我有而不是 9,1,0,0 它们分布不均。我希望我现在更清楚,因为将“均匀分布”的概念应用于值并不是那么容易...
  • @Tarta 这只是你的作业吗?或者您是否遇到了一些功能?

标签: c++ random


【解决方案1】:

您可以生成 n 个具有正态分布的数字,然后将它们归一化为您的总和

【讨论】:

    【解决方案2】:

    首先生成n个随机变量。然后总结它们:randomSum。计算系数总和/随机总和。然后将所有随机变量乘以该系数。

    整数会造成问题...也舍入(可能)

    【讨论】:

    • 我忘了提..对不起..我已经编辑了问题..我还必须提供一个只有无符号整数的算法版本。
    • @Tarta 所以?这不会产生负数,不是吗?我实际上比我更喜欢这个答案
    • 是的,但系数可能不是整数。负数也可以。但不适用于整数。正如我已经写过的,很抱歉我现在才提供更多信息..
    【解决方案3】:

    您可以生成 n个由此定义的值:((Sum - sumOfGeneratedValues) / n - ( numberOfGeneatedValue)) -+X(有X最大偏差

    示例

    总和 = 100 N = 5 +- 10


    介于 100 - 0 / 5 - 0 --> 20 +-10(所以介于 10 和 30 之间)

    值1 = 17;

    兰特介于 100 - 17 / 5 - 1 ---> 21 +-10(所以介于 11 和 31 之间)

    ...等

    Deviance 会让你的随机统一 :)

    【讨论】:

      【解决方案4】:

      您有一个循环,其中迭代次数等于您想要的随机数减 1。对于第一次迭代,您会找到一个介于 0 和总和之间的随机数。然后你从总和中减去那个随机数,在下一次迭代中你得到另一个随机数,然后从子总和减去最后一次迭代中减去它

      在伪代码中可能更容易

      int sum = 10;
      int n = 5; // 5 random numbers summed to equal sum
      int subSum = sum;
      int[] randomNumbers = new int[n];
      
      for(int i = 0; i < n - 2; i++)
      {
          randomNumbers[i] = rand(0, subSum); // get random number between 0 and subSum 
          subSum -= randomNumbers[i];
      }
      
      randomNumbers[n - 1] = subSum; // leftovers go to the last random number
      

      【讨论】:

      • wth。我真的反对你使用你的宽限期来复制我的大部分答案,让它看起来像是我复制了你的答案
      • 说真的老兄?在您发布您的答案之前,我发布了我的答案?谁在抄袭? wtf
      • 你只是碰巧也用c#风格写了你的伪代码,并称之为伪代码? C++ 甚至使用不同的数组语法。不要误会我的意思,不要真的介意,但你本可以注意到这一点,以免让我看起来像模仿猫。
      • 这将导致第一个元素的平均值很大,而最后一个元素的平均值接近于零。虽然您可以通过在生成数字后打乱顺序来解决该问题。
      • nl-x,真的,我发誓在你发布答案之前我已经写了伪代码。我是一名 c# 开发人员,但据我所知,这段代码应该在 c++ 中工作
      【解决方案5】:

      我的 C++ 非常(非常非常)生锈。因此,假设您已经知道如何使用函数random(x,y) 获取xy 之间的随机数。然后这里是一些其他 c 派生语言的伪代码:

      int n = ....; // your input
      int sum = ....; // your input
      int[] answer = new int[n];
      int tmpsum = 0;
      for (int i=0; i < n; i++) {
          int exactpart = sum/n;
          int random = (exactpart/2) + random(0,exactpart);
          int[i] = tmpsum + random > sum ? sum - tmpsum : random;
          tmpsum += int[i];
      }
      int[n-1] += sum - tmpsum;
      

      【讨论】:

      • 如果我没记错的话,不能保证在所有情况下都能到达sum
      • @nispio 哎呀,写这篇文章时,我实际上删除了一些代码太早了:) ...感谢您的注意。我已经编辑了我的答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-25
      • 2018-05-24
      • 1970-01-01
      • 1970-01-01
      • 2022-06-06
      • 1970-01-01
      相关资源
      最近更新 更多