Chia thử

Bách khoa toàn thư mở Wikipedia

Chia thử hay Chia thử nghiệm là cách làm tốn công nhưng đơn giản dễ hiểu nhất trong các thuật toán phân tích số nguyên ra thừa số. Ý tưởng của phương pháp này là thực hiện hàng loạt các phép chia để xem với số nguyên n có chia hết cho lần lượt từng số tự nhiên nhỏ hơn giá trị tuyệt đối của n hay không. Ví dụ với n = 12 sẽ chia hết cho 1, 2, 3, 4, 6, 12. Tối giản thành các thừa số số nguyên tố sẽ thu được 12 = 3 × 4 = 3 × 22 .

Chia thử được Fibonacci lần đầu tiên mô tả trong cuốn Liber Abaci (1202).[1]

Phương pháp[sửa | sửa mã nguồn]

Cho trước một số nguyên dương n, cách chia thử sẽ kiểm tra một cách có hệ thống xem n có chia hết cho bất kỳ số nhỏ hơn n. Phép thử sẽ lấy tăng dần số chia k bắt đầu từ 2 trở lên. Nếu n không chia hết cho k thì cũng không chia hết cho các bội số của k và sẽ không cần kiểm tra, ví dụ nếu đã không chia hết cho 2 thì không cần thử phép chia với 4 hoặc 6. Như vậy, phép thử có thể được giảm bớt khi chọn số chia là số nguyên tố. Ngoài ra, số chia cũng chỉ cần thử khi nhỏ hơn vì nếu n chia hết p, thì n = p × q và nếu q nhỏ hơn p thì đã được phát hiện khi cho q rồi. Nếu nsố chính phương thì căn bậc hai của n cũng là một thừa số dùng làm giới hạn trên cho phép thử.

Cũng có thể dùng thừa số nguyên tố để xác định giới hạn thử nghiệm chặt hơn. Giả sử Pi là số nguyên tố thứ i, nghĩa là P 1 = 2, P 2 = 3, P 3 = 5,... Nếu Pi là số cuối cùng dùng trong phép thử cho n thì P2i + 1 > n nên Pi + 1 chính là giới hạn không cần thử. Ví dụ n = 48 thì chỉ cần thử chia cho 2, 3 và 5 là đủ vì bình phương của số nguyên tố tiếp theo là P24 =72=49 lớn hơn 48 rồi, hoặc n < 25 thì chỉ cần thử chia cho 2 và 3 là đủ.

Đây là một ví dụ của thuật toán chia thử, sử dụng các số tự nhiên liên tiếp thành các số để thử, như sau (trong Python):

def trial_division(n: int) -> List[int]:
    """Trả ra một danh sách các thừa số nguyên tố cho một số tự nhiên."""
    a = []               # Chuẩn bị một danh sách trống.
    f = 2                # Ước số có thể đầu tiên.    
    while n > 1:         # Khi n vẫn còn ước số...
        if n % f == 0:   # Số dư là n chia cho f có thể là 0.        
            a.append(f)  # Nếu cho n chia cho nó, ra kết quả 0. Thêm f vào danh sách.
            n //= f       # Chia ước số trên cho n.
        else:            # Nếu n không phải ước của n,
            f += 1       # Thêm 1 vào f và thử lại.
    return a             # Các ước nguyên tố có thể lặp lại: 12 phân tích ra 2,2,3.

Cách khác hiệu quả hơn gấp đôi:

def trial_division(n: int) -> List[int]:
    a = []
    while n % 2 == 0:
        a.append(2)
        n //= 2
    f = 3
    while f * f <= n:
        if n % f == 0:
            a.append(f)
            n //= f
        else:
            f += 2
    if n != 1: a.append(n)
    # Chỉ có số lẻ là có thể
    return a

Cách chia thử như thế này được đảm bảo tìm ra tất cả ước số của n, nếu n là số nguyên tố thì phép thử có thể chạy đến n. Do đó, nếu thuật toán chỉ tìm thấy một ước số (lớn hơn 1) thì chứng tỏ nsố nguyên tố. Nếu tìm thấy nhiều hơn thì nhợp số.

Tham khảo[sửa | sửa mã nguồn]

  1. ^ Mollin, Richard A. (2002). “A brief history of factoring and primality testing B. C. (before computers)”. Mathematics Magazine. 75 (1): 18–29. doi:10.2307/3219180. MR 2107288.

Liên kết ngoài[sửa | sửa mã nguồn]