2009-03-16 36 views
5

Tôi muốn cung cấp một số và sau đó nhận một tập hợp các số ngẫu nhiên. Tuy nhiên, tôi muốn những con số đó giống nhau bất kể máy tính nào tôi chạy nó (giả sử tôi cung cấp cùng một hạt giống).Số ngẫu nhiên xác định Các luồng trong C++ STL

Về cơ bản câu hỏi của tôi là: trong C++, nếu tôi tận dụng rand(), nhưng cung cấp srand() với một hạt giống người dùng định nghĩa chứ không phải là thời điểm hiện tại, tôi sẽ có thể tạo ra các dòng số ngẫu nhiên cùng trên bất kỳ máy tính?

Trả lời

5

srand() & rand() không nằm trong STL. Chúng thực sự là một phần của thời gian chạy C. Có, họ sẽ tạo ra các kết quả tương tự miễn là nó cùng thực hiện srand()/rand().

Tùy thuộc vào nhu cầu của bạn, bạn có thể muốn xem xét sử dụng Boost.Random. Nó cung cấp một số máy phát điện số ngẫu nhiên chất lượng cao.

+0

Gonna phải nói +1 trên Boost.Random. Hoạt động tốt và thậm chí họ có các lớp xác định cụ thể. – rlbond

4

Giả sử việc triển khai rand() giống nhau, có. Cách đơn giản nhất để đảm bảo điều này là bao gồm triển khai rand() đã biết với chương trình của bạn - hoặc được bao gồm trong mã nguồn của dự án của bạn hoặc dưới dạng một thư viện mà bạn có thể quản lý.

+0

"Mọi" là một từ LỚN. Đủ điều kiện này với "Hầu hết" thay vì "Mọi" là cần thiết. Hầu hết các RNG hiện đại được thiết kế để hoạt động nhất quán trên hầu hết các gia đình phần cứng 32 bit. Nhưng điều đó không nói gì về các máy 64-bit hoặc phần cứng đặc biệt hiếm. –

+0

Đó là lý do tại sao tôi nói rằng bạn cần phải có một bản sao của rand() bạn có thể kiểm soát hoặc ít nhất là dự đoán. – greyfade

+0

Đủ công bằng :-) Điều duy nhất khác để đảm bảo là nó di động về mặt dữ liệu cho tất cả các kiến ​​trúc mục tiêu của bạn. –

0

Tôi tin rằng nếu bạn cung cấp với srand với cùng một hạt giống, bạn sẽ nhận được kết quả tương tự. Đó là khá nhiều định nghĩa của một hạt giống về số lượng giả ngẫu nhiên máy phát điện.

7

Có hàng tá PRNG có sẵn dưới dạng thư viện. Chọn một. Tôi có xu hướng sử dụng Mersenne Twister.

Bằng cách sử dụng thư viện được cung cấp bên ngoài, bạn bỏ qua nguy cơ thực thi lạ hoặc lỗi của thư viện ngôn ngữ rand(). Miễn là các nền tảng của bạn đều tuân theo cùng ngữ nghĩa toán học, bạn sẽ nhận được kết quả nhất quán.

MT là một yêu thích của tôi bởi vì tôi là một nhà vật lý, và tôi sử dụng những thứ này cho Monte Carlo, nơi đảm bảo phân phối bình đẳng với kích thước cao là quan trọng. Nhưng không sử dụng MT làm PRNG mã hóa!

+0

Vì tò mò, tại sao không sử dụng MT cho mật mã? Tâm trí chia sẻ một liên kết? (Đó là một câu hỏi trung thực, tôi không cố gắng để được snarky :-) –

+0

Nó dễ dàng dự đoán từ số lượng nhỏ các đầu ra biết. Có một liên kết trong bài viết wikipedia. – dmckee

+1

http://en.wikipedia.org/wiki/Mersenne_twister#Application –

0

Có. Đối với một hạt giống đã cho (giá trị bắt đầu), chuỗi số rand() trả về sẽ luôn giống nhau.

+0

Bạn nên hội đủ điều kiện này với "triển khai thực hiện của rand()". Không có hai PRNG nào được đảm bảo sản xuất cùng một chuỗi. – greyfade

1

Không, ANSI C chuẩn chỉ xác định rằng rand() phải xuất một dòng số nguyên ngẫu nhiên giữa 0 và RAND_MAX, trong đó phải có ít nhất 32767 (source). Luồng này phải được xác định chỉ trong đó, đối với một thực hiện nhất định trên một máy nhất định, nó phải tạo ra cùng một luồng nguyên cho cùng một hạt giống.

Bạn muốn có PRNG di động.Mersenne Twister (nhiều triển khai được liên kết ở phía dưới) là khá dễ dàng, như là Ben Pfaff's homegrown C99-compliant PRNG. Boost.Random cũng không sao; khi bạn viết mã của mình bằng C++, việc sử dụng Boost không hạn chế lựa chọn nền tảng của bạn nhiều (mặc dù một số trình biên dịch "ít hơn" (nghĩa là không tuân thủ) có thể gặp khó khăn khi sử dụng quá trình lập trình meta mẫu). Đây thực sự là một vấn đề đối với các nền tảng nhúng khối lượng thấp và có lẽ là các kiến ​​trúc nghiên cứu mới, vì vậy nếu bằng "bất kỳ máy tính nào", bạn có nghĩa là "bất kỳ nền tảng x86/PPC/ARM/SPARC/Alpha/etc nào mà GCC nhắm tới", bất kỳ ở trên nên làm tốt.