1. Trang chủ
  2. » Luận Văn - Báo Cáo

Nghiên cứu giải thuật đệ quy ứng dụng trong bồi dưỡng học sinh giỏi

121 37 0

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 121
Dung lượng 1,92 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Đặc biệt, trong công tác bồi dưỡng học sinh giỏi thì yêu cầu học sinh phải nắm vững các kiến thức về tư duy thuật toán, sử dụng ngôn ngữ lập trình thành thạo để có thể giải được các bài

Trang 1

BỘ GIÁO DỤC VÀ ĐÀO TẠO

TRƯỜNG ĐẠI HỌC VINH

Trang 2

TRƯỜNG ĐẠI HỌC VINH

LUẬN VĂN THẠC SĨ CÔNG NGHỆ THÔNG TIN

Người hướng dẫn khoa học: TS PHAN LÊ NA

NGHỆ AN, 8/2018

Trang 3

LỜI CAM ĐOAN

Tôi xin cam đoan luận văn "Nghiên cứu giải thuật đệ quy ứng dụng trong bồi dưỡng học sinh giỏi" này là công trình nghiên cứu của riêng tôi

Các số liệu sử dụng trong luận văn là trung thực Các kết quả nghiên cứu được trình bày trong luận văn chưa từng được công bố tại bất kỳ công trình nào khác

Tác giả

Trần Nam Cường

Trang 4

LỜI CẢM ƠN

Để hoàn thành luận văn này, trước tiên em xin gửi lời cảm ơn sâu sắc tới cô giáo TS Phan Lê Na, người hướng dẫn khoa học, đã định hướng và chỉ bảo tận tình từ những bước nghiên cứu đầu tiên cho tới khi hoàn thành luận văn Em xin chân thành cảm ơn các Thầy cô giáo trong Viện kỹ thuật công nghệ Trường Đại học Vinh đã tâm huyết, nhiệt tình truyền thụ những kiến thức cho em trong quá trình học tập, hỗ trợ em trong quá trình nghiên cứu luận văn Xin cảm ơn các Thầy cô, cán bộ phòng sau đại học Trường Đại học Vinh đã tạo cho em những điều kiện thuận lợi để học tập và nghiên cứu Cuối cùng, xin gửi lời cảm ơn tới cơ quan, gia đình, bạn bè và đồng nghiệp nguồn động viên tinh thần to lớn, đã luôn cổ vũ và tin tưởng để tôi hoàn thành nhiệm

vụ học tập và cuốn luận văn này./

Nghệ An, tháng 7 năm 2018

Tác giả

Trần Nam Cường

Trang 5

MỤC LỤC

LỜI CAM ĐOAN 1

LỜI CẢM ƠN 2

DANH MỤC CÁC TỪ VIẾT TẮT 5

DANH MỤC CÁC HÌNH VẼ 6

DANH MỤC CÁC BẢNG 7

MỞ ĐẦU 8

Chương 1: MỘT SỐ KHÁI NIỆM CƠ BẢN VỀ ĐỆ QUY 10

1.1 Khái niệm đệ quy 10

1.1.1 Khái niệm hình thức đệ quy 10

1.1.2 Khái niệm về đệ quy 11

1.1.3 Các bước để giải bài toán đệ quy 11

1.2 Giải thuật đệ quy 12

1.2.1 Khái niệm giải thuật đệ quy 12

1.2.2 Ví dụ 12

1.3 Chương trình con đệ quy 14

1.3.1 Khái niệm chương tình con đệ quy 14

1.3.2 Cấu trúc chương trình con đệ quy 14

1.3.3 Phân loại đệ quy 15

1.4 Nguyên tắc hoạt động của giải thuật đệ quy 17

1.4.1 Khái niệm Stack 17

1.4.2 Nguyên tắc hoạt động 17

1.4.3 Ưu điểm và hạn chế của giải thuật đệ quy 21

1.5 Một số bài toán về đệ quy 21

1.5.1 Bài toán tìm số Fibonacci thứ n 21

1.5.2 Bài toán sắp xếp mảng 23

1.5.3 Bài toán tìm nghiệm xấp xỉ của phương trình f(x)=0 24

1.5.4 Bài toán tháp Hà Nội 26

1.5.5 Bài toán giả thuyết của Collatz 28

1.6 Kết luận chương 1 30

Chương 2: ĐỆ QUY QUAY LUI 31

2.1 Tổng quan về đệ quy quay lui 31

2.2 Giải thuật đệ quy quay lui tổng quát 36

2.3 Ba dạng của đệ quy quay lui 37

2.3.1 Dạng 1 tìm một nghiệm 37

2.3.2 Dạng 2 tìm mọi nghiệm 41

2.3.3 Dạng 3 tìm nghiệm tối ưu 43

2.4 Một số bài toán về đệ quy quay lui 46

2.4.1 Bài toán Hoán vị 46

Trang 6

2.4.2 Bài toán liệt kê các chỉnh hợp không lặp chập k 48

2.4.3 Bài toán xếp các quân Hậu 49

Chương 3: ỨNG DỤNG GIẢI THUẬT ĐỆ QUY GIẢI MỘT SỐ NHÓM BÀI TOÁN BỒI DƯỠNG HỌC SINH GIỎI 53

3.1 Cài đặt các bài toán điển hình về đệ quy 53

3.1.1 Cài đặt Bài toán tìm số Fibonacci thứ n 53

3.1.2 Cài đặt bài toán sắp xếp mảng 53

3.1.3 Cài đặt Bài toán tìm nghiệm xấp xỉ của phương trình f(x)=0 55

3.1.4 Cài đặt Bài toán Tháp Hà Nội 55

3.2 Cài đặt các bài toán điển hình về đệ quy quay lui 56

3.2.1 Cài đặt Bài toán Hoán vị 56

3.2.2 Cài đặt Bài toán liệt kê các chỉnh hợp không lặp chập k 57

3.2.3 Cài đặt Bài toán Tám quân Hậu 58

3.3 Ứng dụng giải thuật Đệ quy giải nhóm bài toán học sinh giỏi 59

3.3.1 Ứng dụng giải nhóm bài toán tìm một nghiệm 59

3.3.1.1 Bài toán M quân hậu 59

3.3.1.2 Bài toán Mã đi tuần 61

3.3.1.3 Bài toánTìm đường đi trong mê cung 64

3.3.1.4 Bài toán máy rút tiền tự động ATM 69

3.3.2 Ứng dụng giải nhóm bài tập tìm mọi nghiệm 71

3.3.2.1 Bài toán đảo ký tự trong từ 71

3.3.2.2 Bài toán M quân Hậu 74

3.3.2.3 Bài toánTừ chuẩn loại M 76

3.3.2.4 Bài toán Biểu thức Zero 79

3.3.2.5 Bài toán Xổ số điện toán 82

3.3.2.6 Bài toán Phân tích số 85

3.3.3 Ứng dụng giải nhóm bài tập tìm nghiệm tối ưu 88

3.3.3.1 Bài toán cái Valy 88

3.3.3.2 Bài toán tháp Hà Nội xuôi 90

3.3.3.3 Bài toán chia phần thưởng 95

3.3.3.4 Bài toán Palindrome 99

3.3.3.5 Bài toán Mật khẩu 102

3.3.3.6 Bài toán Dây dẫn 105

3.3.3.7 Bài toán Xâu gần nhất 107

3.3.4.8 Bài toán Du lịch khứ hồi 109

3.3.4.9 Bài toán Tam giác số 113

3.5 Kết luận Chương 3 116

KẾT LUẬN 117

TÀI LIỆU THAM KHẢO 119

Trang 8

DANH MỤC CÁC HÌNH VẼ

1 Hình 1.1 Một số hình ảnh ứng dụng của đệ quy trong tạo hình 10

2 Hình 1.2 Chiến thuật tìm kiếm từ trong Tự điển 13

7 Hình 2.1 Quá trình tìm kiếm lời giải của thuật toán quay lui 36

8 Hình 2.2 Một cách xếp quân Hậu trên bàn cờ 8x8 49

9 Hình 3.1 Một phương án đặt quân Hậu trên bàn cờ 4x4 59

10 Hình 3.2 Kết quả chạy chương trình MHAU.PAS 61

11 Hình 3.3 Hai trong số nhiều hành tình của quân Mã 62

12 Hình 3.4 Kết quả chạy chương trình HORSE.PAS 64

14 HÌnh 3.6 Kết quả chạy chương tình MECUNG.PAS 68

15 Hình 3.7 Kết quả chạy chương trình ATM.PAS 70

16 Hình 3.8 kết quả chạy chương tình DAOKT.PAS 73

17 Hình 3.9 Kết quả chạy chương trình MHAU1.PAS 75

18 Hình 3.10 Kết quả chạy chương trình TUCHUAN.PAS 79

19 Hình 3.11 Kết quả chạy chương trình ZERO.PAS 82

20 Hình 3.12 Kết quả chạy chương trình XOSO.PAS 85

21 Hình 3.13 Kết quả chạy chương trình PTS.PAS 87

22 Hình 3.14 Kết quả chạy chương trình VALY.PAS 90

23 Hình 3.15 Quy tắc chuyển Tháp Hà Nội xuôi 91

24 Hình 3.16 Kết quả chạy chương trình HNXUOI.PAS 95

25 Hình 3.17 Kết quả chạy chương trình CHIATH.PAS 99

26 Hình 3.18 Kết quả chạy chương trình PALIN.PAS 102

27 Hình 3.19 Kết quả chạy chương trình MATKHAU.PAS 105

28 Hình 3.20 Kết quả chạy chương trình WIRES.PAS 107

29 Hình 3.21 Kết quả chạy chương trình CSTR.PAS 109

31 Hình 3.23 Kết quả chạy chương trình DULICH.PAS 113

32 Hình 3.24 Kết quả chạy chương trình TGS.PAS 115

Trang 9

DANH MỤC CÁC BẢNG

1 Bảng 1.1 Stack trong khi thực hiện giải thuật tính 3! 21

2 Bảng 1.2 Một số phần tử đầu tiên của dãy số Fibonacci 22

3 Bảng 2.1 Mô hình thuật toán quay lui tìm một nghiệm 34

4 Bảng 2.2 Mô hình thuật toán quay lui tìm mọi nghiệm 35

5 Bảng 3.1 Đặc tả Tháp Hà Nội xuôi khi b đứng sát a 92

6 Bảng 3.2 Hình trạng Tháp Hà Nội xuôi khi b đứng sát a 93

7 Bảng 3.3 Đặc tả Tháp Hà Nội xuôi khi cọc b không sát a 93

8 Bảng 3.4 Hình trạng Tháp Hà Nội xuôi khi b không đứng

sát a

94

9 Bảng 3.5 Tính chất hàm Chia i phần thưởng cho j học sinh 97

Trang 10

MỞ ĐẦU

1 Sự cần thiết của vấn đề nghiên cứu

Ngôn ngữ lập trình là một trong những nội dung được đưa vào giảng dạy chính thức ở bộ môn Tin học trong nhà trường phổ thông Đặc biệt, trong công tác bồi dưỡng học sinh giỏi thì yêu cầu học sinh phải nắm vững các kiến thức về tư duy thuật toán, sử dụng ngôn ngữ lập trình thành thạo để có thể giải được các bài toán trong Tin học

Như chúng ta đã biết, các phép lặp là một trong những kỹ thuật được dùng để giải các bài toán trong Tin học và đã được giới thiệu ở phần tin học

cơ sở Với các phép lặp, ta giải bài toán bằng cách thực hiện liên tiếp một số các câu lệnh trong vòng lặp cho tới khi một điều kiện nào đó được thỏa mãn Một kỹ thuật lập trình được sử dụng để thay thế cho các phép lặp đó là kỹ thuật đệ quy Mặt khác, trong thực tế có rất nhiều bài toán đòi hỏi sự lặp đi lặp lại một cách phức tạp Đệ quy không những giúp người lập trình giải quyết tốt

các bài toán mà còn giúp nâng cao tư duy tính toán, rèn luyện kỹ thuật lập

trình Đệ quy cung cấp cho ta cơ chế giải quyết bài toán phức tạp một cách đơn giản Hơn nữa, đệ quy còn thích hợp để giải quyết các bài toán có bản chất đệ quy và rất nhiều bài toán cho đến nay vẫn chưa có lời giải phi đệ quy

Để có thể hiểu rõ hơn về giải thuật đệ quy, ứng dụng của đệ quy để giải

các bài toán trong Tin học tôi đã chọn đề tài “Nghiên cứu giải thuật đệ quy ứng dụng trong bồi dưỡng học sinh giỏi” để tìm hiểu, nghiên cứu sâu hơn về

giải thuật đệ quy trong bồi dưỡng học sinh giỏi THPT

Qua đề tài này, tôi hy vọng sẽ giúp bản thân và nhiều người có thể hiểu sâu hơn giải thuật đệ quy Một trong những giải thuật khó và được áp dụng nhiều trong các bài toán tin học đặc biệt trong bồi dưỡng học sinh giỏi Đồng thời sẽ tạo ra được một nguồn tài liệu ý nghĩa để giáo viên bồi dưỡng học sinh giỏi tin học tham khảo

Trang 11

2 Mục tiêu nghiên cứu

Nghiên cứu để hiểu rõ giải thuật đệ quy bao gồm cách thức hoạt động, phân loại đệ quy, nghiên cứu các bài toán đệ quy điển hình từ đó hình thành một tài liệu nghiên cứu trong bồi dưỡng học sinh giỏi Đồng thời ứng dụng giải thuật này giải nhóm các bài tập bồi dưỡng học sinh giỏi tại trường THPT Lê Hồng Phong tỉnh Quảng Bình

3 Đối tượng và phạm vi nghiên cứu

3.1 Đối tượng nghiên cứu:

- Giải thuật đệ quy

- Các bài toán đệ quy điển hình

- Giải thuật đệ quy quay lui

- Các bài toán đệ quy quay lui điển hình

3.2 Phạm vi nghiên cứu:

Nghiên cứu lý thuyết đệ quy để áp dụng giải một số nhóm các bài toán bồi dưỡng học sinh giỏi

4 Nội dung nghiên cứu

- Nghiên cứu lý thuyết về giải thuật đệ quy

- Nghiên cứu lý thuyết về giải thuật đệ quy quay lui

- Ứng dụng giải thuật đệ quy giải một số nhóm bài toán bồi dưỡng học sinh giỏi

5 Kết cấu của luận văn

Ngoài phần mở đầu và phần kết luận, luận văn được sắp xếp theo bố cục sau đây:

Chương 1: Một số khái niệm cơ bản về đệ quy

Chương 2: Đệ quy quay lui

Chương 3: Ứng dụng giải thuật đệ quy giải một số nhóm bài toán bồi dưỡng học sinh giỏi

Trang 12

Chương 1: MỘT SỐ KHÁI NIỆM CƠ BẢN VỀ ĐỆ QUY

Chương này giới thiệu tổng quan về giải thuật đệ quy trong toán học và khoa học máy tính, các nghiên cứu trong nước và thế giới về giải thuật đệ quy, những bài toán điển hình sử dụng giải thuật đệ quy Từ đó phân tích, đánh giá và làm rõ những ưu điểm và hạn chế giải thuật này (xem [1], [7], [8])

1.1 Khái niệm đệ quy

1.1.1 Khái niệm hình thức đệ quy

Trong toán học và khoa học máy tính, các tính chất (hoặc cấu trúc) được gọi là đệ quy nếu trong đó một lớp các đối tượng hoặc phương pháp được xác định bằng việc xác định một số rất ít các trường hợp hoặc phương pháp đơn giản (thông thường chỉ một) và sau đó xác định quy tắc đưa các trường hợp phức tạp về các trường hợp đơn giản [1]

Chẳng hạn, định nghĩa sau là định nghĩa đệ quy của tổ tiên [1]

- Bố mẹ của một người là tổ tiên của người ấy (trường hợp cơ bản)

- Bố mẹ của tổ tiên một người bất kỳ là tổ tiên của người ấy (bước đệ quy)

Các định nghĩa kiểu như vậy cũng thường thấy trong toán học (chính là quy nạp toán học)

Tam giác sierpinski Kim tự tháp sierpinski Bông tuyết Koch

Hình 1.1 Một số hình ảnh ứng dụng của đệ quy trong tạo hình

Trang 13

1.1.2 Khái niệm về đệ quy

Từ những định nghĩa trên, khái niệm cơ bản của Đệ quy theo 2 cách:

Đệ quy (trong tiếng Anh là Recursion) là phương pháp dùng trong các chương trình máy tính trong đó có một hàm tự gọi chính nó [7]

Một khái niệm X được định nghĩa theo đệ quy nếu trong định nghĩa X có sử dụng chính khái niệm X

Sau đây là một số ví dụ điển hình về đệ quy:

Ví dụ 1.1: Định nghĩa về số tự nhiên:

0 là một số tự nhiên;

N là một số tự nhiên khi N-1 là một số tự nhiên

Ví dụ 1.2: Định nghĩa về giai thừa (N!):

0! = 1;

Nếu N>0 thì N! = N*(N-1)!

1.1.3 Các bước để giải bài toán đệ quy

Bước 1: Thông số hóa bài toán (hiểu bài toán)

Bước 2: Tìm các điều kiện biên (chặn), tìm giải thuật cho các tình huống này Bước 3: Tìm giải thuật tổng quát theo hướng đệ quy lui dần về tình huống bị chặn [8]

Ví dụ 1.3: Bài toán tính giai thừa của một số tự nhiên (tính N!):

Thông số hóa bài toán: Cách tính giai thừa (N!)

Trang 14

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 một bài toán T được thực hiện bằng lời giải của một bài toán T’ có dạng giống như T, thì đó là một lời giải đệ quy Giải thuật tương ứng với lời giải như vậy gọi là giải thuật đệ quy [5]

Nghe qua ta thấy hơi lạ, nhưng điểm quan trọng cần lưu ý là: T’ tuy có dạng giống như T, tuy nhiên theo một nghĩa nào đó, nó phải "nhỏ" hơn T

Trong khoa học máy tính có một phương pháp chung để giải các bài toán trong Tin học là chia bài toán thành các bài toán con đơn giản hơn cùng loại Phương pháp này được gọi là kỹ thuật lập trình chia để trị Chính nó là chìa khóa để thiết kế nhiều giải thuật quan trọng, là cơ sở của quy hoạch động

Ví dụ 1.5: 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ải thuật như sau:

If Từ điển là một trang Then Tìm từ trong trang này

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ừ 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;

Trang 15

Chiến thuật tìm kiếm này khái quát theo sơ đồ sau:

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ìm kiế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 được sau 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 dừng lại và bài toán trở thành đủ nhỏ để ta có thể giải quyế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

Có thể coi đây là một "chiến thuật " kiểu "chia để trị" 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ường hợp suy biến

Thủ tục sau thể hiện giải thuật tìm kiếm này:

Procedure TIMKIEM (TD,Tu)

{TD được coi là đầu mối để truy nhập được vào tự điển đang xét, Tu chỉ từ cần tìm}

Begin

if Tự điển chỉ còn là một trang then Tìm từ Tu trong trang này else begin

Mở tự điển vào trang giữa

Tìm từ trong Tự điển

Tìm từ trong Tự điển nữa trước

Tìm từ trong Tự điển

nữa sau

Hình 1.2 Chiến thuật tìm kiếm từ trong tự điển

Trang 16

Xác định xem nửa nào của tự điển chứa từ Tu

If Tu nằm ở nửa trước của tự điển

Then TIMKIEM (TD 1,Tu)

Else TIMKIEM (TD 2,Tu);

End;

{TD 1 và TD 2 là đầu mối để truy nhập được vào nửa trước và nửa sau của từ điển}

End;

1.3 Chương trình con đệ quy

1.3.1 Khái niệm chương tình con đệ quy

Khái niệm: Chương tình con đệ quy là một chương trình con (hàm, thủ tục) mà trong thân của nó có lời gọi đến chính nó (hay còn gọi là lời gọi đệ quy) với kích thước nhỏ hơn của tham số [7]

Ví dụ 1.6: Hàm tính giai thừa của một số tự nhiên N (tính N!):

Function GT(N: Word): Longint;

Begin

If N = 0 then GT: =1

Else GT:= N*GT(N - 1);

End;

1.3.2 Cấu trúc chương trình con đệ quy

Một chương trình con đệ qui căn bản gồm hai phần [7]

Phần neo (phần suy biến, cơ sở): chứa các tác động của hàm hoặc thủ tục với

một số giá trị cụ thể ban đầu của tham số

Phần đệ quy (phần tổng quát, hạ bậc): định nghĩa tác động cần được thực hiện

cho giá trị hiện thời của các tham số bằng các tác động đã được định nghĩa trước đây với kích thước tham số nhỏ hơn

Ví dụ1.7: Hàm tính N!

Trang 17

Phần neo: If N:=0 then GT:= 1;

Phần đệ quy: GT:=N*GT(N-1);

1.3.3 Phân loại đệ quy

Tùy theo lời gọi hàm đệ quy mà ta phân loại thành các dạng như sau:

- Đệ quy tuyến tính: là dạng đệ quy mà thân hàm chỉ có một lời gọi chính

- Đệ quy nhị phân: Là dạng đệ quy mà thân hàm gọi 2 lần chính nó Ta

mô tả Hàm tìm dãy số Fibonacci như sau:

Function F(N: integer): integer;

Ví dụ 1.9: Hàm tìm ước chung lớn nhất (UCLN) của hai số nguyên dương:

Function UCLN(M, N: Longint): Longint;

Begin

If(M=N) then UCLN:= N Else

If (M>N) then UCLN:=UCLN(M-N, N) else UCLN:=UCLN(M, N-M); End;

Trang 18

- Đệ quy hỗ tương: nếu có 2 chương trình con B1 và B2 gọi lẫn nhau ta sẽ

có đệ quy hỗ tương

Có những trường hợp cần phải tiến hành khai báo đầu một chương trình con trước khi khai báo đầy đủ chương trình con đó đặc biệt là trong đệ quy hỗ tương, khi B1 gọi B2 và B2 lại gọi B1 ta phải dùng từ khóa Forwar

Ví dụ 1.10: Chương trình có Đệ quy hổ tương:

Program A;

Procedure B2 (X: integer): Forward ;

Procedure B1 (Y: integer) ;

Begin

If Y > 0 then

Begin

Y:= Y + 1 ; B2 (Y)

End ;

BEGIN {Chương trình chính}

B1(3);

END

Trang 19

1.4 Nguyên tắc hoạt động của giải thuật đệ quy

1.4.1 Khái niệm Stack

Stack là một cấu trúc lưu trữ, hoạt động theo nguyên tắc sau [8]:

Mỗi lần nộp vào hoặc lấy ra chỉ thực hiện với một phần tử

Phần tử nộp vào sau sẽ được lấy ra trước

- Stack bị tràn khi bổ sung vào mảng đã đầy

- Stack là rỗng khi số phần tử thực sự đang chứa trong mảng = 0

Hình 1.3 Mô tả Stack

Trang 20

Nguyên tắc 3: Đến lúc nào đó không thể thực hiện lời gọi đệ quy nữa thì các đối tượng được lưu trong Stack sẽ lần lượt được lấy ra để xử lý

Nghĩa là khi một thủ tục đệ quy được gọi tới từ chương trình chính, ta nói: thủ tục được thực hiện ở mức 1 hay độ sâu 1 của tính đệ quy Nhưng khi thực hiện ở mức 1 lại gặp lại lời gọi chính nó, nghĩa là phải đi sâu vào mức 2

và cứ như thế cho tới một mức nào đó Mức k phải được hoàn thành xong thì mức (k-1) mới được thực hiện Vậy việc thực hiện được quay về mức (k-1) Khi từ một mức i, đi sâu vào mức (i+1) thì có thể có một số tham số, biến cục

bộ hay địa chỉ (gọi là địa chỉ quay lui) ứng với mức i cần phải được bảo lưu

để khi quay về tiếp tục sử dụng

Như vậy trong quá trình thực hiện, những tham số, biến cục bộ hay địa chỉ bảo lưu sau lại được khôi phục trước Tính chất “vào sau ra trước” phù hợp với việc sử dụng Stack trong cài đặt thủ tục đệ quy Mỗi khi có lời gọi tới chính nó thì Stack sẽ được nạp để bảo lưu các giá trị cần thiết Còn mỗi khi thoát ra khỏi một mức thì phần tử ở đỉnh Stack sẽ được lấy ra để khôi phục lại các giá trị cần thiết cho mức tiếp theo [12]

Tóm tắt các bước này như sau:

Phần đầu: Bảo lưu tham số, biến cục và địa chỉ quay lui

Phần thân: Nếu tiêu chuẩn cơ sở ứng với trường hợp suy biến đã đạt được thì thực hiện được ở phần tính kết thúc và chuyển sang bước 3

Phần cuối: Khôi phục lại tham số, biến cục bộ và địa chỉ quay lui và chuyển tới địa chỉ quay lui này

Ví dụ 1.11: Sử dụng Stack cài đặt thủ tục đệ qui cho bài toán tính N! [10]

Ta sử dụng một Stack A mà đỉnh được trỏ bởi T Mỗi phần tử của A là một bản ghi gồm có hai trường:

Trường N ghi giá trị động của N ở mức hiện hành

Trường RETADD ghi địa chỉ quay lui

Trang 21

Lúc đầu Stack A rỗng: T = 0

Bản ghi TEMREC được dùng làm bản ghi trung chuyển, nó có 2 trường: PARA ứng với N

ADDRESS ứng với RETADD

Đặt giả thuyết: lúc đầu TEMREC đã chứa các giá trị cần thiết, nghĩa là PARA chứa giá trị n đã cho, ADDRESS chứa địa chỉ ứng với lời gọi trong chương trình chính mà ta gọi là địa chỉ chính (ĐCC)

Các giải thuật PUSH và POS sẽ được sử dụng Ký hiệu N(T) có nghĩa là giá trị ở trường N của phần tử đang trỏ tới bởi T (phần tử ở đỉnh Stack A)

Program Factorial

1.{Bảo lưu giá trị của N và địa chỉ quay lui}

Call PUSH(A,T, TEMREC)

2.{Tiêu chuẩn cơ sở đã đạt?}

Goto bước 1

3.{tính N!}

Factorial:= N(T)* Factorial;

4.{Khôi phục giá trị trước của N và địa chỉ quay lui}

Call POP(A, T, TEMREC);

Goto ADDRESS

5 End

Trang 22

Sau đây là minh hoạ tình trạng của Stack A trong quá trình thực hiện giải thuật, ứng với N =3

Vào mức 1(lời gọi chính)

Bước 1 PUSH(A,O,(3,ĐCC)) Bước 2:

N <>0 PARA:= 2;

ADDRESS:= bước 3

Vào mức 2 (gọi đệ quy lần 1)

Bước 1:

PUSH(A,1,(2,bước 3)) Bước 2:

N<>0 PARA:=1;

ADDRESS:= bước 3

Vào mức 3 (gọi đệ quy lần 2)

Bước 1:

PUSH(A,2,(1, bước 3)) Bước 2:

N<>0;

PARA:=0;

ADDRESS:= bước 3;

Vào mức 4 (gọi đệ quy lần 3)

Bước 1:

PUSH(A,3,(0,bước 3)) Bước 2:

Trang 23

Factorial:=1*1 Bước 4:

Goto bước 3

Quay lại mức 1

Bước 3:

Factorial:= 3*2 Bước 4:

1.5 Một số bài toán về đệ quy

1.5.1 Bài toán tìm số Fibonacci thứ n

Dãy số Fibonacci bắt nguồn từ bài toán cổ về việc sinh sản của các cặp thỏ Bài toán đặt ra như sau [2]:

Bảng 1.1 Mô tả Stack trong khi thực hiện giải thuật đệ quy tính 3!

Trang 24

Các con thỏ không bao giờ chết

Hai tháng sau khi ra đời, mỗi cặp thỏ mới sẽ sinh ra một cặp thỏ con (một đực, một cái)

Khi đã sinh con rồi thì cứ mỗi tháng tiếp theo chúng lại sinh được một cặp thỏ mới

Giả sử từ đầu tháng 1 có một cặp mới ra đời thì đến tháng thứ n sẽ có bao nhiêu cặp?

Ví dụ 1.12 Khi N = 5 ta thấy:

Giữa tháng 1: 1 cặp ab ban đầu

Giữa tháng 2: 1 cặp ab ban đầu chưa đẻ

Giữa tháng 3: 2 cặp ab ban đầu và cặp cd

Giữa tháng 4: 3 cặp ab, cd, ef, cặp ab ban đầu tiếp tục đẻ

Giữa tháng 5: 5 cặp ab, cd, ef, gh, ik; cặp ab ban đầu đẻ thêm và cặp cd bắt đầu đẻ

Ta xét tới việc tính số cặp thỏ ở tháng thứ N: F(N)

Nếu mỗi cặp thỏ ở tháng thứ N-1 đều sinh ra một cặp thỏ con thì số cặp thỏ ở tháng thứ N sẽ là:

F(N) = 2*F(N-1) Nhưng ta cần chú ý là trong các cặp thỏ ở tháng thứ N-1, chỉ có những cặp thỏ đã ở tháng thứ N-2 mới sinh ra con ở tháng thứ N được thôi Do đó F(N)

=F(N-1) + F(N- 2) (= số cũ+ số sinh ra) Vậy có thể tính được F(N) theo công thức sau:

Trang 25

Hàm đệ quy tìm số Fibonacci thứ N viết như sau:

Function F(N: integer): Longint;

Yêu cầu: Hãy sắp xếp dãy số A thành dãy số tăng dần

Ý tưởng giải thuật (QUICKSORT)

Ta dùng phương pháp phân vùng để xử lí nội dung chính là chọn phần

tử X ở giữa của dãy làm chuẩn để so sánh, từ đó phân hoạch dãy này thành 3 dãy con liên tiếp như sau:

* Dãy con thứ nhất gồm các phần tử nhỏ hơn X

* Dãy con thứ hai gồm các phần tử bằng X

* Dãy con thứ ba gồm các phần tử lớn hơn X

Sau đó lại áp dụng giải thuật phân hoạch này cho dãy con thứ nhất và dãy con thứ ba, nếu các dãy con này có nhiều hơn một phần tử (Đệ quy)

Cụ thể là xét một đoạn của dãy từ thành phần thứ L đến thành phần thứ R ta thực hiện các bước sau:

* Lấy giá trị của thành phần thứ (L + R) div 2 gán vào biến X

* Cho i ban đầu là L

* Cho j ban đầu là R

* Lặp lại

• Chừng nào còn A[i] < X thì tăng i

• Chừng nào còn A[j] > X thì giảm J

Trang 26

• Sắp xếp đoạn từ A[L] đến A[j]

• Sắp xếp đoạn từ A[i] đến A[R]

Thủ tục QUICKSORT được viết như sau:

Procedure QUICKSORT (Var A: Array [l N] of integer); Procedure SORT (L, R: integer);

1.5.3 Bài toán tìm nghiệm xấp xỉ của phương trình f(x)=0

Cho Hàm f(x) là hàm liên tục trên đoạn [ao,bo]

Trang 27

Yêu cầu: Tìm một nghiệm xấp xỉ với độ chính xác trên [ao,bo] của phương trình f(x) = 0

Ý tưởng và phân tích bài toán:

- Ta xét trường hợp: bo - ao < ε (Phần neo)

+ Nếu f(ao).f(bo) ≤ 0 thì hàm f có nghiệm trên [ao,bo].Vì ta đang tìm nghiệm xấp xỉ với độ chính xác nên ao là nghiệm xấp xỉ cần tìm

+ Nếu f(ao).f(bo) > 0 thì ta xem như không có nghiệm xấp xỉ trên đoạn xét

- Trương hợp bo - ao ≥ ε: Ta chia đôi đoạn [ao,bo] rồi tìm lần lượt nghiệm trên từng đoạn con: Đoạn con trái, đoạn con phải (Phần đệ quy)

Ta sẽ xây dựng một hàm đệ quy trả về giá trị là nghiệm xấp xỉ của f(x) (nếu có), hoặc là một hằng số E nếu f(x) không có nghiệm xấp xỉ trên [ao,bo]

Thông số cho bài toán:

Tạo hàm ROOT với 3 thông số là g, a, b; (ROOT(g,a,b)) trả về giá trị nghiệm xấp xỉ của phương trình g(x) =0 trên đoạn [a,b] hoặc giá trị C nếu phương trình xét không có nghiệm xấp xỉ Để giải bài toán ban đầu ta gọi hàm ROOT(f,ao,bo), được thể hiện như sau:

Phần neo: Là khi b - a < ε Khi đó:

If ( g(a).g(b)) <= 0 Then ROOT(g,a,b):= a; {a là nghiệm xấp xỉ};

Else ROOT(g,a,b) = E; { không có nghiệm xấp xỉ}

Phần tổng quát: Khi b - a ≥ 0 ta phân [a,b] làm 2 đoạn [a,c] và [c,b] với c = (a + b) / 2

- Nếu ROOT(g, a,c) < E thì ROOT(g, a, b) = ROOT(g,a,c) nghĩa là bài toán tìm nghiệm trên đoạn [a,c];

- Ngược lại thì ROOT(g, a, b) = ROOT(g,c,b) (bài toán tìm nghiệm trên đoạn [c,b])

Trang 28

1.5.4 Bài toán tháp Hà Nội

Có 3 cái cọc, đánh dấu A, B, C, và N cái đĩa Mỗi đĩa đều có một lỗ chính giữa để đặt xuyên qua cọc, các đĩa đều có kích thước khác nhau Ban đầu tất cả đĩa đều được đặt ở cọc thứ nhất theo thứ tự đĩa nhỏ hơn ở trên [8]

Yêu cầu: chuyển tất cả các đĩa từ cọc A qua cọc C với ba ràng buộc như sau:

Quy tắc 1: Mỗi lần chỉ chuyển được một đĩa

Quy tắc 2: Trong quá trình chuyển đĩa có thể dùng cọc còn lại (B) để làm cọc trung gian

Quy tắc 3: Chỉ cho phép đặt đĩa có bán kính nhỏ hơn lên đĩa có bán kính lớn hơn

Ý tưởng và phân tích bài toán:

Trong bài toán trên hình dung một lời giải tổng quát cho trường hợp tổng quát

N đĩa là không dễ dàng

Bài toán Tháp Hà Nội với 1 đĩa: Chỉ cần 1 lần chuyển

Bước 1: Chuyển đĩa từ cọc A sang cọc C

Bài toán Tháp Hà Nội với 2 đĩa: Cần 3 lần chuyển

Bước 1: Chuyển đĩa số 1 từ cọc A sang cọc B

Bước 2: Chuyển đĩa số 2 từ cọc A sang cọc C

Bước 3: Chuyển đĩa số 1 từ cọc B sang cọc C (lên trên đĩa số 2) Kết thúc

Hình 1.4 Bài toán Tháp Hà Nội với N=1

Hình 1.5 Bài toán Tháp Hà Nội với N=2

Trang 29

Bài toán Tháp Hà Nội với 3 đĩa: Cần 7 lần chuyển

Bước 1: Chuyển một đĩa từ A qua C

Bước 2: Chuyển một đĩa từ A qua B

Bước 3: Chuyển một đĩa từ C qua B

Bước 4: Chuyển một đĩa từ A qua C

Bước 5: Chuyển một đĩa từ B qua A

Bước 6: Chuyển một đĩa từ B qua C

Bước7: Chuyểnmột đĩa từ A qua C Kết thúc

Nhận xét: Ở kết quả của bước thứ ba Đây là một kết quả quan trọng vì nó cho

ta thấy từ trường hợp N=3 bài toán đã được phân chia thành hai bài toán với kích thước nhỏ hơn: đó là bài toán chuyển 1 đĩa từ cọc A qua cọc C lấy cọc B làm trung gian và bài toán chuyển 2 đĩa (dời) từ cọc B sang cọc C lấy cọc A làm trung gian Hai bài toán con này đã biết cách giải (trường hợp N=1 và trường hợp N=2)

Nhận xét đó cho ta thấy rằng trong trường hợp tổng quát N đĩa:

Bước 1: Dời (N-1) đĩa trên cùng từ cọc A sang cọc B lấy cọc C làm trung gian

Bước 2: Chuyển 1 đĩa dưới cùng từ cọc A sang cọc C

Hình 1.6 Bài toán Tháp Hà Nội với N=3

Trang 30

Bước 3: Chuyển (N-1) đĩa đang ở cọc B sang cọc C lấy cọc A làm trung gian Như vây, bài toán đối với N đĩa ở trên được “đệ quy” về hai bài toán (N-1) đĩa và bài toán 1 đĩa Quá trình đệ quy sẽ dừng lại khi N=0 nghĩa là khi không còn đĩa để chuyển

Thủ tục đệ quy cho bài toán Tháp Hà Nội như sau:

1.5.5 Bài toán giả thuyết của Collatz

Collatz đưa ra giả thuyết là với một số nguyên dương X, nếu X chẵn thì

ta gán X:= X div 2; nếu X lẻ thì ta gán X:= X*3+1 Sau một số hữu hạn bước,

Phân tích bài toán:

Ta giả sử giả thuyết Collatz là đúng đắn, vậy: Cho trước số 1 cùng với hai phép toán *2 và div 3, hãy sử dụng một cách hợp lí hai phép toán đó để biến số 1 thành giá trị nguyên dương X cho trước

Trang 31

Khi X= 10 ta có 1*2*2*2*2 div 3 =10

Ta thấy rằng lời giải của bài toán này gần như thứ tự ngược của phép biến đổi Collatz: để biểu diễn số X >1 bằng một biểu thức bắt đầu bằng số 1 và hai phép toán “*2”, “div 3” Chia hai trường hợp:

- Nếu X chẵn, thì ta tìm cách biểu diễn số X div 2 và viết thêm phép toán

*2 vào cuối

- Nếu X lẻ, thì ta tìm cách biểu diễn số X*3+1 và viết thêm phép toán div

3 vào cuối

Thủ tục đệ quy cho bài toán giả thuyết Collatz mô tả như sau:

Procedure Collatz(x: Longint);

Begin

If x = 1 then write(x)

Else

If x mod 2 = 0 then Begin

Collatz (x div 2);

write(‘ *2’);

End Else

Trang 32

1.6 Kết luận chương 1

Như vậy, thông qua các nội dung được trình bày ở chương 1 có thể nói rằng đệ quy là quả tim trong các nghiên cứu lý thuyết, cũng như thực hành tính toán đã thể hiện rất nhiều sức mạnh và có ưu điểm trong nhiều bài toán Thuật toán đệ quy đưa ra cách giải quyết một số bài toán một cách tổng quát Hơn nữa, đệ quy còn thích hợp để giải quyết các bài toán có bản chất đệ quy Qua chương 1 đã giúp chúng ta hiểu được sâu hơn về các khái niệm, tính chất

và nguyên tắc hoạt động của giải thuật Đệ quy thông qua việc phân tích một

số bài toán Đệ quy cơ bản

Trang 33

Chương 2: ĐỆ QUY QUAY LUI

Chương này tìm hiểu khái niệm và đưa ra các kiến thức về đệ quy quay lui, các dạng tổng quát của giải thuật đệ quy quay lui Nghiên cứu các bài toán điển hình sử dụng giải thuật đệ quy quay lui để từ đó phân tích, đánh giá và làm rõ những ưu điểm và hạn chế giải thuật đệ quy quay lui (xem [4], [5],

[12], [13])

2.1 Tổng quan về đệ quy quay lui

Trong lập trình có nhiều trường hợp, nghiệm của bài toán là dãy các phần tử được xác định không theo một luật tính toán nhất định, muốn tìm nghiệm phải thực hiện từng bước, tìm kiếm dần từng phần tử của nghiệm Để tìm mỗi phần tử, phải kiểm tra “đúng, sai” các khả năng có thể chấp nhận của phần tử này

+ Nếu khả năng nào đó không dẫn tới giá trị chấp nhận được của phần

tử đang xét thì phải loại bỏ khả năng đó, chuyển sang chọn khả năng khác (chưa được chọn) Mỗi khi chọn một khả năng cho một phần tử thì thông thường trạng thái bài toán sẽ thay đổi vì thế khi chuyển sang chọn khả năng khác, phải trả lại trạng thái như trước khi chọn khả năng vừa loại bỏ (nghĩa là phải quay lui lại trạng thái cũ)

+ Nếu có 1 khả năng chấp nhận được tức là gán được giá trị cho phần

tử đang xét của nghiệm và chưa là phần tử cuối cùng thì tìm tiếp phần tử tiếp theo

+ Nếu bài toán yêu cầu chỉ tìm một nghiệm thì sau khi chọn được một khả năng cho một phần tử của nghiệm, ta kiểm tra phần tử này đã là phần tử cuối cùng của một nghiệm hay chưa gọi là lệnh kiểm tra kết thúc một nghiệm Nếu đúng là phần tử cuối cùng của nghiệm thì: Hiện nghiệm và thoát hẳn khỏi thủ tục đệ quy;

Trang 34

Nếu bài toán yêu cầu tìm tất cả các nghiệm thì chưa kết thúc khi mới kiểm tra kết thúc một nghiệm

+ Trong việc thử mọi khả năng của một phần tử của nghiệm, ta cần tìm những điều kiện để nhanh chóng loại bỏ những khả năng không thể chấp nhận được thì việc thử sẽ nhanh chóng hơn Việc thử mọi khả năng của một phần

tử của nghiệm cũng giống như một người đi đường, mỗi khi đến ngã đường, lần lượt chọn một đường thích hợp trong các con đường của ngã N-đường đó, nếu biết chắc chắn những đường nào đó trong các đường của ngã N-đường là đường “cụt” không thể đi tới đích thì người đi đường sẽ loại ngay những đường đó; hoặc ngược lại nếu nhìn thấy trước những điều kiện cho phép chỉ cần đi theo một số con đường nhất định trong N đường mà vẫn tới đích nhanh chóng thì người đi đường sẽ dùng những điều kiện ấy như là định hướng cho lựa chọn của mình

N-+ Nếu tìm một nghiệm tốt nhất – theo một điều kiện nào đó thì mỗi khi tìm được một nghiệm, ta so sánh với nghiệm tốt nhất đã tìm được cho đến lúc này (gọi là nghiệm tối ưu) Nếu nghiệm vừa tìm được tốt hơn nghiệm tối ưu thì gán lại nghiệm tối ưu là nghiệm mới

Quá trình tiếp diễn cho đến khi duyệt hết các nghiệm của bài toán ta sẽ được nghiệm tối ưu của bài toán

Như vậy: Thuật toán “duyệt trên cơ sở tìm kiếm và quay lui ” - Thuật toán BackTracking có các nội dung sau:

+ 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 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

Trang 35

+ Tuỳ theo yêu cầu, có thể chỉ tìm một nghiệm, cũng có thể tìm mọi nghiệm

Giả sử ta phải tìm trong một tập dữ liệu D cho trước một dãy dữ liệu:

v = (v[1], v[2], , v[n]) thoả mãn đồng thời hai tính chất P và Q Trước hết ta chọn một trong hai tính chất đã cho để làm nền, giả sử ta chọn tính chất P Sau đó ta thực hiện các bước sau đây:

Bước 1 (Khởi trị) Xuất phát từ một dãy ban đầu v = (v[1], , v[i]) nào đó của các phần tử trong D sao cho v thoả P

Bước 2 Nếu v thoả Q ta dừng thuật toán và thông báo kết quả là dãy v, ngược lại ta thực hiện Bước 3

Bước 3 Tìm tiếp một phần tử v[i + 1] để bổ sung cho v sao cho v = (v[1], , v[i], v[i + 1]) thoả P

Có thể xảy ra các trường hợp sau đây:

- Trường hợp 1: Tìm được phần tử v[i + 1]: quay lại bước 2

- Trường hợp 2: Không tìm được v[i + 1] như vậy, tức là với mọi v[i + 1] có thể lấy trong D, dãy v = (v[1], , v[i], v[i + 1]) không thoả P Điều này có nghĩa là đi theo đường v = (v[1], , v[i]) sẽ không dẫn tới kết quả Ta phải đổi hướng tại một vị trí nào đó Để thoát khỏi ngõ cụt này, ta tìm cách thay v[i] bằng một giá trị khác trong D Nói cách khác, ta loại v[i] khỏi dãy v, giảm i đi một đơn vị rồi quay lại Bước 3

Cách làm như trên được gọi là quay lui - Lùi lại một bước

Ta phải đánh dấu v[i] là phần tử đã loại tại vị trí i để sau đó không đặt lại phần tử đó vào vị trí i trong dãy v

Vậy khi nào thì có thể trả lời là không tồn tại dãy v thoả đồng thời hai tính chất P

và Q Hay khi nào thì ta có thể thông báo là bài toán vô nghiệm?

Bài toán vô nghiệm khi ta đã duyệt hết mọi khả năng Ta nói là đã vét cạn mọi khả năng Có thể đến một lúc nào đó ta phải lùi liên tiếp nhiều lần

Trang 36

Từ đó suy ra thông thường bài toán vô nghiệm khi ta không còn có thể lùi được nữa

Có nhiều mô hình giải các bài toán quay lui, dưới đây trình bày hai mô hình khá thông dụng

Mô hình 1: Giải bài toán quay lui

tìm một nghiệm

Mô hình 2: Giải bài toán quay lui

tìm một nghiệm Khởi trị v: v thoả P;

Thông thường ta khởi trị cho v là dãy rỗng hoặc dãy có một phần tử

Ta chỉ yêu cầu dãy v được khởi trị sao cho v thoả P Cả dãy v thoả P chứ không phải từng phần tử trong v thoả P

Có bài toán yêu cầu tìm toàn bộ (mọi nghiệm) các dãy v thoả đồng thời hai tính chất P và Q Khi biết cách tìm một nghiệm ta dễ dàng suy ra cách tìm

Bảng 2.1 Mô hình thuật toán quay lui tìm một nghiệm

Trang 37

mọi nghiệm như sau: Mỗi khi tìm được một nghiệm, ta thông báo nghiệm

đó rồi thực hiện thao tác lùi, tức là giả vờ như không công nhận nghiệm đó,

do đó phải loại v[i] cuối cùng trong dãy v để tiếp tục tìm hướng khác Phương pháp này có tên là phương pháp giả sai Hai mô hình trên sẽ được

mô tả lại như sau để tìm mọi nghiệm

Mô hình 3: Giải bài toán quay lui

tìm mọi nghiệm

Mô hình 4: Giải bài toán quay lui

tìm mọi nghiệm Khởi trị: v thoả P;

Begin

If d = 0 then Ghi nhận: vô nghiệm;

Else Ghi nhận: d nghiệm;

Trang 38

Thuật toán quay lui xây dựng trên cơ sở tìm kiếm dần, kết quả sau hình thành từ kết quả trước, nên có thể dùng các hàm, thủ tục đệ qui để thực hiện thuật toán Cụ thể từ hai mô hình trên ta xây dựng ba dạng dàn bài thường gặp

bắt đầu từ giải thuật đệ quy quay lui tổng quát sau đây:

2.2 Giải thuật đệ quy quay lui tổng quát

Procedure Try(k); {Chọn thực hiện bước thứ k}

Begin

For Các phương án chọn do

If Được chọn then Begin

- Thủ tục trên sẽ được khởi động bởi lệnh: Try(1);

Ta có thể trình bày quá trình tìm kiếm lời giải của thuật toán quay lui bằng cây sau:

Hình 2.1 Quá trình tìm kiếm lời giải của thuật toán quay lui

Trang 39

2.3 Ba dạng của đệ quy quay lui

2.3.1 Dạng 1 tìm một nghiệm

Trên cơ sở tư tưởng của thuật toán quay lui, để giải quyết một số bài toán chỉ yêu cầu hiển thị một nghiệm, ta xây dựng mô hình thuật toán tìm một nhiệm như sau:

Procedure Tim(k: Integer);

* 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

Mô hình giải thuật cho bài toán tìm một nghiệm, cách 1

Thủ tục này có thể viết lại dưới dạng sau:

Trang 40

Procedure Tim(k: Integer);

+ 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ử;

* Nếu chưa phải bước cuối cùng thì Tim(K+1);

* Trả lại trạng thái của bài toán trước khi đề cử; End;

End;

End;

Mô hình giải thuật cho bài toán tìm một nghiệm, cách 2

Một khó khăn khác của bài toán tìm một nghiệm là: Trường hợp bài toán vô nghiệm chúng ta cần kiểm soát như thế nào Ta phải duyệt hết mọi khả năng mới rõ kết luận vô nghiệm hay không vô nghiệm Nghĩa là đã đi theo mọi nhánh nhưng nhánh nào cũng đều không tới đích, do đó theo quy luật cứ quay lui mãi để tìm kiếm thì đến lúc nào đó dẫn đến tình trạng phải trở

Ngày đăng: 27/01/2021, 11:50

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w