如何在没有替换的情况下使用c ++ uniform_int_distribution进行采样

时间:2015-11-19 11:08:00

标签: c++ random

我想在c ++随机库中使用uniform_int_distribution。但是,它只进行替换采样,如下例所示。如何在没有替换的情况下进行采样?

#include <iostream>
#include <random>

int main()
{
  std::default_random_engine generator;
  std::uniform_int_distribution<int> distribution(1,4);

  for(int i=0; i<4; ++i)
    std::cout << distribution(generator) << std::endl;

  return 0;
}

3 个答案:

答案 0 :(得分:3)

使用std::shuffle,例如,std::array<int>std::vector<int>,初始化为{1, 2, 3, 4}

然后按顺序回读容器内容。

这将比绘制一个随机数具有更好的统计特性,只有在之前没有绘制它时才接受它。

参考http://en.cppreference.com/w/cpp/algorithm/random_shuffle

答案 1 :(得分:1)

从c ++ 17开始,现在有一个标准库函数可以完全做到这一点。参见https://en.cppreference.com/w/cpp/algorithm/sample

#include <iostream>
#include <random>
#include <string>
#include <iterator>
#include <algorithm>

int main()
{
    std::string in = "abcdefgh", out;
    std::sample(in.begin(), in.end(), std::back_inserter(out),
                5, std::mt19937{std::random_device{}()});
    std::cout << "five random letters out of " << in << " : " << out << '\n';
}

答案 2 :(得分:0)

如果要对N个均匀分布的整数进行采样而不用从[low, high)范围内进行替换,则可以这样写:

std::vector<int> array(N);   // or reserve space for N elements up front
 
auto gen = std::mt19937{std::random_device{}()};
    
std::ranges::sample(std::views::iota(low, high), 
                    array.begin(),
                    N, 
                    gen);

std::ranges::shuffle(array, gen);  // only if you want the samples in random order 

这里是demo

这类似于Philip M's answer,但是从C ++ 20可以延迟生成输入范围。