2014-02-23 33 views
1

我正在使用Visual Studio 2013(調試模式),它沒有基於迭代器的構造函數std::discrete_distribution,所以我使用了一種解決方法。但是,使用此解決方法時,如果最後一個元素不大於weights中的第一個元素,則會產生運行時錯誤。std :: discrete_distribution的意外行爲

使用初始化列表時不會產生此錯誤。

實施例:

#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; 
} 

輸出:

無效範圍discrete_distribution

添加任何數量大於10的上的weights端將停止運行時錯誤的發生。

這是怎麼發生的?

回答

1

您正在使用第三構造描述here,那就是:

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

std::discrete_distribution實例的正確初始化要求

delta * 2 = (xmax - xmin) > 0

+0

@ pighead10有更多的東西,你需要有解釋呢? – 4pie0

+0

對。那麼除了對矢量進行重新排序以外,還有什麼辦法可以避免? – pighead10

+0

您可以直接指定xmin和xmax並將它們傳遞給discrete_distribution構造函數,但是您還必須確保使用一元謂詞構造的權重將是正確的 – 4pie0

1

對於此解決方法,您的lambda實際上並未使用xmin和xmax(或fw的結果)來計算權重,因此不必擔心重新排序數組。只需傳遞0和1(或任何其他值,其中xmin < xmax),它將起作用。

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

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