Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++11 C++;11:如何使用<;随机>;_C++11_Random - Fatal编程技术网

C++11 C++;11:如何使用<;随机>;

C++11 C++;11:如何使用<;随机>;,c++11,random,C++11,Random,我正在练习C++11的新版本随机库。我编写了以下最小程序: #include <iostream> #include <random> using namespace std; int main() { default_random_engine eng; uniform_real_distribution<double> urd(0, 1); cout << "Uniform [0, 1): " << urd(

我正在练习C++11的新版本随机库。我编写了以下最小程序:

#include <iostream>
#include <random>
using namespace std;
int main() {
    default_random_engine eng;
    uniform_real_distribution<double> urd(0, 1);
    cout << "Uniform [0, 1): " << urd(eng);
}
我想让程序在每次调用时对种子进行不同的设置,以便每次生成不同的随机数。我知道random提供了一个名为seed_seq的工具,但我发现(在cpluplus.com上)对此的解释完全不清楚:

对于如何让一个程序在每次调用时生成一个新的种子,我将不胜感激:越简单越好

我的平台:

  • Windows 7:

拥有
种子的目的在于增加生成序列的熵。如果您的系统中有一个随机_设备,则可以使用该随机设备中的多个数字进行初始化。在一个有伪随机数生成器的系统上,我不认为随机性会增加,即生成的序列熵

在此基础上,您的方法:

如果您的系统确实提供了随机设备,那么您可以这样使用它:

  std::random_device r;
  // std::seed_seq ssq{r()};
  // and then passing it to the engine does the same
  default_random_engine eng{r()};
  uniform_real_distribution<double> urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);
如果你有多个随机性来源,你实际上可以这样做(例如2)

或者只是玩弄CPU的随机性

long unsigned int getseed(int const K)
{

    typedef std::chrono::high_resolution_clock hiclock;

    auto gett= [](std::chrono::time_point<hiclock> t0)
    {
        auto tn = hiclock::now();
        return static_cast<long unsigned int>(std::chrono::duration_cast<std::chrono::microseconds>(tn-t0).count());
    };

    long unsigned int diffs[10];
    diffs[0] = gett(hiclock::now());
    for(int i=1; i!=10; i++)
    {
        auto last = hiclock::now();
        for(int k=K; k!=0; k--)
        {
            diffs[i]= gett(last);
        }
    }

    return *std::max_element(&diffs[1],&diffs[9]);
}
long unsigned int getseed(int const K)
{
typedef std::chrono::高分辨率时钟锁定;
自动获取=[](标准::计时::时间点t0)
{
auto tn=hiclock::now();
返回static_cast(std::chrono::duration_cast(tn-t0).count());
};
长无符号整数差[10];
diff[0]=gett(hiclock::now());
对于(int i=1;i!=10;i++)
{
auto last=hiclock::now();
对于(int k=k;k!=0;k--)
{
diff[i]=gett(最后一个);
}
}
return*std::max_元素(&diff[1]、&diff[9]);
}

您能在代码中添加更多注释来详细说明一下吗?:)bames53:我编译并运行了你的代码。我继续得到确定性的输出,也就是说,每次都是相同的。也许我的平台是个问题。这是Windows 7,我正在运行TDM-GCC编译器。问题是Windows上的libstdc++采用确定性实现。他们还没有尝试为非确定性连接到Windows的操作系统设施(当然Windows也没有提供libstdc++在*nix平台上使用的设施)。如果您在Linux上使用VS2015或gcc构建程序,那么您将获得不重复的结果。如果你想继续在Windows上使用gcc,那么你需要用类似于使用Windows CryptoAPI的东西替换
random_设备
。谢谢,g241。修改默认随机引擎的初始化以包含对时间(0)的调用后,程序输出是不确定的。@Argent,AFAIK在Windows上没有随机引擎,时间(0)以秒精度将种子初始化为当前种子,因此后续运行的种子不同,从而实现您的目标。第二个是粒度。如果这个答案解决了你的问题,请接受它;默认使用rand_s(),它使用RtlGenRandom,它调用advapi32.dll来生成相当好的随机数(而不需要一直到加密的代价。)@JonWatte:我怀疑g24l正在考虑MinGW的问题,至少在Windows上是这样,(截至2017年,不知道它是否/何时会被修复)。MSVC提供了一个可用的随机引擎,这些功能通常在Windows上可用,但MinGW使用的
libstdc++
MinGW甚至不尝试使用它。朋友不允许朋友使用MinGW。VisualStudio是免费下载的。修复警告和发现g++没有的警告,对您的代码有好处!
#include <chrono>
#include <iostream>
#include <random>
#include <thread>
#include <utility>

using namespace std;

// we only use the address of this function
static void seed_function() {}

int main() {
    // Variables used in seeding
    static long long seed_counter = 0;
    int var;
    void *x = std::malloc(sizeof(int));
    free(x);

    std::seed_seq seed{
        // Time
        static_cast<long long>(std::chrono::high_resolution_clock::now()
                                   .time_since_epoch()
                                   .count()),
        // ASLR
        static_cast<long long>(reinterpret_cast<intptr_t>(&seed_counter)),
        static_cast<long long>(reinterpret_cast<intptr_t>(&var)),
        static_cast<long long>(reinterpret_cast<intptr_t>(x)),
        static_cast<long long>(reinterpret_cast<intptr_t>(&seed_function)),
        static_cast<long long>(reinterpret_cast<intptr_t>(&_Exit)),
        // Thread id
        static_cast<long long>(
            std::hash<std::thread::id>()(std::this_thread::get_id())),
        // counter
        ++seed_counter};

    std::mt19937 eng(seed);

    uniform_real_distribution<double> urd(0, 1);

    cout << "Uniform [0, 1): " << urd(eng);
}
  std::random_device r;
  // std::seed_seq ssq{r()};
  // and then passing it to the engine does the same
  default_random_engine eng{r()};
  uniform_real_distribution<double> urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);
  default_random_engine eng{static_cast<long unsigned int>(time(0))};
  uniform_real_distribution<double> urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);
std::seed_seq seed{ r1(), r2() };
  default_random_engine eng{seed};
  uniform_real_distribution<double> urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);
std::seed_seq seed{ r1(), static_cast<long unsigned int>(time(0)) };
  default_random_engine eng{seed};
  uniform_real_distribution<double> urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);
  auto rand = std::bind(std::uniform_real_distribution<double>{0,1},
              std::default_random_engine{std::random_device()()});
  std::cout << "Uniform [0,1): " << rand();
static_cast<long unsigned int>(std::chrono::high_resolution_clock::now().time_since_epoch().count()) 
long unsigned int getseed(int const K)
{

    typedef std::chrono::high_resolution_clock hiclock;

    auto gett= [](std::chrono::time_point<hiclock> t0)
    {
        auto tn = hiclock::now();
        return static_cast<long unsigned int>(std::chrono::duration_cast<std::chrono::microseconds>(tn-t0).count());
    };

    long unsigned int diffs[10];
    diffs[0] = gett(hiclock::now());
    for(int i=1; i!=10; i++)
    {
        auto last = hiclock::now();
        for(int k=K; k!=0; k--)
        {
            diffs[i]= gett(last);
        }
    }

    return *std::max_element(&diffs[1],&diffs[9]);
}