2011-10-13 27 views

Trả lời

26

Bạn cần để gieo rắc bộ tạo số ngẫu nhiên của bạn:

Hãy thử đặt này vào lúc bắt đầu của chương trình:

srand (time(NULL)); 

Lưu ý rằng bạn cần phải #include <ctime>.

Ý tưởng ở đây là gieo hạt RNG với một số khác nhau mỗi khi bạn khởi chạy chương trình. Bằng cách sử dụng thời gian làm hạt giống, bạn sẽ nhận được một số khác nhau mỗi lần bạn khởi chạy chương trình.

+0

Hmm chính xác điều đó có nghĩa là gì khi gieo hạt? – mystycs

+4

Về cơ bản, RNG không thực sự ngẫu nhiên. Họ sử dụng một công thức để tạo ra các số ngẫu nhiên dường như (giả). Và như vậy họ cần một "điểm khởi đầu" để bắt đầu tạo ra một chuỗi. Nếu bạn không hạt giống, nó sẽ sử dụng cùng một hạt giống mặc định và tạo ra cùng một trình tự mỗi lần. – Mysticial

+2

Để có kết quả tốt hơn, hãy gọi 'rand' một lần sau' srand' và vứt bỏ giá trị trả về. Nó chỉ ra rằng hạt giống tương tự tạo ra một giá trị đầu tiên tương tự, nhưng nó phân kỳ nhanh chóng. –

7

Bạn cần cung cấp cho bộ tạo số randum một hạt giống. Điều này có thể được thực hiện bằng cách lấy thời gian hiện tại, vì đây là hy vọng một số loại ngẫu nhiên.

#include <cstdlib> 
#include <ctime> 
using namespace std; 

int main() 
{ 
    int r; 
    srand(time(0)); 
    r = rand(); 
    return 0; 
} 
0

Trình tạo số giả ngẫu nhiên lấy số bắt đầu hoặc hạt giống, sau đó tạo số tiếp theo theo thứ tự từ này. Đó là lý do tại sao chúng được gọi là giả ngẫu nhiên, bởi vì nếu chúng luôn sử dụng cùng một giá trị bắt đầu, chúng sẽ tạo ra cùng một chuỗi các số như trình tạo lib chuẩn C. Điều này có thể được cố định bằng cách cho máy phát điện một giá trị bắt đầu sẽ thay đổi vào lần tiếp theo chương trình được chạy như thời gian hiện tại.

Dù sao, mã bạn đang tìm kiếm giống như những người khác đã nói là:

srand(time(0)); //Seed the generator, give it a starting value 
+0

Không, họ ' được gọi là giả ngẫu nhiên bởi vì chúng không thực sự ngẫu nhiên theo nghĩa toán học, chỉ là một xấp xỉ. PRNG tạo ra các số riêng biệt mỗi lần nó chạy vẫn là giả tạo. –

+0

@KeithThompson Tôi biết, tôi có nghĩa là đó là lý do loại PRNG cụ thể này là PRNG. Nói chung, một PRNG được gọi là giả ngẫu nhiên, bởi vì nó sử dụng một thuật toán xác định để tìm mỗi giá trị của chuỗi, đúng không? – jgon

1

Chức năng rand() là đặc biệt cần thiết để sản xuất cùng một chuỗi các con số khi hạt giống với một hạt giống cho trước (bằng cách gọi srand()) ; mỗi giá trị hạt giống có thể chỉ định một chuỗi. Và nếu bạn không bao giờ gọi srand(), bạn sẽ nhận được cùng một chuỗi bạn có thể nhận được bằng cách gọi srand(1) trước khi có bất kỳ cuộc gọi nào đến rand().

(Điều này không áp dụng trên các triển khai C hoặc C++ khác nhau.)

Điều này có thể hữu ích cho mục đích thử nghiệm. Ví dụ: nếu có lỗi trong chương trình của bạn, bạn có thể tạo lại bằng cách chạy lại nó với cùng một hạt giống, đảm bảo rằng (chặn các hành vi không thể đoán trước khác), bạn sẽ nhận được cùng một chuỗi số giả ngẫu nhiên.

Gọi srand(time(NULL)) là cách được khuyến nghị thông thường để nhận được nhiều số giả ngẫu nhiên không thể đoán trước. Nhưng nó không hoàn hảo. Nếu chương trình của bạn chạy hai lần trong cùng một giây, có thể bạn sẽ nhận được cùng một chuỗi, bởi vì time() (thường) có độ phân giải 1 giây. Và các triển khai “rand()” điển hình là không phải là đủ tốt để sử dụng mật mã; nó quá dễ dàng cho kẻ tấn công để đoán những con số bạn sẽ nhận được.

Có một số triển khai số ngẫu nhiên khác. Các hệ thống Linux có hai thiết bị giả, /dev/random/dev/urandom, từ đó bạn có thể đọc các giá trị byte giả ngẫu nhiên chất lượng cao hợp lý.Một số hệ thống có thể có các chức năng như random(), drand48(), v.v. Và có rất nhiều thuật toán; Tôi đã nghe những điều tốt đẹp về Mersenne Twister.

Đối với nội dung nào đó như trò chơi, nơi bạn không mong đợi hoặc quan tâm đến người chơi đang cố gắng gian lận, srand(time(NULL))rand() có lẽ là đủ tốt. Vì mục đích nghiêm túc hơn, bạn nên nhận lời khuyên từ một người biết nhiều hơn về công cụ này hơn tôi.

Mục 13 của comp.lang.c FAQ có một số thông tin rất tốt về việc tạo số ngẫu nhiên giả.

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