Làm thế nào tôi nên kiểm tra ngẫu nhiên?


127

Xem xét một phương thức để xáo trộn ngẫu nhiên các phần tử trong một mảng. Làm thế nào bạn sẽ viết một bài kiểm tra đơn vị mạnh mẽ nhưng đơn giản để đảm bảo rằng điều này đang hoạt động?

Tôi đã đưa ra hai ý tưởng, cả hai đều có những sai sót đáng chú ý:

  • Xáo trộn mảng, sau đó đảm bảo thứ tự của nó khác với trước. Điều này nghe có vẻ tốt, nhưng thất bại nếu xáo trộn xảy ra để xáo trộn theo cùng một thứ tự. (Không thể cải thiện, nhưng có thể.)
  • Xáo trộn mảng với một hạt giống không đổi và kiểm tra nó với đầu ra được xác định trước. Điều này phụ thuộc vào hàm ngẫu nhiên luôn trả về cùng các giá trị được cung cấp cùng một hạt giống. Tuy nhiên, điều này đôi khi là một giả định không hợp lệ .

Hãy xem xét một hàm thứ hai mô phỏng các cuộn súc sắc và trả về một số ngẫu nhiên. Làm thế nào bạn sẽ kiểm tra chức năng này? Làm thế nào bạn sẽ kiểm tra chức năng ...

  • không bao giờ trả về một số bên ngoài giới hạn nhất định?
  • trả về số trong một phân phối hợp lệ? (Đồng phục cho một người chết, bình thường cho số lượng lớn xúc xắc.)

Tôi đang tìm kiếm câu trả lời cung cấp cái nhìn sâu sắc về kiểm tra không chỉ các ví dụ này mà cả các yếu tố ngẫu nhiên của mã nói chung. Là bài kiểm tra đơn vị thậm chí là giải pháp đúng ở đây? Nếu không, loại thử nghiệm là gì?


Chỉ để làm dịu tâm trí của mọi người Tôi không viết trình tạo số ngẫu nhiên của riêng tôi.


35
Khớp nối chặt chẽ cho thấy đầu của nó. Truyền vào đối tượng tạo ra các số ngẫu nhiên. Sau đó, trong quá trình kiểm tra, bạn có thể vượt qua một đối tượng tạo ra một bộ số được chỉ định mà bạn biết bộ bài trông như thế nào sau khi xáo trộn. Bạn có thể kiểm tra tính ngẫu nhiên của trình tạo số ngẫu nhiên một cách riêng biệt.
Martin York

1
Tôi sẽ cân nhắc mạnh mẽ việc sử dụng một thói quen thư viện hiện có để xáo trộn (java Collections.shuffle () hoặc tương tự). Có một câu chuyện cảnh báo sẽ được đọc tại developer.com/tech/article.php/616221/ trộm về việc viết một thuật toán xáo trộn thiếu sót. Để viết hàm d6 (), người ta sẽ kiểm tra nó đủ để tự tin rằng nó sẽ không tạo ra một số ngoài phạm vi và sau đó thực hiện kiểm tra bình phương trên phân phối (chi bình phương khá nhạy cảm với các chuỗi ngẫu nhiên giả). Nhìn vào hệ số tương quan nối tiếp.

"Điều này phụ thuộc vào hàm ngẫu nhiên luôn trả về cùng các giá trị được cung cấp cùng một hạt giống. Tuy nhiên, đôi khi đây là một giả định không hợp lệ." Tôi đã theo liên kết và tôi không thấy giả định không hợp lệ. Nó nói khá đơn giản: "Nếu cùng một hạt giống được sử dụng lặp đi lặp lại, cùng một chuỗi số được tạo ra."
Kyralessa

@Kyralessa "Việc triển khai trình tạo số ngẫu nhiên trong lớp Ngẫu nhiên không được đảm bảo giữ nguyên trên các phiên bản chính của .NET Framework." Vì vậy, không phải là một mối quan tâm lớn, nhưng vẫn còn một cái gì đó để xem xét.
dlras2

4
@Kyralessa Tôi đã bỏ lỡ một nửa quan trọng của câu trích dẫn đó: "Do đó, mã ứng dụng của bạn không nên cho rằng cùng một hạt giống sẽ dẫn đến cùng một chuỗi giả ngẫu nhiên trong các phiên bản khác nhau của .NET Framework."
dlras2

Câu trả lời:


102

Tôi không nghĩ các bài kiểm tra đơn vị là công cụ phù hợp để kiểm tra tính ngẫu nhiên. Một thử nghiệm đơn vị nên gọi một phương thức và kiểm tra giá trị được trả về (hoặc trạng thái đối tượng) theo giá trị mong đợi. Vấn đề với kiểm tra tính ngẫu nhiên là không có giá trị mong đợi cho hầu hết những điều bạn muốn kiểm tra. Bạn có thể kiểm tra với một hạt giống nhất định, nhưng điều đó chỉ kiểm tra độ lặp lại . Nó không cung cấp cho bạn bất kỳ cách nào để đo mức độ phân phối ngẫu nhiên , hoặc nếu nó thậm chí ngẫu nhiên.

May mắn thay, có rất nhiều bài kiểm tra thống kê mà bạn có thể chạy, chẳng hạn như Pin thử nghiệm ngẫu nhiên của Diehard . Xem thêm:

  1. Làm thế nào để kiểm tra đơn vị một trình tạo số ngẫu nhiên giả?

    • Steve Jessop khuyên bạn nên tìm một triển khai đã được thử nghiệm của cùng một thuật toán RNG mà bạn đang sử dụng và so sánh kết quả đầu ra của nó với các hạt giống được chọn so với triển khai của chính bạn.
    • Greg Hewgill đề xuất bộ kiểm tra thống kê ENT .
    • John D. Cook giới thiệu đến độc giả bài viết CodeProject của mình Tạo số ngẫu nhiên đơn giản , bao gồm triển khai thử nghiệm Kolmogorov-Smirnov được đề cập trong tập 2, Thuật toán tổng hợp của Donald Knuth.
    • Một số người khuyên kiểm tra rằng phân phối số được tạo là đồng nhất, kiểm tra Chi bình phương và kiểm tra rằng giá trị trung bình và độ lệch chuẩn nằm trong phạm vi dự kiến. (Lưu ý rằng chỉ kiểm tra phân phối là không đủ. [1,2,3,4,5,6,7,8] là phân phối đồng đều, nhưng chắc chắn không phải là ngẫu nhiên.)
  2. Kiểm tra đơn vị với các hàm trả về kết quả ngẫu nhiên

    • Brian Genisio chỉ ra rằng việc chế nhạo RNG của bạn là một tùy chọn để làm cho các thử nghiệm của bạn có thể lặp lại và cung cấp mã mẫu C #.
    • Một lần nữa, một số người khác chỉ đến việc sử dụng các giá trị hạt giống cố định cho độ lặp lại và các thử nghiệm đơn giản để phân phối đồng đều, bình phương, v.v.
  3. Kiểm tra đơn vị Tính ngẫu nhiên là một bài viết wiki nói về nhiều thách thức đã gặp phải khi cố gắng kiểm tra xem, về bản chất, không thể lặp lại. Một điều thú vị mà tôi lượm lặt được từ nó là:

    Tôi đã thấy winzip được sử dụng như một công cụ để đo tính ngẫu nhiên của một tệp các giá trị trước đó (rõ ràng, nó càng nhỏ có thể nén tệp càng ít ngẫu nhiên).


Một bộ thử nghiệm tốt khác cho tính ngẫu nhiên thống kê là 'ent' được tìm thấy tại Fourmilab.ch/random .

1
Bạn có thể tóm tắt một số liên kết bạn đã đăng, để hoàn thành câu trả lời không?
dlras2

@DanRasmussen Chắc chắn, tôi sẽ có thời gian để làm điều đó vào cuối tuần.
Lập hóa đơn cho thằn lằn

4
Vấn đề với tính ngẫu nhiên của LỚN là không có giá trị kỳ vọng, phạm vi mạnh mẽ - thật mỉa mai, cho rằng giá trị kỳ vọng của VÒNG là một thuật ngữ được xác định rõ trong thống kê. Và mặc dù đây không phải là ý bạn, nhưng nó gợi ý cho giải pháp phù hợp: sử dụng các thuộc tính đã biết của phân phối thống kê, kết hợp với lấy mẫu ngẫu nhiên và kiểm tra thống kê , để xác định xem thuật toán có hoạt động với xác suất rất cao hay không. Vâng, đó không phải là một thử nghiệm đơn vị cổ điển nhưng tôi muốn đề cập đến nó vì trong trường hợp dễ nhất, nó chỉ nhìn vào sự phân phối của giá trị mong đợi .
Konrad Rudolph

2
Có một phiên bản cập nhật của Pin thử nghiệm ngẫu nhiên nổi tiếng tại Dieharder, bao gồm Bộ kiểm tra thống kê (STS) do Viện Tiêu chuẩn và Công nghệ Quốc gia (NIST) phát triển. Nó có sẵn để chạy trong Ubuntu và có lẽ là các bản phát hành khác: phy.duke.edu/~rgb/General/dieharder.php
nealmcb

21

1. Đơn vị kiểm tra thuật toán của bạn

Đối với câu hỏi đầu tiên tôi sẽ xây dựng một lớp giả mà bạn cung cấp một chuỗi các số ngẫu nhiên mà bạn biết kết quả của thuật toán của mình. Bằng cách đó, bạn chắc chắn rằng thuật toán bạn xây dựng dựa trên chức năng ngẫu nhiên của bạn hoạt động. Vì vậy, một cái gì đó dọc theo dòng:

Random r = new RandomStub([1,3,5,3,1,2]);
r.random(); //returns 1
r.random(); //returns 3
...

2. Xem nếu chức năng ngẫu nhiên của bạn có ý nghĩa

Đối với bài kiểm tra đơn vị, bạn nên thêm một bài kiểm tra chạy nhiều lần và khẳng định rằng kết quả

  • nằm trong các ranh giới mà bạn đặt (vì vậy, một cuộn súc sắc nằm trong khoảng từ 1 đến 6) và
  • hiển thị phân phối hợp lý (thực hiện nhiều lần chạy thử và xem liệu phân phối có nằm trong x% so với những gì bạn mong đợi hay không, ví dụ: đối với cuộn súc sắc, bạn sẽ thấy tỷ lệ 2tăng từ 10% đến 20% (1/6 = 16,67%) thời gian cho rằng bạn cuộn nó 1000 lần).

3. Kiểm tra tích hợp cho thuật toán và hàm ngẫu nhiên

Bao lâu bạn sẽ mong đợi mảng của bạn được sắp xếp trong sắp xếp ban đầu? Sắp xếp vài trăm lần và khẳng định rằng chỉ x% thời gian sắp xếp không thay đổi.

Đây thực sự đã là một bài kiểm tra tích hợp, bạn đang kiểm tra thuật toán cùng với hàm ngẫu nhiên. Khi bạn đang sử dụng chức năng ngẫu nhiên thực sự, bạn không thể thoát khỏi các lần chạy thử duy nhất nữa.

Từ kinh nghiệm (tôi đã viết một thuật toán di truyền) tôi sẽ nói rằng việc kết hợp kiểm tra đơn vị thuật toán của bạn, kiểm tra phân phối chức năng ngẫu nhiên của bạn và kiểm tra tích hợp là cách tốt nhất.


14

Một khía cạnh của PRNG dường như bị lãng quên là tất cả các thuộc tính của nó đều có tính chất thống kê: bạn không thể ngờ rằng việc xáo trộn một mảng sẽ dẫn đến một hoán vị khác với cái mà bạn bắt đầu. Về cơ bản, nếu bạn đang sử dụng PRNG bình thường, điều duy nhất bạn được đảm bảo là nó không sử dụng một mẫu đơn giản (hy vọng) và nó có phân phối đồng đều giữa các bộ số mà nó trả về.

Một thử nghiệm thích hợp cho PRNG sẽ liên quan đến việc chạy nó ít nhất 100 lần và sau đó kiểm tra phân phối đầu ra (đây là câu trả lời trực tiếp cho phần thứ hai của câu hỏi).

Một câu trả lời cho câu hỏi đầu tiên gần như giống nhau: chạy thử nghiệm khoảng 100 lần với {1, 2, ..., n} và đếm số lần mỗi phần tử đã ở mỗi vị trí. Tất cả chúng nên gần bằng nhau nếu phương pháp xáo trộn là tốt.

Một vấn đề hoàn toàn khác là làm thế nào để kiểm tra PRNG cấp mật mã. Đây là một vấn đề mà có lẽ bạn không nên sống, trừ khi bạn thực sự biết những gì bạn đang làm. Mọi người đã biết phá hủy (đọc: mở các lỗ hổng thảm khốc) trong các hệ thống mật mã tốt chỉ bằng một vài 'tối ưu hóa' hoặc chỉnh sửa tầm thường.

EDIT: Tôi đã đọc lại câu hỏi, câu trả lời hàng đầu và của riêng tôi. Trong khi những điểm tôi đưa ra vẫn đứng vững, tôi sẽ trả lời câu trả lời của Bill The Lizard. Các thử nghiệm đơn vị là Boolean về bản chất - chúng thất bại hoặc thành công và do đó không được phép thử nghiệm "tính tốt" của các PRNG (hoặc phương pháp sử dụng PRNG), vì mọi câu trả lời cho câu hỏi này sẽ là định lượng , hơn là cực.


1
Tôi nghĩ bạn có nghĩa là số lần mỗi phần tử ở mỗi vị trí nên gần bằng nhau. Nếu chúng luôn chính xác như nhau, có gì đó rất sai.
octern

@octern Cảm ơn, tôi không biết làm thế nào tôi có thể viết rằng ... nó hoàn toàn sai cho đến bây giờ ...
K.Steff

6

Có hai phần này: kiểm tra ngẫu nhiên và kiểm tra những thứ sử dụng ngẫu nhiên.

Thử nghiệm ngẫu nhiên là tương đối đơn giản. Bạn kiểm tra xem khoảng thời gian của trình tạo số ngẫu nhiên như bạn mong đợi (đối với một số mẫu sử dụng một vài hạt ngẫu nhiên, trong một số ngưỡng) và phân phối đầu ra trên một cỡ mẫu lớn như bạn mong đợi nó được (trong một số ngưỡng).

Thử nghiệm những thứ sử dụng ngẫu nhiên được thực hiện tốt nhất với bộ tạo số ngẫu nhiên xác định. Vì đầu ra của ngẫu nhiên được biết đến dựa trên hạt giống (đầu vào của nó), nên bạn có thể kiểm tra đơn vị như bình thường dựa trên đầu vào so với đầu ra dự kiến. Nếu RNG của bạn không mang tính quyết định, thì hãy giả định nó với một cái mang tính xác định (hoặc đơn giản là không ngẫu nhiên). Kiểm tra tính ngẫu nhiên trong sự cô lập với mã tiêu thụ nó.


6

Hãy để nó chạy một loạt các lần và trực quan hóa dữ liệu của bạn .

Dưới đây là một ví dụ về việc xáo trộn từ Mã hóa kinh dị , bạn có thể thấy thuật toán này có ổn hay không:

nhập mô tả hình ảnh ở đây

Thật dễ dàng để thấy rằng mọi mặt hàng có thể được trả lại ít nhất một lần (ranh giới là OK) và phân phối là OK.


1
Trực quan +1 là chìa khóa. Tôi luôn thích ví dụ này với hình ảnh một chú chim cánh cụt trong phần ECB của bài viết về mật mã khối ). Một phần mềm tự động hiếm khi có thể phát hiện các quy tắc như vậy
Maksee

Hở? Điểm của hình dung đó là chỉ ra rằng phân phối không ổn. Thuật toán xáo trộn ngây thơ làm cho các đơn đặt hàng nhất định nhiều khả năng hơn các thuật toán khác. Chú ý các thanh 2341, 2314, 2143 và 1342 kéo dài bao xa?
hvd

4

Con trỏ chung Tôi thấy hữu ích khi xử lý mã lấy đầu vào ngẫu nhiên: Kiểm tra các trường hợp cạnh của tính ngẫu nhiên dự kiến ​​(giá trị tối đa và tối thiểu và giá trị tối đa 1 và tối thiểu 1 nếu có). Kiểm tra các vị trí (trên, trên và dưới) trong đó các số có điểm uốn (tức là -1, 0, 1 hoặc lớn hơn 1, nhỏ hơn 1 và không âm đối với các trường hợp trong đó giá trị phân số có thể làm rối hàm). Kiểm tra một vài nơi hoàn toàn bên ngoài đầu vào được phép. Kiểm tra một vài trường hợp điển hình. Bạn cũng có thể thêm một đầu vào ngẫu nhiên, nhưng đối với thử nghiệm đơn vị có tác dụng phụ không mong muốn mà giá trị tương tự không được kiểm tra mỗi khi thử nghiệm được chạy (mặc dù cách tiếp cận hạt giống có thể hoạt động, hãy kiểm tra 1.000 số ngẫu nhiên đầu tiên từ hạt giống S hoặc somesuch).

Để kiểm tra đầu ra của một hàm ngẫu nhiên, điều quan trọng là xác định mục tiêu. Trong trường hợp thẻ, mục tiêu là kiểm tra tính đồng nhất của trình tạo ngẫu nhiên 0-1, để xác định xem tất cả 52 thẻ xuất hiện trong kết quả hay một số mục tiêu khác (có thể là tất cả danh sách này và hơn thế nữa)?

Trong ví dụ cụ thể, bạn phải giả sử trình tạo số ngẫu nhiên của mình mờ đục (giống như việc kiểm tra đơn vị hệ điều hành hoặc malloc- trừ khi bạn viết OS). Có thể hữu ích khi đo trình tạo số ngẫu nhiên, nhưng mục tiêu của bạn không phải là tạo trình tạo ngẫu nhiên, chỉ để thấy rằng bạn nhận được 52 thẻ mỗi lần và rằng chúng thay đổi thứ tự.

Đó là một cách dài để nói rằng thực sự có hai nhiệm vụ thử nghiệm ở đây: kiểm tra rằng RNG đang tạo ra phân phối đúng và kiểm tra xem mã xáo trộn thẻ của bạn đang sử dụng RNG đó để tạo ra kết quả ngẫu nhiên. Nếu bạn đang viết RNG, hãy sử dụng phân tích thống kê để chứng minh phân phối của bạn, nếu bạn đang viết bộ xáo trộn thẻ, hãy đảm bảo có 52 thẻ không lặp lại trong mỗi đầu ra (đó là trường hợp tốt hơn để kiểm tra bằng cách kiểm tra bạn đang sử dụng RNG).


4

Bạn có thể dựa vào các trình tạo số ngẫu nhiên an toàn

Tôi vừa có một suy nghĩ kinh khủng: bạn không viết trình tạo số ngẫu nhiên của riêng mình phải không?

Giả sử bạn không phải, thì bạn nên kiểm tra mã mà bạn chịu trách nhiệm chứ không phải mã của người khác (chẳng hạn như việc SecureRandomtriển khai cho khung của bạn).

Kiểm tra mã của bạn

Để kiểm tra xem mã của bạn có phản hồi chính xác hay không, thông thường sử dụng phương thức hiển thị thấp để tạo ra các số ngẫu nhiên để có thể dễ dàng bị ghi đè bởi một lớp kiểm tra đơn vị. Phương pháp ghi đè này có hiệu quả giả lập trình tạo số ngẫu nhiên và cung cấp cho bạn toàn quyền kiểm soát những gì được sản xuất và khi nào. Do đó, bạn hoàn toàn có thể thực hiện mã của mình, đó là mục tiêu của kiểm thử đơn vị.

Rõ ràng là bạn sẽ kiểm tra các điều kiện cạnh và đảm bảo rằng việc xáo trộn diễn ra chính xác như thuật toán của bạn đưa ra các đầu vào thích hợp.

Kiểm tra trình tạo số ngẫu nhiên an toàn

Nếu bạn không chắc chắn rằng trình tạo số ngẫu nhiên an toàn cho ngôn ngữ của bạn không thực sự ngẫu nhiên hoặc có lỗi (cung cấp các giá trị phạm vi, v.v.), thì bạn cần thực hiện phân tích thống kê chi tiết về đầu ra qua hàng trăm triệu lần lặp. Vẽ tần số xuất hiện của mỗi số và nó sẽ hiển thị với xác suất bằng nhau. Nếu kết quả nghiêng theo cách này hay cách khác, bạn nên báo cáo kết quả của mình cho các nhà thiết kế khung. Họ chắc chắn sẽ quan tâm đến việc khắc phục sự cố vì các trình tạo số ngẫu nhiên an toàn là nền tảng cho nhiều thuật toán mã hóa.


1

Chà, bạn sẽ không bao giờ chắc chắn 100%, vì vậy điều tốt nhất bạn có thể làm là có thể các con số là ngẫu nhiên. Chọn một xác suất - giả sử rằng một mẫu số hoặc vật phẩm sẽ tăng x lần cho một triệu mẫu, trong phạm vi sai số. Chạy thứ đó một triệu lần và xem nó có nằm trong lề không. May mắn thay, máy tính làm cho loại điều này dễ dàng để làm.


Nhưng các bài kiểm tra đơn vị như thế này có được coi là thực hành tốt không ..? Tôi đã luôn nghĩ rằng một bài kiểm tra đơn vị nên đơn giản nhất có thể: không có vòng lặp, nhánh hoặc bất cứ điều gì khác có thể tránh được.
dlras2

4
Các bài kiểm tra đơn vị phải chính xác . Nếu nó phân nhánh, vòng lặp, đệ quy - đó là giá. Bạn không thể kiểm tra một lớp cực kỳ tinh vi, được tối ưu hóa cao với các bài kiểm tra đơn vị một lớp. Tôi đã thực hiện thuật toán của Dijkstra để kiểm tra đơn vị một lớp.
K.Steff

3
@ K.Steff, wow. Bạn đã kiểm tra đơn vị kiểm tra đơn vị của mình để xác minh thuật toán Dijkstra có đúng không?
Winston Ewert

Điểm tốt, như một vấn đề thực tế - có, nhưng lần này với các bài kiểm tra 'tầm thường'. Tuy nhiên, chúng cũng là các bài kiểm tra đơn vị cho chương trình gốc (A *). Tôi nghĩ rằng đó là một thực tiễn tốt - thử nghiệm các thuật toán nhanh tạo ra các triển khai khập khiễng (nhưng đúng).
K.Steff

1

Để kiểm tra xem một nguồn số ngẫu nhiên đang tạo ra thứ gì đó ít nhất có sự xuất hiện ngẫu nhiên, tôi sẽ kiểm tra tạo ra một chuỗi byte khá lớn, ghi chúng vào một tệp tạm thời, sau đó trình bày ra công cụ ent của Fourmilab . Cung cấp cho công tắc -t (terse) để nó tạo ra CSV dễ phân tích. Sau đó kiểm tra các con số khác nhau để thấy rằng chúng là "tốt".

Để quyết định con số nào là tốt, hãy sử dụng một nguồn ngẫu nhiên đã biết để hiệu chỉnh bài kiểm tra của bạn. Bài kiểm tra hầu như luôn luôn vượt qua khi được cung cấp một bộ số ngẫu nhiên tốt. Bởi vì ngay cả một chuỗi thực sự ngẫu nhiên cũng có xác suất tạo ra một chuỗi dường như không ngẫu nhiên, bạn không thể có được một bài kiểm tra chắc chắn để vượt qua. Bạn chỉ cần chọn các ngưỡng khiến cho một chuỗi ngẫu nhiên không chắc chắn sẽ gây ra lỗi thử nghiệm. Không phải là ngẫu nhiên vui vẻ sao?

Lưu ý: Bạn không thể viết bài kiểm tra cho thấy PRNG tạo ra chuỗi "ngẫu nhiên". Bạn chỉ có thể viết một bài kiểm tra mà nếu nó vượt qua, chỉ ra một số xác suất rằng chuỗi được tạo bởi PRNG là "ngẫu nhiên". Chào mừng đến với niềm vui của sự ngẫu nhiên!


1

Trường hợp 1: Kiểm tra shuffle:

Hãy xem xét một Mảng [0, 1, 2, 3, 4, 5], xáo trộn nó, điều gì có thể sai? Các công cụ thông thường: a) không xáo trộn chút nào, b) xáo trộn 1-5 nhưng không 0, xáo trộn 0-4 nhưng không 5, xáo trộn và luôn tạo ra cùng một mô hình, ...

Một thử nghiệm để bắt tất cả:

Xáo trộn 100 lần, thêm các giá trị trong mỗi khe. Tổng của từng vị trí phải tương tự với các vị trí khác. Trung bình / Stddev có thể được tính toán. (5 + 0) /2=2,5, 100 * 2,5 = 25. Chẳng hạn, giá trị dự kiến ​​là khoảng 25.

Nếu các giá trị nằm ngoài phạm vi, có một cơ hội nhỏ, rằng bạn có âm tính giả. Bạn có thể tính toán, cơ hội đó lớn đến mức nào. Lặp lại thử nghiệm. Chà - tất nhiên có một cơ hội nhỏ, đó là bài kiểm tra thất bại 2 lần liên tiếp. Nhưng bạn không có thói quen tự động xóa nguồn của mình, nếu bài kiểm tra đơn vị thất bại, phải không? Chạy lại đi!

Nó có thể thất bại 3 lần liên tiếp? Có lẽ bạn nên thử vận ​​may tại xổ số.

Trường hợp 2: Lăn xúc xắc

Câu hỏi xúc xắc là cùng một câu hỏi. Ném xúc xắc 6000 lần.

for (i in 0 to 6000) 
    ++slot [Random.nextInt (6)];
return (slot.max - slot.min) < threshold;
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.