代码之家  ›  专栏  ›  技术社区  ›  Rick Jim DeLaHunt

为什么我一直得到相同的第一个数字,而我已经种子发电机与时间?

c++
  •  27
  • Rick Jim DeLaHunt  · 技术社区  · 7 年前

    我不明白为什么我一直得到相同的第一位数字,而我已经种子了 default_random_engine 具有 time(0) ( C++引物 告诉我怎么用 时间(0)

    我试过一个在线编译器,有趣的是,我得到了相同的第一位数字使用 gcc clang++ .

    https://wandbox.org/permlink/kiUg1BW1RkDL8y8c

    代码:

    #include <iostream>
    #include <ctime>
    #include <random>
    using namespace std;
    int main(){
        auto t = time(0);
        cout << "time: " << t << endl;
        default_random_engine e(t);
        uniform_int_distribution<int> uniform_dist(0, 9);
        cout << "sequence:";
        for(int i = 0; i < 10; i++){
            cout << uniform_dist(e);
        }
        cout << endl;
        return 0;
    }
    

    如你所见,我一直 6 作为随机数的第一位 g++ 编译。 enter image description here

    2 回复  |  直到 7 年前
        1
  •  29
  •   Wheezil    7 年前

    你在你的随机发生器中设置的初始状态非常相似。根据发电机的质量,这可能会或可能不会产生类似的输出。为了说明这一点,我将您的示例扩展为(a)只打印第一个序列,因为这是我们所关心的,(b)打印不同分辨率的几个结果:

    int main(){
        auto t = time(0);
        cout << "time: " << t << endl;
        default_random_engine e(t);
        default_random_engine e2(t);
        default_random_engine e3(t);
        default_random_engine e4(t);
        uniform_int_distribution<int> uniform_dist(0, 9);
        uniform_int_distribution<int> uniform_dist2(0,999);
        uniform_int_distribution<int> uniform_dist3(0,99999);
        uniform_int_distribution<int> uniform_dist4(0,9999999);
        cout << "sequence: ";
        cout << uniform_dist(e) << " " << uniform_dist2(e2) << " " << uniform_dist3(e3) << " " << uniform_dist4(e4);
        cout << endl;
        return 0;
    }
    

    运行时:

    $ ./a.out
    time: 1541162210
    sequence: 7 704 70457 7070079
    $ ./a.out
    time: 1541162211
    sequence: 7 704 70457 7070157
    $ ./a.out
    time: 1541162212
    sequence: 7 704 70458 7070236
    $ ./a.out
    time: 1541162213
    sequence: 7 704 70459 7070315
    $ ./a.out
    time: 1541162214
    sequence: 7 704 70460 7070393
    $ ./a.out
    time: 1541162215
    sequence: 7 704 70461 7070472
    $ ./a.out
    time: 1541162216
    sequence: 7 704 70461 7070550
    $ ./a.out
    time: 1541162217
    sequence: 7 704 70462 7070629
    $ ./a.out
    time: 1541162218
    sequence: 7 704 70463 7070707
    $ ./a.out
    time: 1541162219
    sequence: 7 704 70464 7070786
    

    虽然我不知道这个随机生成器实现到底在做什么,但是您可以很容易地看到它正在执行一个非常简单的转换,将种子转换为状态,并将状态转换为输出值。正如其他评论所建议的,有更好的随机生成器和更好的种子。还要注意的是,不同实现的质量不同;Visual Studio 2017不显示此行为。

        2
  •  1
  •   jpa    7 年前

    std::random_device time() .

    但是,如果需要使用带有线性同余生成器的小种子,则可以扩展种子值以生成更好的初始值设定项。线性生成器在重新分配种子值中的位时很慢,因此很小的差异将导致初始的几个值彼此接近。

    标准库提供 std::seed_seq 它会将一个小种子扩展到一个更好的初始值:

    seed_seq seed({t});
    default_random_engine e(seed);