2013-07-22 42 views
6

Tôi rất ngạc nhiên khi thấy rằng đầu ra của chương trình này:Có bao nhiêu số ngẫu nhiên std :: uniform_real_distribution sử dụng?

#include <iostream> 
#include <random> 

int main() 
{ 
    std::mt19937 rng1; 
    std::mt19937 rng2; 
    std::uniform_real_distribution<double> dist; 

    double random = dist(rng1); 
    rng2.discard(2); 

    std::cout << (rng1() - rng2()) << "\n"; 

    return 0; 
} 

0 - ví dụ: std::uniform_real_distribution sử dụng hai số ngẫu nhiên để tạo ra một double giá trị ngẫu nhiên trong khoảng [0,1). Tôi nghĩ rằng nó sẽ chỉ tạo ra một và rescale đó. Sau khi suy nghĩ về nó, tôi đoán rằng điều này là bởi vì std::mt19937 sản xuất int 32 bit và gấp đôi kích thước này gấp đôi và do đó không "đủ ngẫu nhiên".

Câu hỏi: Làm cách nào để tìm ra con số này một cách tổng quát, tức là nếu trình tạo số ngẫu nhiên và loại dấu phẩy động là các loại tùy ý?

Chỉnh sửa: Tôi vừa nhận thấy rằng tôi có thể sử dụng std::generate_canonical thay vào đó, vì tôi chỉ quan tâm đến số ngẫu nhiên [0,1]. Không chắc chắn nếu điều này làm cho một sự khác biệt.

+0

Bạn không thể tìm thấy điều này một cách tổng quát. –

+2

@ R.MartinhoFernandes: vì ... – arne

+1

Như một sang một bên, hãy suy nghĩ về những gì nó có nghĩa là để "rescale" một số nguyên 32-bit cho một đôi 64-bit: có khoảng 2^62 giá trị kép riêng biệt. Có 2^32 giá trị int riêng biệt. Điều này có nghĩa rằng chỉ có ** một trong số hàng tỷ ** giá trị gấp đôi có thể là đại diện trong kết quả kép. Điều này rõ ràng là không thể chấp nhận được. – JohannesD

Trả lời

2

Đối template<class RealType, size_t bits, class URNG> std::generate_canonical tiêu chuẩn (phần 27.5.7.2) định nghĩa một cách rõ ràng số lượng các cuộc gọi đến các máy phát điện số ngẫu nhiên thống nhất (URNG) là

max (1, b/log_2 R),

nơi b là số bit tối thiểu trong phần mantissa của RealType và số bit được cung cấp cho tham số generate_canonical làm tham số mẫu. R là phạm vi các số mà URNG có thể trả về (URNG::max()-URNG::min()+1). Tuy nhiên, trong ví dụ của bạn điều này sẽ không tạo ra bất kỳ sự khác biệt nào, vì bạn cần 2 cuộc gọi đến mt19937 để điền vào 53 bit của phần định trị của giá trị kép.

Đối với các bản phân phối khác, tiêu chuẩn không cung cấp một cách chung để nhận bất kỳ thông tin nào về số lượng URNG tạo ra để có được một số phân bố.

Lý do có thể là đối với một số bản phân phối số ngẫu nhiên thống nhất cần thiết để tạo ra một số phân phối không cố định và có thể thay đổi từ cuộc gọi đến cuộc gọi. Một ví dụ là std::poisson_distribution, thường được triển khai dưới dạng vòng lặp để vẽ số ngẫu nhiên đồng nhất trong mỗi lần lặp cho đến khi sản phẩm của những con số này đạt đến một ngưỡng nhất định (xem ví dụ: implementation of the GNU C++ library (dòng 1523-1528)).

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