Hiểu về sự ngẫu nhiên của người Viking


829

Tôi không thể hiểu được cái này, cái nào ngẫu nhiên hơn?

rand()

HOẶC :

rand() * rand()

Tôi đang tìm thấy nó một lời trêu ghẹo não thực sự, bạn có thể giúp tôi không?


BIÊN TẬP:

Theo trực giác tôi biết rằng câu trả lời toán học sẽ là chúng ngẫu nhiên như nhau, nhưng tôi không thể không nghĩ rằng nếu bạn "chạy thuật toán số ngẫu nhiên" hai lần khi bạn nhân hai số đó với nhau, bạn sẽ tạo ra thứ gì đó ngẫu nhiên hơn là chỉ làm nó một lần


162
Bạn có ý nghĩa gì bởi "ngẫu nhiên hơn"?
dan04

55
Như những người khác đã nêu, hai số lượng này không có cùng phân phối. Xem mathworld.wolfram.com/Uniform ProducttDistribution.html để biết bản phân phối mà bạn thực sự nhận được. So sánh điều này với một số ngẫu nhiên thống nhất duy nhất, trong đó tất cả các giá trị trong khoảng đều có khả năng như nhau, vì vậy hàm mật độ xác suất là một đường thẳng nằm ngang.
bnaul

44
Tôi thực sự khuyên bạn nên đọc Ngẫu nhiên ngẫu nhiên trên WTF hàng ngày . Đặc biệt đọc bình luận này , nơi họ phân tích đầu ra của số ngẫu nhiên mới này. Thông điệp cần loại bỏ đó là: các thao tác tùy ý trên các số ngẫu nhiên không nhất thiết dẫn đến đầu ra ngẫu nhiên .
gièm pha

51
Ngoài ra: Theo trực giác tôi biết rằng câu trả lời toán học sẽ là chúng ngẫu nhiên như nhau - nếu bạn có thể làm toán bằng trực giác một mình, chúng ta sẽ không cần tất cả các biểu tượng đẫm máu đó: P
detly

92
Đừng mang số liệu thống kê và trực giác đến cùng một nhóm ....
Tiến sĩ belisarius

Câu trả lời:


1481

Chỉ cần làm rõ

Mặc dù các câu trả lời trước là đúng bất cứ khi nào bạn cố gắng phát hiện tính ngẫu nhiên của biến giả ngẫu nhiên hoặc phép nhân của nó, bạn nên lưu ý rằng trong khi Random () thường được phân phối đồng đều, Random () * Random () thì không.

Thí dụ

Đây là mẫu phân phối ngẫu nhiên thống nhất được mô phỏng thông qua biến giả ngẫu nhiên:

Biểu đồ ngẫu nhiên ()

        BarChart[BinCounts[RandomReal[{0, 1}, 50000], 0.01]]

Trong khi đây là phân phối bạn nhận được sau khi nhân hai biến ngẫu nhiên:

Biểu đồ ngẫu nhiên () * Ngẫu nhiên ()

        BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] * 
                                 RandomReal[{0, 1}, 50000], {50000}], 0.01]]

Vì vậy, cả hai đều là ngẫu nhiên, nhưng phân phối của chúng rất khác nhau.

Một vi dụ khac

Trong khi 2 * Random () được phân phối đồng đều:

Biểu đồ 2 * Ngẫu nhiên ()

        BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]

Ngẫu nhiên () + Ngẫu nhiên () thì không!

Biểu đồ ngẫu nhiên () + Ngẫu nhiên ()

        BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + 
                                 RandomReal[{0, 1}, 50000], {50000}], 0.01]]

Định lý giới hạn trung tâm

Các giới hạn trung tâm lý khẳng định rằng tổng của Random () có xu hướng một phân phối chuẩn như các điều khoản gia tăng.

Chỉ với bốn điều khoản bạn nhận được:

Biểu đồ ngẫu nhiên () + Ngẫu nhiên () + Ngẫu nhiên () + Ngẫu nhiên ()

BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000] +
                   Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000],
                   {50000}],
         0.01]]  

Và ở đây, bạn có thể thấy đường từ đồng phục đến phân phối bình thường bằng cách thêm 1, 2, 4, 6, 10 và 20 biến ngẫu nhiên phân phối đồng đều:

Biểu đồ số lượng khác nhau của các biến ngẫu nhiên được thêm vào

Biên tập

Một vài khoản tín dụng

Cảm ơn Thomas Ahle đã chỉ ra trong các ý kiến ​​rằng các phân phối xác suất hiển thị trong hai hình ảnh cuối cùng được gọi là phân phối Irwin-Hall

Cảm ơn Heikechức năng [] rách tuyệt vời của cô


41
+1. Vì OP có thể muốn phân phối đồng đều, đây sẽ là câu trả lời được chấp nhận. Và nếu bạn đã làm rand()+rand(), bạn sẽ kết thúc với phân phối kiểu "2d6" với một trung tâm chất béo.
Thilo

8
Điều này rất thú vị, nhưng nó giết chết tôi ở bên trong cách chống trực giác. Tôi sẽ cung cấp một cái nhìn kỹ lưỡng hơn sau khi tôi đọc thêm một chút về phân phối. Cảm ơn rât nhiều!
Trufa

46
@Trufa: Có lẽ điều này sẽ giúp với một phần của trực giác, ít nhất là cho các khoản tiền. Hãy tưởng tượng lấy "trung bình" của một con lăn. Bây giờ hãy tưởng tượng lấy trung bình của hai con xúc xắc. Bây giờ một trăm. Điều gì xảy ra với cơ hội nhận được một hoặc sáu cho mức trung bình khi bạn thêm xúc xắc?
johncip

3
@matt b Biểu đồ là một lớp trong Mathicala. Mã này là văn bản in đậm trước mỗi biểu đồ. Mathematica là một ngôn ngữ tuyệt vời để thực hiện Plots!
Tiến sĩ belisarius

4
@thenonhacker: vâng, biểu đồ thể hiện sự thiên vị, nhưng chúng không thể hiện tính không ngẫu nhiên. Số ngẫu nhiên thiên vị không ít ngẫu nhiên. Đối với câu trả lời chính xác cho câu hỏi ban đầu của người dùng là: "đừng cố tỏ ra thông minh, bạn sẽ chỉ làm mọi thứ tồi tệ hơn" và câu trả lời này thực sự đã làm được điều đó.
Kennet Belenky

151

Tôi đoán cả hai phương pháp là ngẫu nhiên mặc dù gutfeel của tôi sẽ nói rằng điều đó rand() * rand()ít ngẫu nhiên hơn vì nó sẽ tạo ra nhiều số không. Ngay sau khi một rand()0, tổng trở nên0


18
Câu trả lời của tôi cho tất cả các câu trả lời bằng cách sử dụng dải này là: Tôi thích sự hài hước, nhưng nó phải là CW!
Andreas Rejbrand

4
@Andomar: Không, không phải vậy. Không có gì. Bạn có biết CW là gì không?
Andreas Rejbrand

17
@Andreas Rejbrand: CW là vũ khí giết chết những câu hỏi thú vị bằng cách từ chối danh tiếng cho những người trả lời nó. Có vẻ như nó đã được meta.stackexchange.com/questions/392/ (có lẽ là lý do tại sao câu hỏi thú vị này xuất hiện!)
Andomar

11
@Andomar - Có, CW giết chết những câu hỏi thú vị, nhưng (từ Câu hỏi thường gặp ) "Danh tiếng là thước đo sơ bộ về mức độ cộng đồng tin tưởng bạn." Nếu bạn bao gồm một hình ảnh hài hước, có bản quyền trong câu trả lời của bạn, nó sẽ khiến tôi nghĩ rằng câu trả lời của bạn rất tuyệt và tôi có thể sẽ nghĩ bạn cũng rất tuyệt, nhưng nó không khiến bạn đáng tin hơn - vì vậy, lý tưởng nhất là không có đại diện nên được trao tặng. Cho dù điều đó có nghĩa là CW, hay liệu nó có nghĩa là người ta không nên bỏ phiếu thì câu trả lời lại là một vấn đề khác.
Richard JP Le Guen

13
trò troll "trình tạo ngẫu nhiên" trong phim hoạt hình có thể chỉ là một người đọc thuộc lòng, và đạt đến điểm Feynman . btw, là các chữ số π ngẫu nhiên? :)
mykhal

82

Không phải là "ngẫu nhiên hơn".

rand()tạo ra một tập hợp số có thể dự đoán được dựa trên hạt giống ngẫu nhiên psuedo (thường dựa trên thời gian hiện tại, luôn thay đổi). Nhân hai số liên tiếp trong chuỗi sẽ tạo ra một chuỗi số khác nhau, nhưng không thể đoán trước được.

Giải quyết liệu điều này sẽ làm giảm va chạm, câu trả lời là không. Nó thực sự sẽ tăng va chạm do hiệu ứng nhân hai số trong đó 0 < n < 1. Kết quả sẽ là một phần nhỏ hơn, gây ra sự sai lệch trong kết quả về phía dưới của phổ.

Một số giải thích thêm. Trong phần sau đây, 'không thể đoán trước' và 'ngẫu nhiên' đề cập đến khả năng ai đó đoán được số tiếp theo sẽ dựa trên những số nào trước đó, tức là. một lời sấm truyền.

Hạt giống xđã tạo ra danh sách các giá trị sau:

0.3, 0.6, 0.2, 0.4, 0.8, 0.1, 0.7, 0.3, ...

rand()sẽ tạo danh sách trên và rand() * rand()sẽ tạo:

0.18, 0.08, 0.08, 0.21, ...

Cả hai phương pháp sẽ luôn tạo ra cùng một danh sách các số cho cùng một hạt giống, và do đó có thể dự đoán như nhau bởi một lời sấm truyền. Nhưng nếu bạn nhìn vào kết quả để nhân hai cuộc gọi, bạn sẽ thấy tất cả chúng đều nằm dưới 0.3mặc dù có sự phân phối hợp lý trong chuỗi ban đầu. Các số bị sai lệch vì hiệu ứng nhân hai phân số. Con số kết quả luôn nhỏ hơn, do đó nhiều khả năng là một vụ va chạm mặc dù vẫn không thể đoán trước được.


9
+1 Lưu ý rằng mặt khác rand()+rand()+rand()...ngày càng "ít ngẫu nhiên" (nếu ngẫu nhiên bạn có nghĩa là phân phối đồng đều).
Thilo

4
@Thilo Không, nó không ...? Nếu một biến ngẫu nhiên được phân phối đồng đều trong phạm vi (0,1) và bạn lấy mẫu biến n lần và lấy tổng, thì nó sẽ chỉ được phân phối đồng đều trong phạm vi (0, n).
dùng359996

5
@Trufa chỉ tin tưởng rand()là thực sự ngẫu nhiên và đừng cố gắng 'nâng cao' tính ngẫu nhiên. Đừng đặt hạt giống nhiều lần. Bất kỳ hạt giống riêng lẻ nào cũng hoàn toàn tốt, miễn là bản thân nó bán ngẫu nhiên. Rất nhiều triển khai tôi đã thấy sử dụng kỷ nguyên UNIX làm hạt giống, nó thay đổi mỗi giây và là duy nhất mỗi khi nó thay đổi.
Matthew Scharley

61
@ user359996 rand () + rand () không được phân phối đồng đều. Thêm hai con xúc xắc, bạn có nhiều khả năng nhận được 7 hơn 2.
Liam

4
@thenonhacker Xem định nghĩa của tôi về tính ngẫu nhiên trong bài viết của tôi. Chỉ vì các giá trị có xu hướng về một đầu của phổ không làm tăng khả năng dự đoán của các giá trị chính xác được tạo ra, đó là điều tôi đã đề cập khi tôi sử dụng từ ngẫu nhiên. Sau đó tôi tiếp tục giải quyết vấn đề sai lệch một cách riêng biệt.
Matthew Scharley

80

Đơn giản hóa để minh họa một điểm.

Giả sử chức năng ngẫu nhiên của bạn chỉ đầu ra 0hoặc 1.

random()là một trong (0,1), nhưng random()*random()là một trong(0,0,0,1)

Bạn có thể thấy rõ rằng các cơ hội để có được 0trong trường hợp thứ hai là không có cách nào bằng với những người có được a 1.


Khi tôi lần đầu tiên đăng câu trả lời này, tôi muốn giữ nó càng ngắn càng tốt để một người đọc nó sẽ hiểu từ sự khác biệt giữa random()random()*random(), nhưng tôi không thể giữ mình trả lời câu hỏi quảng cáo ban đầu:

Cái nào ngẫu nhiên hơn?

Là rằng random(), random()*random(), random()+random(), (random()+1)/2hoặc bất kỳ sự kết hợp khác mà không dẫn đến một kết quả cố định có cùng một nguồn entropy (hoặc tình trạng ban đầu tương tự trong trường hợp máy phát điện giả ngẫu nhiên), câu trả lời sẽ là rằng họ là như nhau ngẫu nhiên (Sự khác biệt là trong phân phối của họ). Một ví dụ hoàn hảo mà chúng ta có thể nhìn vào là trò chơi Craps. Con số bạn nhận được sẽ là random(1,6)+random(1,6)và tất cả chúng ta đều biết rằng nhận được 7 có cơ hội cao nhất, nhưng điều đó không có nghĩa là kết quả của việc gieo hai con xúc xắc là ít nhiều ngẫu nhiên hơn kết quả của việc gieo một con.


+1 để cô đọng một thứ gì đó quỷ quyệt thành "ngẫu nhiên như nhau trên các bản phân phối khác nhau". Rất thanh lịch.
Jens Roland

3
Vì vậy, về mặt kỹ thuật, (ngẫu nhiên () * 0 + 9) là ngẫu nhiên như nhau, vì nó trả về ngẫu nhiên một giá trị từ tập hợp 1 phần tử: [9]. Phim hoạt hình Dilbert đã đúng.
Jens Roland

2
@Jens Rolan "bất kỳ sự kết hợp nào khác không dẫn đến một kết quả cố định";). 999999 <i> có lẽ </ i> không được tạo ngẫu nhiên và cơ hội được tạo ngẫu nhiên có thể được tính toán.
Alin Purcaru

69

Đây là một câu trả lời đơn giản. Hãy xem xét độc quyền. Bạn cuộn hai con xúc xắc sáu mặt (hoặc 2d6 cho những người thích ký hiệu chơi game) và lấy tổng của chúng. Kết quả phổ biến nhất là 7 vì có 6 cách có thể bạn có thể cuộn 7 (1,6 2,5 3,4 4,3 5,2 và 6,1). Trong khi đó 2 chỉ có thể được lăn trên 1,1. Thật dễ dàng để thấy rằng cán 2d6 khác với cán 1d12, ngay cả khi phạm vi là như nhau (bỏ qua việc bạn có thể nhận được 1 trên 1d12, điểm vẫn giữ nguyên). Nhân kết quả của bạn thay vì thêm chúng sẽ khiến chúng bị lệch theo cách tương tự, với hầu hết các kết quả của bạn sẽ xuất hiện ở giữa phạm vi. Nếu bạn đang cố gắng giảm các ngoại lệ, đây là một phương pháp tốt, nhưng nó sẽ không giúp phân phối đồng đều.

(Và thật kỳ lạ, nó cũng sẽ tăng các cuộn thấp. Giả sử tính ngẫu nhiên của bạn bắt đầu từ 0, bạn sẽ thấy tăng đột biến ở 0 vì nó sẽ biến bất kỳ cuộn nào khác thành 0. Hãy xem xét hai số ngẫu nhiên từ 0 đến 1 (đã bao gồm ) và nhân lên. Nếu một trong hai kết quả là 0, toàn bộ kết quả trở thành 0 cho dù kết quả khác là cách duy nhất để có được 1 trong số đó là cho cả hai cuộn là 1. Trong thực tế, điều này có lẽ sẽ không thành vấn đề nhưng nó làm cho một đồ thị kỳ lạ.)


4
"Nhân kết quả của bạn thay vì thêm chúng sẽ khiến chúng bị lệch theo cách tương tự, với hầu hết các kết quả của bạn sẽ xuất hiện ở giữa phạm vi." - kiểm tra khẳng định này với biểu đồ thứ hai trong câu trả lời từ belisarius.
Daniel Earwicker

52

Xkcd bắt buộc ...
trả lại 4;  // được chọn bởi cuộn súc sắc công bằng, đảm bảo là ngẫu nhiên.


7
danmn này luôn luôn xuất hiện khi từ "ngẫu nhiên xuất hiện" :) Tôi đã chờ đợi nó !!
Trufa

9
Tôi thích sự hài hước, nhưng nó phải là CW.
Andreas Rejbrand

2
@Andreas Rejbrand - tại sao câu trả lời "hài hước" này phải là CW?
warren

16
Nếu đó không phải là CW, danh tiếng sẽ được đánh thức bằng poster của câu trả lời mỗi khi nó được bình chọn (160 rep cho đến nay). Bây giờ, danh tiếng giống như điểm số ở trường - nó phải là một chứng chỉ về kỹ thuật (trong trường hợp này là lập trình). Do đó, người ta không thể có được danh tiếng bằng cách đăng một cái gì đó dễ dàng được nâng cao nhưng điều đó không cần phải có sự thành thạo như vậy. Hơn nữa, điểm danh tiếng cũng xác định các đặc quyền của người dùng. Chẳng hạn, ở mức 10 000, người dùng có quyền truy cập vào các công cụ kiểm duyệt tại StackOverflow.
Andreas Rejbrand

35

Nó có thể giúp nghĩ về điều này với số lượng rời rạc hơn. Cân nhắc muốn tạo số ngẫu nhiên trong khoảng từ 1 đến 36, vì vậy bạn quyết định cách dễ nhất là ném hai con xúc xắc 6 mặt công bằng. Bạn nhận được điều này:

     1    2    3    4    5    6
  -----------------------------
1|   1    2    3    4    5    6
2|   2    4    6    8   10   12
3|   3    6    9   12   15   18
4|   4    8   12   16   20   24   
5|   5   10   15   20   25   30
6|   6   12   18   24   30   36

Vì vậy, chúng tôi có 36 số, nhưng không phải tất cả chúng đều được thể hiện một cách công bằng và một số không xảy ra. Các số gần đường chéo trung tâm (góc dưới bên trái đến góc trên bên phải) sẽ xảy ra với tần suất cao nhất.

Các nguyên tắc tương tự mô tả phân phối không công bằng giữa súc sắc áp dụng như nhau cho các số dấu phẩy động giữa 0,0 và 1,0.


3
+1 để hiển thị cụ thể hơn, sự thay đổi trong phân phối khi nhân các số ngẫu nhiên. Ma trận đã giúp nhiều hơn chỉ là các từ hoặc thậm chí là một biểu đồ phân phối.
Marjan Venema

26

Một số điều về "tính ngẫu nhiên" là phản trực giác.

Giả sử phân phối phẳng rand(), sau đây sẽ giúp bạn phân phối không phẳng:

  • thiên vị cao: sqrt(rand(range^2))
  • đỉnh thiên vị ở giữa: (rand(range) + rand(range))/2
  • thấp: thiên vị: range - sqrt(rand(range^2))

Có rất nhiều cách khác để tạo đường cong thiên vị cụ thể. Tôi đã làm một bài kiểm tra nhanh rand() * rand()và nó giúp bạn phân phối rất phi tuyến tính.


24

Hầu hết các triển khai rand () có một số giai đoạn. Tức là sau một số lượng lớn các cuộc gọi lặp lại trình tự. Trình tự đầu ra của các rand() * rand()lần lặp lại trong một nửa thời gian, vì vậy nó "ít ngẫu nhiên hơn" theo nghĩa đó.

Ngoài ra, nếu không xây dựng cẩn thận, thực hiện số học trên các giá trị ngẫu nhiên có xu hướng gây ra ít ngẫu nhiên hơn. Một poster ở trên đã trích dẫn " rand()+ rand()+ rand()..." (k lần, nói) trong thực tế sẽ có xu hướng gấp k lần giá trị trung bình của phạm vi giá trị rand()trả về. (Đó là một bước đi ngẫu nhiên với các bước đối xứng về ý nghĩa đó.)

Giả sử cụ thể rằng hàm rand () của bạn trả về một số thực ngẫu nhiên được phân phối đồng đều trong phạm vi [0,1). (Có, ví dụ này cho phép độ chính xác vô hạn. Điều này sẽ không thay đổi kết quả.) Bạn đã không chọn một ngôn ngữ cụ thể và các ngôn ngữ khác nhau có thể làm những việc khác nhau, nhưng phân tích sau đây có sửa đổi cho bất kỳ triển khai rand không sai lầm nào ( ). Sản phẩm rand() * rand()cũng nằm trong phạm vi [0,1) nhưng không còn được phân phối đồng đều. Trên thực tế, sản phẩm có khả năng nằm trong khoảng [0,1 / 4) như trong khoảng [1 / 4,1). Phép nhân nhiều hơn sẽ làm lệch kết quả hơn nữa về 0. Điều này làm cho kết quả dễ dự đoán hơn. Trong các nét rộng, dễ dự đoán hơn == ít ngẫu nhiên hơn.

Khá nhiều bất kỳ chuỗi hoạt động nào trên đầu vào ngẫu nhiên thống nhất sẽ là ngẫu nhiên không đồng nhất, dẫn đến tăng khả năng dự đoán. Nếu cẩn thận, người ta có thể khắc phục tính chất này, nhưng sau đó sẽ dễ dàng tạo ra một số ngẫu nhiên phân phối đồng đều trong phạm vi bạn thực sự muốn thay vì lãng phí thời gian với số học.


Tôi cũng có suy nghĩ đó, rằng nó sẽ trải qua giai đoạn tạo ngẫu nhiên nhanh gấp đôi.
Jared Updike

3
Độ dài chuỗi sẽ chỉ được cắt làm đôi nếu nó là số chẵn. Nếu là số lẻ, bạn nhận được r1 * r2, r3 * r4, ..., rn * r1, r2 * r3, r4 * r5 và tổng chiều dài là như nhau.
Jander

23

"Ngẫu nhiên" so với "ngẫu nhiên hơn" giống như hỏi Zero nào là không hơn.

Trong trường hợp này, randlà một PRNG, vì vậy không hoàn toàn ngẫu nhiên. (trong thực tế, khá dễ đoán nếu hạt giống được biết đến). Nhân nó với một giá trị khác làm cho nó không ít nhiều ngẫu nhiên.

Một RNG loại tiền điện tử thực sự sẽ thực sự ngẫu nhiên. Và chạy các giá trị thông qua bất kỳ loại hàm nào cũng không thể thêm entropy cho nó và rất có thể loại bỏ entropy, làm cho nó không còn ngẫu nhiên nữa.


3
Lưu ý, điều này không bình phương vì mỗi cuộc gọi trả về một giá trị khác nhau. Tất cả mọi thứ khác là chính xác mặc dù.
Matthew Scharley

2
@thenonhacker: Theo mô tả của riêng bạn, chuỗi "1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10 , 1,2,3,4,5,6,7,8,9,10 ... "là ngẫu nhiên. Nó được phân bổ đều, với tất cả các con số nhận được một cơ hội công bằng. Không có đỉnh hoặc thiên vị. Bạn có thực sự xem xét chuỗi đó ngẫu nhiên ??? Bạn cần thay đổi định nghĩa của bạn. Ngẫu nhiên không phải là về đầu ra, ngẫu nhiên là về quá trình được sử dụng để tạo đầu ra.
abelenky

2
@CurtainDog: Nén văn bản giữ mức độ entropy như nhau trong khi giảm số lượng bit cần thiết để thể hiện cùng một lượng entropy đó.
Kennet Belenky

4
@thenonhacker, @abelenky: Ngay cả phân phối cũng dễ dàng. Điều quan trọng trong trình tạo số ngẫu nhiên là số bit ở trạng thái của trình tạo số ngẫu nhiên. Một trình tạo số ngẫu nhiên trạng thái không (ví dụ 4, 4, 4, 4, 4, ...) là hoàn toàn có thể dự đoán được. Một miếng đệm một lần có nhiều trạng thái như số lượng giá trị mà nó tạo ra, do đó làm cho nó không thể dự đoán được. Một tổ hợp của hai PNRG sẽ tạo ra một PNRG có nhiều bit entropy như cả hai đều chứa, trừ đi hiệp phương sai của chúng.
Kennet Belenky

1
@Kennet - Cảm ơn, bạn đã hoàn toàn xóa nó cho tôi. @abelenky - tuyệt, tôi hiểu bạn ngay bây giờ.
RèmDog

20

Khái niệm bạn đang tìm kiếm là "entropy", "mức độ" rối loạn của một chuỗi bit. Ý tưởng là dễ hiểu nhất về khái niệm "entropy tối đa".

Một định nghĩa gần đúng của một chuỗi bit có entropy tối đa là nó không thể được biểu diễn chính xác theo chuỗi bit ngắn hơn (nghĩa là sử dụng một số thuật toán để mở rộng chuỗi nhỏ hơn trở lại chuỗi ban đầu).

Sự liên quan của entropy tối đa với tính ngẫu nhiên bắt nguồn từ thực tế là nếu bạn chọn một số "ngẫu nhiên", bạn gần như chắc chắn sẽ chọn một số có chuỗi bit gần với entropy tối đa, nghĩa là không thể nén được. Đây là sự hiểu biết tốt nhất của chúng tôi về những gì đặc trưng cho một số "ngẫu nhiên".

Vì vậy, nếu bạn muốn tạo một số ngẫu nhiên trong số hai mẫu ngẫu nhiên là "hai lần" là ngẫu nhiên, bạn sẽ ghép hai chuỗi bit lại với nhau. Thực tế, bạn chỉ cần nhét các mẫu vào nửa cao và thấp của một từ có độ dài gấp đôi.

Nói một cách thực tế hơn, nếu bạn thấy mình buồn với rand (), đôi khi nó có thể giúp xor một vài mẫu với nhau --- mặc dù, nếu nó thực sự bị hỏng ngay cả quy trình đó sẽ không giúp ích gì.


2
Tôi chưa bao giờ nghĩ về các thế hệ số ngẫu nhiên thông qua xor, nhưng tôi đoán bạn có thể đưa khái niệm này đi khá xa ( en.wikipedia.org/wiki/Mersenne_twister )! Cảm ơn câu trả lời.
Gabriel Mitchell

1
Tôi thực sự đấu tranh để tìm ra câu trả lời này ... Không phải là entropy tối đa bị đánh bại bởi các câu trả lời được đưa ra trong stackoverflow.com/questions/3956478/under Hiểu-brandomness / trộmstackoverflow.com/questions/3956478/under Hiểu-brandomness / . Trong những trường hợp này, số được chọn không thể được nén nhưng bạn khó có thể gọi chúng là ngẫu nhiên.
RèmDog

1
+1 Đẹp như câu trả lời được chấp nhận là, đây là yêu thích của tôi. Khi nói đến máy tính, hãy luôn nghĩ theo bit - ít gây nhầm lẫn và phù hợp hơn nhiều so với cố gắng nghĩ về mặt thực tế. (Tôi đã viết câu trả lời của mình và sau đó nhận thấy câu trả lời này, vì vậy của tôi không gì khác hơn là một bản mở rộng của câu hỏi này - có thể với một số entropy được thêm vào).
Daniel Earwicker

1
Số ngẫu nhiên 4hoặc nhị phân của @CurtainDog xkcd 0100có thể được nén thành 0 bit. Chương trình giải nén đơn giản sẽ trả về '4'. Nó không nhận được ít ngẫu nhiên hơn thế. Vấn đề với Dilbert là, chúng tôi không biết liệu chúng tôi có thể nén nó về 0 bit hay không (giải nén bằng cách luôn trả về 'chín'). Nó có thể trả về tám aswell, sau đó chúng ta có thể nén thành 1 bit. Giải nén bằng cách: 0-> chín, 1-> tám. Chúng ta sẽ có 1 bit ngẫu nhiên.
Ishtar

14

Câu trả lời được chấp nhận là khá đáng yêu, nhưng có một cách khác để trả lời câu hỏi của bạn. Câu trả lời của PachydermPuncher đã áp dụng phương pháp thay thế này và tôi sẽ mở rộng ra một chút.

Cách dễ nhất để suy nghĩ về lý thuyết thông tin là về đơn vị thông tin nhỏ nhất, một bit.

Trong thư viện chuẩn C, rand()trả về một số nguyên trong phạm vi 0 đến RAND_MAX, một giới hạn có thể được xác định khác nhau tùy thuộc vào nền tảng. Giả sử RAND_MAXxảy ra được định nghĩa là 2^n - 1vị trí của nmột số nguyên (điều này xảy ra trong trường hợp triển khai của Microsoft, trong đó nlà 15). Sau đó, chúng tôi sẽ nói rằng một triển khai tốt sẽ trả về ncác bit thông tin.

Hãy tưởng tượng rằng rand()xây dựng các số ngẫu nhiên bằng cách lật một đồng xu để tìm giá trị của một bit, sau đó lặp lại cho đến khi nó có một lô 15 bit. Sau đó, các bit là độc lập (giá trị của bất kỳ một bit nào không ảnh hưởng đến khả năng các bit khác trong cùng một lô có một giá trị nhất định). Vì vậy, mỗi bit được xem xét độc lập giống như một số ngẫu nhiên nằm trong khoảng từ 0 đến 1 và được "phân bổ đều" trong phạm vi đó (có thể là 0 là 1).

Sự độc lập của các bit đảm bảo rằng các số được biểu thị bằng các lô bit cũng sẽ được phân bổ đều trên phạm vi của chúng. Điều này là trực quan rõ ràng: nếu có 15 bit, phạm vi được phép là 0 đến 2^15 - 1= 32767. Mỗi số trong phạm vi đó là một mẫu bit duy nhất, chẳng hạn như:

010110101110010

và nếu các bit độc lập thì không có mẫu nào có khả năng xảy ra hơn bất kỳ mẫu nào khác. Vì vậy, tất cả các số có thể trong phạm vi đều có khả năng như nhau. Và điều ngược lại là đúng: nếu rand()tạo ra các số nguyên phân bố đồng đều, thì các số đó được tạo từ các bit độc lập.

Vì vậy, hãy nghĩ về rand()như một dây chuyền sản xuất để tạo ra các bit, điều này chỉ xảy ra để phục vụ chúng theo từng đợt có kích thước tùy ý. Nếu bạn không thích kích thước, chia các lô thành từng bit riêng lẻ, sau đó đặt chúng lại với nhau theo bất kỳ số lượng nào bạn thích (mặc dù nếu bạn cần một phạm vi cụ thể không phải là lũy thừa 2, bạn cần thu nhỏ số của mình và cho đến nay, cách dễ nhất để làm điều đó là chuyển đổi thành dấu phẩy động).

Quay trở lại đề xuất ban đầu của bạn, giả sử bạn muốn đi từ đợt 15 đến đợt 30, yêu cầu rand()số đầu tiên, thay đổi bit theo 15 vị trí, sau đó thêm số khác rand()vào đó. Đó là một cách để kết hợp hai cuộc gọi đến rand()mà không làm phiền phân phối đồng đều. Nó hoạt động đơn giản vì không có sự chồng chéo giữa các vị trí nơi bạn đặt các bit thông tin.

Điều này rất khác với "kéo dài" phạm vi rand()bằng cách nhân với một hằng số. Ví dụ: nếu bạn muốn nhân đôi phạm vi của rand()mình, bạn có thể nhân hai lần - nhưng bây giờ bạn chỉ nhận được số chẵn và không bao giờ là số lẻ! Đó không hẳn là một bản phân phối mượt mà và có thể là một vấn đề nghiêm trọng tùy thuộc vào ứng dụng, ví dụ như một trò chơi giống như roulette được cho là đặt cược lẻ / chẵn. (Bằng cách suy nghĩ về các bit, bạn sẽ tránh được sai lầm đó bằng trực giác, bởi vì bạn nhận ra rằng nhân với hai cũng giống như dịch chuyển các bit sang trái (ý nghĩa lớn hơn) ở một vị trí và điền vào khoảng trống bằng 0. Vì vậy, rõ ràng lượng thông tin là như nhau - nó chỉ di chuyển một chút.)

Các khoảng trống như vậy trong các phạm vi số không thể được xử lý trong các ứng dụng số dấu phẩy động, bởi vì các phạm vi dấu phẩy động vốn có các khoảng trống đơn giản không thể biểu thị ở tất cả: một số lượng vô hạn các số thực bị thiếu tồn tại trong khoảng cách giữa hai dấu phẩy có thể biểu diễn số điểm! Vì vậy, chúng ta chỉ cần học cách sống với những khoảng trống.

Như những người khác đã cảnh báo, trực giác là rủi ro trong lĩnh vực này, đặc biệt là bởi vì các nhà toán học không thể cưỡng lại sức hấp dẫn của những con số thực, đó là những điều khó hiểu khủng khiếp đầy rẫy những điều vô lý và những nghịch lý rõ ràng.

Nhưng ít nhất nếu bạn nghĩ nó liên quan đến bit, trực giác của bạn có thể giúp bạn tiến xa hơn một chút. Bits thực sự dễ dàng - ngay cả máy tính cũng có thể hiểu chúng.


3
+1: Trên thực tế, có nhiều số bị thiếu giữa bất kỳ hai số phao chính xác kép nào của IEEE so với số nguyên trong toàn bộ số nguyên (toán học).
Donal Fellows

13

Như những người khác đã nói, câu trả lời ngắn gọn dễ dàng là: Không, nó không ngẫu nhiên hơn, nhưng nó thay đổi sự phân phối.

Giả sử bạn đang chơi một trò chơi súc sắc. Bạn có một số xúc xắc hoàn toàn công bằng, ngẫu nhiên. Liệu các cuộn súc sắc sẽ "ngẫu nhiên hơn" nếu trước mỗi lần lăn, trước tiên bạn đặt hai con xúc xắc vào một cái bát, lắc xung quanh, chọn một con xúc xắc một cách ngẫu nhiên, và sau đó cuộn con súc sắc đó? Rõ ràng nó sẽ không làm cho sự khác biệt. Nếu cả hai con xúc xắc cho số ngẫu nhiên, thì việc chọn ngẫu nhiên một trong hai con xúc xắc sẽ không có sự khác biệt. Dù bằng cách nào, bạn sẽ nhận được một số ngẫu nhiên từ 1 đến 6 với phân phối đồng đều trên một số lượng cuộn đủ.

Tôi cho rằng trong cuộc sống thực, một quy trình như vậy có thể hữu ích nếu bạn nghi ngờ rằng xúc xắc có thể KHÔNG công bằng. Nếu, giả sử, con xúc xắc hơi mất cân bằng nên một con có xu hướng cho 1 thường xuyên hơn 1/6 thời gian và con khác có xu hướng cho 6 lần bất thường, sau đó chọn ngẫu nhiên giữa hai con sẽ có xu hướng che khuất sự thiên vị. (Mặc dù trong trường hợp này, 1 và 6 vẫn sẽ xuất hiện nhiều hơn 2, 3, 4 và 5. Chà, tôi đoán tùy thuộc vào bản chất của sự mất cân bằng.)

Có nhiều định nghĩa về tính ngẫu nhiên. Một định nghĩa của một chuỗi ngẫu nhiên là nó là một chuỗi các số được tạo ra bởi một quá trình ngẫu nhiên. Theo định nghĩa này, nếu tôi lăn một cái chết công bằng 5 lần và nhận được các số 2, 4, 3, 2, 5, đó là một chuỗi ngẫu nhiên. Nếu sau đó tôi quay cái công bằng đó chết thêm 5 lần nữa và nhận được 1, 1, 1, 1, 1, thì đó cũng là một chuỗi ngẫu nhiên.

Một số áp phích đã chỉ ra rằng các chức năng ngẫu nhiên trên máy tính không thực sự ngẫu nhiên mà là giả ngẫu nhiên, và nếu bạn biết thuật toán và hạt giống thì chúng hoàn toàn có thể dự đoán được. Điều này là đúng, nhưng hầu hết thời gian hoàn toàn không liên quan. Nếu tôi xáo trộn một cỗ bài và sau đó lật chúng lần lượt, đây sẽ là một chuỗi ngẫu nhiên. Nếu ai đó nhìn trộm vào các thẻ, kết quả sẽ hoàn toàn có thể dự đoán được, nhưng theo hầu hết các định nghĩa về tính ngẫu nhiên, điều này sẽ không làm cho nó ít ngẫu nhiên hơn. Nếu loạt bài vượt qua các bài kiểm tra thống kê về tính ngẫu nhiên, thì việc tôi nhìn trộm các lá bài sẽ không thay đổi thực tế đó. Trong thực tế, nếu chúng tôi đang đánh bạc số tiền lớn vào khả năng đoán thẻ tiếp theo của bạn, thì thực tế là bạn đã lén nhìn vào các thẻ có liên quan cao. Nếu chúng tôi đang sử dụng chuỗi để mô phỏng các menu của khách truy cập vào trang web của chúng tôi để kiểm tra hiệu suất của hệ thống, thì thực tế là bạn đã nhìn trộm sẽ không có gì khác biệt cả. (Miễn là bạn không sửa đổi chương trình để tận dụng kiến ​​thức này.)

BIÊN TẬP

Tôi không nghĩ rằng tôi có thể trả lời vấn đề của Monty Hall trong một bình luận, vì vậy tôi sẽ cập nhật câu trả lời của mình.

Đối với những người không đọc liên kết Belisarius, ý chính của nó là: Một thí sinh tham gia chương trình trò chơi được lựa chọn 3 cửa. Đằng sau một là một giải thưởng có giá trị, đằng sau những thứ khác vô giá trị. Anh chọn cửa số 1. Trước khi tiết lộ liệu đó là người chiến thắng hay kẻ thua cuộc, chủ nhà mở cửa số 3 để tiết lộ rằng đó là kẻ thua cuộc. Sau đó, anh cho thí sinh cơ hội chuyển sang cửa số 2. Thí sinh có nên làm điều này hay không?

Câu trả lời, xúc phạm trực giác của nhiều người, là anh ta nên chuyển đổi. Xác suất mà lựa chọn ban đầu của anh ta là người chiến thắng là 1/3, và cánh cửa khác là người chiến thắng là 2/3. Trực giác ban đầu của tôi, cùng với nhiều người khác, là sẽ không có lợi ích gì khi chuyển đổi, tỷ lệ cược vừa được thay đổi thành 50:50.

Rốt cuộc, giả sử rằng ai đó đã bật TV ngay sau khi chủ nhà mở cửa thua. Người đó sẽ thấy hai cánh cửa đóng kín còn lại. Giả sử anh ta biết bản chất của trò chơi, anh ta sẽ nói rằng có 1/2 cơ hội cho mỗi cánh cửa ẩn giải thưởng. Làm thế nào tỷ lệ cược cho người xem là 1/2: 1/2 trong khi tỷ lệ cược cho thí sinh là 1/3: 2/3?

Tôi thực sự đã phải suy nghĩ về điều này để đánh bại trực giác của mình thành hình dạng. Để xử lý vấn đề này, hãy hiểu rằng khi chúng ta nói về xác suất trong một vấn đề như thế này, chúng tôi muốn nói đến xác suất bạn chỉ định cho thông tin có sẵn. Đối với một thành viên của phi hành đoàn đặt giải thưởng phía sau, giả sử, cửa số 1, xác suất giải thưởng đứng sau cửa số 1 là 100% và xác suất rằng nó đứng sau một trong hai cửa còn lại là 0.

Tỷ lệ cược của các thành viên phi hành đoàn khác với tỷ lệ cược của thí sinh bởi vì anh ta biết điều gì đó mà thí sinh không làm, cụ thể là, anh ta đặt giải thưởng phía sau. Tương tự như vậy, tỷ lệ cược của người dự thi khác với tỷ lệ cược của người xem bởi vì anh ta biết một cái gì đó mà người xem không biết, cụ thể là, cửa nào anh ta chọn ban đầu. Điều này không liên quan, bởi vì lựa chọn mở cửa của chủ nhà không phải là ngẫu nhiên. Anh ta sẽ không mở cánh cửa mà thí sinh đã chọn, và anh ta sẽ không mở cánh cửa che giấu giải thưởng. Nếu đây là cùng một cánh cửa, điều đó cho anh ta hai sự lựa chọn. Nếu chúng là những cánh cửa khác nhau, chỉ còn lại một.

Vậy làm thế nào để chúng ta đến với 1/3 và 2/3? Khi thí sinh ban đầu chọn một cánh cửa, anh ta có 1/3 cơ hội chọn người chiến thắng. Tôi nghĩ rằng nhiều là rõ ràng. Điều đó có nghĩa là có 2/3 cơ hội rằng một trong những cánh cửa khác là người chiến thắng. Nếu chủ nhà cho anh ta cơ hội để chuyển đổi mà không cung cấp thêm thông tin nào, sẽ không có lợi ích gì. Một lần nữa, điều này nên rõ ràng. Nhưng một cách để nhìn vào nó là nói rằng có 2/3 cơ hội anh ta sẽ giành chiến thắng bằng cách chuyển đổi. Nhưng anh có 2 lựa chọn thay thế. Vì vậy, mỗi người chỉ có 2/3 chia cho 2 = 1/3 cơ hội là người chiến thắng, điều này không tốt hơn so với lựa chọn ban đầu của anh ta. Tất nhiên chúng tôi đã biết kết quả cuối cùng, điều này chỉ tính toán nó theo một cách khác.

Nhưng bây giờ chủ nhà tiết lộ rằng một trong hai lựa chọn đó không phải là người chiến thắng. Vì vậy, trong số 2/3 cơ hội mà một cánh cửa anh ta không chọn là người chiến thắng, giờ anh ta biết rằng 1 trong 2 lựa chọn thay thế không phải là nó. Cái khác có thể hoặc không thể. Vì vậy, anh ta không còn có 2/3 chia cho 2. Anh ta có số không cho cửa mở và 2/3 cho cửa đóng.


Tương tự rất tốt! Tôi đoán đây là một lời giải thích bằng tiếng Anh đơn giản và không giống như nhiều người khác, bạn thực sự đã trả lời câu hỏi của tôi :)
Trufa

@Trufa @Jay Sự nhầm lẫn giữa các kiến ​​thức có thể có trước về các sự kiện và tính ngẫu nhiên là RẤT phổ biến. Hãy để tôi chia sẻ với bạn câu chuyện thú vị này về một người phụ nữ đã giải quyết vấn đề và bỏ một đống sự xấu hổ về một số nhà toán học giỏi hơn trong học viện. Họ nói nhiều điều phải hối hận về sau (chẳng hạn như "Bạn đã phạm sai lầm, nhưng hãy nhìn vào mặt tích cực. Nếu tất cả những bằng tiến sĩ đó đều sai, đất nước sẽ gặp một số rắc rối rất nghiêm trọng."). Vì vậy, đây là câu chuyện, liên quan đến cân nhắc của bạn ... thưởng thức! marilynvossavant.com/articles/gameshow.html
Tiến sĩ belisarius

@ Belisarius vâng. Tôi nói blackjack21 :) chỉ đùa thôi tôi sẽ cho bạn điểm!
Trufa

@belisarius BTW không bao giờ có cái đó tôi sẽ thử lại ngay!
Trufa

@Trufa Và đây là một bài viết cho thấy phản ứng học thuật đối với truy vấn tuyên bố của Marilyn.nytimes.com/gst/ dọa (RẤT RẤT vui vẻ)
Tiến sĩ belisarius

11

Hãy xem xét bạn có một vấn đề lật đồng xu đơn giản trong đó thậm chí được coi là đầu và lẻ được coi là đuôi. Việc thực hiện logic là:

rand() mod 2

Trong một phân phối đủ lớn, số lượng số chẵn phải bằng số lượng số lẻ.

Bây giờ hãy xem xét một điều chỉnh nhỏ:

rand() * rand() mod 2

Nếu một trong các kết quả là chẵn thì toàn bộ kết quả sẽ là chẵn. Hãy xem xét 4 kết quả có thể xảy ra (chẵn * chẵn = chẵn, chẵn * lẻ = chẵn, lẻ * chẵn = chẵn, lẻ * lẻ = lẻ). Bây giờ, qua một phân phối đủ lớn, câu trả lời nên là 75% thời gian.

Tôi đặt cược đầu nếu tôi là bạn.

Nhận xét này thực sự là một lời giải thích về lý do tại sao bạn không nên thực hiện một hàm ngẫu nhiên tùy chỉnh dựa trên phương pháp của bạn hơn là một cuộc thảo luận về các tính chất toán học của tính ngẫu nhiên.


1
Coi chừng! rand()%2có thể không ngẫu nhiên lắm; điều đó thực sự phụ thuộc vào tính ngẫu nhiên của bit thấp và một số PRNG không tốt theo cách đó. (Tất nhiên, trong một số ngôn ngữ, bạn nhận được kết quả dấu phẩy động rand()nên bạn không thể làm theo cách đó ở tất cả các môn
phái

10

Khi nghi ngờ về những gì sẽ xảy ra với sự kết hợp của các số ngẫu nhiên, bạn có thể sử dụng các bài học bạn đã học trong lý thuyết thống kê.

Trong tình huống của OP, anh ta muốn biết kết quả của X * X = X ^ 2 trong đó X là biến ngẫu nhiên được phân phối dọc theo Đồng phục [0,1]. Chúng tôi sẽ sử dụng kỹ thuật CDF vì đây chỉ là ánh xạ một-một.

Vì X ~ Đồng phục [0,1] nên cdf là: f X (x) = 1 Chúng tôi muốn phép biến đổi Y <- X ^ 2 do đó y = x ^ 2 Tìm nghịch đảo x (y): sqrt (y) = x điều này cho chúng ta x là một hàm của y. Tiếp theo, tìm đạo hàm dx / dy: d / dy (sqrt (y)) = 1 / (2 sqrt (y))

Phân phối của Y được cho là: f Y (y) = f X (x (y)) | dx / dy | = 1 / (2 sqrt (y))

Chúng ta chưa hoàn thành, chúng ta phải lấy miền của Y. vì 0 <= x <1, 0 <= x ^ 2 <1 nên Y nằm trong phạm vi [0, 1). Nếu bạn muốn kiểm tra xem pdf của Y có thực sự là pdf hay không, hãy tích hợp nó qua tên miền: Tích hợp 1 / (2 sqrt (y)) từ 0 đến 1 và thực sự, nó bật lên là 1. Ngoài ra, hãy chú ý hình dạng của cho biết chức năng trông giống như những gì tin tưởng được đăng.

Đối với những thứ như X 1 + X 2 + ... + X n , (trong đó X i ~ Đồng phục [0,1]), chúng ta chỉ có thể kháng cáo Định lý giới hạn trung tâm hoạt động cho bất kỳ phân phối nào có khoảnh khắc tồn tại. Đây là lý do tại sao Z-test tồn tại thực sự.

Các kỹ thuật khác để xác định pdf kết quả bao gồm chuyển đổi Jacobian (là phiên bản tổng quát của kỹ thuật cdf) và kỹ thuật MGF.

EDIT: Để làm rõ, xin lưu ý rằng tôi đang nói về sự phân phối của biến đổi kết quả và không phải là tính ngẫu nhiên của nó . Đó thực sự là một cuộc thảo luận riêng biệt. Ngoài ra những gì tôi thực sự bắt nguồn là cho (rand ()) ^ 2. Đối với rand () * rand () thì phức tạp hơn nhiều, trong mọi trường hợp sẽ không dẫn đến sự phân phối đồng đều của bất kỳ loại nào.


9

Nó không chính xác rõ ràng, nhưng rand()thường là ngẫu nhiên hơn rand()*rand(). Điều quan trọng là điều này thực sự không quan trọng đối với hầu hết các mục đích sử dụng.

Nhưng trước tiên, họ sản xuất các bản phân phối khác nhau. Đây không phải là một vấn đề nếu đó là những gì bạn muốn, nhưng nó quan trọng. Nếu bạn cần một bản phân phối cụ thể, thì hãy bỏ qua toàn bộ câu hỏi đó là câu hỏi ngẫu nhiên hơn. Vậy tại sao lại rand()ngẫu nhiên hơn?

Cốt lõi của tại sao rand()là ngẫu nhiên hơn (theo giả định rằng nó đang tạo ra các số ngẫu nhiên dấu phẩy động với phạm vi [0..1], rất phổ biến) là khi bạn nhân hai số FP cùng với nhiều thông tin trong lớp phủ, bạn sẽ nhận được một số mất thông tin cuối cùng; không có đủ bit trong một phao có độ chính xác kép của IEEE để chứa tất cả thông tin trong hai phao có độ chính xác kép của IEEE được chọn ngẫu nhiên từ [0..1] và những bit thông tin bổ sung đó sẽ bị mất. Tất nhiên, điều đó không quan trọng lắm vì bạn (có thể) sẽ không sử dụng thông tin đó, nhưng sự mất mát là có thật. Nó cũng không thực sự quan trọng việc bạn phân phối sản phẩm nào (nghĩa là bạn sử dụng thao tác nào để thực hiện kết hợp). Mỗi số ngẫu nhiên đó có (tốt nhất) 52 bit thông tin ngẫu nhiên - đó '

Hầu hết việc sử dụng các số ngẫu nhiên không sử dụng thậm chí gần với số lượng ngẫu nhiên nhiều như thực tế có sẵn trong nguồn ngẫu nhiên. Có được một PRNG tốt và đừng quá lo lắng về nó. (Mức độ tốt lành của tinh tế. Phụ thuộc vào những gì bạn đang làm với nó; bạn phải cẩn thận khi thực hiện mô phỏng hoặc mật mã Monte Carlo, nhưng nếu không, bạn có thể sử dụng PRNG tiêu chuẩn vì thường nhanh hơn nhiều.)


1
Câu trả lời này thực sự cần phải được đọc cùng với câu trả lời tuyệt vời của belisarius; chúng bao gồm các khía cạnh khác nhau của vấn đề.
Donal Fellows

7

Nói chung, các randoms nổi dựa trên một thuật toán tạo ra một số nguyên nằm giữa 0 và một phạm vi nhất định. Như vậy, bằng cách sử dụng rand () * rand (), về cơ bản bạn đang nói int_rand () * int_rand () / rand_max ^ 2 - có nghĩa là bạn đang loại trừ bất kỳ số nguyên tố / rand_max ^ 2 nào.

Điều đó thay đổi phân phối ngẫu nhiên đáng kể.

rand () được phân phối đồng đều trên hầu hết các hệ thống và khó dự đoán nếu được gieo đúng cách. Sử dụng điều đó trừ khi bạn có một lý do cụ thể để làm toán trên đó (nghĩa là định hình phân phối cho một đường cong cần thiết).


@ Belisarius: Đó chỉ là trường hợp nếu 1 là kết quả có thể xảy ra của quá trình ngẫu nhiên.
Joris Meys

Tôi đã phải đọc một đoạn dài các câu trả lời trước khi tôi tìm thấy câu trả lời này. Bạn nêu một vấn đề rõ ràng: không gian kết quả (số lượng giá trị có thể) rand()*rand()nhỏ hơn không gian kết quả của rand()- vì nó loại trừ các số nguyên tố. Nhận phiếu bầu của tôi ...
Floris

7

Nhân số sẽ kết thúc trong một phạm vi giải pháp nhỏ hơn tùy thuộc vào kiến ​​trúc máy tính của bạn.

Nếu màn hình máy tính của bạn hiển thị 16 chữ số rand()sẽ là 0.1234567890123 nhân với một giây rand(), 0.1234567890123, sẽ cung cấp cho 0,0152415 thứ gì đó bạn chắc chắn sẽ tìm thấy ít giải pháp hơn nếu bạn lặp lại thử nghiệm 10 ^ 14 lần.


3

Hầu hết các phân phối này xảy ra vì bạn phải giới hạn hoặc bình thường hóa số ngẫu nhiên.

Chúng tôi bình thường hóa nó là tất cả tích cực, phù hợp trong một phạm vi và thậm chí để phù hợp với các ràng buộc của kích thước bộ nhớ cho loại biến được chỉ định.

Nói cách khác, vì chúng ta phải giới hạn cuộc gọi ngẫu nhiên trong khoảng từ 0 đến X (X là giới hạn kích thước của biến), chúng ta sẽ có một nhóm các số "ngẫu nhiên" trong khoảng từ 0 đến X.

Bây giờ khi bạn thêm số ngẫu nhiên vào một số ngẫu nhiên khác, tổng sẽ nằm trong khoảng từ 0 đến 2X ... điều này sẽ làm lệch các giá trị khỏi các điểm cạnh (xác suất cộng hai số nhỏ lại với nhau và hai số lớn với nhau là rất nhỏ khi bạn có hai số ngẫu nhiên trong một phạm vi lớn).

Hãy nghĩ về trường hợp bạn có một số gần bằng 0 và bạn thêm nó với một số ngẫu nhiên khác, nó chắc chắn sẽ lớn hơn và cách xa 0 (điều này sẽ đúng với số lớn cũng như không có hai số lớn (số gần với X) được trả về bởi hàm Random hai lần.

Bây giờ nếu bạn thiết lập phương thức ngẫu nhiên với số âm và số dương (trải dài bằng trục 0) thì điều này sẽ không còn nữa.

Ví dụ, RandomReal({-x, x}, 50000, .01)sau đó bạn sẽ nhận được phân phối số chẵn ở mặt âm một mặt tích cực và nếu bạn cộng các số ngẫu nhiên lại với nhau thì chúng sẽ duy trì "tính ngẫu nhiên" của chúng.

Bây giờ tôi không chắc điều gì sẽ xảy ra với khoảng Random() * Random()âm đến dương ... đó sẽ là một biểu đồ thú vị để xem ... nhưng tôi phải quay lại viết mã ngay bây giờ. :-P


2
  1. Không có điều gì là ngẫu nhiên hơn . Nó là ngẫu nhiên hoặc không. Ngẫu nhiên có nghĩa là "khó dự đoán". Nó không có nghĩa là không xác định. Cả ngẫu nhiên () và ngẫu nhiên () * ngẫu nhiên () đều ngẫu nhiên như nhau nếu ngẫu nhiên () là ngẫu nhiên. Phân phối là không liên quan như xa ngẫu nhiên. Nếu phân phối không đồng nhất xảy ra, điều đó chỉ có nghĩa là một số giá trị có nhiều khả năng hơn các giá trị khác; họ vẫn không thể đoán trước.

  2. Vì giả ngẫu nhiên có liên quan, các con số rất có tính quyết định. Tuy nhiên, giả ngẫu nhiên thường đủ trong các mô hình xác suất và mô phỏng. Một điều khá nổi tiếng là việc tạo một bộ tạo số giả ngẫu nhiên phức tạp chỉ gây khó khăn cho việc phân tích. Nó không có khả năng cải thiện tính ngẫu nhiên; nó thường làm cho nó thất bại trong các bài kiểm tra thống kê.

  3. Các tính chất mong muốn của các số ngẫu nhiên rất quan trọng: độ lặp lại và độ tái lập, độ ngẫu nhiên thống kê, (thường) phân bố đồng đều, và một khoảng thời gian lớn là một số ít.

  4. Liên quan đến các phép biến đổi trên các số ngẫu nhiên: Như ai đó đã nói, tổng của hai hoặc nhiều kết quả phân phối đồng đều trong một phân phối bình thường. Đây là định lý giới hạn trung tâm phụ gia . Nó áp dụng bất kể phân phối nguồn miễn là tất cả các phân phối là độc lập và giống hệt nhau. Phép nhânĐịnh lý giới hạn trung tâm cho biết tích của hai hoặc nhiều biến ngẫu nhiên độc lập và phân phối thụt vào là bất thường. Biểu đồ mà người khác tạo ra có vẻ theo cấp số nhân, nhưng nó thực sự là logic. Vì vậy, Random () * Random () được phân phối lognormally (mặc dù nó có thể không độc lập do các số được kéo từ cùng một luồng). Điều này có thể được mong muốn trong một số ứng dụng. Tuy nhiên, thường là tốt hơn để tạo một số ngẫu nhiên và chuyển đổi nó thành một số phân phối lognormally. Random () * Random () có thể khó phân tích.

Để biết thêm thông tin, tham khảo cuốn sách của tôi tại www.performorama.org. Cuốn sách đang được xây dựng, nhưng các tài liệu có liên quan là ở đó. Lưu ý rằng số chương và phần có thể thay đổi theo thời gian. Chương 8 (lý thuyết xác suất) - phần 8.3.1 và 8.3.3, chương 10 (số ngẫu nhiên).


1

Chúng ta có thể so sánh hai mảng số liên quan đến tính ngẫu nhiên bằng cách sử dụng độ phức tạp Kolmogorov Nếu chuỗi số không thể nén được, thì đó là ngẫu nhiên nhất chúng ta có thể đạt được ở độ dài này ... Tôi biết rằng loại phép đo này là lý thuyết hơn Lựa chọn...


1

Trên thực tế, khi bạn nghĩ về nó rand() * rand()ít ngẫu nhiên hơnrand() . Đây là lý do tại sao.

Về cơ bản, có cùng số lượng số lẻ với số chẵn. Và nói rằng 0,04325 là số lẻ và giống như 0,388 là số chẵn và 0,4 là số chẵn và 0,15 là số lẻ,

Điều đó có nghĩa là rand()có một số thập phân chẵn hoặc lẻ .

Mặt khác, rand() * rand()tỷ lệ cược của nó được xếp chồng lên nhau một chút. Hãy cùng nói nào:

double a = rand();
double b = rand();
double c = a * b;

abcả hai đều có 50% cơ hội tiền chẵn hoặc lẻ. Biết rằng

  • chẵn * chẵn = chẵn
  • chẵn * lẻ = chẵn
  • lẻ * lẻ = lẻ
  • lẻ * chẵn = chẵn

phương tiện rằng có một cơ hội 75%cthậm chí còn, trong khi chỉ có một cơ hội 25% đó là số lẻ, làm cho giá trị của rand() * rand()dự đoán hơn rand(), do đó ít ngẫu nhiên.


rand()thường đưa ra một số từ 0 đến 1. Việc nói về việc nó chẵn hay lẻ có ý nghĩa gì không?
Teepeemm

1
Trên thực tế, 0.2*0.2=0.04điều này cho thấy một lỗ hổng cơ bản với cách tiếp cận này: nhân 53 bit của hai nhân đôi sẽ cho khoảng 100 bit trong kết quả. Nhưng nửa cuối của các bit này sẽ bị loại bỏ. Vì vậy, khi bạn lấy hai nhân đôi với 1 là bit ít quan trọng nhất của họ, bạn không thể nói bất cứ điều gì về bit ít quan trọng nhất của sản phẩm của họ.
Teepeemm

Hoặc, nói cách khác, bạn đã cho rằng định nghĩa "chẵn" và "lẻ" có ý nghĩa đối với phân phối rand()giống như các định nghĩa "chẵn" và "lẻ" có ý nghĩa đối với phân phối của rand()*rand(). Nếu đó không phải là trường hợp, đối số này thất bại. Điều đó đúng với số nguyên, nhưng đây không phải là số nguyên.
David Schwartz

0

Sử dụng một thanh ghi dịch chuyển phản hồi tuyến tính (LFSR) thực hiện đa thức nguyên thủy.

Kết quả sẽ là một chuỗi gồm 2 ^ n số giả ngẫu nhiên, tức là không lặp lại trong chuỗi trong đó n là số bit trong LFSR .... dẫn đến phân phối đồng đều.

http://en.wikipedia.org/wiki/Linear_feedback_shift_register http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf

Sử dụng hạt giống "ngẫu nhiên" dựa trên microsec của đồng hồ máy tính của bạn hoặc có thể là tập hợp con của kết quả md5 trên một số dữ liệu thay đổi liên tục trong hệ thống tệp của bạn.

Ví dụ, LFSR 32 bit sẽ tạo ra 2 ^ 32 số duy nhất theo thứ tự (không có 2 số giống nhau) bắt đầu bằng một hạt giống nhất định. Trình tự sẽ luôn theo cùng một thứ tự, nhưng điểm bắt đầu sẽ khác nhau (rõ ràng) cho một hạt giống khác nhau. Vì vậy, nếu một chuỗi có thể lặp lại giữa các lần gieo không phải là vấn đề, thì đây có thể là một lựa chọn tốt.

Tôi đã sử dụng LFSR 128 bit để tạo các thử nghiệm ngẫu nhiên trong các trình giả lập phần cứng bằng cách sử dụng hạt giống là kết quả md5 trên dữ liệu hệ thống thay đổi liên tục.


0

Giả sử rand()trả về một số giữa [0, 1)nó là hiển nhiên rand() * rand()sẽ bị sai lệch về 0. Điều này là do nhân xvới một số giữa [0, 1)sẽ dẫn đến một số nhỏ hơn x. Dưới đây là phân phối của 10000 số ngẫu nhiên hơn :

Nếu rand()trả về một số nguyên giữa [x, y]thì bạn có phân phối sau. Lưu ý số lượng giá trị lẻ so với giá trị chẵn:


-1

OK, vì vậy tôi sẽ cố gắng thêm một số giá trị để bổ sung cho câu trả lời của người khác bằng cách nói rằng bạn đang tạo và sử dụng trình tạo số ngẫu nhiên.

Trình tạo số ngẫu nhiên là các thiết bị (theo nghĩa rất chung) có nhiều đặc điểm có thể được sửa đổi để phù hợp với mục đích. Một số trong số họ (từ tôi) là:

  • Entropy: như trong Shannon Entropy
  • Phân phối: phân phối thống kê (poisson, bình thường, v.v.)
  • Loại: nguồn của các số (thuật toán, sự kiện tự nhiên, kết hợp, v.v.) và thuật toán được áp dụng là gì.
  • Hiệu quả: nhanh chóng hoặc phức tạp của việc thực hiện.
  • Mô hình: định kỳ, trình tự, chạy, vv
  • và có lẽ nhiều hơn ...

Trong hầu hết các câu trả lời ở đây, phân phối là điểm quan tâm chính, nhưng bằng cách trộn và kết hợp các hàm và tham số, bạn tạo ra các cách tạo số ngẫu nhiên mới có các đặc điểm khác nhau cho một số đánh giá có thể không rõ ràng ngay từ cái nhìn đầu tiên.


-1

Thật dễ dàng để chỉ ra rằng tổng của hai số ngẫu nhiên không nhất thiết là ngẫu nhiên. Hãy tưởng tượng bạn có một khuôn mặt 6 cuộn và cuộn. Mỗi số có 1/6 cơ hội xuất hiện. Bây giờ nói rằng bạn đã có 2 con xúc xắc và tổng hợp kết quả. Phân phối của những khoản tiền đó không phải là 1/12. Tại sao? Bởi vì số lượng nhất định xuất hiện nhiều hơn những số khác. Có nhiều phân vùng của chúng. Ví dụ, số 2 chỉ là tổng của 1 + 1 nhưng 7 có thể được hình thành bởi 3 + 4 hoặc 4 + 3 hoặc 5 + 2, v.v ... vì vậy nó có cơ hội lớn hơn sắp tới.

Do đó, áp dụng một biến đổi, trong trường hợp này, việc thêm vào một hàm ngẫu nhiên không làm cho nó trở nên ngẫu nhiên hơn, hoặc nhất thiết phải bảo toàn tính ngẫu nhiên. Trong trường hợp súc sắc ở trên, phân phối bị lệch thành 7 và do đó ít ngẫu nhiên hơn.


-1

Như những người khác đã chỉ ra, câu hỏi này rất khó trả lời vì tất cả mọi người trong chúng ta đều có hình ảnh ngẫu nhiên của riêng mình trong đầu.

Đó là lý do tại sao, tôi thực sự khuyên bạn nên dành chút thời gian và đọc qua trang web này để có được ý tưởng tốt hơn về tính ngẫu nhiên:

Để trở lại câu hỏi thực sự. Không có nhiều hoặc ít ngẫu nhiên trong thuật ngữ này:

cả hai chỉ xuất hiện ngẫu nhiên !

Trong cả hai trường hợp - chỉ rand () hoặc rand () * rand () - tình huống là như nhau: Sau vài tỷ số, chuỗi sẽ lặp lại (!) . Nó xuất hiện ngẫu nhiên cho người quan sát, bởi vì anh ta không biết toàn bộ chuỗi, nhưng máy tính không có nguồn ngẫu nhiên thực sự - vì vậy anh ta cũng không thể tạo ra sự ngẫu nhiên.

vd: Thời tiết có ngẫu nhiên không? Chúng tôi không có đủ cảm biến hoặc kiến ​​thức để xác định xem thời tiết có ngẫu nhiên hay không.


-2

Câu trả lời sẽ là tùy thuộc, hy vọng rand () * rand () sẽ ngẫu nhiên hơn rand (), nhưng như:

  • cả hai câu trả lời phụ thuộc vào kích thước bit của giá trị của bạn
  • rằng trong hầu hết các trường hợp bạn tạo tùy thuộc vào thuật toán giả ngẫu nhiên (phần lớn là trình tạo số phụ thuộc vào đồng hồ máy tính của bạn và không có nhiều ngẫu nhiên).
  • làm cho mã của bạn dễ đọc hơn (và không gọi một số thần ngẫu nhiên ngẫu nhiên ngẫu nhiên với loại thần chú này).

Chà, nếu bạn kiểm tra bất kỳ thứ nào ở trên, tôi khuyên bạn nên dùng "rand ()" đơn giản. Bởi vì mã của bạn sẽ dễ đọc hơn (sẽ không tự hỏi tại sao bạn lại viết cái này, trong ... tốt ... hơn 2 giây), dễ bảo trì (nếu bạn muốn thay thế chức năng rand của mình bằng super_rand).

Nếu bạn muốn ngẫu nhiên tốt hơn, tôi khuyên bạn nên truyền phát nó từ bất kỳ nguồn nào cung cấp đủ nhiễu ( vô tuyến tĩnh ), và sau đó đơn giản rand()là đủ.

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.