Cách tôi học được ban đầu là gieo giống bộ tạo số ngẫu nhiên với srand(time(NULL))
và sau đó sử dụng các cuộc gọi tới rand()
để tạo các số ngẫu nhiên. Vấn đề với cách tiếp cận này là nếu tôi chạy chương trình của tôi nhiều lần trong cùng một giây, các số ngẫu nhiên được tạo sẽ luôn giống nhau. Một cách tốt xung quanh điều này là gì?Cách tốt nhất để hạt giống srand() là gì?
Trả lời
Bên cạnh việc sử dụng thời gian, một cách phổ biến khác để gộp hàm rand của bạn là sử dụng id tiến trình của chương trình, vì nó được đảm bảo là duy nhất.
Mã thực tế là nền tảng phụ thuộc, nhưng nếu bạn đang ở trên Windows, tôi tin rằng bạn có thể sử dụng chức năng GetCurrentProcessId()
, như trong
srand(GetCurrentProcessId());
Bằng cách này, bạn sẽ nhận được cùng một dãy số rand mỗi khi bạn gọi hàm 'rand'. – prehistoricpenguin
@prehistoricpenguin Ý của bạn là gì? – Matt
@prehistoricpenguin, Chỉ khi quá trình của bạn có cùng một PID mỗi lần. Đó là lý do tại sao bạn nên trộn nó với chức năng thời gian. – chris
Bên cạnh nhập thời điểm đó, bạn có thể thêm thời gian CPU để điều này, mà tôi tin rằng có thể làm với đồng hồ(). Vì vậy, nó sẽ trông như thế này: srand(time() + clock())
.
int pid ; // get it as per your OS
timeval t;
gettimeofday(&t, NULL);
srand(t.tv_usec * t.tv_sec * pid);
thời gian mang đến cho bạn giá trị dựa trên second
. gettimeofday được dựa trên microseconds
. Vì vậy, ít cơ hội của cùng một hạt giống xảy ra. Ngoài ra, bạn cũng đang sử dụng id tiến trình.
Trên hệ thống POSIX, hãy sử dụng clock_gettime
để nhận thời gian hiện tại bằng nano giây. Nếu bạn không cần nhiều bit, bạn có thể quên PRNG và sử dụng các bit có thứ tự thấp của thời gian làm số ngẫu nhiên của bạn trực tiếp. :-)
Tại sao lại là downvote? – Jean
Tôi đoán ai đó không thích ý tưởng của tôi về việc sử dụng các bit thấp của thời gian hiện tại cho RNG. Tuy nhiên, do các yếu tố ảnh hưởng đến chúng (độ trễ của bộ nhớ, số lần truy cập bộ nhớ cache/lỗi, TLB nhớ, hoán đổi, ngắt thời gian, lập lịch, ...) và thực tế là nano giây tương ứng với chu trình trên các máy hiện đại, chúng khá là chết tiệt nguồn entropy tốt. –
Tôi đồng ý. Nó vừa thông minh vừa tao nhã. Do đó câu hỏi của tôi. Tôi nhìn bối rối tại downvote cho câu trả lời thích hợp để phát hành trong tầm tay. Nó khá nhiều giải quyết các câu hỏi (chạy chương trình nhiều lần trong cùng một giây và nhận được kết quả tương tự mỗi lần). – Jean
Nếu * nix, Tại sao bạn không đọc trực tiếp từ /dev/random
?
Ngoài ra, bạn có thể thu thập nhiễu từ các thiết bị khác, như bàn phím, chuột hoặc nhiệt độ CPU.
Bạn có thể sử dụng gia tốc kế và sử dụng nó để thu thập tiếng ồn từ sóng biển. Gió cũng tạo ra tiếng ồn.
Tôi tin rằng Glib cung cấp một chức năng, g_random_int()
trong đó tạo ra các số ngẫu nhiên phân phối đều nhau một cách nhanh chóng và di động.
Hoặc bạn chỉ có thể đọc số lượng tệp thời gian trong /tmp
và sử dụng số đó để cấp srand()
với hàm time.h
hoặc đọc nội dung của một tệp trong /tmp
.
Bạn có thể đọc từng tệp từ /usr/bin
hoặc /
và thu thập một số thực phẩm cho srand()
.
Mr -1, tôi rất mong được đọc lý do. – yeyo
Bạn có thể sử dụng phương pháp cụ thể theo hệ thống để có độ chính xác cao hơn. Ví dụ, Windows có 'GetTickCount'. * nix có [clock_gettime] (http://linux.die.net/man/3/clock_gettime). – chris
Tiêu đề và thân câu hỏi của bạn đang hỏi hai điều khác nhau. – Pubby
Không chạy chương trình liên tiếp nhanh chóng? Nhận hẹn giờ với độ chính xác cao hơn? –