std :: discrete_distribution的意外行为

时间:2014-02-23 19:05:28

标签: c++ algorithm math random std

我正在使用Visual Studio 2013(调试模式),它没有std::discrete_distribution的基于迭代器的构造函数,因此我使用了一种解决方法。但是,使用此变通方法时,如果最后一个元素不大于weights中的第一个元素,则会产生运行时错误。

使用初始化列表时不会产生此错误。

示例:

#include <iostream>
#include <random>
#include <vector>

int main(){
    std::discrete_distribution<> dist1 = { 10.f,11.f,5.f };

    std::cout << "!" << std::endl;

    std::vector<float> weights = { 10.f, 11.f, 5.f};

    std::size_t i(0);

    std::discrete_distribution<> dist2(weights.size(), weights.front(), weights.back(),
        [&weights, &i](double){
        auto w = weights[i];
        ++i;
        return w;
    });

    std::cout << "!!" << std::endl;

    return 0;
}
  

输出:

     

<!/ P>      

discrete_distribution的无效范围

weights的末尾添加任何大于10的数字将停止发生运行时错误。

为什么会这样?

2 个答案:

答案 0 :(得分:1)

您正在使用描述为here的第3个构造函数,即:

template< class UnaryOperation >
discrete_distribution( std::size_t count, double xmin, double xmax,
                       UnaryOperation unary_op );

正确初始化std::discrete_distribution实例需要

delta * 2 = (xmax - xmin) > 0

答案 1 :(得分:1)

对于这种解决方法,你的lambda实际上并没有使用xmin和xmax(或fw的结果)来计算权重,因此不必担心重新排序你的数组。只需传递0和1(或任何其他值,其中xmin

std::discrete_distribution<> dist2(weights.size(), 0, 1,
    [&weights, &i](float){
    auto w = weights[i];
    ++i;
    return w;
});

示例:http://ideone.com/351Jhg