【问题标题】:rand() returns the same value, even after a srand [duplicate]rand() 返回相同的值,即使在 srand [重复]
【发布时间】:2016-05-18 09:54:35
【问题描述】:

我正在尝试获取一个随机值,但这不起作用。

我以此为例。

  srand(time(NULL) ^ getpid());

  int a = rand() % 100;

我第一次得到一个随机值,但每隔一次我调用 rand(),我得到相同的值。

我的完整代码:

Worms::Worms(std::string const& name, Ogre::SceneManager *scene,
  Ogre::ColourValue &color, unsigned char hp) :
  _name(name), _hp(hp), _scene(scene), _color(color)
{
  srand(time(NULL) ^ getpid());
  std::cout << "creating worms" << name << std::endl;
  std::cout << color << std::endl;
  this->_ent = scene->createEntity(name, "Worm.mesh");
  this->generatePosition();
  this->setColor(color);
}

void                            Worms::generatePosition()
{
  int a = rand() % 10;
  std::cout << a << std::endl;
  Ogre::Vector3 pos(rand() % 800 + 100 , 450, 0);
  std::cout << pos << std::endl;
  this->_node = this->_scene->getRootSceneNode()->createChildSceneNode(this->_name);
  this->_node->attachObject(this->_ent);
  this->_node->showBoundingBox(true);
  this->_node->scale(_node->getScale() * 4);
  _node->rotate(Ogre::Vector3::UNIT_X, Ogre::Degree(90));
  _node->rotate(Ogre::Vector3::UNIT_Z, Ogre::Degree(90));
  _node->setPosition(pos);
}

然后输出:

4
Vector3(498, 450, 0)
creating worms K04L4_1
creating wormsK04L4_1 Captain_2
ColourValue(1, 0, 0, 0)
4
Vector3(498, 450, 0)
creating worms K04L4_1
creating wormsK04L4_1 Captain_3
ColourValue(1, 0, 0, 0)
4
Vector3(498, 450, 0)
creating worms K04L4_1
ok
creating wormsOP3X_2 Pride_1
ColourValue(0, 1, 0, 0)
4
Vector3(498, 450, 0)
creating worms OP3X_2
creating wormsOP3X_2 Captain_2
ColourValue(0, 1, 0, 0)

【问题讨论】:

  • 您是否多次致电srand(time(NULL) ^ getpid());?如果您使用与time() 相同的值调用srand(),则会重置“随机”数字生成。
  • rand() 是---已弃用---又旧又丑。考虑改用&lt;random&gt;
  • 仅供参考,除非您的流程中只创建了一个 Worms 对象曾经(并且根据您的输出判断,情况并非如此),否则 srand 确实不属于该构造函数;它属于只执行一次的代码块,通常是main() 的头部。我完全同意 Bartek。 &lt;random&gt; 是现代 C++ 程序的晚餐,我强烈鼓励它。
  • See related question 并考虑它如何适用于您的情况。
  • 也请阅读Minimal, Complete, Verifiable Examples。只需几行任何人都可以编译的完整代码,就很容易证明这个问题。而且这个问题与食人魔无关。

标签: c++ random ogre


【解决方案1】:

我在我的程序中多次使用 srand(),现在我在 main() 函数中调用它一次,效果很好。

【讨论】:

  • 这不是答案。请删除它,并对您的问题发表评论
  • @Ajay 为什么?我会说这是一个有效的答案。也许不是很详细,但仍然是一个答案。
【解决方案2】:

time(NULL) 只有第二个分辨率,因此如果您的函数在同一秒内被调用,它将始终使用相同的种子。尝试GetTickCount() 获得毫秒分辨率或将微秒ticks 传递给srand()

using namespace std::chrono;
auto ticks = time_point_cast<microseconds>(system_clock::now()).time_since_epoch().count();

从 64 位向下转换到 32 位(srand() 采用 32 位参数)是特定于编译器的,但它通常会丢弃您想要获得更随机种子的高位。

如您所说,您可以拨打srand() 一次,然后继续拨打rand()。然后,您将逐步完成整个伪随机序列。

【讨论】:

  • 我很困惑为什么你推荐std::chrono来代替std::time,并且没有做出推荐std::random而不是std::srand的逻辑步骤。
  • 好点。伪随机数生成器的问题是周期短且随机性不令人满意。我没用过std::random,所以不能评论。我很久以前就和统计学家一起工作过,他们推出了自己的 PNG,这样他们就可以保证在序列重复之前有一个合适的周期长度,并通过一系列统计随机性测试。
猜你喜欢
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多