【问题标题】:How to make sure that std::random_shuffle always produces a different result?如何确保 std::random_shuffle 总是产生不同的结果?
【发布时间】:2011-10-19 09:42:38
【问题描述】:

是否有一些类似于srand() 的函数需要调用以确保std::random_shuffle() 总是产生不同的结果?即,如果我用相同的数据多次调用它,我希望每次的顺序都不同。我怎样才能确定这一点?

【问题讨论】:

  • 这对我来说听起来不是很随意......
  • @Blindy:是随机的,但结果不是均匀分布的。
  • srand 相当不错。如果它不能满足您的需要,请搜索其他随机生成器(也许是 boost)
  • 确保你从不在一个程序中多次调用 srand()。
  • srand() 不能确保任何事情都会产生不同的结果。 @John:每次都越来越随机,因为每次都越来越可预测。

标签: c++ random std shuffle


【解决方案1】:

std::random_shuffle 有两种形式。一个接受 2 个参数(开始/结束迭代器),一个接受 3 个参数(开始/结束迭代器和随机生成器)。

第一种形式使用std::rand(),因此您可以使用std::srand() 来播种它的随机数生成器。您也可以使用 3 参数版本并自己提供 RNG。

【讨论】:

  • 据我了解,第一个表单如何实现它是它的业务。某些平台可能不使用std::rand
  • 你是对的。我在看 libstdc++ 版本。原作者应查阅您的 STL 的文档。或者,如果他们不想依赖它,他们应该使用第 3 种形式并使用 boost::random 或 C++0x std::random 之类的东西。
【解决方案2】:

std::random_shuffle 有一个用于指定 RNG 的模板重载。

template <class RandomAccessIterator, class RandomNumberGenerator>
  void random_shuffle ( RandomAccessIterator first, RandomAccessIterator last,
                        RandomNumberGenerator& rand );

reference

【讨论】:

    【解决方案3】:

    random_shuffle 自 C++14 起被弃用(在 C++17 中被移除)并被 shuffle 取代(自 C++11 起存在) http://en.cppreference.com/w/cpp/algorithm/random_shuffle

    可能的用法:

    shuffle(items.begin(), items.end(), std::default_random_engine(std::random_device()()));
    

    【讨论】:

      【解决方案4】:

      我认为你可以给 std::random_shuffle 一个随机生成器函子,这样你就可以完全控制随机数的生成。看看here,这个函子代替了 RandomNumberGenerator 模板参数。

      【讨论】:

        【解决方案5】:

        通常调用srand(time(NULL))之前调用std::random_shuffle() 会给你你所需要的,它给你每次调用std::random_shuffle() 不同的结果。这是因为 std::random_shuffle() 在许多流行的实现(例如 VS-2008 和 GCC)中内部调用 rand()

        当然,如果你想用一个额外的参数调用另一个重载的std::random_shuffle,你可以自己补充一个RNG。

        【讨论】:

          【解决方案6】:

          作为最后的手段,您可以:

          • 致电std::random_shuffle
          • 计算序列的哈希值,将其存储在std::set
          • 如果哈希已经存在则丢弃

          我看不出使用自定义生成器如何保证序列是唯一的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-11-10
            • 1970-01-01
            • 1970-01-01
            • 2018-05-23
            • 2017-09-11
            • 2020-03-14
            • 1970-01-01
            相关资源
            最近更新 更多