Giải bài toán số nguyên tố

4 1.3K 15
Giải bài toán số nguyên tố

Đang tải... (xem toàn văn)

Thông tin tài liệu

Giải bài toán số nguyên tố

Một phương pháp lập bảng số nguyên tốNgô Minh ĐứcTrong bài viết này tôi xin giới thiệu một phương pháp lập bảng số nguyên tốkhác, ngoài phương pháp sàng Eratosthenes đã qúa quen thuộc với cácbạn. Xin nhắc lại về sàng Eratosthenes (mang tên nhà toán học Hy Lạp, 275 - 194 TCN): - Ta sắp xếp các số tự nhiên từ 2 đến N vào một bảng theo thứ tự 2,3,4,5, . N. - Lưu lại số 2, lần lượt xóa đi các bội số của 2. - Sau số 2, số không bị xóa đầu tiên là số 3, lần lượt xóa đi các bội số của 3 - Sau số 3, số không bị xóa đầu tiên là số 5, lần lượt xóa đi các bội số của 5, . - Lặp lại đến khi không thể xóa được nữa thì thôi Như vậy các số không bị xóa lập thành bảng các số nguyên tố nhỏ hơn hoặc bằng N. Trong bộ sách ″Câu Chuyện Toán Học″ (một bộ sách rất hay gồm 6 tập của các thầy Nguyễn Bá Đô, Đỗ Mạnh Hùng và Nguyễn Văn Túc), tập 3 có giới thiệu một phương pháp lập bảng số nguyên tố khác. Tôi xin trình bày lạiở đây: Học sinh Sundaram người ấn Độ đã đưa ra phương pháp này năm 1934. Trước tiên Sundaram liệt kê một bảng các số như sau: 4 7 10 13 16 19 22 . 7 12 17 22 27 32 37 . 10 17 24 31 38 45 52 . (1) 13 22 31 40 48 58 67 . 16 27 38 49 60 71 82 . . Bảng số này có tính đối xứng (số ở hàng m cột n bằng số hàng n cột m) Các số này được chọn bằng cách lần lượt thực hiện các bước sau đây: 1. Viết số 4 vào góc bên trái 2. Các số tiếp theo của hàng 1 lần lượt là số liền trước cộng thêm 3 (các sốtrên hàng 1 lập thành cấp số cộng với công sai là 3) 3. Các số tiếp theo của hàng 2 lần lượt là số liền trước cộng thêm 5 (các sốtrên hàng 5 lập thành cấp số cộng với công sai là 5) . Dễ dàng tìm được công thức để tính giá trị số thứ m hàng thứ n: S m,n = (2m+1)n + m = 2mn + m + n Sundaram chỉ ra rằng: Nếu N có trong bảng (1) thì 2N+1 là hợp số. Nếu N không có trong bảng (1) thì 2N+1 là số nguyên tố. Để khẳng định điều đó, ta chứng minh mệnh đề tương đương sau: 2N+1 là hợpsố khi và chỉ khi N thuộc bảng (1) Chứng minh: (2N+1=2(2mn+m+n)+1=(2m+1)(2n+1) Do đó 2N+1 là hợp số (=>) Nếu 2N+1 là hợp số, ta có: 2N+1=xy (x,y lẻ) Đặt x=2m+1, y=2n+1 => 2N+1=(2m+1)(2n+1)=2(2mn+m+n)+1 => N=2mn+m+n Suy ra N là số thứ m của hàng n trong bảng Bây giờ ta thử xây dựng hai phương pháp trên thành chương trình. Chương trình: Vì Pascal không xây dựng được các mảng kích thước lớn (cỡ vài chục triệuphần tử), tôi xin chọn VB 6.0 để thể hiện thuật toán. Bạn tạo một Project và mở Module mới (lưu ý chọn Project Properties − Startup Object − Sub Main()) để chạy chương trình. Ta sử dụng mảng Mark() kiểu Byte để đánh dấu, lưu ý đối với mỗi phương phápmảng này có ý nghĩa khác đôi chút: - Sàng Eratosthenes: Mark(I)=0 nếu I là số nguyên tố, =1 nếu I là hợp số - Phương pháp của Sundaram: Mark(I)=0 nếu 2*I+1 là số nguyên tố, =1 nếu 2*I+1 là hợp số Khai báo như sau: Option Explicit Dim Mark() As Byte Dim N As Long Trong đó biến N xác định cần tìm các số nguyên tố từ 2 đến N. Sàng Eratosthenes Đây là thủ tục thể hiện sàng Eratosthenes, vì đã qúa quen thuộc nên có lẽ không cần giải thích nhiều với các bạn. Lưu ý một chút là ta chỉ cần xétcác số từ 2 đến sqrt(N): Private Sub Eratosthenes() '---------------------------------------------------------------------------------------------------------- ' Thủ tục: Eratosthenes() ' Lập bảng số nguyên tố bằng sàng Eratosthenes '---------------------------------------------------------------------------------------------------------- Dim I As Long Dim K As Long ReDim Mark(N) ′ định lại dung lượng cho mảng Mark(0) = 1: Mark(1) = 1 ' 0 và 1 không phải số nguyên tố ' sử dụng sàng Eratosthenes For I = 2 To Int(Sqr(N)) IfMark(I) = 0 Then ' nếu i là số nguyên tố K= I * 2 ' gạch các bội số của i Do While K >N/2 thì dừng lại Xét hàng 2, tất nhiên xét từ ô (2,2) để bỏ qua giá trị trùng lặp, cho đến sốhạng > N/2 thì dừng lại . Cho đến hàng n mà giá trị của ô (n,n)>N/2 thì dừng lại. ở mỗi số hạng K tìm thấy, ta đều đánh dấu Mark(K)=1 để chỉ 2*K+1 là hợp số Toàn bộ qúa trình trên là để xác định trong phạm vi 2->N/2, số nào có trong bảng, số nào không có trong bảng. Nhờ đó mà xác định được từ 2->N,số nào là số nguyên tố, số nào là hợp số. Thủ tục như sau: Private Sub Sundaram() '---------------------------------------------------------------------------------------------------------- ' Thủ tục: Sundaram() ' Tạo bảng số nguyên tố bằng phương pháp của Sundaram '---------------------------------------------------------------------------------------------------------- DimM As Long DimK As Long DimP As Long ' Lưu ý:Mark(0)=0 để chỉ 2 là số nguyên tố ReDim Mark(N 2) ′ định lại dung lượng cho mảng M = 0 Do M = M + 1 P = 2 * M + 1 ' các số trên hàng M lập thành cấp số cộng có công sai 2*M+1 K = M * (P +1) ' K là số nằm trên đường chéo của hàng M Do While K> N/2 ' cho đến khi số trên đường chéo của hàng M+1 > N/2 thì dừng. End Sub Bạn có thểso sánh tốc độ hai thủ tục trên cùng một giá trị N như sau: Dim t AsDouble N = 10000000 So sánh giữa giá trị hiện ra trong hộp thông báo của đoạn mã: t= Timer() CallSundaram MsgBoxTimer() − t Và: t= Timer() CallErastosthenes MsgBoxTimer() − t Ngoài ra nếuthích bạn có thể trình bày bảng số nguyên tố ra file văn bản bằngthủ tục sau: Private SubPrintPrimes(ByVal FileName As String, ByVal Kind As Boolean) '---------------------------------------------------------------------------------------------------------- ' Thủ tục:PrintPrimes ' In bảng sốnguyên tố đã tạo được ra text file ' Mô tả:FileName= tên File cần xuất ' Kind=Truenếu sử dụng sàng Eratosthenes, ' = False nếusử dụng sàng của Sundaram '----------------------------------------------------------------------------------------------------------DimI As Long DimJ As Long DimK As Long DimP As Long OpenFileName For Output As #1 ' tiêu đề Print#1, Space(20) & 'Bang cac so nguyen to tu 2 den ' & N K = 6 ' viếtmột hàng 6 số I = 0 Do If Mark(I) =0 Then IfKind Then ' sàng Eratosthenes P= I ' Mark(I)=0 thì số nguyên tố cần viết là I Else' sàng của Sundaram P= IIf(I = 0, 2, 2 * I + 1) ' quy ước số nguyên tố cần viết = 2 nếuI=0, . EndIf IfK = 6 Then Print#1, ' xuống dòng K= 1 Else K = K + 1 EndIf Print#1, Space(11 - Len(CStr(P))) + CStr(P); ' căn lề phải sao cho mỗi số đựơc12 kí tự EndIf I= I + 1 LoopUntil ((I > N/ 2) And (Not Kind)) Or (I > N) ' chỉ duyệt đến N/2 vớiphương pháp của Sundaram Close #1 End Sub Ví dụ đểsử dụng thủ tục: Sub Main() N=10000000 CallSundaram PrintPrimes(″D:Sundaram.txt″,False) End Sub Bạn nênxem file văn bản bằng font Courier New (nếu xem trên Windows), vì font nàycó bề rộng các chữ bằng nhau (fixed-width font) nên các số sẽ đượcsắp thẳng cột Tôi đã chạythử thủ tục Sundaram() với N=100 000 000- số nguyên tố lớn nhất tìmđược là 99 999 989, mất khoảng 88 giây (trên máy Celeron 700 Mhz, 128MB Ram, Windows 98 − chương trình chạy trực tiếp, chưa biên dịch rafile.EXE), riêng file văn bản chiếm 60 MB dung lượng. Trong khi đó thủtục Eratosthenes() mất tới 144 giây (thật không ngờ !!) Có thểtrong các trường hợp trên, cách viết mã cũng như thuật toán chưađạt được hiệu qủa cao nhất, dẫn đến việc so sánh không hợp lý. Vìthế rất mong nhận được sự góp ý của các bạn, mọi trao đổi xin gửivề địa chỉ: attilathehunvn@yahoo.com. Thân! . đi các bội số của 2. - Sau số 2, số không bị xóa đầu tiên là số 3, lần lượt xóa đi các bội số của 3 - Sau số 3, số không bị xóa đầu tiên là số 5, lần lượt. Mark(I)=0 nếu I là số nguyên tố, =1 nếu I là hợp số - Phương pháp của Sundaram: Mark(I)=0 nếu 2*I+1 là số nguyên tố, =1 nếu 2*I+1 là hợp số Khai báo như sau:

Ngày đăng: 07/09/2012, 10:55

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan