【问题标题】:Rand generating same numbers兰德产生相同的数字
【发布时间】:2012-06-28 14:05:25
【问题描述】:

我制作的小游戏有问题。

#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
int span = 100;
srand(time(0));
int TheNumber = static_cast<double> (rand()) /RAND_MAX * (span -1) +1;
cout << "You need to guess the number between 1 and " << span << endl;
int mynumber;
int numberofAttempts = 0;

do {
    cout << ++numberofAttempts <<" Attempt: ";
    cin >> mynumber;
    if (mynumber > TheNumber)
        cout <<"Lower!" << endl;
    else if (mynumber < TheNumber)
        cout <<"Higher!" << endl;
} while (mynumber != TheNumber);

cout << "SUCESS!!!" << endl;
return 0;
}

游戏应该生成一个介于 0-100 之间的随机数,你应该猜到它。运行此代码 15-20 次后,相同的数字甚至生成了 8 次(在我的例子中是数字 2)。

我知道没有绝对随机数并且它使用一些数学公式或其他东西来获得一个。我知道使用srand(time(0)) 使它依赖于当前时间。但是我如何让它“更”随机,因为我不希望发生我上面提到的事情。

我第一次运行它的结果是 11,再次运行后(猜对了数字后),它仍然是 11,即使时间改变了。

【问题讨论】:

  • 我刚刚更新了最后一部分,经过猜测(肯定过了几秒钟),数字还是一样。
  • 将TheNumber的声明改为int TheNumber = rand() % 100 + 1;
  • @jrok,不好的建议。众所周知,rand() 的低位不是随机的。
  • 我很确定它会比他现在拥有的要好得多。 rand() 的问题可能超出了当前 Q 和 OP 的经验范围,你不觉得吗?
  • @FredOverflow:这就是罪魁祸首!

标签: c++ random


【解决方案1】:

[ADDITION1]

如果您确实希望研究更好的随机数生成,那么这是一个很好的开始算法:

http://en.wikipedia.org/wiki/Mersenne_twister

请记住,任何“计算机生成”(即数学生成)随机数都只是伪随机数。伪随机意味着虽然算法的输出看起来具有正态分布,但如果知道输入种子,它们是真正确定的。真正的随机数是完全不确定的。

[原创] 只需尝试以下行之一:

rand() % (span + 1);  // This will give 0 - 100
rand() % span;        // this will give 0 - 99
rand() % span + 1;    // This will give 1 - 100

代替:

(rand()) /RAND_MAX * (span -1) +1

另外,不要将结果转换为 double,然后放入 int。

也看这里:

http://www.cplusplus.com/reference/clibrary/cstdlib/rand/

回应评论!!! 如果你使用:

rand() / (span + 1);

那么为了获得 0 到 100 之间的值,rand 的输出值确实必须在 0 到 (100 * 100) 之间,并且必须保证这种性质。这是因为简单的划分。当 rand() 产生 101 - 201 时,值 1 基本上会弹出,当 rand() 输出值 202 - 302 时,2 将从除法中弹出,等等......

在这种情况下,100 * 100 只有10000,你也许可以侥幸逃脱,而且在32位空间中肯定有比这更大的整数,但一般做除法不会让你取利用提供的全部数字空间的优势!!!

【讨论】:

  • 你的意思是 rand() / (span + 1); ,因为我不能使用 % 因为左操作数有双倍。那么这导致了同样的事情。在更多尝试中生成相同的数字(在这之间有一段时间,因为我必须重新运行程序)。
  • 不,我的意思是我放的,看这里!!! cplusplus.com/reference/clibrary/cstdlib/rand
  • 对不起,我在这方面做得不好,我忘了删除 static_cast。这成功了,谢谢。
  • @trumpetlicks:cplusplus.com 不是一个好的参考。将 mod 与 rand() 一起使用是个坏主意。 rand() 的低位不是随机的。
  • @David Hammen - 虽然你是对的,但不一定是关于使用 mod 例程,但肯定是关于 rand 输出的随机分布,我不打算把这个作业问题放在更好的随机数生成算法等。也许是他的下一个任务,但我确实理解你的评论,并向上箭头:-)
【解决方案2】:

rand() 存在许多问题。您遇到了其中一个,即前几个值不是“随机的”。如果您必须使用rand(),最好放弃前四个或rand() 的结果。

srand (time(0));
rand();
rand();
rand();
rand();

rand() 的另一个问题是众所周知的低位是非随机的,即使在上述破解之后也是如此。在某些系统上,最低位交替 0,1,0,1,0,1,... 使用高位总是更好,例如使用商而不是余数。

其他问题:非随机性(rand() 的大多数实现未能通过随机性测试)和短周期。对于所有这些问题,最好的建议是使用除rand() 之外的任何东西。

【讨论】:

    【解决方案3】:

    首先,rand() / RAND_MAX 没有给出介于 0 和 1 之间的数字,它返回 0。这是因为 RAND_MAX 在 rand() 的结果中适合 0 次。两者都是整数,所以整数除法不会返回浮点数。

    其次,RAND_MAX 可能与 INT 大小相同。将 RAND_MAX 乘以任何东西都会产生溢出。

    【讨论】:

    • 他正在将rand() 转换为替身。
    • 在这种情况下,rand() 给出了一个介于 0 和 RAND_MAX 之间的随机数,为了使它生成一个介于 1 和 span(int span = 100) 之间的数字,我将它除以 RAND_MAX(然后跨度在 0 和 1 之间)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    相关资源
    最近更新 更多