Thuật toán AKS (Agrawal-Kayal-Saxena) tìm số nguyên tố trong Python

Lap trinh c++ Python

Thuật toán AKS là gì?

Thuật toán AKS (Agrawal-Kayal-Saxena) là một thuật toán kiểm tra số nguyên tố đầy tham vọng và phức tạp. Nó được phát triển bởi Manindra Agrawal, Neeraj Kayal và Nitin Saxena vào năm 2002 và là một trong những thuật toán đầu tiên có thể kiểm tra số nguyên tố trong thời gian đa thức.

Ý tưởng cơ bản của thuật toán AKS là kiểm tra tính nguyên tố của một số nguyên dương n bằng cách kiểm tra các đẳng thức số học được áp dụng cho các đa thức trên trường Z/nZ (trường chia lấy dư modulo n).

Dưới đây là mô tả tổng quan về thuật toán AKS:

  1. Bước 1: Kiểm tra xem n có là một lũy thừa của số nguyên tố nào đó không. Nếu có, thì n không phải là số nguyên tố.
  2. Bước 2: Tìm số nhỏ nhất r sao cho r là số nguyên tố và r ≤ log_2(n). Nếu tồn tại một số nguyên a, 1 < a < r, sao cho a^n ≡ 1 (mod n) hoặc a^(n/p) ≡ 1 (mod n) với mọi số nguyên p từ 1 đến r, thì n không phải là số nguyên tố.
  3. Bước 3: Tìm số nhỏ nhất k sao cho đẳng thức sau đây không đúng với bất kỳ a và r nào: (X + a)^n ≡ (X^n + a) (mod X^r – 1, n) với 0 ≤ a ≤ k và 1 ≤ (X^r – 1, n) ≤ n.
  4. Bước 4: Nếu n ≤ k, thì đánh giá n là số nguyên tố.
  5. Bước 5: Kiểm tra đẳng thức sau: (X + a)^n ≡ (X^n + a) (mod X^r – 1, n) với 1 ≤ a ≤ sqrt(phi(r)) * log_2(n) và (X^r – 1, n) > n/k.

Nếu đẳng thức trên không đúng cho bất kỳ a và X nào, thì n là số nguyên tố. Ngược lại, n không phải là số nguyên tố.

Thuật toán AKS sử dụng các đẳng thức số học để kiểm tra tính nguyên tố của số n. Tuy nhiên, thuật toán này có độ phức tạp thời gian là O(n^6) với n là số lượng chữ số của số n, do đó không phải là một thuật toán hiệu quả cho các số lớn.

Trong thực tế, thuật toán AKS không được sử dụng rộng rãi để kiểm tra số nguyên tố. Thay vào đó, các thuật toán khác như thuật toán Miller-Rabin và thuật toán sàng Eratosthenes được ưu tiên vì hiệu quả hơn và có thời gian chạy nhanh hơn.

Thuật toán AKS tạo ra một đột phá trong việc chứng minh rằng việc kiểm tra tính nguyên tố có thể được thực hiện trong thời gian đa thức. Nó đã mở ra cánh cửa cho các nghiên cứu tiếp theo trong lĩnh vực này và đã góp phần vào sự phát triển của lý thuyết số và thuật toán liên quan đến số nguyên tố.

Cài đặt Thuật toán AKS

Dưới đây là một phiên bản đơn giản của thuật toán AKS được cài đặt bằng Python:

def is_prime(n):
    # Kiểm tra xem n có là lũy thừa của số nguyên tố không
    for i in range(2, int(n**(1/2)) + 1):
        if n % i == 0:
            return False
    
    # Tìm số nhỏ nhất r thỏa mãn điều kiện
    r = 2
    while r < n:
        if (n % r != 0) and ((r**(n-1) % n) == 1):
            break
        r += 1
    
    if r == n:
        return True
    
    # Tìm số nhỏ nhất k thỏa mãn điều kiện
    k = 2
    while k <= n:
        a = 1
        while a <= int((k * (math.log2(n)))): 
            # Kiểm tra đẳng thức (X + a)^n ≡ (X^n + a) (mod X^r - 1, n)
            if (mod_exp(a, n, k) != (mod_exp(a, n, r) + a) % n):
                return False
            a += 1
        k += 1
    
    return True

def mod_exp(base, exponent, modulus):
    result = 1
    while exponent > 0:
        if exponent % 2 == 1:
            result = (result * base) % modulus
        base = (base * base) % modulus
        exponent = exponent // 2
    return result

Bạn có thể sử dụng hàm is_prime(n) để kiểm tra xem một số n có là số nguyên tố hay không. Ví dụ:

print(is_prime(17))  # Output: True
print(is_prime(25))  # Output: False

Lưu ý rằng phiên bản trên chỉ là một cài đặt đơn giản và không hiệu quả với các số lớn. Thuật toán AKS được sử dụng để chứng minh tính nguyên tố và không phải là phương pháp tìm số nguyên tố hiệu quả trong thực tế.

Dưới đây là một cách để tìm dãy số nguyên tố từ 1 đến 10000 bằng cách sử dụng thuật toán AKS:

def is_prime(n):
    # Kiểm tra xem n có là lũy thừa của số nguyên tố không
    for i in range(2, int(n**(1/2)) + 1):
        if n % i == 0:
            return False
    
    # Tìm số nhỏ nhất r thỏa mãn điều kiện
    r = 2
    while r < n:
        if (n % r != 0) and ((r**(n-1) % n) == 1):
            break
        r += 1
    
    if r == n:
        return True
    
    # Tìm số nhỏ nhất k thỏa mãn điều kiện
    k = 2
    while k <= n:
        a = 1
        while a <= int((k * (math.log2(n)))): 
            # Kiểm tra đẳng thức (X + a)^n ≡ (X^n + a) (mod X^r - 1, n)
            if (mod_exp(a, n, k) != (mod_exp(a, n, r) + a) % n):
                return False
            a += 1
        k += 1
    
    return True

primes = []
for i in range(2, 10001):
    if is_prime(i):
        primes.append(i)

print(primes)

Kết quả sẽ là một danh sách gồm các số nguyên tố từ 1 đến 10000: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *