C++ random_shuffle 总是给出相同的结果

问题描述 投票:0回答:3

以下对随机洗牌的调用始终为向量 v 提供相同的结果

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>

using namespace std;

int main(){
  vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  srand(time(0));
  random_shuffle(v.begin(), v.end());
  for (int i = 0; i < v.size(); ++i) printf("%d ", v[i]); printf("\n");
  printf("%d\n", rand() % 100);

  return 0;
}

我尝试使用

进行编译
g++ -std=c++0x
g++ -std=c++11

但是每次都给出相同的结果,所以我不太明白发生了什么。

$./a.out
7 1 4 6 8 9 5 2 3 10 
26
$ ./a.out
7 1 4 6 8 9 5 2 3 10 
41
$ ./a.out
7 1 4 6 8 9 5 2 3 10 
39
c++ c++11 libc++ apple-clang
3个回答
7
投票

OP 的评论清楚地表明这是他们使用的 Clang 和 libc++,而不是 GCC/libstdc++。

快速浏览一下 libc++ 的

random_shuffle
实现 可以看出,它使用
__rs_default
类型的对象作为随机源,检查
__rs_default
的实现表明,它只是使用默认构造的
std::mt19937 
对象:

__rs_default::result_type
__rs_default::operator()()
{
    static mt19937 __rs_g;
    return __rs_g();
}

换句话说,在此实现中,

srand
random_shuffle
的两参数版本所使用的“随机性”来源没有任何影响。 (可怕的引号,因为它总是使用固定种子。)请注意,根本不需要使用
random_shuffle
,因此您无论如何都不能指望
rand
在可移植代码中“工作”。

请使用

srand

std::shuffle
设施。
    


4
投票
<random>

-std=c++0x
的意思是
完全相同
,所以测试两者是没有意义的。 您没有提供完整的程序(请下次阅读

https://stackoverflow.com/help/mcve

),所以我猜测了您其余的代码,我尝试了这个: -std=c++11

我每秒都会得到不同的结果:

#include <iostream> #include <vector> #include <algorithm> #include <stdlib.h> using namespace std; int main() { vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; srand(time(0)); random_shuffle(v.begin(), v.end()); for (int i : v) std::cout << i << ' '; std::cout << std::endl; }

产生相同结果的次数是因为 
tmp$ ./a.out 2 1 8 5 9 7 6 3 10 4 tmp$ ./a.out 10 7 6 3 1 8 9 4 5 2 tmp$ ./a.out 4 7 3 6 5 8 1 9 10 2 tmp$ ./a.out 4 7 3 6 5 8 1 9 10 2 tmp$ ./a.out 4 7 3 6 5 8 1 9 10 2 tmp$ ./a.out 10 2 6 3 9 4 5 7 8 1 tmp$ ./a.out 10 2 6 3 9 4 5 7 8 1 tmp$ ./a.out 10 2 6 3 9 4 5 7 8 1 tmp$ ./a.out 2 1 3 7 5 8 9 6 4 10

返回的秒数相同,因此

time(0)
函数的种子相同,因此结果相同。如果您稍等一下,以便
rand()
返回不同的值,您应该会得到不同的元素随机洗牌。

如果您运行的代码与我的不同,您可能会得到不同的结果,但我们不可能解释结果,因为您没有向我们展示您的代码。


0
投票

标准中不保证

time(0)

将依赖于

std::random_shuffle
。最重要的是:C++14 中已弃用
srand
,C++17 中已删除
从 C++11 开始(问题用 std::random_shuffle

标记),最好使用

c++11

,从 C++20 开始使用 
std::shuffle
,并带有显式随机生成器引擎。示例:
std::ranges::shuffle


© www.soinside.com 2019 - 2024. All rights reserved.