std :: random_shuffle每次产生相同的结果

pan*_*hro 12 c++

可能重复:
如何确保std :: random_shuffle总是产生不同的结果?

我有一个阵列,我希望将其改组,我使用:

answerPositionArray[0] = 100;
answerPositionArray[1] = 400;
answerPositionArray[2] = 800;
std::random_shuffle(answerPositionArray, answerPositionArray + 2);
Run Code Online (Sandbox Code Playgroud)

但每次我运行我的程序时都会出现相同的洗牌,400,800,100.有没有办法让shuffle每次都变得不同?例如.第一次100,800,400然后800,400,100等

谢谢

bam*_*s53 36

std::random_shuffle(b,e)使用实现定义的随机源,因此无法进行可移植控制.通常实现使用std::rand(),因此使用std::srand()种子rng经常有效.

// not portable, depends on implementation defined source of randomness in random_shuffle
std::srand(some_seed);
std::random_shuffle(answerPositionArray, answerPositionArray+size);
Run Code Online (Sandbox Code Playgroud)

有一个重载std::random_shuffle()作为随机数生成器的第三个参数.您可以使用此表单来定义随机源,以便您可以播种它.

struct RNG {
    int operator() (int n) {
        return std::rand() / (1.0 + RAND_MAX) * n;
    }
};

std::srand(seed);
std::random_shuffle(answerPositionArray, answerPositionArray+size, RNG());
Run Code Online (Sandbox Code Playgroud)

C++ 11引入了另一种算法std::shuffle,该算法采用UniformRandomNumberGenerator,允许您使用C++ 11 <random>生成器:

std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);

std::shuffle(std::begin(answerPositionArray), std::end(answerPositionArray), eng);
Run Code Online (Sandbox Code Playgroud)

你的评论表明问题在于你没有改组整个数组,你只是在洗牌前两个元素,而最后一个元素没有被触及.

这是一个很好的演示如何使用魔术数字,如代码中所示:

std::random_shuffle(answerPositionArray, answerPositionArray + 2);
                                                               ^
                                                               |
                                                 magic number --
Run Code Online (Sandbox Code Playgroud)

可能容易出错.相反,您应该尝试编写独立于此类值的代码.

// trick for getting an array size
template<typename T, int N> int array_size(T (&)[N]) { return N; }

int answerPositionArray[] = {100, 400, 800};

std::random_shuffle(answerPositionArray,
                    answerPositionArray + array_size(answerPositionArray));
Run Code Online (Sandbox Code Playgroud)

或者一旦你可以使用C++ 11,就可以在数组上使用std::beginstd::end:

std::random_shuffle(std::begin(answerPositionArray), std::end(answerPositionArray));
Run Code Online (Sandbox Code Playgroud)

或者你可以使用上面的数组大小技巧在C++ 03中自己实现beginend运行:

template<typename T, int N> T *begin(T (&a)[N]) { return a; }
template<typename T, int N> T   *end(T (&a)[N]) { return a + N; }
Run Code Online (Sandbox Code Playgroud)

这些方法允许您避免必须使用数字大小的幻数,因此当您编写或修改代码时,您将不太可能错误地使用错误的值.

  • @ user1013512:阅读整篇文章.他包括C++ 98/03和C++ 11的解决方案. (4认同)

KCH*_*KCH 23

C++随机数不是真正随机的 - 它们是从称为种子的初始值生成的.如果不设置种子,它将始终相同,因此生成的序列不会更改.std::random_shuffle取决于随机数生成,因此它也会以这种方式运行.

那么如何设定种子呢?使用:

srand(time(0));
Run Code Online (Sandbox Code Playgroud)

在使用随机数调用函数之前.它会将种子设置为当前时间(以秒为单位).不要忘记添加appropritate头文件.

  • 这是行不通的. (7认同)
  • 将`answerPositionArray + 2`改为`answerPositionArray + 3` (4认同)