【问题标题】:Generating Random Number with Certain Rate以一定速率生成随机数
【发布时间】:2009-03-05 02:06:06
【问题描述】:

我有以下 C++ 代码试图生成 一个随机数。 idea 是我们给出了一些速率“x”和运行次数; 我们希望它会产生与 (x * number of runs times) 一样多的数字。

#include <iostream>      
#include <vector>
#include <fstream>
#include <sstream>       
#include <time.h>        
using namespace std;     


int main  () {

    // Initialize Random Seed 
    srand (time(NULL));

    string line;
    double SubsRate = 0.003;  
    double nofRuns   = 1000000;

    for (unsigned i=0; i < nofRuns ; i++) {

        int toSub = rand() % 1000 + 1;

        if (toSub == (SubsRate * 1000)) {
         cout << toSub << " Sub"  << endl; 
        }

    }
    return 0;
}

因此,如果我们使用此命令运行上述代码 K 次:

$ a=0 ; while test $a -lt 10 ; do ./MyCode | wc -l ; a=`expr $a + 1` ; done

我们预计它会在 1M 次运行中生成多达约 3000 次的数字“3”。但 一些我上面的代码如何只生成数字“3”多达 900 ~ 1000 次。

如何改进我上面的代码?

【问题讨论】:

    标签: c++ algorithm random


    【解决方案1】:

    换句话说,您正在检查结果 == 3,而不是结果是

    3 只会发生,千分之一,但

    【讨论】:

      【解决方案2】:
      • 您将期望在 1000 次中获得第 3 次,即在 1M 中获得 1000 次。
      • 您希望在 1000 次中获得第 9 次,即在 1M 中获得 1000 次。
      • 您希望在 1000 次中获得第 7 次,即在 1M 中获得 1000 次。
      • 您将期望在 1000 次中获得 3、7 或 9 中的任意一种,即 1M 中的 3000 次。

      【讨论】:

        【解决方案3】:

        我觉得你这里的数学有点不对...

        根据您那里的代码,您将统一生成 1 到 1000 之间的随机数。

        您的检查 (toSub==(SubsRate*1000)) 仅检查您生成的数字是否为 3(因为 rate*1000=3)。因此,您只会得到 3 次大约 1000 次,而不是 3000 次。

        你没有提到你的数字的范围是什么,但一般来说,如果你想使用均匀分布生成一个介于 IMIN 和 IMAX 之间的数字(每个值出现的机会相同),那么你只需写:

        int I = IMin + rand() % (IMax - IMin);
        

        在这种情况下,如果您希望每个数字每 3000 次出现一次,则必须在 1 到 3000 之间随机化一个数字。否则,您不是在谈论均匀分布。

        【讨论】:

        【解决方案4】:

        正如其他人所提到的,您的原件是在测试随机数是否等于您想要的分布的分数,而不是低于该分数。

        rand() 生成一个介于 0 和 RAND_MAX(含)之间的值。 RAND_MAX 可能非常小 - 典型值为 32767。如果使用模 1000,则有 32 个值 rand() 返回映射到从 768 到 999 的每个值,以及 33 个映射到值 0 到 767 的值. 所以这有点歪。

        您似乎已经抽出 1000 个。相反,如果您将 RAND_MAX 本身按您想要的分布比例缩放,那么您不会得到倾斜效果,也不必处理 rand() 的输出来进行比较:

        int main  () {
            srand (time(NULL));
        
            double subsRate = 0.003;  
        
            unsigned int nofRuns   = 1000000;
        
            int cutoff = (int) ( subsRate * ( (long) RAND_MAX + 1L ) );
        
            for (unsigned int i = 0; i < nofRuns ; i++) 
                if ( rand() < cutoff ) 
                    cout << " Sub "  << endl; 
        
            return 0;
        }
        

        【讨论】:

          猜你喜欢
          • 2017-03-24
          • 2016-01-06
          • 1970-01-01
          • 2017-10-01
          • 2016-01-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-18
          相关资源
          最近更新 更多