2009-07-13 25 views
9

Tôi đang cố gắng sử dụng C++ STD TechnicalReport1 phần mở rộng để tạo ra các số sau một phân phối chuẩn, nhưng mã này (chuyển thể từ this article):C++ TR1: cách sử dụng phân phối bình thường như thế nào?

mt19937 eng; 
eng.seed(SEED); 

normal_distribution<double> dist; 
// XXX if I use the one below it exits the for loop 
// uniform_int<int> dist(1, 52); 

for (unsigned int i = 0; i < 1000; ++i) { 
    cout << "Generating " << i << "-th value" << endl; 
    cout << dist(eng) << endl; 
} 

chỉ in 1 "Tạo ..." log nhắn , sau đó không bao giờ thoát khỏi vòng lặp! Nếu tôi sử dụng bản phân phối mà tôi đã nhận xét thay vào đó, nó sẽ chấm dứt, vì vậy tôi tự hỏi tôi đang làm gì sai. Bất kỳ ý tưởng?

Cảm ơn rất nhiều!

Trả lời

2

Điều này chắc chắn sẽ không treo chương trình. Nhưng, không chắc chắn nếu nó thực sự đáp ứng nhu cầu của bạn.

#include <random> 
#include <iostream> 

using namespace std; 

typedef std::tr1::ranlux64_base_01 Myeng; 

typedef std::tr1::normal_distribution<double> Mydist; 

int main() 
{ 
     Myeng eng; 
     eng.seed(1000); 
     Mydist dist(1,10); 

     dist.reset(); // discard any cached values 
     for (int i = 0; i < 10; i++) 
     { 
      std::cout << "a random value == " << (int)dist(eng) << std::endl; 
     } 

return (0); 
} 
+0

cảm ơn người đàn ông, nó hoạt động như một say mê, nhưng tôi tự hỏi tại sao với động cơ này nó hoạt động, và không phải với khác .. – puccio

+0

Rõ ràng sự khác biệt duy nhất là bạn sử dụng máy phát điện số mt19937 trong khi Jagannath sử dụng std :: tr1 :: ranlux64_base_01. Về mặt logic, tôi đoán lỗi có thể là do bạn đang triển khai đối tượng mt19937 (bản ngã mà tôi chưa từng nghe trước đây, thx cho :-)) đó không phải là một phần của thư viện std. –

+0

Có thể vector hóa vòng lặp như vậy khi vẽ các số ngẫu nhiên không? Tôi nhớ rằng bạn không thể vector hóa một vòng lặp có một cuộc gọi hàm. – Lindon

1

Trong khi điều này dường như là một lỗi, một xác nhận nhanh sẽ là để vượt qua các tham số 0.0, 1.0 mặc định. normal_distribution<double>::normal_distribution() phải bằng normal_distribution<double>::normal_distribution(0.0, 1.0)

+0

nó không hoạt động hoặc , nó vẫn còn bị mắc kẹt thực hiện tính toán đầu tiên .. – puccio

2

Nếu triển khai tạo số ngẫu nhiên TR1 của bạn bị lỗi, bạn có thể tránh TR1 bằng cách viết trình phát bình thường của riêng bạn như sau.

Tạo hai mẫu ngẫu nhiên (0, 1) ngẫu nhiên u và v bằng bất kỳ trình tạo ngẫu nhiên nào mà bạn tin cậy. Sau đó cho r = sqrt (-2 log (u)) và trả về x = r sin (2 pi v). (Điều này được gọi là phương pháp Box-Mueller.)

Nếu bạn cần mẫu mẫu bình thường với mu trung bình và sigma độ lệch chuẩn, trả về sigma * x + mu thay vì chỉ x.

+1

không sử dụng Box Muller. –

+0

Hộp Müller là chậm – Lindon

+0

Chỉ cần thử này. Nó chạy siêu nhanh - được thử nghiệm với các mẫu 1M và nó trình bày số liệu thống kê gần như hoàn hảo cho các mẫu trong 1-sigma, 2-sigma, v.v ... –

7

Tôi đã có cùng một vấn đề với mã ban đầu được đăng tải và tra việc thực hiện GNU của

đầu tiên một số quan sát: với g ++ - 4.4 và sử dụng bị treo mã, với g ++ - 4.5 và sử dụng -std = C++ 0x (tức là không TR1 nhưng thực tế) ở trên mã hoạt động

IMHO, có sự thay đổi giữa TR1 và C++ 0x liên quan đến bộ điều hợp giữa số ngẫu nhiên và tiêu thụ số ngẫu nhiên - mt19937 tạo số nguyên, phân phối bình thường tiêu thụ tăng gấp đôi

C++ 0x sử dụng thích ứng tự động, g ++ TR1 mã không

để có được mã của bạn làm việc với g ++ - 4.4 và TR1, làm như sau

std::tr1::mt19937 prng(seed); 
std::tr1::normal_distribution<double> normal; 
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<double> > randn(prng,normal); 
double r = randn(); 
Các vấn đề liên quan