Theo mình biết thì có :
+ Cách xét từ 2 -> sqrt(n). Nhưng mà chúng ta cải tiến chút xíu, thay vì việc tăng từng đơn vị rồi chia,ta tăng 2 rùi 4 rùi 2... mỗi lần như thế lại chia xem có dư ko. VD:5->7->11->13->17->19->23....
Chạy nhanh khoảng gấp 3 lần so với việc xét từng số 1.
+Dùng phuơng pháp xác suất MillerTest:
Thuật toán xác xuất tiếp cận bài toán theo hướng khác, không theo con đường tìm một ước không tầm thường mà dựa vào hai tính chất khác của số nguyên tố. Cho p là một số nguyên tố, a là số nguyên không chia hết cho p, ta có :
a^(p-1) = 1 (mod p) (1)
a^2 = 1 (mod p) <-> a = 1 (mod p) hoặc a = -1 (mod p). (2).
Giả sử p-1 = q.2^t trong đó q là một số nguyên dương lẻ. Theo (1) và (2), với mọi số a không chia hết cho p ta đều có :
+ a^(q) = 1 (mod p) hoặc
+ a^(q.2^r) = -1(mod p) với một số nguyên r nào đó thoả 0 <= r < t. (*)
Như vậy, một số n là nguyên tố thì nó phải thoả mãn điều kiện trên với mọi 1 <= a <= n-1, ngược lại nếu tồn tại một a không thoả mãn tính chất trên thì chắc chắn n không phải là số nguyên tố. Mặt khác, ta có thể chứng minh được rằng, nếu n là một hợp số lẻ > 3 thì có không quá (n-1) / 4 giá trị a trong khoảng 1 đến n-1 thoả mãn (*). Do đó, với một số a chọn ngẫu nhiên trong khoảng 1 đến n-1, thì xác suất a thoả mãn (*) không quá 1/4 , và nếu k lần chọn thì xác suất để mọi lần chọn đều thoả mãn là không quá 1/(4^k).
Đây là code
Giải thích hộc máu mất
Code:
Function Prime(n : Integer) : Boolean;
Var
i, a : Integer;
Begin
Prime := False;
Cal(n, q, t) {phân tích n-1 = q.2^t}
For i := 1 to k do
Begin
a := Random(n-1) + 1;
if MillerTest(n, a, q, t) = False then Exit;
End;
Prime := True;
End;
Function Power(a, q, n : Integer) : Integer;
Var
c, p2, u : Integer;
Begin
c := 1;
u := a;
p2 := 1;
repeat
if q and p2 <> 0 then c := (c * u) mod n;
p2 := p2 shl 1;
u := (u * u) mod n;
until p2 > q;
Power := c;
End;
Function MillerTest(n, a, q, t : Integer) : Boolean;
Var
pre, c, i, j : Integer;
Begin
c := Power(a, q, n);
pre := n-1;
for i := 0 to t do
begin
if c = 1 then
begin
MillerTest := (pre = n-1);
Exit;
end;
pre := c;
c := (c * c) mod n;
end;
MillerTest := False;
End;
Thuật toán thực hiện k lần kiểm tra có chi phí cỡ O(k(logn)^3), xác suất sai không quá 1/4^k . Độ phức tạp của thuật toán tăng tuyến tính theo k, xác suất sai lầm giảm theo hàm mũ với k. Chỉ cần chọn k không quá lớn (k > 30) thì xác suất sai lầm quá nhỏ, do đó nếu n trải qua phép thử với k cơ sở a chọn ngẫu nhiên thì có thể khẳng định gần như chắc chắn n là số nguyên tố.
--------------
Err..còn cái nào nữa ko nhỉ ?
Bookmarks