2011-01-24 38 views
8

Tôi muốn đặt lại các chuỗi ngẫu nhiên bằng cách sử dụng các số hạt giống khác nhau. Khi chạy mã kiểm tra này:Đặt tăng hạt giống :: ngẫu nhiên

boost::mt19937 gener(1); 
boost::normal_distribution<> normal(0,1); 
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal); 
cout << rng() << endl; 
cout << rng() << endl; 
cout << rng() << endl; 
gener.seed(2); 
cout << rng() << endl; 
cout << rng() << endl; 
gener.seed(1); 
cout << rng() << endl; 
gener.seed(2); 
cout << rng() << endl; 
gener.seed(3); 
cout << rng() << endl; 

tôi nhận được kết quả như sau:

# seed(1) via constructor 
-2.971829031 
1.706951063 
-0.430498971 
# seed(2) 
-2.282022417 
-0.5887503675 
# seed(1) 
0.2504171986 
# seed(2) 
-0.5887503675 
# seed(3) 
0.2504171986 

Rõ ràng tôi đang làm một cái gì đó rất sai. Làm thế nào tôi có thể khắc phục vấn đề này?

Trả lời

14

Tiếp theo Jim, Alan và Igor đề nghị thực hiện một số thay đổi đối với mã: rng.engine().seed() thay vì gener.seed(), và gọi rng.distribution().reset() sau khi cuộc gọi đến rng.engine().seed() và nó hoạt động như một sự quyến rũ.

Rất cám ơn!

+3

Rất vui khi nó hoạt động! Nhân tiện, bạn được phép (và khuyến khích) chấp nhận câu trả lời của riêng bạn, đặc biệt nếu nó kết hợp ý tưởng của nhiều người để giải quyết vấn đề của bạn. –

1

Tôi tin rằng boost::variate_generator<> tạo bản sao đối tượng boost::mt19937 gener của bạn. Vì vậy, khi bạn gieo lại bản sao của gener, nó không ảnh hưởng đến đối tượng rng đã được xây dựng . Xây dựng một đối tượng rng mới mỗi khi bạn gieo hạt nên cung cấp cho bạn hành vi mà bạn muốn (từ chối trách nhiệm: không được kiểm tra!)

+0

Tôi tin rằng việc khởi đầu lại mà là có một số ảnh hưởng đến rng, bởi vì tôi nhận được các giá trị lặp đi lặp lại -0,5887503675 và 0,2504171986. Nhưng sau đó tiếc là không phải ở tất cả những gì tôi mong đợi. –

+0

Tuyệt vời để xem vấn đề được giải quyết, nhưng tôi có thể hỏi tại sao 'boost :: variate_generator <>' tạo một bản sao của 'gener' trong trường hợp này? Tôi nghĩ rằng các OP thông qua tài liệu tham khảo khi viết 'tăng :: variate_generator >', tôi thiếu bất cứ điều gì? ... – Vokram

5

Bạn nên gọi normal.reset() sau khi gọi đến gener.seed(). Đó là quy định để đảm bảo rằng đầu ra của bình thường sẽ không phụ thuộc vào bất kỳ đầu ra trước đó từ gener.

(Sự phân bố có lẽ là bộ nhớ đệm một số trạng thái mà bạn cần phải hiểu rõ ràng.)

+0

Có nó trông giống như một vấn đề bộ nhớ đệm. Tôi đã làm như bạn đề nghị nhưng tôi vẫn nhận được kết quả tương tự ... –

+2

RNG thông thường được phân phối sử dụng [Biến đổi hộp-Muller] (http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform) tạo các số ngẫu nhiên theo cặp (xem: [Ví dụ về công thức số] (http://dimacs.rutgers.edu/~graham/code.html)) – Mike

1

Tuyệt vời để xem sự cố được giải quyết! Nhưng tôi đoán tôi chỉ tìm ra lý do tại sao phương pháp của Alan sẽ không hoạt động ...

Khi viết boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal), bạn không tạo một bản sao của gener vì đó là một cuộc gọi bằng cách tham khảo, nhưng bạn đã làm tạo một bản sao của normal với số variate_generate.

Vì vậy, thay vì normal.reset, chỉ đặt lại số normal gốc, bạn nên sử dụng rng.distribution().reset(). Nhưng bạn chỉ có thể giữ gener.seed(), mà tôi nghi ngờ sẽ có tác dụng tương tự như rng.engine().seed().

Tôi đã thử nghiệm nó trong mã của tôi và nó hoạt động như mong đợi.

Vâng, chỉ trong trường hợp ai sẽ chăm sóc :)

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