提问人:Ana Echavarria 提问时间:10/5/2016 最后编辑:AmitAna Echavarria 更新时间:10/16/2023 访问量:1318
C++ random_shuffle总是给出相同的结果
C++ random_shuffle is always giving the same results
问:
以下对随机洗牌的调用总是为向量提供相同的结果v
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
int main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::srand(time(0));
std::random_shuffle(v.begin(), v.end());
for (int i = 0; i < v.size(); ++i) {
printf("%d ", v[i]); printf("\n");
}
printf("%d\n", std::rand() % 100);
}
我试过使用
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
答:
首先,意思是完全一样的,所以测试两者是没有意义的。-std=c++0x
-std=c++11
你没有提供一个完整的程序(请下次阅读 https://stackoverflow.com/help/mcve),所以我猜到了你的代码的其余部分,我试了一下:
#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()
time(0)
如果您运行的代码与我的代码不同,您可能会得到不同的结果,但我们不可能解释结果,因为您没有向我们展示您的代码。
评论
srand(time(0))
rand()
random_shuffle
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
<random>
评论
<random>
std::random_shuffle
time()
<random>
现代 C++
它不在标准中得到保证,这将依赖于.std::random_shuffle
std::srand
--
脚注:在 C++14 中已弃用,并在 C++17 中删除。std::random_shuffle
由于 C++11(问题标有 ),因此最好使用,并且由于 C++20 使用 ,带有显式随机生成器。示例:c++11
std::shuffle
std::ranges::shuffle
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
int main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::random_device rd;
std::mt19937 gen(rd()); // Mersenne Twister generator.
// std::shuffle(v.begin(), v.end(), gen);
std::ranges::shuffle(v, gen); // (Since C++20)
for (const auto& i : v) {
std::cout << i << std::endl;
}
}
评论
srand(time(0));
random_shuffle
rand