CHUYÊN ĐỀ BỒI DƯỠNG HSG: BÁO CÁO DẠY HỌC CHUYÊN ĐỀ ĐỆ QUY ĐỆ QUY QUAY LUI. LÀ TÀI LIỆU ĐƯỢC DÙNG ĐỂ BỒI DƯỠNG HỌC SINH GIỎI MÔN TIN HỌC Ở TRUNG HỌC PHỔ THÔNG RẤT HIỆU QUẢ. TRÂN TRỌNG CẢM ƠN MỌI NGƯỜI ĐÃ QUAN TÂM RẤT MONG ĐƯỢC SỰ ỦNG HỘ
Trang 1BÁO CÁO DẠY HỌC CHUYÊN ĐỀ ĐỆ
QUY, ĐỆ QUY QUAY LUI
SỞ GIÁO DỤC VÀ ĐÀO TẠO ĐĂKNÔNG
TỔ BỘ MÔN TIN HỌC
Tham luận:
Phạm Thị Hồng Loan Trường THPT Chu Văn An – Tx Gia Nghĩa – Tỉnh ĐăkNông
Trang 2A ĐỆ QUY
Trang 31 Khái niệm
Trong một chương trình, một CTC có thể gọi một CTC khác vào làm việc Nếu như CTC đó gọi lại chính nó thì gọi là sự đệ qui
Trang 42 Phương pháp thiết kế giải thuật đệ qui
- Tham số hóa bài toán
- Tìm trường hợp suy biến
- Phân tích các trường hợp chung (đưa về các bài toán cùng loại nhưng nhỏ hơn)
Ví dụ: Viết hàm đệ qui để tính n! = 1.2 n
Tham số hóa: n! = gt(n);
Trường hợp suy biến Gt(0) = 1
Trường hợp chung Gtl(n) = n*Gt(n-1)
Trang 53 Lưu ý
+ Trong thủ tục và hàm đệ qui cần chứa các lệnh thể hiện tính dừng của đệ qui Nghĩa là các thủ tục , hàm đệ qui chỉ gọi tới chính nó một số hữu hạn lần rồi gặp điều kiện
thoát ( để nó không gọi tới chính nó nữa )
Trong hàm Gt, điều kiện dừng là 0! = 1, vì mỗi lần gọi tới hàm Gt thì N giảm đi 1 đơn vị nên sẽ dẫn tới
trường hợp N=0
+ Thủ tục và hàm đệ qui phải thể hiện tính đệ qui: Nó gọi tới chính nó
VD: Gt := N*gt(N-1);
Trang 64 Ưu, khuyết điểm của đệ quy:
- Chương trình sử dụng pp đệ quy thường gọn, dễ hiểu,
diễn tả ý tưởng quy nạp hay hạ bậc trong toán học tức là
đưa một vấn đề phức tạp về vấn đề đơn giản hơn
- Chương trình sử dụng thuật toán đệ quy phải thực hiện một tập lớn các thao tác trùng lặp, tốn nhiều bộ nhớ, khuyết điểm này có thể khắc phục bằng cách phá vỡ đệ quy hoặc dùng mảng để tính toán giá trị các bước
- Thuật toán đệ quy là một thuật toán rất thông dụng, có
nhiều bài toán không thể giải được nếu không dùng thuật toán đệ quy như bài toán tháp hà nội
Trang 75 Ví dụ
Lập trình bài toán : Tính số cách chia M vật thành N phần theo qui luật :
S1 S2 SN-1 SN 0 ( Si là số vật của phần thứ i ) và
(1<=M,N<=70)
Trang 85 Ví dụ
Gợi ý :
+ Nếu số đồ vật M=0 thì coi như có 1 cách chia: đó là cách chia mỗi người không được vật nào Số cách chia =1
+ Nếu số người N=0 thì không thể chia được số cách chia =0 + Nếu 0<M<N thì trong mọi cách chia, luôn có ít nhất N-M người không được chia, do vậy các cách chia khác nhau ở chỗ: chia có khác nhau cho M người còn lại hay không? Nói cách khác số cách chia trong trường hợp này bằng số cách chia của bài toán chia M vật cho M người, tức Chia(M,N) = Chia (M,M)
+ Nếu M>=N>0, ta phân trường hợp này thành 2 trường hợp không giao nhau: Trh 1: Mọi người đều được chia: Với M>=N trong cách chia này có chỗ giống nhau là mọi người đều có ít nhất 1 vật và ta chỉ cần tính số cách chia M-N vật còn lại cho N người Chia(M-N,N)
Trh: Có 1 người không được chia vật nào: Ta tính số cách chia M vật cho N-1 người Chia(M,N-1).
Tổng số cách chia = Chia(M-N,N) + Chia(M,N-1).
Trang 95 Ví dụ
Function Chia(M,N : LongInt) : LongInt;
Begin
If M=0 then Chia := 1
Else {M>0}
If N=0 then Chia := 0
Else {N>0}
If M<N then Chia := Chia(M,M)
Else
Chia := Chia(M-N,N)+Chia(M,N-1); End;
Trang 10B QUAY LUI + VÉT CẠN + LỰA CHỌN TỐI ƯU KẾT HỢP ĐỆ QUY
Trang 111 Ý nghĩa
Thuật toán BackTracking mang các đặc điểm:
+ Vét cạn mọi nghiệm bằng tìm kiếm tiến dần về đích đồng thời biết quay lui khi không thể tiến
+ Có thể đặt các “mắt lọc” để việc tìm kiếm nhanh chóng hơn: hoặc loại bỏ hoặc chỉ chọn một số hướng.
+ Có thể so sánh các nghiệm để có nghiệm tối ưu + Tuỳ theo yêu cầu, có thể chỉ tìm 1 nghiệm, cũng có thể tìm mọi nghiệm
Trang 122 Ba dạng đệ qui thường gặp để thực hiện thuật toán BackTracking
Dạng 1 : Tìm mọi nghiệm
Procedure Tim(k : Integer);
Begin
Vòng lặp đề cử mọi khả năng của bước thứ k trong tìm kiếm 1 nghiệm
Begin + Thử chọn 1 đề cử cho bước k
+ Nếu đề cử này chấp nhận được thì
Begin
* Ghi nhận giá trị đề cử;
* Lưu trạng thái mới của bài toán sau đề cử;
* Nếu chưa phải bước cuối cùng thì Tim(K+1) Else {là bước cuối cùng} thì Hiện Nghiệm;
* Trả lại trạng thái của bài toán trước khi đề cử;
End;
End;
End;
Trang 132 Ba dạng đệ qui thường gặp để thực hiện thuật toán BackTracking
Dạng 1 : Tìm mọi nghiệm
Ví dụ: MÃ ĐI TUẦN
Cho bàn cờ vua n*n ô (n<=20) Quân mã trên bàn cờ đi theo luật của cờ vua Tìm tất cả các đường đi của quân mã từ vị trí (x,y)
Trang 142 Ba dạng đệ qui thường gặp để thực hiện thuật toán BackTracking
Dạng 2 : Tìm một nghiệm
Procedure Tim(k : Integer);
Begin
Vòng lặp đề cử mọi khả năng của bước thứ k trong tìm kiếm 1 nghiệm
Begin
+ Thử chọn 1 đề cử + Nếu đề cử này chấp nhận được thì Begin
* Ghi nhận giá trị đề cử
* Lưu trạng thái mới của bài toán sau đề cử
* Nếu là bước cuối cùng thì Begin
Hiện Nghiệm; Thoát End
* Trả lại trạng thái trước khi đề cử End;
End;
End;
Trang 152 Ba dạng đệ qui thường gặp để thực hiện thuật toán BackTracking
Dạng 3 : Tìm nghiệm tối ưu
Procedure Tim(k : Integer);
Begin
Nếu bước k là bước sau bước cuối cùng thì
Begin
Nếu tìm được nghiệm mới thì So sánh nghiệm mới với nghiệm lưu tối ưu trước để chọn lại nghiệm lưu tối ưu
End;
Vòng lặp đề cử mọi khả năng của bước thứ k trong tìm kiếm 1 nghiệm
( Chú ý nên kết hợp với nghiệm lưu tối ưu đã có để thu hẹp diện đề cử )
Begin
+ Thử chọn 1 đề cử cho bước k
+ Nếu đề cử này thoả mãn bài toán thì Begin
* Ghi nhận giá trị đề cử;
* Lưu trạng thái mới của bài toán sau đề cử;
* Tim(k+1);
* Trả lại trạng thái của bài toán trước khi đề cử;
End;
End;
End;
Trang 162 Ba dạng đệ qui thường gặp để thực hiện thuật toán BackTracking
Dạng 3 : Tìm nghiệm tối ưu
Procedure Tim(k : Integer);
Begin
Nếu bước k là bước sau bước cuối cùng thì
Begin
Nếu tìm được nghiệm mới thì So sánh nghiệm mới với nghiệm lưu tối ưu trước để chọn lại nghiệm lưu tối ưu
End;
Vòng lặp đề cử mọi khả năng của bước thứ k trong tìm kiếm 1 nghiệm
( Chú ý nên kết hợp với nghiệm lưu tối ưu đã có để thu hẹp diện đề cử )
Begin
+ Thử chọn 1 đề cử cho bước k
+ Nếu đề cử này thoả mãn bài toán thì Begin
* Ghi nhận giá trị đề cử;
* Lưu trạng thái mới của bài toán sau đề cử;
* Tim(k+1);
* Trả lại trạng thái của bài toán trước khi đề cử;
End;
End;
End;