Số ngẫu nhiên trên C ++


12

Gần đây tôi đã quen với các ngôn ngữ hiện đại bao gồm một trình tạo ngẫu nhiên tốt, thường là Mersenne Twister; Bây giờ tôi đã trở lại C ++, tôi phải quyết định sử dụng cái gì.

Tôi đã tìm kiếm các triển khai Mersenne Twister và tôi nhận thấy có rất nhiều: có một cái nào được sử dụng nhiều hơn và phổ biến hơn không, hay tôi nên chọn một thứ giả sử chúng đều tốt như nhau?


1
Tôi thích sự tách biệt của bạn về C ++ và các ngôn ngữ hiện đại.
jcora

2
Có lẽ nói "cấp cao hơn" là phù hợp hơn.
o0 '.

Tôi nghĩ rằng câu hỏi này thuộc về stackoverflow
TravisG 18/03 '

5
Trên SO tôi sẽ đưa ra một câu trả lời khác bởi vì tôi không biết nó dành cho một công cụ trò chơi trái ngược với mô phỏng Monte Carlo cho các liệu pháp y tế, trong trường hợp không có 624 kích thước ngẫu nhiên có thể gây tử vong.

Câu trả lời:


19

C ++ 11 bao gồm một trình tạo Mersenne Twister theo mặc định như một phần của <random>giao diện mới . Ví dụ: để tạo các số nguyên thống nhất giữa [-10, 10] bằng MT:

std::mt19937 eng; // This is the Mersenne Twister
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

Hầu hết điều này cũng có sẵn trong bất kỳ trình biên dịch nào cung cấp TR1 mặc dù tên hơi khác nhau; std::tr1::mt19937std::tr1::uniform_int<int>.

Tôi thường cảnh báo mọi người tránh sử dụng Mersenne Twister. Đó là một thuật toán ổn nhưng rất nhiều sự phổ biến của nó chỉ là tiếp thị. 624 kích thước ngẫu nhiên là nhiều hơn hầu hết mọi người cần, và MT thực hiện các yêu cầu trạng thái tương đối nặng và khi thực hiện lại toàn bộ bảng, nó có thể thổi bộ đệm. Cá nhân tôi là một phần của xorshift , cung cấp các giai đoạn tuyệt vời và phân phối hợp lý cho mọi thứ mà trò chơi cần, với các yêu cầu nhỏ về bộ nhớ và CPU.

Tôi đã viết một trình tạo xorshift tương thích (hầu hết?) C ++ 11 - xorshift.hpp , xorshift.cpp - và đặt nó vào miền công cộng. Bạn có thể cắm cái này vào bất kỳ chức năng ngẫu nhiên hóa C ++ 11 nào, như trên:

xorshift eng;
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

5
Vâng, đó là loại câu trả lời tôi đang tìm kiếm, đó là lý do tại sao tôi đăng ở đây trên gamedev :)
o0 '.

1
Chỉ muốn lưu ý rằng không có gì trong các tệp bạn liên kết cho biết rằng chúng nằm trong miền công cộng. Cách thức hoạt động của luật bản quyền, thực sự cần phải có một lưu ý rõ ràng về điều đó, vì luật cho rằng "tất cả các quyền được bảo lưu" theo mặc định. Thực sự thậm chí còn an toàn hơn khi chỉ sử dụng một cái gì đó như giấy phép 2 điều khoản của MIT hoặc BSD, vì một số khu vực pháp lý về cơ bản không thừa nhận "đây là trong phạm vi công cộng" là ràng buộc về mặt pháp lý. Nếu bạn quan tâm đến việc mọi người sử dụng mã của mình, có thể đáng để quan tâm đến điều đó.
Sean Middleditch

1
@seanmiddleditch: Tôi đang nói rõ về nó ngay tại đây. Nếu bạn muốn nó theo giấy phép theo kiểu MIT, tôi sẽ theo sự dẫn dắt của SQLite và cung cấp cho bạn chỉ với 1000 đô la.

Việc thiếu nếu một tiêu đề trong mã khai báo bất cứ điều gì (mà SQLite làm, iirc) là vấn đề chính. Nếu bạn không quan tâm, điều đó thật tuyệt. Chỉ là cho bạn một đề nghị thân thiện.
Sean Middleditch

1

Một RNG khác mà tôi đã sử dụng trước đây cho các mục đích gamedev là RNG "nhỏ" của Bob Jenkins, được mô tả ở đây .

(Anh ta cũng có một RNG sức mạnh mã hóa được gọi là ISAAC, nhưng nó lớn hơn và chậm hơn và các trò chơi không cần mức độ sức mạnh đó.)


1
Điều đó có vẻ đắt hơn xorshift (4 xors và 3 ca so với 4 thêm, 6 ca, 2 or và xor), có thời gian tồi tệ hơn và có nguy cơ chu kỳ rất ngắn với một số khởi tạo nhất định. Nó trông nhanh nhưng không nhanh nhất; thời gian ổn nhưng không nơi nào gần tối ưu; chất lượng phân phối cơ bản tương tự như xorshift; Tôi không thấy bất kỳ lý do để sử dụng nó.

Đủ công bằng. Tôi không biết đủ về phân tích RNG để đào sâu vào các thuộc tính chu kỳ và phân phối.
Nathan Reed
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.