简体   繁体   English

写入交流函数,生成一个随机数,或一对随机数,或给定特定范围的随机数的三元组

[英]write a c function that generates one random number, or a pair of random numbers, or a triplet of random numbers given the particular ranges

i have to generate random numbers for 3 different cases. 我必须为3个不同的案例生成随机数。 i. 一世。 1 dice ii. 1个骰子ii。 a pair of dice iii. 一对骰子iii。 3 dices my questions: 1. please suggest me sm good logic to generate random numbers for all the 3 cases. 3我的问题:1。请建议我为所有3个案例生成随机数的良好逻辑。 2. does the logic change when i consider the cses of 2 dices, rather than 1? 2.当我考虑2个骰子而不是1个时,逻辑会改变吗? 3.how much of an effect does the range in which we have to genrate a random number affect the logic of the random function? 3.我们必须生成一个随机数的范围会影响随机函数的逻辑吗?

If the range is small enough, you shouldn't have problems in using the usual modulo method 如果范围足够小,则在使用通常的模数方法时应该没有问题

int GetRandomInt(int Min, int Max)
{
    return (rand()%(Max-Min+1))+Min;
}

(where Min a Max specify a closed interval, [ Min , Max ]) (其中Min a Max指定一个封闭的间隔,[ MinMax ])

and calling it once for each dice roll. 并为每个骰子掷骰子调用一次。 Don't forget to call srand(time(NULL)) at the start of the application (at the start only , not each time you want to get a random number) to seed the random number generator. 不要忘记在应用程序开始srand(time(NULL))调用srand(time(NULL))在开始时,而不是每次想要获得一个随机数)来为随机数生成器播种。

If the range starts to be bigger, you may have to face two problems: 如果范围开始变大,您可能不得不面临两个问题:

First, the range of rand() obviously isn't [0, +∞), instead it's [0, RAND_MAX ], where RAND_MAX is a #define guaranteed to be at least 32767. If your range ( Max-Min ) spans over RAND_MAX , then, with this method, you'll have some numbers that will have a zero probability of being returned. 首先, rand()的范围显然不是[0,+∞],而是[0, RAND_MAX ],其中RAND_MAX#define保证至少为32767.如果你的范围( Max-Min )跨越然后,使用此方法,您将获得一些返回概率为零的RAND_MAX

This is more subtle: suppose that RAND_MAX is bigger than your range, but not that bigger, let's say that RAND_MAX==1.5*/(Max-Min) . 这是更为微妙:假设RAND_MAX比你更大的范围内,但不是做大,让我们说, RAND_MAX==1.5*/(Max-Min) In this case, the distribution of results won't be uniform: rand() returns you an integer in the range [0, RAND_MAX ] (and each integer in this range should be equiprobable), but you are taking the rest of the division with (Max-Min) . 在这种情况下,结果的分布将不一致: rand()返回一个范围为[0, RAND_MAX ]的整数(并且此范围内的每个整数应该是等概率的),但是您正在接受除法的其余部分用(Max-Min) This means that the numbers in the first half of your required range have twice the probability of being returned than the others: they can actually come from the first and the third third of the rand() range, while the second half of the required range can come only from the second third of the rand() range. 这意味着所需范围的前半部分中的数字的返回概率是其他数字的两倍:它们实际上可以来自rand()范围的第一个第三个三分之一,而所需范围的后半部分只能来自rand()范围的第二个三分之一。

What does this mean for you? 这对你意味着什么?

Probably nothing. 可能没什么。 If all you want to do is a dice-roll simulator, you can go without problems with the modulo method, since the range involved is small, and the second problem, despite being still present, it's almost irrelevant: suppose your range is 3 and MAX_RAND 32767: from 0 to 32765, 0, 1 and 2 has the same probability, but going up to 32767 0 and 1 gain one potential exit, which is almost irrelevant, since they pass from a perfect 1/3 (10922/32766=0,333...) probability for each one to a 10922/32767 for 2 (~0,33332) and 10923/32767 (~0,33335) for 0 and 1 (assuming that rand() provides a perfect distribution). 如果你想做的只是一个骰子滚动模拟器,你可以毫无问题地使用模数法,因为所涉及的范围很小,而第二个问题,尽管仍然存在,它几乎无关紧要:假设你的范围是3和MAX_RAND 32767:从0到32765,0,1和2具有相同的概率,但是上升到32767 0和1获得一个潜在的退出,这几乎是不相关的,因为它们从完美的1/3传递(10922/32766 = 0,333 ...)对于0和1(假设rand()提供完美分布),对于2(~0,33332)和10923/32767(~0,33335),每一个的概率为10922/32767。

Anyhow, to overcome such problems a quite used method is to "stretch" the rand() range over a wider range (or compressing it to a smaller range) using a method like this: 无论如何,为了克服这些问题,一个非常常用的方法是使用如下方法在更宽的范围内“拉伸” rand()范围(或将其压缩到更小的范围):

int GetRandomInt(int Min, int Max)
{
    return (int)(((double)rand())/MAX_RAND*(Max-Min))+Min;
}

based on the equivalence rand():MAX_RAND=X:(Max-Min) . 基于等价rand():MAX_RAND=X:(Max-Min) The conversion to double is necessary, otherwise the integer division between rand() and its maximum value will always yield 0 (or 1 in the rare case of rand()==MAX_RAND ); 转换为double是必要的,否则rand()和它的最大值之间的整数除法总是会产生0(或者在罕见的rand()==MAX_RAND情况下为1); it could be done in integer arithmetic performing the product first if MAX_RAND is small and the range too is not too wide, otherwise there's a high risk of overflow. 如果MAX_RAND很小且范围也不太宽,则可以在执行产品的整数运算中完成,否则存在溢出的高风险。

I suspect that, if the output range is bigger than the range of rand() , the "stretching" and the fp value truncation (due to the conversion to int) affect in some way the distribution, but just locally (eg in small ranges you may never get a certain number, but globally the distribution will look ok). 我怀疑,如果输出范围大于rand()的范围,“拉伸”和fp值截断(由于转换为int)会以某种方式影响分布,但只是局部影响(例如在小范围内)你可能永远不会得到一定的数字,但在全球范围内,分发看起来还不错)。

Notice that this method helps to overcome to a diffused limitation of the C standard library random number generator, ie the low randomness of the lower bits of the returned value - which are, incidentally, the ones you are using when you perform a modulo operation with a small output range. 请注意,此方法有助于克服C标准库随机数生成器的扩散限制,即返回值的低位的低随机性 - 顺便提一下,当您执行模运算时使用的那些输出范围小。

However, keep in mind that the C standard library RNG is a simple one, that strives to comply with "easy" statistical rules, and as such is easily predictable; 但是,请记住,C标准库RNG是一个简单的,它努力遵守“简单”的统计规则,因此很容易预测; it shouldn't be used when "serious" random numbers are required (eg cryptography). 当需要“严重”随机数时(例如加密),不应使用它。 For such needs there are dedicated RNG libraries (eg the RNG part of the GNU Scientific Library), or, if you need really random stuff, there are several real random number services (one of the most famous is this ), which do not use mathematical pseudo-RNG, but take their numbers from real random sources (eg radioactive decay). 对于这样的需求,有专门的RNG库(例如GNU科学库的RNG部分 ),或者,如果你需要真正随机的东西,有几个真正的随机数服务(其中最着名的是这个 ),它们不使用数学伪RNG,但从真实的随机源(例如放射性衰变)中获取它们的数字。

Yea, like DarkDust said, this sounds like homework, so, to answer your questions with that in mind, I'd say: 是的,就像DarkDust说的那样,这听起来像是家庭作业,所以,为了回答你的问题,我会说:

--> No, the logic doesnt not change, no matter how many dices you include.

--> Easiest way to do this would be, just make a function that give you ONE
    random function, and depending on how many dices you have, call it that
    many times. 

--> You can instead include for loop in the function and add the values into 
    array and return the array.

This way, you can generate random number for 100 dices too. 这样,您也可以生成100个骰子的随机数。

Since this sounds like homework I'm just going to give hints which should be "good enough" for you (a pro would do it slightly differently): use the random() function and the % (modulo) operator. 因为这听起来像是家庭作业,所以我只是给你一些“足够好”的提示(专业人员会稍微不同):使用random()函数和% (modulo)运算符。 Modulo is the "reminder" after a division. 模数是分裂后的“提醒”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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