2010-08-17 9 views
5

Tôi khá thích có thể tạo cùng một bộ dữ liệu giả ngẫu nhiên nhiều lần, đặc biệt là với việc chỉnh sửa mã thử nghiệm. Qua quan sát, tôi có thể nói rằng rand() dường như cung cấp cùng một chuỗi số mỗi lần *.Liệu rand() của stdlib có luôn giống nhau không?

Có đảm bảo thực hiện việc này để thực hiện lặp lại trên cùng một máy/cho các máy khác nhau/cho các kiến ​​trúc khác nhau không?

* Đối với cùng một hạt giống rõ ràng.

Trả lời

18

Có, được cung cấp cùng một môi trường cho chương trình. Từ tiêu chuẩn C § 7.20.2.2/2,

Chức năng srand sử dụng lập luận như một hạt giống cho một chuỗi mới của số giả ngẫu nhiên để được trả lại bởi các cuộc gọi tiếp theo để rand. Nếu srand sau đó được gọi với cùng giá trị hạt giống, phải lặp lại chuỗi số ngẫu nhiên giả. Nếu rand được gọi trước khi bất kỳ cuộc gọi đến srand đã được thực hiện, cùng một chuỗi được tạo ra như khi srand là lần đầu tiên được gọi với một giá trị hạt giống 1.

Tất nhiên, điều này giả định nó được sử dụng thực hiện tương tự chi tiết (tức là cùng một máy, cùng một thư viện tại cùng một thời gian thực hiện). Tiêu chuẩn C không yêu cầu thuật toán tạo số ngẫu nhiên chuẩn, do đó, nếu bạn chạy chương trình với một thư viện chuẩn C khác, người ta có thể nhận được một chuỗi số ngẫu nhiên khác.

Xem câu hỏi Consistent pseudo-random numbers across platforms nếu bạn cần một chuỗi số ngẫu nhiên được bảo đảm và di động với một hạt giống đã cho.

+0

tiêu chuẩn WIN ... –

+0

OK. Tôi đồng ý rằng đối với một lib thời gian chạy cụ thể, trình tự sẽ giống nhau. Vì vậy, một khi một ứng dụng được xây dựng (chống lại một phiên bản thời gian chạy cụ thể) nó sẽ luôn tạo ra cùng một trình tự. Nhưng ở mức độ này với các phiên bản khác nhau của thời gian chạy (ví dụ trên các phiên bản OS/kiến ​​trúc/thời gian chạy), v.v. Điều đó có nghĩa là tiêu chuẩn xác định việc triển khai chính xác cho thuật toán rand(). chúng phù hợp). –

+3

Nó không mở rộng trên các phiên bản khác nhau của các thời gian chạy - và nếu bạn liên kết động với việc thực hiện 'rand()', nó có khả năng có thể hoạt động khác nhau mà không cần xây dựng lại bất cứ thứ gì. –

1

số

Tiêu chuẩn C nói:

Nếu srand sau đó được gọi với giá trị hạt giống, trình tự của số giả ngẫu nhiên được lặp đi lặp lại.

Nhưng không nơi nào nó nói chuỗi thứ tự của các số giả ngẫu nhiên thực sự là gì - vì vậy nó khác nhau giữa các lần triển khai.

Đảm bảo duy nhất được thực hiện là rand() sẽ cung cấp cùng một chuỗi số cho một hạt giống nhất định cho một triển khai nhất định. Không có gì đảm bảo rằng trình tự sẽ giống nhau trên các máy khác nhau hoặc các kiến ​​trúc khác nhau - và nó gần như chắc chắn sẽ không như vậy.

0

Nếu bạn cần sử dụng cùng một số giả ngẫu nhiên cho mục đích thử nghiệm, một điều bạn có thể làm là sử dụng srand để tạo chuỗi số ngẫu nhiên dài và ghi chúng vào tệp/cơ sở dữ liệu. Sau đó, viết một hàm "generator number random" di động trả về các giá trị tuần tự từ tệp đó. Bằng cách đó, bạn có thể yên tâm rằng bạn đang sử dụng cùng một dữ liệu đầu vào bất kể nền tảng, triển khai srand hoặc giá trị của hạt giống.

+0

Ý tưởng hay. Nếu tôi có một yêu cầu để làm điều đó, tôi chắc chắn sẽ có cách tiếp cận đó. Câu hỏi của tôi được sinh ra nhiều hơn từ sự tò mò hơn là nhu cầu cho một chuỗi đã biết. – Joe

+0

Hoặc bạn chỉ có thể viết một chức năng ngẫu nhiên của riêng bạn? – dcousens

0

Khi chuyển sang một máy khác/thời gian chạy/bất kỳ điều gì bạn có thể không may mắn. Có một lựa chọn khác có thể là họ của các chức năng drand48. Chúng được chuẩn hóa để sử dụng cùng một thuật toán trên tất cả các máy.

2

Đảm bảo cung cấp cùng một trình tự cho cùng một hạt giống được chuyển đến srand() - nhưng chỉ trong thời gian thực hiện một chương trình. Nói chung, nếu thực hiện có một sự lựa chọn trong hành vi, không có yêu cầu cụ thể cho sự lựa chọn đó vẫn giữ nguyên trong các lần thực hiện tiếp theo.

Nó sẽ phù hợp để thực hiện chọn "hạt giống chính" ở mỗi lần khởi động chương trình và sử dụng nó để làm rối loạn trình tạo số giả ngẫu nhiên theo cách khác nhau mỗi khi chương trình bắt đầu.

Nếu bạn muốn xác định nhiều hơn, bạn nên triển khai PRNG với các tham số cụ thể trong chương trình của bạn.

0

Nếu bạn đang ở trong một UNIX/Linux môi trường bạn sẽ nhìn thấy drand48()srand48 () tại trang người đàn ông của bạn nếu bạn không phải là bạn có thể thấy online manuals cho ngôn ngữ C. Các nguyên mẫu có thể được tìm thấy tại /usr/include/stdlib.h. Phương pháp đầu tiên sử dụng Phương pháp tiếp tuyến tuyến tính thường được sử dụng trong Mô phỏng.

Nếu bạn cung cấp cùng một hạt giống cho srand48() tức là srand48 (2) và sau đó đặt dran48() trong vòng lặp for thì chuỗi sẽ giống nhau mỗi lần. tức là

include stdio.h 
include stdlib.h 
double drand48(); 
int main(void){ 
    int i; 
    double rn; 
    srand48(2); 
    for(i=0; i<10; i++){ 
     randNum = drand48(); 
     printf("%.6l\n", randNum); 
     return 0; 
}