C ++。加权std :: shuffle

时间:2018-05-07 19:26:37

标签: c++ c++11 random shuffle weighted

有没有办法使用标准库进行漂亮优雅的加权改组? 有std::discrete_distribution。 我想要的是这样的:

std::vector<T> data { N elements };
std::vector<int> weights { N weights };
std::shuffle(std::begin(data), std::end(data), something based on discrete distribution);

1 个答案:

答案 0 :(得分:8)

如果OP意图是混淆列表 r 的项目

  

这样,给定一个权重列表 w ,权重 w [i] 的元素 a [i] 应该是第一个随机洗牌 r 的元素,概率 w [i] / sum(w)

page所链接的Severin Pappadeux中所述:

  

加权随机改组与无替换的列表a中的加权随机抽样相同。也就是说,从a中选择概率w [i] / sum(w)元素a [i]。将此元素存储在列表r中。然后,从w中删除元素a [i]和从w中删除w [i],并选择修改后的列表a的新元素,依此类推,直到a为空。

我不知道标准库中的这种算法,但一个简单的实现可能是:

#include <random>
#include <algorithm>
#include <iterator>

template <class D, class W, class URBG>
void weighted_shuffle
    ( D first, D last
    , W first_weight, W last_weight
    , URBG&& g )
{
    while (first != last and first_weight != last_weight)
    {
        std::discrete_distribution dd(first_weight, last_weight);
        auto i = dd(g);
        if ( i )
        {
            std::iter_swap(first, std::next(first, i));
            std::iter_swap(first_weight, std::next(first_weight, i));
        }
        ++first;
        ++first_weight;
    }
}

直播示例HERE