Tài liệu về đệ quy và đệ quy nâng cao . Bao gồm kỹ thuật giải đệ quy , khử đệ quy dùng đệ quy để giải các bài toán phức tạp ... Luận văn cao học được trình bày chi tiết và cẩn thận bởi các thạc sĩ trường đhqg hà nội khoa toán tin
Trang 1MỤC LỤC
Trang 2Lời cảm ơn
Trang 3LỜI NÓI ĐẦU
Trong quá trình nghiên cứu giải quyết các vấn đề - bài toán, người ta đãđưa ra những nhận xét như sau:
− Có nhiều bài toán cho đến nay vẫn chưa tìm ra một cách giải theo kiểuthuật toán và cũng không biết là có tồn tại thuật toán hay không;
− Có nhiều bài toán đã có thuật toán để giải nhưng không chấp nhậnđược vì thời gian giải theo thuật toán đó quá lớn hoặc các điều kiệncho thuật toán khó áp dụng;
− Có những bài toán được giải theo những cách giải vi phạm thuật toánnhưng vẫn chấp nhận được
Thuật toán đệ quy là một trong những sự mở rộng cơ bản nhất của kháiniệm thuật toán Như đã biết, một thuật toán cần phải thỏa mãn các tính chất:
− Tính hữu hạn;
− Tính xác định;
− Tính đúng đắn
Tuy nhiên, có những bài toán mà việc xây dựng một thuật toán với đầy đủ
ba tính chất trên là rất khó khăn Trong khi đó, nếu ta xây dựng một thuật toán viphạm một vài tính chất trên thì cách giải lại trở nên đơn giản hơn nhiều và có thểchấp nhận được Một trong những trường hợp đó là thuật toán đệ quy
Khi thực hiện đề tài này, mục đích chính của em là tìm hiểu các vấn đềcăn bản nhất, những lý thuyết nền tảng của thuật toán đệ quy cũng như thấy
rõ ưu điểm của sự đệ quy trong việc đơn giản hóa quá trình tính toán, giải một
số bài toán khó, bài toán điển hình có tính ứng dụng trong thực tiễn Đồngthời chỉ ra cài đặt đệ quy trong máy tính đôi lúc lại không đơn giản như phátbiểu đệ quy, từ đó giới thiệu phương pháp khử đệ quy và mục đích, ý nghĩacủa phương pháp khử đệ quy
Bố cục của luận văn được chia làm 3 chương:
Chương I: TỔNG QUAN VỀ ĐỆ QUY VÀ GIẢI THUẬT ĐỆ QUYChương II: MỘT SỐ BÀI TOÁN GIẢI BẰNG GIẢI THUẬT ĐỆ
Trang 4QUY ĐIỂN HÌNHChương III: KHỬ ĐỆ QUY
KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN CỦA ĐỀ TÀI
Với thời gian làm đề tài không dài, vốn kiến thức tiếp thu còn hạn chế
và chưa có kinh nghiệm trong lập trình nên bài khóa luận của em không tránhkhỏi những thiếu sót, em rất mong nhận được sự đóng góp cũng như phê bìnhcủa thầy cô và các bạn để bài khóa luận được hoàn thiện hơn!
Trang 5CHƯƠNG I TỔNG QUAN VỀ ĐỆ QUY VÀ GIẢI THUẬT ĐỆ QUY
1.1 Khái niệm về đệ quy
Đệ quy là một khái niệm tồn tại trong thực tế sống, trong toán học vànhất là trong các ngôn ngữ lập trình Sau đây là một số hiện tượng có tính đệquy trong thực tế cuộc sống
Bộ Matruska là một mặt hàng mỹ nghệ nổi tiếng thế giới của các nghệnhân người Nga mà đã từng xuất hiện ở Việt Nam Một con to nhất có cáibụng rỗng, thân nó được chia thành hai phần như cái hộp, khi mở nắp ra cómột con bé hơn nằm trong bụng của nó Con lật đật thứ hai này cũng như conlớn hơn, khi mở nắp ra cũng thấy con bé hơn nằm trong bụng nó, lại mở ra talại được con bé hơn Xếp tất cả các con lật đật này cạnh nhau ta thấy chúng cóhình dáng giống nhau nhưng kích thước và khi lồng chúng vào nhau thì tathấy dường như mỗi con chứa trong nó hình ảnh của chính bản thân nó
Hiện tượng thứ hai quen thuộc hơn, khi chúng ta theo dõi các chươngtrình “cầu truyền hình” của đài truyền hình Việt Nam, một hiện tượng khá lýthú mà ta có thể nhìn thấy khi ngồi xem truyền hình Trên màn ảnh tivi tanhìn thấy hướng dẫn viên truyền hình đang nói, bên cạnh anh ta là một chiếctivi dùng để phát ngay lại cảnh của trường quay, trong màn ảnh của tivi ta lạithấy hình ảnh của chính nó, và một chuỗi các hình ảnh tivi lồng vào nhau
Cả hai hiện tượng mà ta thấy ở trên và nhiều hiện tượng khác tương tựnhư vậy đều có tính chất chung, là một đối tượng bao hàm trong nó hình ảnh
của chính nó và ta gọi đó là hiện tượng đệ quy.
Một vấn đề đặt ra là: các hiện tượng đệ quy mà ta đã xét ở phần trênđều mang tính chất tự nhiên trong cuộc sống đời thường Vậy còn trong toánhọc, thường các đối tượng đều được thông qua các đối tượng khác, liệu cóhiện tượng một đối tượng được tính toán dựa trên dữ kiện của chính nókhông? Có thể trả lời câu hỏi này thông qua một số ví dụ sau:
Ví dụ 1: Tính giai thừa của số tự nhiên n (ký hiệu n!)
Trang 6n! được tính như sau:
a a
u r
n a
u q
n a
1.2 Giải thuật đệ quy
1.2.1 Khái niệm giải thuật đệ quy
Nếu lời giải của bài toán P được thực hiện bằng lời giải của bài toán P’
có dạng giống như P thì đó là một lời giải đệ quy Giải thuật tương ứng với lờigiải như vậy gọi là giải thuật đệ quy Mới nghe có vẻ hơi lạ nhưng điểm mấuchốt cần lưu ý là: P’ tuy có dạng giống như P, nhưng theo một định nghĩa nào
đó P’ phải “nhỏ” hơn P, dễ giải hơn P và việc giải nó không cần dùng đến P
Hãy xét bài toán tìm một từ trong một quyển từ điển Có thể nêu giảithuật như sau:
Trang 7Tìm từ trong từ điển
Tìm từ trong từ điển nửa trước
Mở từ điển vào trang “giữa”;
Xác định xem nửa nào của từ điển chứa từ cần tìm;
If (Từ đó nằm ở nửa trước của từ điển) then (Tìm từ đó
trong nửa trước)
Else (Tìm từ đó trong nửa sau);
End;
Tất nhiên giải thuật trên mới chỉ được nêu dưới dạng “thô” và cònnhiều chỗ chưa cụ thể, chẳng hạn:
− Tìm từ trong một trang thì làm thế nào?
− Thế nào là mở từ điển vào trang giữa?
− Làm thế nào để biết từ đó nằm ở nửa nào của từ điển?
Để trả lời rõ những câu hỏi trên không phải là khó, nhưng ta sẽ không
sa vào các chi tiết này mà muốn tập trung vào việc xét “chiến thuật” của lờigiải Có thể hình dung chiến thuật tìm kiếm này một cách khái quát như sau:
Hình 1.1 Mô tả đệ quy tìm một từ trong từ điển
Ta thấy có hai điểm chính cần lưu ý:
Sau mỗi lần từ điển được tách đôi thì một nửa thích hợp sẽ lại được tìmkiếm bằng một “chiến thuật” như đã dùng trước đó
Có một trường hợp đặc biệt, khác với mọi trường hợp trước, sẽ đạt đượcsau nhiều lần tách đôi, đó là trường hợp từ điển chỉ còn duy nhất một trang.Lúc đó việc tách đôi ngừng lại và bài toán trở thành đủ nhỏ để ta có thể giải
Trang 8quyết trực tiếp bằng cách tìm từ mong muốn trên trang đó chẳng hạn bằng cách
tìm tuần tự Trường hợp đặc biệt này được gọi là trường hợp suy biến
(degenerate case)
Có thể coi đây là một “chiến thuật” kiểu “chia để trị” (devide andconquer) Bài toán được tách thành bài toán nhỏ hơn và bài toán nhỏ hơn lạiđược giải quyết với thuật chia để trị như trước, cho tới khi xuất hiện trườnghợp suy biến
Ta thể hiện giải thuật tìm kiếm này dưới dạng một thủ tục:
Procedure TIMKIEM (TD,Tu)
{TD được coi là đầu mối để truy nhập vào từ điển đang xét, Tu chỉ từ cần tìm}
1 If (Từ điển là một trang) then (Tìm từ trong trang này)
2 Else Begin
Mở từ điển vào trang “giữa”;
Xác định xem nửa nào của từ điển chứa từ Tu;
If (Từ đó nằm ở nửa trước của từ điển) then
call TIMKIEM (TD1,Tu) Else call TIMKIEM (TD2,Tu)End;
{TD1 và TD2 là đầu mối để truy nhập vào nửa trước và nửa saucủa từ điển}
3 ReturnThủ tục như trên gọi là thủ tục đệ quy Từ đó, có thể nêu ra các đặcđiểm sau:
− Trong thủ tục đệ quy có lời gọi đến chính thủ tục đó Ở đây, trongthủ tục TIMKIEM có call TIMKIEM;
− Mỗi lần có lời gọi lại thủ tục thì kích thước của bài toán đã thu nhỏhơn trước Ở đây, khi có call TIMKIEM thì kích thước chỉ còn bằngmột “nửa” trước đó;
Trang 9− Có một trường hợp đặc biệt: Trường hợp suy biến Đó chính làtrường hợp mà từ điển chỉ còn là một trang Khi trường hợp này xảy
ra thì bài toán còn lại sẽ được giải quyết theo một cách khác hẳn vàgọi đệ quy cũng kết thúc Chính tình trạng kích thước của bài toán
cứ giảm dần sẽ đảm bảo dẫn tới trường hợp suy biến
1.2.2 Bố cục một chương trình con đệ quy
Phương pháp đệ quy mạnh ở chỗ nó cho phép mô tả một tập lớn các đốitượng chỉ bởi một số ít các mệnh đề hoặc mô tả một giải thuật phức tạp bằngmột số ít các thao tác (một chương trình con đệ quy)
Một chương trình con đệ quy căn bản gồm hai phần:
− Phần neo (anchor): Tương ứng với các trường hợp suy biến, thôngthường trong trường hợp suy biến ta đã biết lời giải của bài toán.Một chương trình đệ quy nhất thiết phải có phần suy biến này, nếukhông có chương trình của chúng ta có thể bị rơi vào tình trạng gọi
đệ quy vô hạn lần và chương trình không thể tiếp tục được
− Phần đệ quy: Tương ứng với trường hợp tổng quát, qui bài toán vềbài toán tương tự bằng cách gọi tới chương trình con đó với các bộ
dữ liệu “đơn giản hơn”, thông thường bài toán con này có kích
thước nhỏ hơn bài toán ban đầu Phần đệ quy thể hiện tính “quynạp” của lời giải
Ví dụ: Tính giai thừa của số tự nhiên n:
*
) 1 ( ) 0 ( 1
n n
GT n
n
Khi đó: (1) là phần neo; (2) là phần đệ quy
1.2.3 Phương pháp tìm giải thuật đệ quy cho một bài toán
Để xây dựng giải thuật một bài toán có tính đệ quy bằng phương pháp
đệ quy ta cần thực hiện tuần tự 3 nội dung sau:
− Thông số hóa bài toán;
− Tìm các trường hợp neo cùng giải thuật giải tương ứng;
Trang 10− Tìm giải thuật giải trong trường hợp tổng quát bằng phân rã bài toántheo kiểu đệ quy.
1.2.3.1 Thông số hóa bài toán
Tổng quát hóa bài toán cụ thể cần giải thành bài toán tổng quát (một họcác bài toán chứa bài toán cần giải), tìm ra các thông số cho bài toán tổng quátđặc biệt là nhóm các thông số biểu thị kích thước của bài toán - các thông sốđiều khiển (các thông số mà độ lớn của chúng đặc trưng cho độ phức tạp củabài toán và giảm đi qua mỗi lần gọi đệ quy)
Ví dụ: GiaiThua(0) = 1;
USCLN(m,n) = m khi m = n
1.2.3.3 Tìm thuật giải trong trường hợp tổng quát
Tìm phương án (giải thuật) giải bài toán tổng quát bằng cách phân chia
nó thành các thành phần mà hoặc có giải thuật không đệ quy hoặc là bài toántrên nhưng có kích thước nhỏ hơn
Ví dụ: GiaiThua = n*GiaiThua(n-1)
1.3 Phân loại đệ quy
1.3.1 Phân loại theo mô tả đệ quy
Trong nhiều tình huống việc mô tả các bài toán, các giải thuật, các sựkiện, các sự vật, các quá trình, các cấu trúc sẽ đơn giản và hiệu quả hơn nếu
ta nhìn được nó dưới góc độ mang tính đệ quy
Mô tả mang tính đệ quy về một đối tượng là mô tả theo cách phân tíchđối tượng thành nhiều thành phần mà trong số các thành phần có thành phần
Trang 11mang tính chất của chính đối tượng được mô tả Tức là mô tả đối tượng quachính nó.
Người ta phân đệ quy thành 2 loại: Đệ quy trực tiếp và đệ quy gián tiếp
− Đệ quy trực tiếp: Là loại đệ quy mà đối tượng được mô tả trực tiếpqua nó: A mô tả qua A, B, C, trong đó B, C, không chứa A
− Đệ quy gián tiếp: Là đệ quy mà đối tượng được mô tả gián tiếp quanó: A mô tả qua A1, A2, A3 ,An Trong đó có một Ai được mô tảqua A
1.3.2 Phân loại theo cách gọi hàm
1 (
*
) 0 ( 1
n n
n
n
− Dạng hàm trong ngôn ngữ tựa Pascal:
Function GiaiThua(n): Item;
Begin
If (n=0) then GiaiThua := 1Else Giaithua := n*GiaiThua(n-1);
End;
Trang 12{Item quy ước là một kiểu dữ liệu bất kỳ nào đó}
Ví dụ 2: Chương trình con tính USCLN của 2 số nguyên dương a và b
− Dạng ngôn ngữ toán học:
USCLN(a,b) =
( ) ( , ) ( ) (b , ) ( )
− Dạng hàm trong ngôn ngữ tựa Pascal:
Function USCLN(a,b): Item;
P ≡ If (thỏa mãn điều kiện dừng) then thực hiện S
Else
Begin
Thực hiện S*;Gọi P(x); Gọi P(y);
End;
Với S, S* là các thao tác không đệ quy
Ví dụ: Hàm FIBO(n) tính số hạng n của dãy FIBONACCI
−
=
= ) 1 ( ) 1 ( ) 2 (
) 1
; 0 ( 1
n n
F n
F
n n
Ở bài toán này, trường hợp suy biến ứng với hai giá trị FIBO(0) =FIBO(1) = 1
Trang 13− Dạng hàm trong ngôn ngữ tựa Pascal:
Function FIBO(n): Item;
Begin
If (n<=1) then FIBO := 1Else FIBO := FIBO(n-2) + FIBO(n-1);
End;
1.3.2.3 Đệ quy phi tuyến
Chương trình con đệ quy phi tuyến là chương trình con đệ quy trực tiếp
mà lời gọi đệ quy được thực hiện bên trong vòng lặp
Dạng tổng quát của chương trình con đệ quy phi tuyến:
P ≡ If (thỏa điều kiện dừng) then thực hiện S
Với S, S* là các thao tác không đệ quy
Ví dụ: Cho dãy {X n} xác định theo công thức truy hồi:
Trang 14End;
1.3.2.4 Đệ quy hỗ tương
Trong đệ qui tương hỗ thì thường có 2 hàm, và trong thân của hàm này
có lời gọi của hàm kia, điều kiện dừng và giá trị trả về của cả hai hàm có thểgiống nhau hoặc khác nhau
Dạng tổng quát của chương trình con đệ quy hỗ tương:
Function TenHamY(thamso): Item; forward;
Function TenHamX(thamso): Item;
Function TenHamY(thamso): Item;
{hoặc Function TenHamY;}
Trang 15− Dạng hàm trong ngôn ngữ mã giả:
TimX ≡ Nếu n = 0 thì TimX = 1
Còn không TimX = TimX(n-1) + TimY(n-1);TimY ≡ Nếu n = 0 thì TimY = 1
Còn không TimY = TimX(n-1) * TimY(n-1);
− Dạng hàm trong ngôn ngữ tựa Pascal:
Function TimY(n): Item; forward;
Function TimX(n): Item;
Begin
If (n=0) then TimX:=1 Else TimX:=TimX(n-1)+TimY(n-1);
End;
Function TimY(n): Item; {hoặc Function TimY;}
Begin
If (n=0) then TimY:=1 Else TimY:=TimX(n-1)*TimY(n-1);
End;
Trang 161.4 Độ phức tạp của các chương trình đệ quy
Với các chương trình con đệ quy, ta không thể áp dụng các quy tắcthông thường như quy tắc nhân, quy tắc cộng để tính độ phức tạp củachúng, bởi vì một chương trình đệ quy sẽ gọi chính bản thân nó
Với chương trình đệ quy, trước hết ta cần thành lập các phương trình đệquy, sau đó giải các chương trình đệ quy Nghiệm của phương trình đệ quy làthời gian thực hiện chương trình đệ quy đó
1.4.1 Thành lập phương trình đệ quy
Phương trình đệ quy là một phương trình biểu diễn mối liên hệ giữaT(n) và T(k), trong đó: T(n) là thời gian thực hiện với kích thước dữ liệu nhập
là n, T(k) là thời gian thực hiện với kích thước dữ liệu nhập là k (k < n)
Để thành lập phương trình đệ quy ta căn cứ vào chương trình đệ quy
Ví dụ 1: Hàm tính giai thừa của số tự nhiên n viết bằng giải thuật đệ
quy có dạng:
Function GiaiThua(n:integer): integer;
Begin
If (n=0) then GiaiThua := 1Else Giaithua := n*GiaiThua(n-1);
End;
Gọi: T(n) là thời gian thực hiện tính n!
T(n-1) là thời gian thực hiện tính (n-1)!
Trường hợp n = 0, chương trình chỉ thực hiện một lệnh gán GiaiThua := 1,nên tốn O(1), do đó ta có T(0) = C1
Trường hợp n > 0, chương trình gọi đệ quy GiaiThua(n-1), việc gọi đệquy này tốn thời gian là T(n-1), sau khi có kết quả của việc gọi đệ quy,chương trình phải nhân kết quả đó với n và gán cho GiaiThua Thời gian đểthực hiện phép nhân và phép gán là một hằng C2
Vậy ta có phương trình đệ quy để tính thời gian thực hiện của chươngtrình đệ quy GiaiThua là:
Trang 171 (
) 0 ( C
2
1
n C
n T
n
Ví dụ 2: Xét thủ tục Mergesort một cách phác thảo như sau:
Function Mergesort (L:List; n:integer):List;
Var L1, L2:List;
Begin
If n=1 then return(L);
Else Begin
Chia L thành 2 nửa L1 và L2, mỗi nửa có độ dài n/2; Return (Merge(Mergesort(L1,n/2),Mergesort(L2,n/2))); End;
End;
Hàm Mergesort nhận một danh sách có độ dài n và trả về một danh sách
đã được sắp xếp Thủ tục Merge nhận 2 danh sách đã được sắp L1và L2 mỗidanh sách có độ dài n/2, trộn chúng lại với nhau để được một danh sách gồm
n phần tử có thứ tự Giải thuật chi tiết của Merge ta không bàn đến, chúng tachỉ để ý rằng thời gian để Merge các danh sách có độ dài n/2 là O(n)
Gọi: T(n) là thời gian thực hiện Mergesort một danh sách có n phần tử; T(n/2) là thời gian thực hiện Mergesort một danh sách có n/2 phần tử
Ta có phương trình đệ quy như sau:
2 / ( 2
) 1 ( C
2
1
n n C n
T
n
Trong đó:
− C1 là thời gian phải tốn khi L có độ dài bằng 1;
− Trường hợp n > 1, thời gian Mergesort được chia làm 2 phần:
• Phần gọi đệ quy Mergesort 1 danh sách có độ dài n/2 làT(n/2);
Trang 18• Phần thứ 2 bao gồm phép thử n > 1, chia danh sách thành 2nửa và Merge Ba thao tác này có thời gian không đổi, thờigian thực hiện là C2n.
1.4.2 Giải phương trình đệ quy
Để giải phương trình đệ quy ta có thể giải bằng những phương phápnhư: phương pháp truy hồi, phương pháp đoán nghiệm, phương pháp giảiphương trình đặc trưng, sử dụng định lý Master Ta đi tập trung nghiên cứuphương pháp truy hồi
Từ phương trình đệ quy ta thay thế T(m) (m < n) vào phía phải củaphương trình cho đến khi tất cả T(m) (m > 1) được thay thế bởi biểu thức củaT(1) Vì T(1) luôn là hằng nên ta có công thức của T(n) chứa các số hạng chỉliên quan tới n và các hằng số
2 / ( 2
) 1 ( C
2
1
n n C n
T(1) + kC2n
Vì 2k = n ⇒ k = logn và với T(1) = C1 ⇒ T(n) = C1n + C2nlogn
Vậy thời gian thực hiện thuật toán là O(nlogn)
1.5 Đệ quy và quy nạp toán học
Có một mối quan hệ giữa đệ quy và quy nạp toán học Cách giải đệ quymột bài toán dựa trên việc định rõ lời giải cho trường hợp suy biến rồi thiết kế
Trang 19làm sao để lời giải của bài toán được suy từ lời giải của bài toán nhỏ hơn,cùng loại như thế.
Tương tự như vậy, quy nạp toán học chứng minh một tính chất nào đóứng với số tự nhiên cũng bằng cách chứng minh tính chất ấy đúng đối với một
số trường hợp cơ sở (chẳng hạn với n = 1) và rồi chứng minh tính chất ấyđúng với n bất kỳ, nếu nó đã đúng với các số tự nhiên nhỏ hơn n
Do đó, ta không lấy làm lạ khi thấy quy nạp toán học được dùng đểchứng minh các tính chất có liên quan đến giải thuật đệ quy Chẳng hạn, sauđây ta chứng minh tính đúng đắn của giải thuật đệ quy tính n! và giải thuậttìm ước chung lớn nhất của 2 số nguyên dương
1.5.1 Tính đúng đắn của giải thuật đệ quy tính n!
GiaiThua(n) ≡ If (n=0) then GiaiThua := 1
Else Giaithua := n*GiaiThua(n-1);
Chứng minh tính đúng đắn của thuật toán trên là chứng minh với mọitham số đầu vào n (nguyên không âm) thì thuật toán đều dừng và cho kết quả
là n! Ta chứng minh bằng quy nạp như sau:
Trường hợp cơ sở với n = 0 thuật toán thực hiện 1 lần và cho kết quả là 0! = 1Giả sử thuật toán đúng với n = k (k>0), tức là với n = k thì GiaiThua(k)dừng và cho kết quả là k!
Xét n = k + 1, ta có thuật toán tính n! lúc này là tính (k+1)! sẽ đượcthực hiện như sau:
GiaiThua(k+1) := (k+1) * GiaiThua(k)Theo giả thiết quy nạp thì GiaiThua(k) dừng và cho kết quả là k! và dovậy GiaiThua(k+1) cũng dừng và cho kết quả là (k+1)!
1.5.2 Tính đúng đắn của giải thuật đệ quy tính USCLN của hai số nguyên dương
Thuật toán tìm ước số chung lớn nhất của 2 số nguyên dương như sau:
− Nếu a = b thì USCLN(a,b) = a
− Nếu a ≠ b thì:
USCLN(a,b) = USCLN(a - b,b) nếu a > bUSCLN(a,b) = USCLN(a,b - a) nếu a < b
Trang 20Ta phải chứng minh với mọi cặp số nguyên dương (a,b) thì thuật toánđều kết thúc và cho kết quả d = (a,b) là ước chung lớn nhất của a và b.
Thật vậy, với a = b thì thuật toán dừng và cho kết quả đúng
Ta phải chứng minh với a ≠ b thì sau một số hữu hạn lần gọi đệ quy nó
sẽ trở về trường hợp suy biến Thật vậy:
Nếu a > b, gọi d là ước chung lớn nhất của a và b, xét
d
b d
a d
b a
a− ∈Z+ hay (a - b)
cũng chia hết cho d hay nói cách khác d cũng là ước chung của a - b và b
Nếu a < b, gọi d là ước chung lớn nhất của a và b, xét
d
a d
b d
b− ∈Z+ hay (b - a)
cũng chia hết cho d hay nói cách khác d cũng là ước chung của a và b - a
Theo thuật toán đệ quy trên do quá trình đệ quy mới được tiếp tục bằngcách lấy số lớn trừ số bé, nên dãy thu được đơn điệu giảm và bị chặn dưới bởi
0 nên quá trình đó ắt phải dừng và đến lúc nào đó chúng phải bằng nhau(trường hợp suy biến)
Trang 21Chương II MỘT SỐ BÀI TOÁN GIẢI BẰNG GIẢI THUẬT ĐỆ QUY ĐIỂN HÌNH
2.1 Bài toán “Tháp Hà Nội” (Tower of Hanoi)
Phát biểu bài toán: Đây là một bài toán mang tính chất một trò chơi,
nội dung như sau:
Có n đĩa, kích thước nhỏ dần, đĩa có lỗ ở giữa (như đĩa hát) Có thể xếpchồng chúng lên nhau xuyên qua một cọc, to dưới nhỏ trên để cuối cùng cómột chồng đĩa dạng như hình tháp (hình 2.1)
1 Mỗi lần chỉ được chuyển một đĩa;
2 Không khi nào có tình huống đĩa to ở trên đĩa nhỏ (dù là tạm thời);
3 Được phép sử dụng một cọc trung gian, chẳng hạn cọc B để đặt tạm đĩa (gọi là cọc trung gian) khi chuyển từ cọc A sang cọc C
Phân tích bài toán:
Trang 22Để đi tới cách giải tổng quát, trước hết xét vài trường hợp đơn giản.
− Trường hợp một đĩa:
• Chuyển đĩa từ cọc A sang cọc C
− Trường hợp hai đĩa:
• Chuyển đĩa thứ nhất từ cọc A sang cọc B;
• Chuyển đĩa thứ hai từ cọc A sang cọc C;
• Chuyển đĩa thứ nhất từ cọc B sang cọc C
Ta thấy trường hợp n đĩa (n>2) nếu coi (n-1) đĩa ở trên, đóng vai trò như đĩa thứ nhất thì có thể xử lý giống như trường hợp 2 đĩa được, nghĩa là:
• Chuyển (n-1) đĩa trên từ cọc A sang cọc B;
• Chuyển đĩa thứ n từ cọc A sang cọc C;
• Chuyển (n-1) đĩa từ cọc B sang cọc C
Có thể hình dung việc thực hiện 3 bước này theo mô hình (hình
2.2) như sau:
Trang 23Bước 1
Bước 2
Trang 24Bước 3
Hình 2.2 Mô hình chuyển đĩa bài toán “Tháp Hà Nội”
Như vậy, bài toán “Tháp Hà Nội” tổng quát với n đĩa được dẫn đếnbài toán tương tự với kích thước nhỏ hơn, chẳng hạn từ chỗ chuyển n đĩa
từ cọc A sang cọc C nay là chuyển (n-1) đĩa từ cọc A sang cọc B Và ở mức này thì giải thuật lại là:
• Chuyển (n-2) đĩa trên từ cọc A sang cọc C;
• Chuyển 1 đĩa từ cọc A sang cọc B;
• Chuyển (n-2) đĩa từ cọc C sang cọc B
Và cứ như thế cho đến khi trường hợp suy biến xảy ra, đó là trường hợpứng với bài toán chuyển 1 đĩa thôi
Vậy thì các đặc điểm của đệ quy trong giải thuật đã được xác định và ta
có thể viết giải thuật đệ quy của bài toán “Tháp Hà Nội” như sau:
Procedure HANOI (n,A,B,C)
{Chuyển n đĩa từ cọc A sang cọc C thông qua cọc B}
1 If n=1 then chuyển đĩa từ A sang C
2 Else
Trang 25Đánh giá độ phức tạp của thuật toán:
Gọi Sn là số lần chuyển đĩa để chơi xong trò chơi với n đĩa
Nếu n = 1 thì rõ ràng là S1 = 1
Nếu n > 1 thì trước hết ta chuyển n-1 đĩa trên sang cọc B (giữ yên đĩathứ n ở dưới cùng của cọc A) Số lần chuyển n-1 đĩa là Sn− 1 Sau đó ta chuyểnđĩa thứ n từ cọc A sang cọc C Cuối cùng, ta chuyển n-1 đĩa từ cọc B sang cọc
2
n i
i
= 2n - 1Giả sử n = 64, đòi hỏi 264 - 1 lần chuyển đĩa (xấp xỉ 18,4 tỉ tỉ lần) Nếumỗi lần chuyển đĩa mất 1 giây thì thời gian thực hiện thuật toán xấp xỉ 585 tỉnăm! Ta nói độ phức tạp của bài toán là 2n - 1
Bài toán trên cho thấy rằng: một thuật toán phải kết thúc sau một sốhữu hạn bước, nhưng nếu số hữu hạn này quá lớn thì thuật toán không thểthực hiện được trong thực tế
2.2 Mở rộng bài toán “Tháp Hà Nội” - bài toán “Tháp Hà Nội vòng”
Trang 26Phát biểu bài toán: Phát biểu bài toán giống như bài toán “Tháp Hà
Nội” nhưng ta chỉ được phép chuyển thứ tự đĩa từ cọc A → B; B → C và
C → A Trong đó: A là cọc nguồn, B là cọc đích
Để đi tới cách giải tổng quát, trước hết xét vài trường hợp đơn giản
− Trường hợp một đĩa:
• Chuyển đĩa từ cọc A sang cọc B
− Trường hợp hai đĩa:
• Chuyển đĩa thứ nhất từ cọc A sang cọc B;
• Chuyển đĩa thứ nhất từ cọc B sang cọc C;
• Chuyển đĩa thứ hai từ cọc A sang cọc B;
• Chuyển đĩa thứ nhất từ cọc C sang cọc A;
• Chuyển đĩa thứ hai từ cọc A sang cọc B
Ta thấy trường hợp n đĩa (n>2) nếu coi (n-1) đĩa ở trên, đóng vai trò như đĩa thứ nhất thì có thể xử lý giống như trường hợp 2 đĩa được, nghĩa là:
• Chuyển (n-1) đĩa trên từ cọc A sang cọc B;
• Chuyển (n-1) đĩa trên từ cọc B sang cọc C;
• Chuyển đĩa thứ n từ cọc A sang cọc B;
• Chuyển (n-1) đĩa trên từ cọc C sang cọc A;
• Chuyển (n-1) đĩa trên từ cọc A sang cọc B
Có thể hình dung việc thực hiện 3 bước này theo mô hình (hình 2.3) như sau:
Trang 27A B C
Bước 1