我想知道是否有人可以提供帮助。
我正在寻找一种相当简单且理想的快速方法,从带有权重的元组向量中进行采样。
e.g。说我有一个元组的向量,每个都包含一个值和相应的权重/概率:
vector<tuple<int, double>> foo = { {1,0.04},{2,0.8},{ 3,0.01 },{ 4,0.03 },{
5,0.1 },{ 6,0.9 } };
我想通过foo并根据权重随机抽样,所以我最终得到一个向量(一个新的向量或替换foo中的元素),在这种情况下,有问题的大多数将是2和6.例如
vector<tuple<int, double>> bar = { {2,0.8},{2,0.8},{ 6,0.9},{ 6,0.9 },{
6,0.9 },{ 6,0.9 } };
我确信使用像std :: discrete_distribution这样的东西很简单,虽然我还没弄清楚究竟是怎么做的。
编辑: 感谢您的帮助到目前为止,我可能已经使用了一些不良的术语&#34;重新采样&#34;。
本质上我想要的是采用元组的向量&#34; foo&#34;如上所述,并产生一个新的矢量&#34; bar&#34;它与foo的大小相同,由foo的元组组成,但元组是根据元组中的概率加权随机选择的。 - 希望这是有道理的。
答案 0 :(得分:2)
这样的东西?
// Example program
#include <iostream>
#include <string>
#include <map>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::discrete_distribution<> d({0.04, 0.8, 0.01, 0.03, 0.1, 0.9});
std::map<int, int> m;
for(int n=0; n<100000; ++n) {
++m[d(gen)];
}
for(auto p : m) {
std::cout << p.first+1 << " generated " << p.second << " times\n";
}
}
1 generated 2089 times
2 generated 42472 times
3 generated 544 times
4 generated 1631 times
5 generated 5473 times
6 generated 47791 times
答案 1 :(得分:1)
是std::discrete_distribution
可行。以下使用权重来置换对的向量。它倾向于收敛到2或6,正如人们所期望的那样。
#include <random>
#include <vector>
#include <tuple>
#include <iostream>
std::ostream& operator<<(std::ostream& os,const std::vector<std::tuple<int, double>>& v)
{
for(auto&& i : v)
std::cout << "{" << std::get<0>(i) << ", " << std::get<1>(i) << "}\t";
return os;
}
auto permute(std::vector<std::tuple<int, double>>& foo)
{
std::vector<std::tuple<int, double>> temp; // return value
std::vector<double> v; // weights
for(auto&& i : foo)
v.push_back(std::get<1>(i)); // get weights
std::discrete_distribution<int> dd{v.begin(), v.end()}; // create distribution
static std::random_device rd;
for(size_t i{}; i < foo.size(); ++i)
temp.push_back(foo[dd(rd)]); // build return vector by selecting from foo according to weights
return temp;
}
int main()
{
std::vector<std::tuple<int, double>> foo = {{1, 0.04}, {2, 0.8}, {3, 0.01}, {4, 0.03}, {5, 0.1}, {6, 0.9}};
std::cout << foo << '\n';
for(size_t i{}; i < 10; ++i) {
foo = permute(foo);
std::cout << foo << '\n';
}
}
示例输出:
{1, 0.04} {2, 0.8} {3, 0.01} {4, 0.03} {5, 0.1} {6, 0.9}
{2, 0.8} {5, 0.1} {6, 0.9} {2, 0.8} {6, 0.9} {6, 0.9}
{6, 0.9} {2, 0.8} {6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9}
{6, 0.9} {6, 0.9} {6, 0.9} {2, 0.8} {6, 0.9} {6, 0.9}
{6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {2, 0.8}
{6, 0.9} {6, 0.9} {2, 0.8} {6, 0.9} {6, 0.9} {6, 0.9}
{6, 0.9} {6, 0.9} {2, 0.8} {6, 0.9} {2, 0.8} {6, 0.9}
{6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {2, 0.8}
{6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9}
{6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9}
{6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9} {6, 0.9}