标题:关于随机种子的问题
只看楼主
rohalloway
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:97
专家分:405
注 册:2018-9-28
结帖率:75%
已结贴  问题点数:20 回复次数:5 
关于随机种子的问题
程序代码:
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
#include <algorithm>
#include <random>
using namespace std;

class A{
public:
    static string getName();
};

string A::getName(){
    vector<string> v1{ "","", "", "", "", "", "", "", "", "" };
    vector<string> v2{ "","", "", "", "", "", "", "", "", "" };
    vector<string> v3{ "","", "", "", "", "", "", "", "", "" };
    vector<int> v{ 0,1,2,3,4,5,6,7,8,9 };

    random_device rd;
    mt19937 g(rd());
    shuffle(v.begin(), v.end(), g);

    return v1[v[0]] + v2[v[1]] + v3[v[2]];
}
int main()
{
    for (int i = 0; i < 20; i++)
    {
        cout << A::getName() << endl;
    }

    system("pause");
    return 0;
}


此代码段在vc下可以正确获得20个随机中文名
可能的输出:
程序代码:
/*
赵晓强 张世强 王世明 王世   周小新
安志新 李佳   吴月明 周明强 赵佳锋
张世林 赵志艳 赵明强 吴明林 周晓红
郑志锋 高其红 张晓锋 周晓   吴玉
*/



在mingw下,20个结果全部一样。
我尝试将
random_device rd;
mt19937 g(rd());
更改为
std::mt19937 g(time(NULL));

但问题没有得到解决,请问mingw下应该如何设置随机数种子才能解决这个问题,谢谢
搜索更多相关主题的帖子: 随机 include vector string int 
2018-11-28 16:56
rohalloway
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:97
专家分:405
注 册:2018-9-28
得分:0 
程序代码:
string A::getName(){
    std::vector<std::string> v1{ "","", "", "", "", "", "", "", "", "" };
    std::vector<std::string> v2{ "","", "", "", "", "", "", "", "", "" };
    std::vector<std::string> v3{ "","", "", "", "", "", "", "", "", "" };
    std::vector<int> v{ 0,1,2,3,4,5,6,7,8,9 };

    static QTime t = QTime::currentTime();
    QTime T = QTime::currentTime();

    int i = T.msecsTo(t);

    std::mt19937 g(i);
    std::shuffle(v.begin(), v.end(), g);

    return v1[v[0]] + v2[v[1]] + v3[v[2]];
}


利用毫秒的差值做随机种子时,会出现运行速度太快而存在重复结果的问题,如:

程序代码:
/*
张明
张明
张明
张明
张明
张明
张明
张明
高小林
高小林
高小林
高小林
高小林
高小林
高小林
高小林
安月明
安月明
安月明
安月明
*/
2018-11-28 17:21
rohalloway
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:97
专家分:405
注 册:2018-9-28
得分:0 
程序代码:
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
#include <algorithm>
#include <random>
#include <QTime>
#include <set>
using namespace std;

class A{
public:
    static string getName();
};

string A::getName(){
    std::vector<std::string> v1{ "","", "", "", "", "", "", "", "", "" };
    std::vector<std::string> v2{ "","", "", "", "", "", "", "", "", "" };
    std::vector<std::string> v3{ "","", "", "", "", "", "", "", "", "" };
    std::vector<int> v{ 0,1,2,3,4,5,6,7,8,9 };

    static QTime t = QTime::currentTime();
    QTime T = QTime::currentTime();

    int i = T.msecsTo(t);

    std::mt19937 g(i);
    std::shuffle(v.begin(), v.end(), g);

    return v1[v[0]] + v2[v[1]] + v3[v[2]];
}
int main()
{
    set<std::string> se;
    while(true)
    {
        se.insert(A::getName());
        if(se.size() == 20)
            break;
    }

    for(auto s : se)
        std::cout << s << endl;

    return 0;
}


此代码段在mingw下可以正确的获取20个不重复的随机中文名,
可能的输出:
程序代码:
/*
安明
安月明
高小林
高月强
李世
李晓
李小强
王明
王小锋
王玉
张明
赵佳锋
赵明
赵世林
郑明红
郑小新
周明
周玉明
周月新
周志
*/

存在2楼提到的“会出现运行速度太快而存在重复结果的问题”,我使用set容器过滤掉了。
总算是勉强实现了需求:)


如果您有好的办法解决1楼的问题,请帮助我,谢谢

[此贴子已经被作者于2018-11-28 17:32编辑过]

2018-11-28 17:30
Jonny0201
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:52
帖 子:488
专家分:2603
注 册:2016-11-7
得分:20 
把随机引擎设为 static?
程序代码:
string get_name() {
    vector<string> v1{ "","", "", "", "", "", "", "", "", "" };
    vector<string> v2{ "","", "", "", "", "", "", "", "", "" };
    vector<string> v3{ "","", "", "", "", "", "", "", "", "" };
    static default_random_engine e(time(nullptr));
    uniform_int_distribution<decltype(v1.size())> u(0, v1.size() - 1);
    return v1[u(e)] + v2[u(e)] + v3[u(e)];
}

周玉明    王丽新    安志林    张志明    张丽林    周月林    王丽明    王丽林    赵玉强    吴月强    赵月明    张佳艳    高月艳    高佳    张志红    高志    张世新    赵小    安佳新    赵月艳   
郑佳艳    王佳    高月明    王志明    安晓明    郑晓    李小林    赵其红    王小艳    郑小艳    周玉    郑小锋    郑晓    郑志    周其    吴志红    李世红    李丽锋    赵志    李世   
张世    王佳红    王世红    安佳新    张月    周玉红    赵志    赵明强    郑世    高晓锋    李佳    吴明强    周玉红    王佳新    高月红    王小林    周玉    周明明    高月新    王小林
王明林    周玉    赵志    安世    赵玉林    王月新    高世    李丽    赵明强    高志锋    郑其锋    周小明    吴玉锋    郑明艳    王佳    王玉锋    李丽    张月红    高佳明    高玉强
王玉    王晓明    郑志强    高晓强    王玉    吴晓强    郑小红    高月红    高佳    高明林    王其明    张玉    李小林    赵世强    高佳强    王佳林    郑世锋    王小强    王佳锋    王晓   
2018-11-28 18:10
Jonny0201
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:52
帖 子:488
专家分:2603
注 册:2016-11-7
得分:0 
不过你第一个例子在我这好像也没问题啊

我看过别人的一篇博客
有些硬件设备会记录客户键盘的按键和鼠标点击位置还有移动位置
这种才是真正的随机
不过坏处是会用完, 要等客端再次产生随机数据才能接着用这个随机引擎
2018-11-28 18:26
rohalloway
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:97
专家分:405
注 册:2018-9-28
得分:0 
以下是引用Jonny0201在2018-11-28 18:10:09的发言:

把随机引擎设为 static?
string get_name() {
    vector<string> v1{ "张","王", "李", "赵", "周", "吴", "郑", "王", "安", "高" };
    vector<string> v2{ "小","晓", "明", "月", "佳", "志", "其", "世", "玉", "丽" };
    vector<string> v3{ "明","新", "锋", "", "林", "红", "艳", "", "强", "" };
    static default_random_engine e(time(nullptr));
    uniform_int_distribution<decltype(v1.size())> u(0, v1.size() - 1);
    return v1 + v2 + v3;
}



在mingw下测试正确,非常感谢!


以下内容摘自网络,分享给遇到同样问题的朋友:

c/c++老版本的rand()存在一定的问题,在转换rand随机数的范围,类型或者分布时,常常会引入非随机性。

定义在<random> 中的随机数库通过一组协作类来解决这类问题:随机数引擎 和 随机数分布类

一个给定的随机数发生器一直会生成相同的随机数序列。

一个函数如果定义了局部的随机数发生器,应该将(引擎和分布对象)定义为 static 的。否则每次调用函数都会生成相同的序列。
2018-11-30 04:37



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-491639-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.196731 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved