1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Bài tập lớn môn toán rời rạc Đề bài tìm hiểu bài toán liệt kê và cách giải bài toán

29 1 0
Tài liệu đã được kiểm tra trùng lặp

Đ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

Tiêu đề Tìm Hiểu Bài Toán Liệt Kê Và Cách Giải Bài Toán
Tác giả Đào Huy Hùng, Nguyễn Thành Vinh, Bùi Quang Huy, Hoàng Xuân Tùng
Người hướng dẫn Đào Huy Hùng (Bàn Trưởng)
Trường học Học viện Công nghệ Bưu chính Viễn thông
Chuyên ngành Toán Rời Rạc
Thể loại bài tập lớn
Định dạng
Số trang 29
Dung lượng 1,42 MB

Nội dung

Các bài toán liệt kê có thể có nhiều dạng, từ việc liệt kê các hoán vị của một dãy số, tổ hợp của các phần tử trong một tập hợp, đến các vấn đề phức tạp hơn như liệt kê các cấu trúc đồ t

Trang 1

HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNG

- -

BÀI TẬP LỚN MÔN: TOÁN RỜI RẠC NHÓM MÔN HỌC: 01

Trang 2

ĐỀ BÀI: Tìm hiểu bài toán liệt kê và cách giải bài toán

Bảng phân công công việc

việc, tổng hợp nội dung, viết tiểu luận

dung, thuyết trình

Trang 3

Mục Lục

I Giới thiệu và tìm hiểu chung về bài toán liệt kê 4

1 Giới thiệu 4

2 Mục tiêu của bài toán liệt kê 5

3 Tầm quan trọng của bài toán liệt kê 6

4 Các phương pháp giải bài toán liệt kê 6

5 Phân tích độ phức tạp thuật toán 7

6 Một số dạng toán điển hình của bài toán liệt kê: 7

II Tìm hiểu chi tiết về phương pháp sinh 9

1 Nguyên lý 9

2 Ưu điểm 10

3 Nhược điểm 11

III Tìm hiểu chi tiết về phương pháp quay lui 11

1 Nguyên lý 11

2 Ưu điểm 13

3 Nhược điểm 14

IV Một số ví dụ minh họa thuật toán sinh 14

a) Sinh xâu nhị phân có độ dài N 14

b) Bài toán sinh tổ hợp chập k của N phần tử 17

V Ví Dụ Phương Pháp quay lui: 19

a) Sinh xâu nhị phân có độ dài N 19

b) Tổ hợp chập K của N 20

c) Quay lui hoán vị của N phần tử 20

d) Bài toán N-queen (bài toán kinh điển của thuật toán quay lui) 22

VI Tổng Kết 25

1 So sánh giữa phương pháp sinh và quay lui 25

2 Ứng dụng thực tiễn của bài toán liệt kê 25

3 Hướng phát triển của bài toán liệt kê 26

4 Một số tài liệu tham khảo về bài toán liệt kê 26

5 Kết luận 28

Trang 4

Leonhard Euler (1707–1783): Ông là một trong những nhà toán học đầu

tiên đưa ra các lý thuyết tổ hợp, mà bài toán liệt kê là một phần quan trọng Euler đã giải quyết các bài toán liệt kê thông qua lý thuyết đồ thị, trở thành nền tảng cho lý thuyết đồ thị hiện đại

Claude Shannon (1916–2001): Claude Shannon được xem là "cha đẻ

của lý thuyết thông tin", một lĩnh vực có sự kết nối mạnh mẽ với bài toán liệt kê trong việc giải quyết các vấn đề truyền thông và mã hóa Shannon đã nghiên cứu cách thức truyền và lưu trữ thông tin hiệu quả, và điều này bao gồm cả việc liệt kê các mã và ký tự trong các hệ thống mã hóa Khả năng liệt kê tất cả các

mã có thể giúp đảm bảo an toàn và hiệu quả trong truyền thông Đóng góp của ông về lý thuyết mã hóa và thuật toán nén thông tin là một trong những ví dụ nổi bật về việc áp dụng bài toán liệt kê trong thế giới hiện đại

Trang 5

Donald Knuth (sinh năm 1938): Donald Knuth là một nhà khoa học

máy tính lừng danh và là tác giả của bộ sách The Art of Computer

Programming, một tác phẩm kinh điển trong lĩnh vực thuật toán và cấu trúc dữ liệu Ông đã phát triển các thuật toán hiệu quả để sinh ra hoán vị, tổ hợp và các cấu trúc tổ hợp khác Những công trình của Knuth không chỉ giúp tối ưu hóa các thuật toán liệt kê mà còn mở ra những ứng dụng rộng rãi trong lập trình và

giải thuật hiện đại

Các bài toán liệt kê có thể có nhiều dạng, từ việc liệt kê các hoán vị của một dãy số, tổ hợp của các phần tử trong một tập hợp, đến các vấn đề phức tạp hơn như liệt kê các cấu trúc đồ thị hoặc chuỗi ký tự,

2 Mục tiêu của bài toán liệt kê

Mục tiêu chính của bài toán liệt kê là tạo ra tất cả các kết quả hợp lệ từ một tập hợp dữ liệu cho trước Khác với bài toán tổ hợp yêu cầu liệt kê tất cả các tập con có thể có từ một tập hợp các phần tử mà không quan tâm đến thứ tự của chúng.Bài toán liệt kê lại cần xác định một thuật toán để theo đó có thể xây dựng được lần lượt tất cả các cấu hình cần quan tâm Một thuật toán liệt kê phải đảm bảo hai nguyên tắc:

Trang 6

• Không được lặp lại bất kỳ một cấu hình nào

• Không được bỏ sót bất kỳ một cấu hình nào

3 Tầm quan trọng của bài toán liệt kê

• Tìm kiếm toàn bộ giải pháp

Trong nhiều trường hợp, không chỉ việc tìm ra một giải pháp đúng là quan trọng, mà cần phải liệt kê tất cả các giải pháp có thể

• Phân tích và tối ưu

Thông qua liệt kê, chúng ta có thể phân tích toàn bộ không gian giải pháp để tìm ra giải pháp tối ưu hoặc có những đặc tính cụ thể

• Ứng dụng rộng rãi

Bài toán liệt kê có mặt trong nhiều bài toán khác nhau như giải quyết bài toán tối ưu hóa, mật mã, lập thời gian biểu, tổ hợp, và nhiều ứng dụng trong trí tuệ nhân tạo

Bài toán liệt kê có nhiều ứng dụng quan trọng thực tiễn: tối ưu hóa trong sản xuất và logistics, phân tích và xử lý dữ liệu lớn (Big Data), mật mã và bảo mật, thiết kế và triển khai hệ thống mạng, ,tối ưu hóa tài nguyên trong hệ thống viễn thông, xác suất và thống kê, Khoa học máy tính và thuật toán,

4 Các phương pháp giải bài toán liệt kê

Có hai phương pháp chính thường được sử dụng để giải quyết các bài toán liệt kê:

• Phương Pháp Sinh (Generation):

Phương pháp sinh là một kỹ thuật cơ bản nhưng mạnh mẽ, cho phép chúng

ta tạo ra từng phần tử của không gian tìm kiếm một cách tuần tự Phương pháp

Trang 7

thái một cách có hệ thống mà không cần kiểm tra lại các trạng thái đã sinh ra trước đó

• Phương Pháp Quay Lui (Backtracking):

Phương pháp quay lui, ngược lại, là một chiến lược đệ quy linh hoạt, cho phép chúng ta khám phá không gian trạng thái bằng cách thử các lựa chọn khác nhau và quay lại (backtrack) khi phát hiện lựa chọn sai Đây là phương pháp đặc biệt hiệu quả khi không gian tìm kiếm quá lớn và việc kiểm tra từng khả năng là không khả thi

5 Phân tích độ phức tạp thuật toán

Độ phức tạp của các phương pháp liệt kê thường được tính toán dựa trên số lượng phần tử có thể sinh ra và các thao tác cần thiết để sinh ra mỗi phần tử Cả phương pháp sinh và quay lui đều có độ phức tạp cao, vì mục tiêu của chúng là liệt kê tất cả các khả năng có thể có

Phương pháp sinh thường có độ phức tạp là O(n!) cho các bài toán hoán vị

(với n là số lượng phần tử) hoặc O(2^n) cho các bài toán tổ hợp hoặc tập con

Đây là vì số lượng phần tử cần liệt kê tăng theo cấp số nhân khi số lượng phần

tử ban đầu tăng lên Phương pháp này có thể nhanh hơn trong một số trường hợp, nhưng không phải lúc nào cũng hiệu quả với các bài toán lớn, do số lượng phần tử cần liệt kê quá lớn

Phương pháp quay lui có độ phức tạp tương tự tùy vào bài toán cụ thể,

thường là O(n!) cho bài toán hoán vị và O(2^n) cho bài toán tổ hợp Tuy nhiên,

nhờ vào tính năng quay lui, phương pháp này có thể tránh được việc kiểm tra những trường hợp không khả thi, từ đó giúp giảm đáng kể số lượng thao tác cần thực hiện trong một số trường hợp Điều này giúp quay lui trở thành một

phương pháp ưu việt khi không gian tìm kiếm quá lớn và cần có cách tiếp cận khôn ngoan để giảm bớt các thao tác dư thừa

6 Một số dạng toán điển hình của bài toán liệt kê:

• Liệt kê tổ hợp

Xác định tất cả các tổ hợp có thể từ một tập hợp phần tử Tính số lượng tổ hợp của k phần tử từ n phần tử

• Liệt kê hoán vị

Xác định tất cả các hoán vị của một dãy số hoặc đối tượng

Trang 8

• Liệt kê tập con

Xác định tất cả các tập con của một tập hợp cho trước

• Bài toán N-Queens

Bài toán này yêu cầu đặt N quân hậu trên bàn cờ N x N sao cho không quân hậu nào có thể tấn công nhau Sinh tất cả các cách đặt quân hậu hợp lệ, Tìm

số cách đặt quân hậu cho N

Trang 9

II Tìm hiểu chi tiết về phương pháp sinh

1 Nguyên lý

Nguyên lý của phương pháp sinh là tạo ra tất cả các cấu hình hoặc tổ hợp

có thể từ một tập hợp các phần tử theo một thứ tự xác định Phương pháp này

dựa trên việc liệt kê tuần tự các phần tử trong không gian tìm kiếm mà không

cần kiểm tra lại các trạng thái đã sinh ra trước đó

Để liệt kê được hết các cấu hình trong một bài toán liệt kê sử dụng phương pháp sinh chúng ta cần biết :

• Cầu hình đầu tiên: Là điểm bắt đầu của quá trình tìm kiếm

• Cấu hình cuối cùng: Là điểm dừng, khi đã đạt được giải pháp hoàn chỉnh

• Phương pháp sinh: Các điều kiện để xác định tính hợp lệ của một cấu

hình

Phương pháp sinh thường được thực hiện thông qua một vòng lặp hoặc đệ quy Dưới đây là cách thức hoạt động chính:

Trang 10

1 Khởi tạo: Đặt các giá trị ban đầu cho các biến và điều kiện cần thiết

2 Tạo phần tử: Dựa trên các quy tắc đã định, sinh ra phần tử tiếp theo từ

tập hợp phần tử hiện tại

3 Kiểm tra và lưu trữ: Kiểm tra tính hợp lệ của phần tử đã sinh ra và lưu

trữ nếu nó đáp ứng điều kiện

4 Tiếp tục: Lặp lại quy trình cho đến khi cấu hình cuối cùng xuất hiện

Dưới đây là Mã giả cho phương pháp sinh:

<Đưa ra cấu hình đang có>;

if (cấu hình đang có chưa là cuối cùng) then <Sinh_kế_tiếp>

else Stop:= true;

Trang 11

Hiệu quả với bài toán có không gian tìm kiếm rõ ràng: Phương pháp này thường được áp dụng cho các bài toán mà tất cả các tổ hợp đều có thể sinh ra dễ dàng và không yêu cầu kiểm tra tính hợp lệ

b) Dễ cài đặt

Các thuật toán sinh thường có cấu trúc lặp đơn giản hoặc đệ quy với số bước

rõ ràng, không yêu cầu quá nhiều điều kiện phức tạp hay kiểm tra nhiều lần trong quá trình sinh ra cấu hình

c) Sinh các cấu hình tuần tự

Phương pháp sinh thường sinh ra các cấu hình theo thứ tự, từ cấu hình nhỏ nhất đến lớn nhất Điều này giúp dễ dàng theo dõi quá trình sinh ra các kết quả

và có thể dừng ngay khi đạt được cấu hình mong muốn mà không phải sinh toàn

bộ

3 Nhược điểm

a) Không hiệu quả với các bài toán có ràng buộc phức tạp

Phương pháp sinh không phù hợp khi bài toán có nhiều điều kiện ràng buộc phức tạp hoặc yêu cầu phải kiểm tra tính hợp lệ của từng cấu hình

b) Tốn thời gian khi không gian tìm kiếm lớn, giảm hiệu suất

Trong các bài toán có không gian tìm kiếm lớn, phương pháp sinh có thể tốn rất nhiều thời gian để liệt kê toàn bộ các cấu hình Phương pháp sinh chỉ sinh ra cấu hình theo cách tuần tự mà không có cơ chế tối ưu hóa nào giúp giảm thiểu thời gian xử lý

c) Không tận dụng được tính chất của bài toán

Phương pháp sinh liệt kê tất cả các cấu hình mà không tận dụng được các tính chất đặc thù của bài toán để giảm không gian tìm kiếm Trong khi các phương pháp khác, như quay lui hoặc chia để trị, có thể loại bỏ nhiều khả năng không cần thiết trước khi sinh ra cấu hình

III Tìm hiểu chi tiết về phương pháp quay lui

1 Nguyên lý

Trang 12

Nguyên lý của phương pháp quay lui là xây dựng giải pháp từng bước một và quay lại khi phát hiện rằng bước nào đó không dẫn đến một giải pháp hợp lệ Kỹ thuật này giúp tối ưu hóa quá trình tìm kiếm bằng cách loại bỏ những lựa chọn không khả thi, nhờ đó giảm số lượng khả năng cần kiểm tra

Để liệt kê được hết các cấu hình trong một bài toán liệt kê sử dụng phương pháp sinh chúng ta cần biết :

• Cầu hình đầu tiên: Là điểm bắt đầu của quá trình tìm kiếm

• Cấu hình cuối cùng: Là điểm dừng, khi đã đạt được giải pháp hoàn chỉnh

• Phương pháp quay lui: Các điều kiện để xác định tính hợp lệ của một cấu hình

Phương pháp quay lui thường được thực hiện thông qua một quy trình đệ quy hoặc vòng lặp Dưới đây là cách thức hoạt động chính:

1 Khởi tạo: Đặt các giá trị ban đầu cho các biến và điều kiện cần thiết

2 Lựa chọn: Chọn một phần tử từ các lựa chọn khả thi

3 Kiểm tra: Kiểm tra tính hợp lệ của phần tử đã chọn Nếu nó không hợp

lệ, quay lại bước trước đó và thử lựa chọn khác

4 Ghi nhận: Nếu phần tử hợp lệ, lưu trữ cấu hình và tiếp tục lựa chọn cho

bước tiếp theo

5 Tiếp tục: Lặp lại quy trình cho đến khi cấu hình cuối cùng xuất hiện

Dưới đây là Mã giả cho phương pháp sinh:

procedure Backtrack;

Trang 13

Begin

<Xây dựng cấu hình đầu tiên>;

if (cấu hình đang có là hợp lệ) then Begin

Backtrack; // Gọi lại hàm đệ quy

<Quay lại>; // Thực hiện quay lui nếu cần

Trang 14

Phương pháp quay lui giúp tiết kiệm tài nguyên tính toán bằng cách loại

bỏ những nhánh không khả thi ngay từ đầu, do đó không phải thử nghiệm tất cả

các khả năng

b) Linh hoạt

Quay lui có thể được áp dụng cho nhiều loại bài toán khác nhau, từ hoán vị,

tổ hợp đến các bài toán lập lịch và tìm kiếm đường đi, nhờ tính linh hoạt trong quy tắc kiểm tra và lựa chọn

b) Không tận dụng được tính chất của bài toán

Hiệu suất của phương pháp quay lui phụ thuộc vào cách kiểm tra tính hợp

lệ Nếu quy trình này mất nhiều thời gian, nó sẽ làm giảm hiệu suất tổng thể của thuật toán

c) Khó khăn trong việc tối ưu hóa

Mặc dù quay lui có thể loại bỏ nhiều lựa chọn không khả thi, nhưng trong một số trường hợp, việc tìm ra cách tốt nhất để tối ưu hóa và chọn lựa vẫn là một thách thức

IV Một số ví dụ minh họa thuật toán sinh

a) Sinh xâu nhị phân có độ dài N

Trang 15

Mục tiêu: Sinh tất cả các dãy nhị phân có độ dài n, tức là các dãy chỉ

chứa các phần tử 0 và 1

Số lượng dãy: Sẽ có 2^n dãy nhị phân cho một n

Ví dụ: với n =3 thì ta phải sinh được 1 dãy nhị phân: 000, 001, 010, 011,

tử đó sẽ được tăng giá trị lên 1 và các phần tử bên phải phần tử đó sẽ

bị giảm hết về 0, các phần tử bên trái phần tử đó giữ nguyên trạng thái

Mã giả code:

1 Nhập

2 Khởi tạo mảng a[] gồm n phần tử, tất cả đều là 0

3 Bool final = false

4 While final = false{

Code: Sinh nhi phan

Trang 16

Đoạn code hoàn chỉnh

Kết quả chạy code với nhập n =3

Trang 17

b) Bài toán sinh tổ hợp chập k của N phần tử

• Bắt đầu từ vị trí đầu tiên và đi đến vị trí cuối cùng

• Cấu hình đầu tiên sẽ là từ 1 đến phần từ k

từ i đến N-k+i Như ví dụ trên với i = 1 thì giá trị a[i] sẽ chạy từ 1 đến 4-2+1 = 3, với i=2 giá trị a[i] sẽ chạy từ 2 đến 4-2+2 = 4

Mã giả code:

1 Nhập N và k

2 Khởi tạo mảng a[] gồm N phần tử, phần từ a[i] có giá trị = i

3 Bool final = false

4 While final = false{

Code: Sinh to hop chap K cua N phan tu

Trang 18

Đoạn code hoàn chỉnh

Kết quả chạy code với nhập n =3

Trang 19

V Ví Dụ Phương Pháp quay lui:

a) Sinh xâu nhị phân có độ dài N

Giải thích code: nhập N số nhị phân cần tim Khởi tạo mảng a[100] để lưu kết

quả Truyền vào hàm thuatToan(1) là để bắt đầu từ số nhị phân đầu tiền Vòng for gán các giá trị có thể của số nhị phân là 0 và 1 sau đó kiểm tra nếu i = n thì

in ra kết quả nếu không gọi hàm thuatToan(2) và gán a[2] bằng các giá trị 0 hoặc 1 và kiểm tra 2 # 3 tiếp tục gọi thuaToan(3) gán a[3] bằng 0 kiểm tra i = 3 trả ra kết quả 000 Vẫn trong vòng for đó gán a[3] = 1 kiểm tra i = 3 trả ra kết quả 001 Quay lại vòng for của thuatToan(2) gán a[2] = 1 kiểm tra i = 2 chưa bằng 3 lại gọi thuatToan(3) và trả ra kết quả 010 và 011 Backtrack lại

thuatToan(1) gán a[1] = 1 và tiếp tục như vậy

Trang 20

b) Tổ hợp chập K của N

Giải thích code: cơ bản thuật toán này hoạt động giống thuật toán trên Thay

đổi là vòng for kết thúc khi sinh đến k phần tử và tìm giá trị nhỏ nhất của a[i] là giá giá trị đứng trước nó cộng thêm 1: j = a[i-1] +1; và giá trị cao max của a[i]:

j = N – K + i; ví dụ ở vị trí i = 1 thì giá trị max của i = 6 – 4 + 1 = 3 để đảm bảo rằng nếu j tăng lên 4 thì số được sinh ra chỉ có 456 không phải là 4 phần tử

Trang 21

Giải thích code: bài toán này sẽ có thêm điều kiện là 1 phần tử không được

xuất hiện 2 lần trong một cấu hình vì vậy sẽ dùng mảng visited[100] = {0} để đánh dấu chưa xét và đã xét Thuật toán hoạt động như sau:

Trang 22

d) Bài toán N-queen (bài toán kinh điển của thuật toán quay lui)

Để giải quyết bài toán thì ta phải xác định các các nước mà 2 quân Hậu có thể

ăn nhau là theo chiều dọc, ngang và chéo Vì vậy chúng ta sẽ xếp mỗi quân Hậu

ở 1 hàng và đánh dấu cột và 2 đường chéo quân Hậu đó có thể đi thì đến hàng tiếp theo xét các ô mà quân hậu 1 đó không thể ăn để đặt quân hậu 2 và cứ như thế đánh dấu các cột và 2 đường chéo cho đến khi xếp được quân Hậu thứ N

Ngày đăng: 01/12/2024, 20:32

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

TÀI LIỆU LIÊN QUAN

w