Math.random của JavaScript ngẫu nhiên như thế nào?


116

Trong 6 năm, tôi đã có một trang tạo số ngẫu nhiên 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 các diễn đàn và blog thảo luận (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 qua).

Hôm nay, ai đó đã gửi email cho tôi để nói với tôi rằng nó có thể không ngẫu nhiên như tôi nghĩ. Cô ấy đã thử tạo 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 một số chữ số. Thật vậy, tôi đã quấn hàm 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, đối với những con số rất lớn, sự thay đổi chỉ khoảng 2 bậc của độ lớn.

Tại sao?

Đây là phiên bản lặp lại, vì vậy bạn có thể tự mình thử:

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

Nó bao gồm cả cách triển khai đơn giản được lấy từ Mạng nhà phát triển Mozilla và một số mã từ năm 1997 mà tôi đã xóa trên một trang web không còn tồn tại ("Bộ lấy ngẫu nhiên trung tâm 1.3" của Paul Houle). Xem nguồn để xem cách hoạt động của từng phương pháp.

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


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

5
Nếu bạn đang tìm câu trả lời cho câu hỏi trong tiêu đề, hãy xem stackoverflow.com/questions/2344312/…
Andrew B.

Câu trả lời:


182

Cho các số 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 các 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à như thế.

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


11
Ý tưởng của bạn ngẫu nhiên có nghĩa là một cách hoàn hảo và phân bố đều là hấp dẫn ...

19
@ R.Pate - số ngẫu nhiên thế hệ không phải là sử dụng nhiều trừ khi nó được phân bố đều trên thang điểm từ lâu
annakata

3
Đọc lại lần nữa. @David chỉ cho biết có loại số nào giữa các giới hạn, không phải kết quả của việc chọn N số ngẫu nhiên. Tôi thừa nhận tiêu đề là sai lệch.
nikc.org

3
Đối với hồ sơ, tôi đã bình chọn cả câu trả lời này và câu trả lời của @ jwoolard. Tôi chọn câu này là câu trả lời được chấp nhận bởi vì các ví dụ làm cho nó rõ ràng như pha lê tại sao sự phân bố của các số lại bị lệch thành các số có nhiều chữ số hơn.
Andrew Hedges

1
@ andrew-hàng rào hoàn toàn đúng - đây là câu trả lời rõ ràng hơn, nhưng nhờ :)
jwoolard

56

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


8
Chính xác. Sự phân bố của số chữ số dự kiến ​​sẽ bị lệch. Tuy nhiên, sự phân bố của nhật ký số chữ số là đồng nhất.
Noldorin

45

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

Nếu bạn muốn các thứ tự cường độ khác nhau, tôi khuyên bạn nên sử dụng một hàm mũ để tạo ra cái được gọi là phân phối luật lũy thừa :

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

Hàm này sẽ cung cấp cho bạn số lượng gần giống các số có 1 chữ số với số có 2 chữ số và số có 3 chữ số.

Ngoài ra còn có các phân phối khác cho các số ngẫu nhiên như phân phối chuẩn (còn gọi là phân phối Gaussian).


Với thuật toán này, tôi đặt minimum = 1maximum = 10và đôi khi sẽ nhận được kết quả là 11. Bạn có thể muốn sử dụng Math.floorthay vìMath.round
Sam Eaton

1
Tại sao nó hoạt động? Nó có chuyển đổi phân phối đều thành phân phối mũ không?
shinzou

@shinzou Tôi đã hỏi trên math.stackexchange và nhận được một công thức hơi khác làm câu trả lời. Tôi đã thay đổi mã để phản ánh công thức toán học có nguồn gốc từ math.stackexchange.
Christian

20

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

Cá nhân tôi nghĩ rằng việc triển khai của tôi sẽ tốt hơn, mặc dù tôi đã đánh cắp nó khỏi XKCD , người LUÔN LUÔN phải được thừa nhận:

function random() {
  return 4; // Chosen by a fair dice throw. Guaranteed to be random.
}

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

Bắt buộc hay không, vì đó là xkcd, nó được quy. :)
Arafangion

2
OT: Tôi ngạc nhiên và hạnh phúc rằng "XKCD" là câu trả lời cho một câu hỏi Đại học Challenge tuần này: D
Matt Sách

2
Bergi: Một liên kết trực tiếp là không đủ?
Arafangion

Tôi nghĩ rằng họ có nghĩa là trò đùa không được trích dẫn chính xác ( "ngẫu nhiên = 4;" thay vì "trả lại 4;")
Eren Tantekin

18

Bài báo sau giải thích cách math.random () trong các trình duyệt Web chính (không) an toàn: "Theo dõi người dùng tạm thời trong các trình duyệt chính và rò rỉ và tấn công thông tin tên miền chéo" của Amid Klein (2008) . Nó không mạnh hơn các chức năng PRNG tích hợp sẵn của Java hoặc Windows.

Mặt khác, việc triển khai SFMT của giai đoạn 2 ^ 19937-1 yêu cầu 2496 byte trạng thái bên trong được duy trì cho mỗi chuỗi 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 là tuyệt vời, vượt xa những gì câu hỏi ban đầu là về.
Roland Illig

6

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 mà Javascript đang sử dụng. Lưu ý rằng tất cả các số được tạo đều kết thúc bằng "00".


1
Đó không phải là vấn đề của anh ấy trong trường hợp này.
Joey

3
@ Johannes - đó là một trong những vấn đề của mình :)
annakata

Sự phân phối của IEE754 không đồng đều. Có thể bạn có thể biểu diễn từ 0 đến 999 theo gia số của hai và có đủ độ chính xác cho điều đó để bạn nhận thấy phân phối đồng đều trên phạm vi đó nếu bạn chọn số nhiều lần. 10% sẽ là hai chữ số và 90% là ba chữ số. Tuy nhiên, khi bạn bắt đầu đạt đến những con số thực sự cao, mức tăng sẽ vượt quá 1. Bạn có thể chỉ có thể bước từ một nghìn tỷ tỷ lên một nghìn tỷ tỷ một nghìn chứ không phải nghìn tỷ tỷ lẻ. Mặc dù đối với số lượng / quy mô nhỏ, ảnh hưởng này sẽ không đáng kể đến không tồn tại. Tuy nhiên, hiệu ứng quy mô sẽ có nhiều tác động hơn.
jgmjgm

5

Tôi đã thử trình tạo số giả ngẫu nhiên JS trên Trò chơi hỗn loạn .

Tam giác Sierpiński của tôi nói rằng nó khá ngẫu nhiên: Fractal


2
Bạn có phiền chia sẻ mã hình tam giác ở đây và jsfiddle / jsbin để chúng tôi có thể dễ dàng kiểm tra nó trên thực tế cho các trình duyệt khác nhau không?
Fabrício Matté

1
Được, 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-Ba Lan và tôi còn rất nhiều việc.
zie1ony

1
@ zie1ony vài ngày nữa là hết.
trusktr

1
usp :( work, work, work Link: kubaplas.vot.pl/green/fractal Tham số đầu tiên là nr của đỉnh. Tham số thứ hai là giao điểm (từ 0 đến 1) của đoạn thẳng. Chỉ cần thử nghiệm.
zie1ony

4
Liên kết đã chết - có thể là repo Github?
Mark K Cowan

3

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


0

Các số không ngẫu nhiên phân bố đồng đều từ 1 đến N có cùng tính chất. Lưu ý rằng (theo một nghĩa nào đó) đó là vấn đề chính xác. Phân phối đồng đều trên 0-99 (dưới dạng số nguyên) có 90% số của nó có hai chữ số. Phân phối đồng đều trên 0-999999 có 905 số của nó có năm chữ số.

Bất kỳ bộ số nào (trong một số điều kiện không quá hạn chế) đều có mật độ. Khi ai đó muốn thảo luận về các con số "ngẫu nhiên", mật độ của những con số này nên được chỉ định (như đã lưu ý ở trên.) Mật độ chung là mật độ đồng nhất. Có những thứ khác: mật độ theo cấp số nhân, mật độ bình thường, v.v. Người ta phải chọn mật độ nào có liên quan trước khi đề xuất một bộ tạo số ngẫu nhiên. Ngoài ra, các con số đến từ một mật độ này thường có thể dễ dàng được chuyển đổi sang một mật độ khác bằng các phương tiện cẩn trọng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.