2012-06-12 27 views
13

Tôi cố gắng để sử dụng phương pháp C++ 11 này sang thế hệ số ngẫu nhiên:Làm cách nào để đặt lại một công cụ số ngẫu nhiên?

#include <random> 
#include <functional> 
#include <iostream> 

int main(int argc, char *argv[]) 
{  
    std::normal_distribution<double> normal(0, 1); 
    std::mt19937 engine; // Mersenne twister MT19937 
    auto generator = std::bind(normal, engine); 

    int size = 2; 

    engine.seed(0); 
    normal.reset(); 
    for (int i = 0; i < size; ++i) 
     std::cout << generator() << std::endl; 

    std::cout << std::endl; 

    engine.seed(1); 
    normal.reset(); 
    for (int i = 0; i < size; ++i) 
     std::cout << generator() << std::endl; 

    std::cout << std::endl; 

    engine.seed(0); 
    normal.reset(); 
    for (int i = 0; i < size; ++i) 
     std::cout << generator() << std::endl; 

    return 0; 
} 

Đầu ra là:

0.13453 
-0.146382 

0.46065 
-1.87138 

0.163712 
-0.214253 

đó có nghĩa là người đầu tiên và trình tự thứ ba là không giống nhau ngay cả khi chúng được gieo với cùng một số. Làm ơn, tôi đang làm gì sai? Có phải là

std::normal_distribution<double> 

Chỉ cần một hàm theo nghĩa toán học (tạo ra y ngoài x xác định) hoặc tôi thiếu gì đó không? Nếu nó chỉ là một hàm, thì phương thức reset sẽ thực sự làm gì?

Trả lời

19

Bạn đang ràng buộc động cơ và phân phối, chẳng hạn các cuộc gọi sau khi đặt lại sẽ không ảnh hưởng đến chức năng bị ràng buộc.

Giải pháp là để ràng buộc tham chiếu đến động cơ và các distro

auto generator = std::bind(std::ref(normal), std::ref(engine)); 
+0

Đó là nó. Tôi đoán tôi phải học STL nhiều hơn nữa :) Nó hoạt động hoàn hảo với giải pháp của bạn. Cảm ơn! –

+0

'auto generator = std :: bind (bình thường, std :: ref (engine));' là đủ tôi đoán. – Tengis

11

Vấn đề bạn gặp phải là với std::bind. std::bind sao chép các đối số của nó. Lý do std::bind tạo bản sao là vì hàm sẽ được gọi tại một số điểm không xác định trong tương lai khi các đối số có thể không còn tồn tại nữa. Điều này có nghĩa là các cuộc gọi của bạn đến engine.seed(), v.v. là vô ích. Sử dụng std::ref bạn có thể ràng buộc đối số của bạn bằng cách tham chiếu sẽ cung cấp cho bạn đầu ra dự kiến.

auto generator = std::bind(std::ref(normal), std::ref(engine)); 
+0

Cảm ơn bạn! Điều đó là vậy đó. Bây giờ nó hoạt động tốt! :) –

Các vấn đề liên quan