5

我正在为 AI 竞赛做主持人,并且有一个 randomBot 可以选择随机的可能值。

该机器人有 2 个导出函数:Init(_seed) 和 MakeMove()

为了玩完全相同的游戏,主机为每个机器人定义了种子值。并将其传递给 Init 函数。

random bot 的 Init 函数有一个 srand(_seed) 函数调用。random bot 的 MakeMove 函数有一个 rand() 函数调用。

现在的问题是,在加载 2 个机器人后,每个游戏都应该具有相同的种子值,但它们是不同的。

据我所知,srand 应该为每个模块/线程存储它的值,而不是共享它。

我做了一个测试并创建了一个函数 mysrand 和 myrand ,它们不会分别通过调用 srand 和 rand 导出。

我用 mysrand 和 myrand 替换了导出函数中的 srand 和 rand ......它起作用了......

我知道为什么会发生这种情况,但不确定...

那么为什么它会发生以及如何避免它,因为我希望参赛者在导出的函数中使用他们想要的任何函数(不想使用我的代理函数)。

谢谢。

我正在使用 windows,编译器:gcc、visual C++、borland C++ builder

4

3 回答 3

5

如果你想获得一致的行为,<random>图书馆可能是一个更好的选择。您可以控制 RNG 状态的存储位置,并且引擎可以在实现之间产生相同的值(尽管标准分布不需要在实现之间产生相同的输出)。

#include <random>
#include <iterator>
#include <algorithm>
#include <iostream>

int main() {
    std::mt19937 eng;
    std::generate_n(std::ostream_iterator<int>(std::cout, " "), 10, [&] {
        // A simple example distribution function; not intended for real use.
        return static_cast<int>(eng()/static_cast<double>(eng.max() + 1ull) * 20.0) + 1;
    });
}

这应该在所有实现上输出以下内容:

17 3 19 17 3 20 19 5 13 7

如果您只需要在实现中而不是跨实现的一致行为,那么您可以使用标准分布,并且您仍然可以控制 RNG 的状态。

#include <random>
#include <iterator>
#include <algorithm>
#include <iostream>

int main() {
    std::mt19937 eng;
    std::uniform_int_distribution<> dist(1,20);
    std::generate_n(std::ostream_iterator<int>(std::cout, " "), 10, [&] { return dist(eng); });
}

标准发行版应该比编写自己的发行版更受欢迎。

于 2012-06-10T06:21:59.210 回答
2

据我所知,srand 应该为每个模块/线程存储它的值,而不是共享它。

这不一定是真的。从randUbuntu 的手册页:

 The function rand() is not reentrant or thread-safe, since it uses hid‐
   den state that is modified on each call.  This might just be  the  seed
   value to be used by the next call, or it might be something more elabo‐
   rate.  In order to get reproducible behavior in a threaded application,
   this  state must be made explicit; this can be done using the reentrant
   function rand_r().

如果您的 C 库实现没有明确使用本地状态而不是共享状态,您最终可能会破坏 RNG 状态rand

于 2012-06-10T04:31:13.033 回答
1

您可以将每个 dll 静态链接到 CRT,它将为每个 dll 提供自己的 rand 状态。

于 2012-06-10T04:48:22.330 回答