Thuật toán tạo ngẫu nhiên
Thuật toán Tạo số ngẫu nhiên và kiểm tra tính ngẫu nhiênThu Hương1. Khái niệm số ngẫu nhiênThực tế chúng ta đã gặp rất nhiều số ngẫu nhiên, vậy số ngẫu nhiên là gì?Có thể hiểu một cách đơn giản khi ai đó đòi hỏi một số ngẫu nhiên cũng có nghĩa là không chú ý đó là số mấy và đó là số nào cũng được. Ngược lại, Ngẫu nhiên là một khái niệm toán học được định nghĩa chính xác: mọi số đều có khả năng xuất hiện tương đương nhau”.Vậy các số được dùng làm số ngẫu nhiên phải giới hạn vào một phạm vi nhất định. Không thể có một số nguyên ngẫu nhiên, chỉ có một số nguyên trong một miền xác định nào đó.Không có cách nào để tạo ra các số ngẫu nhiên thực sự từ một máy tính vì thực ra khi chương trình cho chúng ta viết, thì chắc chắn các số tạo ra có thể suy luận được. Chỉ có thể hi vọng viết chương trình tạo ra các chuỗi số có được nhiều thuộc tính giống như số ngẫu nhiên. Các số này thường được gọi là các số giả ngẫu nhiên (pseudo-random). Chúng không thực sự ngẫu nhiên nhưng chúng có thể hữu dụng như sự xấp xỉ của các số ngẫu nhiên.2. Một số ứng dụng của số ngẫu nhiênMột trong những ứng dụng phổ biến nhất với mục đích chính là mã hóa các thông điệp để chỉ người nhận thông điệp mới đọc được chúng. Có thể hiểu việc làm điều này là tạo cho thông điệp có dạng như một chuỗi số ngẫu nhiên bằng cách tạo ra một chuỗi giả ngẫu nhiên để mã hóa và cũng với chuỗi đó, người nhận có thể giải mã được.Lĩnh vực ứng dụng số ngẫu nhiên là lĩnh vực mô phỏng. Các số ngẫu nhiên rất thích hợp làm dữ liệu để nhập cho các chương trình mô phỏng lớn. Một số lượng dữ liệu phân tích lớn đôi khi chỉ cần xử lý trên một tập con nhỏ của nó, bằng cách lựa chọn theo kiểu thử ngẫu nhiên là đủ.3. Một số phương pháp tạo số ngẫu nhiên (Phương pháp đồng dư tuyến tính)Là một thuật toán nổi tiếng tạo số ngẫu nhiên được D.Lehner đưa ra vào những năm 1951. Thuật toán này được thể hiện ngắn gọn qua đoạn chương trình sau tạo N số ngẫu nhiên cho mảng A:A[0]:=s;For i:=1 to N do A[i]: =A[i-1]*b + 1 mod m;Với 3 hằng số s, N và m,Trong thuật toán này, để tạo một số ngẫu nhiên mới, ta lấy số trước đó nhân với b, cộng thêm 1, và lấy phần dư trong phép chia cho m. Như vậy, số nhận được luôn nằm từ 0 đến (m-1). Thuật toán này có vẻ thật đơn giản, nhưng phương pháp tạo số ngẫu nhiên Đồng dư tuyến tính này đã là chủ đề của nhiều tập toán khó và chi tiết. Bởi việc chọn các hằng số (s, N và m) là thực sự không hề đơn giản. Đầu tiên, m nên lớn, nó có thể là giá trị tối đa của một word, nhưng cũng không cần phải hoàn toàn lớn như vậy nếu không tiện. Thường thì chọn m là luỹ thừa của 10 hay của 2 là thuận lợiKhông nên chọn hằng b quá lớn hay quá nhỏ: an toàn hơn cả là chọn b có ít hơn m một chữ số. Quy luật chọn hằng số trên được phát triển bởi D.E.Knuth. Knuth đã chứng minh rằng sự lựa chọn này làm phương pháp đầy đủ tuyến tính làm phương pháp tạo ra số ngẫu nhiên tốt, thoả mãn được nhiều kiểm tra thống kê phức tạp. Câu hỏi đặt ra là sẽ thế nào nếu ta tạo ra một chu kỳ nhỏ so với miền xác định của nó? Ví dụ 1:Chọn b=19, m=481, s=0, sẽ tạo ra chuỗi 0, 1, 20, 1,… một chuỗi không ngẫu nhiên trong khoảng từ 0 đến 480.Không phải dễ dàng nhận ra những khó khăn đó. Bởi vậy việc sử dụng những chỉ dẫn chọn các hằng số (b, m và s) là nên chú ý.Giá trị khởi động bất kỳ nào cũng có thể sử dụng được trong việc tạo các số ngẫu nhiên mà không có ảnh hưởng gì đặc biệt. Thường thì không cần thiết phải lưu trữ cả chuỗi như trong ví dụ nêu trên. Ta chỉ cần giữ lại một biến toàn cục a, khởi động với một giá trị nào đó, rồi cập nhật bằng phép tính a:=(a*b+1) mod m.Để có thể lập trình được bằng Pascal(hay một số ngôn ngữ lập trình khác), ta phải qua 1 bước nữa vì chúng ta không thể bỏ qua tình trạng tràn: nó đựoc định nghĩa là một trường hợp lỗi mà có thể tạo ra các kết quả không dự đoán được. Giả sử máy vi tính của chúng ta có word 32 bit, mà ta chọn m=1000000000, b=33332245 và a=2345678. Tất cả các giá trị này đều nhỏ hơn giá trị tối đa của một số nguyên, nhưng phép toán đầu tiên (a*b+1) đã làm tràn. Kết quả đã gây ra sự tràn thì không có quan hệ với sự tính toán của chúng ta vì chúng ta chỉ quan tâm đến 8 ký số sau. Một thủ thuật để tạo bỏ sự tràn là phân nhỏ phép nhân ra làm nhiều phần. Để nhân p và q, chúng ta viết p=104p1 + p0 và q = 104q1 + q0Do đó kết quả là:Q p = (10 4 p 1 + p 0 )(10 4 q1 + q0) = 10 4 q 1 p 1 + 10 4 (p 1 q 0 + p 0 q 1 + p0 q 0) Chúng ta chỉ muốn 8 ký số cho kết quả, vì thế ta có thể bỏ qua số hạng đầu tiên 104 q1p1 và ở số hạng thứ 2 ta sẽ bỏ qua 4 ký số đầu (04 (p1q0+p0q1) ta sẽ có thực hiện điều này qua hàm mult sau:Fuction mult(p,q : integer) :integer ;Var p1, p0, q1, q0:integer;Beginp1:= p div m1;p0:=p mod m1;q1:=q div m1;q0:=q mod m1;mult:=(((p0*q1+p1*q0)mod m1)*m1 +p0q0) mod m;End;End;Hàm mult tính (p*q mod m), không bị tràn khi m nhỏ hơn ½ giá trị số nguyên tối đa. Kỹ thuật này hiển nhiên có thể đáp ứng với các giá trị m1 khác theo nguyên tắc m=m1 * m1.Chương trình tạo số ngẫu nhiênProgram random(input,output);Const m=100000000; m1=10000; b=3141581;Var i,a,N:integer;Function random:integer;Begina:=(mult(a,b)+1) mod m;random:=a;End;BeginReadln(N,a);For i:=1 to N do writeln(random);End.Khi chạy chương trình với dữ liệu nhập n=10 ; q=1234567; chương trình sẽ tạo được 10 số như sau 35884508, 80001069, 63512650,43635651, 1034472, 87181513, 6917174, 209855,67115956,599398771. Kiểm tra sự ngẫu nhiênThực tế cho thấy, trong một chuỗi ngẫu nhiên gồm 50 số thuộc miền xác định [1,50], một vài số có thể xuất hiện hơn một lần và cũng sẽ có vài số khác có thể không có trong chuỗi số. Nếu không đạt được điều này trong một chuỗi giả ngẫu nhiên thì đã có điều gì đó sai trong việc tạo chuỗi ngẫu nhiên. Nhiều phương pháp kiểm tra đặt cơ sở trên các nhận xét kiểu này được áp dụng cho phương pháp tạo số ngẫu nhiên để kiểm tra xem 1 chuỗi giả ngẫu nhiên có các thuộc tính của chuỗi ngẫu nhiên hay không. Ta sẽ xét một trong những thuật toán kiểm tra nàyThường thì dễ dàng nhận ra một chuỗi không ngẫu nhiên, nhưng rất khó chứng minhmột chuỗi là ngẫu nhiên, cũng không thể xác định chính xác thuộc tính nào của số ngẫu nhiên là quan trọng đối với một trình ứng dụng. Bởi vậy việc đưa ra những kiểm tra là thực sự cần thiết để đảm bảo không có tình huống suy thoái xảy ra. Nhiều kiểm tra đã được triển khai để xác định một chuỗi có được nhiều tính chất của chuỗi ngẫu nhiên thực sự hay không. Hầu hết các kiểm tra này đều có cơ sở giá trị trong toán học. Một trong những kiểm tra đó là phương pháp kiểm tra chi-bình phương, một kiểm tra thống kê, có bản chất cơ bản, dễ cài đặt và hữu dụng trong nhiều ứng dụng.Ý tưởng của phương pháp chi-bình phương là xét các số tạo ra có phân bố một cách hợp lý hay không. Nếu chúng tạo ra N số dương có giá trị nhỏ hon r, thì ta mong muốn nhận được khoảng N/r số cho mỗi giá trị. Đây là cốt lõi của vấn đề, số lần xuất hiện của tất cả các giá trị lại không nên lúc nào cũng bằng nhau, vì như thế thì không ngẫu nhiên.Dẫn đến việc cần tính toán xem một chuỗi các số có được phân bố giống như một chuỗi ngẫu nhiên hay không, đơn giản như chương trình sau:Fuction kiemtraRD(N,r,s:integer):real;Var I,t:integer; f: array[0 rmax] of integer;BeginRaninit(s);For i:=0 to rmax do f[i]:=0;For i:=1 to N doBeginT:=randomint(r);f[t]:=f[t]+1;end;t:=0;for i:=0 to r-1 do t:=t+f[i]*f[i];kiemtraRD:=((r*t/N) - N) ;End ;Đơn giản là tính tổng số của bình phương tần số(số lần) xuất hiện của mỗi giá trị, chia cho tần số mong muốn (N/r), rồi trừ bớt chiều dài chuỗi(N).Giá trị thống kê chi-bình phương này có thể biểu diễn theo công thức toán như sau:(0<I< nga^~u kho^ng chu?ng thi` r xa no? ne^?u la.i ngu+o+.c nhie^n, la` ddo? so^? ca?c vo+?i ga^`n ca`ng phu+o+ng chi-bi`nh tri. gia?> Đối với phương pháp kiêm tra đơn giản mà chúng ta đang thực hiện, giá trị chi-bình phương chỉ nên lệch một khoảng so với r. Điều này chỉ đúng nếu N lớn hơn 10r. Để đảm bảo nên thực hiện kiểm tra vài lần, bởi nó có thể sai 1 trong 10 lần kiểm tra.Phương pháp kiểm tra này cài đặt đơn giản nên thích hợp cho kết nó vào bên trong mỗi chương trình tạo số ngẫu nhiên, chỉ để đảm bảo rằng không có điều gì ngoài dự tính có thể gây ra các vấn đề nghiêm trọng. . Thuật toán Tạo số ngẫu nhiên và kiểm tra tính ngẫu nhiênThu Hương1. Khái niệm số ngẫu nhiênThực tế chúng ta đã gặp rất nhiều số ngẫu nhiên, vậy số ngẫu. theo kiểu thử ngẫu nhiên là đủ.3. Một số phương pháp tạo số ngẫu nhiên (Phương pháp đồng dư tuyến tính)Là một thuật toán nổi tiếng tạo số ngẫu nhiên được