编写 ac 函数,在给定特定范围的情况下生成一个随机数、一对随机数或一组随机数

发布于 2024-09-24 18:18:26 字数 143 浏览 3 评论 0原文

我必须为 3 种不同的情况生成随机数。 我。 1 个骰子 二.一对骰子 三. 3 个骰子 我的问题: 1.请建议我为所有 3 种情况生成随机数的良好逻辑。 2.当我考虑2个骰子而不是1个骰子的cses时,逻辑会改变吗? 3.我们生成随机数的范围对随机函数的逻辑有多大影响?

i have to generate random numbers for 3 different cases.
i. 1 dice
ii. a pair of dice
iii. 3 dices
my questions:
1. please suggest me sm good logic to generate random numbers for all the 3 cases.
2. does the logic change when i consider the cses of 2 dices, rather than 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

嘿咻 2024-10-01 18:18:26

如果范围足够小,那么使用通常的取模方法应该不会有问题

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

(其中 MinMax 指定一个闭区间,[Min code>, Max])

并为每次掷骰子调用一次。不要忘记在应用程序开始时调用 srand(time(NULL))(仅在开始时调用,而不是每次您想要获取随机数时)为随机数生成器提供种子。

如果范围开始变大,你可能要面临两个问题:

首先,rand()的范围显然不是[0, +∞),而是[0, RAND_MAX],其中 RAND_MAX 是保证至少为 32767 的 #define。如果您的范围 (Max-Min) 跨越超过 RAND_MAX,那么,使用此方法,您将得到一些返回概率为零的数字。

这更微妙:假设 RAND_MAX 大于您的范围,但没有更大,假设 RAND_MAX==1.5*/(Max-Min)
在这种情况下,结果的分布不会均匀:rand() 返回 [0, RAND_MAX] 范围内的一个整数(并且该范围内的每个整数应该是等概率的),但是你用 (Max-Min) 来取除法的其余部分。这意味着所需范围前半部分的数字被返回的概率是其他数字的两倍:它们实际上可以来自 rand() 的前第三个​​三分之一 范围,而所需范围的后半部分只能来自 rand() 范围的第二个三分之一。

这对你来说意味着什么?

可能什么也没有。如果您想做的只是一个掷骰子模拟器,那么使用取模方法就不会出现任何问题,因为涉及的范围很小,而第二个问题尽管仍然存在,但几乎无关紧要:假设你的范围是 3 和 MAX_RAND 32767:从 0 到 32765,0、1 和 2 具有相同的概率,但直到 32767 0 和 1 获得一个潜在的退出,这几乎是无关的,因为它们从每个 1 的完美 1/3 (10922/32766=0,333...) 概率转变为 2 (~0,33332) 的 10922/32767 和 0 和 1 的 10923/32767 (~0,33335) (假设rand()提供完美分布)。

无论如何,为了克服这些问题,一个常用的方法是使用如下方法将 rand() 范围“拉伸”到更宽的范围(或将其压缩到更小的范围):

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

基于等价rand():MAX_RAND=X:(最大-最小值)。转换为 double 是必要的,否则 rand() 与其最大值之间的整数除法将始终产生 0(或者在 rand()==MAX_RAND 的罕见情况下产生 1) >);如果 MAX_RAND 很小并且范围也不是太宽,可以用整数运算来先执行乘积,否则溢出的风险很高。

我怀疑,如果输出范围大于 rand() 的范围,“拉伸”和 fp 值截断(由于转换为 int)会以某种方式影响分布,但是仅在本地(例如,在小范围内,您可能永远不会得到某个数字,但在全球范围内,分布看起来不错)。

请注意,此方法有助于克服 C 标准库随机数生成器的分散限制,即返回值的低位随机性较低 - 顺便说一句,这些位是您在执行模运算时使用的那些输出范围小。

然而,请记住,C 标准库 RNG 是一个简单的库,它努力遵守“简单”的统计规则,因此很容易预测;当需要“严重”随机数时(例如密码学),不应该使用它。对于此类需求,有专用的 RNG 库(例如 RNG 部分GNU 科学图书馆的 ),或者,如果您需要真正随机的东西,有几种真正随机数服务(最著名的之一是this),不使用数学伪 RNG,而是从真正的随机源(例如放射性衰变)。

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])

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.

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.

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

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

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:

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

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 (e.g. in small ranges you may never get a certain number, but globally the distribution will look ok).

Notice that this method helps to overcome to a diffused limitation of the C standard library random number generator, i.e. 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.

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; it shouldn't be used when "serious" random numbers are required (e.g. cryptography). For such needs there are dedicated RNG libraries (e.g. 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 (e.g. radioactive decay).

唠甜嗑 2024-10-01 18:18:26

是的,就像 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.

这样,你也可以为 100 个骰子生成随机数。

Yea, like DarkDust said, this sounds like homework, so, to answer your questions with that in mind, I'd say:

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

羁拥 2024-10-01 18:18:26

因为这听起来像是家庭作业,所以我只是给出一些对你来说应该“足够好”的提示(专业人士的做法略有不同):使用 random() 函数和 %(模)运算符。 Modulo 是除法之后的“提醒”。

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. Modulo is the "reminder" after a division.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文