2009-06-30 70 views
96

Trong 6 năm tôi đã có một trang random number generator trên trang web của mình. Trong một thời gian dài, đó là kết quả đầu tiên hoặc thứ hai trên Google cho "trình tạo số ngẫu nhiên" và đã được sử dụng để quyết định hàng chục, nếu không phải hàng trăm cuộc thi và bản vẽ trên diễn đàn thảo luận và blog (tôi biết vì tôi thấy các liên kết giới thiệu trong nhật ký web và thường đi xem).Math.random của JavaScript ngẫu nhiên như thế nào?

Hôm nay, một người nào đó đã gửi email cho tôi để cho tôi biết nó có thể không giống như tôi nghĩ. Cô đã thử tạo ra các số ngẫu nhiên rất lớn (ví dụ: từ 1 đến 10000000000000000000) và nhận thấy rằng chúng hầu như luôn có cùng số chữ số. Thật vậy, tôi bọc chức năng trong một vòng lặp để tôi có thể tạo ra hàng nghìn con số và chắc chắn đủ, với số lượng rất lớn, biến thể chỉ khoảng 2 đơn vị độ lớn.

Tại sao?

Dưới đây là phiên bản lặp, vì vậy bạn có thể thử nó ra cho chính mình:

http://andrew.hedges.name/experiments/random/randomness.html

Nó bao gồm cả việc thực hiện đơn giản lấy từ Mozilla Developer Network và một số mã từ năm 1997 mà tôi swiped khỏi một trang web không còn tồn tại ("Randomizer 1.3" của Paul Houle). Xem nguồn để xem mỗi phương thức hoạt động như thế nào.

Tôi đã đọc hereelsewhere về Mersenne Twister. Điều tôi quan tâm là lý do tại sao sẽ không có sự thay đổi lớn hơn trong các kết quả từ hàm tích hợp sẵn của JavaScript Math.random. Cảm ơn!

+1

sarnath'd bởi * mọi * – annakata

+0

Tôi không nhận được nó. "sarnath'd"? –

+0

"sarnath'd" như trong, bị đánh vào cú đấm, hoặc trong trường hợp này, câu trả lời – maetl

Trả lời

153

số Với từ 1 đến 100.

  • 9 có 1 chữ số (1-9)
  • 90 có 2 chữ số (10-99)
  • 1 có 3 chữ số (100)

Cho số từ 1 đến 1000.

  • 9 có 1 chữ số
  • 90 có 2 chữ số
  • 900 có 3 chữ số
  • 1 có 4 chữ số

và vân vân.

Vì vậy, nếu bạn chọn ngẫu nhiên, thì phần lớn các số được chọn sẽ có cùng số chữ số, vì phần lớn các giá trị có thể có cùng số chữ số.

+7

Ý tưởng về ý nghĩa ngẫu nhiên của bạn là hoàn toàn và phân bố đồng đều ... –

+13

@ R.Pate - số ngẫu nhiên * thế hệ * không được sử dụng nhiều trừ khi nó được phân phối đồng đều trên một quy mô dài – annakata

+1

Đọc lại. @David chỉ ghi rõ loại số có giữa các giới hạn, không phải là kết quả của việc chọn N số ngẫu nhiên. Tôi thừa nhận việc chuẩn độ là sai lầm. –

13

Trông hoàn toàn ngẫu nhiên với tôi! (Gợi ý:. Đó là trình duyệt phụ thuộc)

Cá nhân, tôi nghĩ rằng thực hiện của tôi sẽ tốt hơn, mặc dù tôi đã đánh cắp nó đi từ XKCD, LUÔN LUÔN nên được thừa nhận:

random = 4; // Chosen by a fair dice throw. Guaranteed to be random. 
+16

1 cho đề cập đến nó phụ thuộc vào trình duyệt, -1 cho vay xkcd mà không cần liên kết. –

+0

Được yêu cầu hay không, vì nó là xkcd, nó được phân bổ. :) – Arafangion

+1

OT: Tôi ngạc nhiên và hạnh phúc rằng "XKCD" là câu trả lời cho câu hỏi của Đại học Challenge trong tuần này: D –

49

Kết quả của bạn đang thực sự mong đợi. Nếu các số ngẫu nhiên được phân bố đồng đều trong khoảng từ 1 đến 10^n, thì bạn sẽ mong đợi khoảng 9/10 số có chữ số n và thêm 9/100 số có chữ số n-1.

+8

Chính xác. Việc phân phối số chữ số dự kiến ​​sẽ bị sai lệch. Tuy nhiên, việc phân phối nhật ký số chữ số shoudl sẽ đồng đều. – Noldorin

5

Nếu bạn sử dụng một số như 10000000000000000000, bạn sẽ vượt quá độ chính xác của kiểu dữ liệu Javascript đang sử dụng. Lưu ý rằng tất cả các số được tạo kết thúc bằng "00".

+1

Tuy nhiên, đó không phải là vấn đề của anh ta trong trường hợp này. – Joey

+3

@Johannes - đó là * một * các vấn đề của anh ấy :) – annakata

3

Vâng, nếu bạn đang tạo số lên tới, giả sử, 1e6, bạn hy vọng sẽ nhận được tất cả các số có xác suất xấp xỉ bằng nhau. Điều đó cũng có nghĩa là bạn chỉ có một trong mười cơ hội nhận được một con số với một chữ số ít hơn. Một trong một trăm cơ hội nhận được hai chữ số ít hơn, vv Tôi nghi ngờ bạn sẽ thấy nhiều sự khác biệt khi sử dụng một RNG, bởi vì bạn có một phân phối thống nhất trên các con số, không logarithm của họ.

37

Có nhiều loại ngẫu nhiên khác nhau. Math.random cung cấp cho bạn phân phối đồng đều các số.

Nếu bạn muốn thứ tự khác nhau của cường độ, tôi sẽ đề nghị sử dụng một hàm mũ để tạo ra những gì được gọi là một power law distribution:

function random_powerlaw(mini, maxi) { 
    return Math.ceil(Math.exp(Math.random()*(Math.log(maxi)-Math.log(mini)))*mini) 
} 

Chức năng này sẽ cho bạn khoảng cùng một số số 1 chữ số như 2- chữ số và số gồm 3 chữ số.

Ngoài ra còn có các bản phân phối khác cho các số ngẫu nhiên như normal distribution (còn được gọi là phân phối Gaussian).

+2

Đó là hữu ích, cảm ơn! –

+0

Với thuật toán này, tôi đặt 'tối thiểu = 1' và' tối đa = 10' và đôi khi sẽ nhận được 11 kết quả. Bạn có thể sử dụng 'Math.floor' thay vì' Math.round' –

+0

@SamEaton: Cảm ơn, tôi đã cập nhật nó. – Christian

17

Bài sau giải thích cách math.random() trong các trình duyệt Web chính là (un) an toàn: "Temporary user tracking in major browsers and Cross-domain information leakage and attacks" by Amid Klein (2008). Nó không mạnh hơn các hàm PRNG được xây dựng trong Java hoặc Windows điển hình.

Mặt khác, triển khai SFMT của giai đoạn 2^19937-1 yêu cầu 2496 byte của trạng thái nội bộ được duy trì cho mỗi trình tự PRNG. Một số người có thể coi đây là chi phí không thể tha thứ.

+1

+1: Bài báo được đề cập rất hay, vượt xa câu hỏi ban đầu. –

+0

Thx @trikly để cập nhật liên kết. – jj1bdx

4

Tôi đã thử trình tạo số giả ngẫu nhiên JS trên Chaos Game.

My Sierpiński triangle nói nó khá ngẫu nhiên: Fractal

+2

Bạn có nhớ chia sẻ mã tam giác ở đây và jsfiddle/jsbin để chúng tôi có thể dễ dàng kiểm tra nó trong thực tế cho các trình duyệt khác nhau không? –

+1

OK, nhưng hãy cho tôi vài ngày, vì tôi cần dịch mã sang tiếng Anh. Bây giờ nó là tiếng anh đánh bóng và tôi có rất nhiều công việc. – zie1ony

+1

@ zie1ony một vài ngày nữa. – trusktr

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