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

SKKN sáng kiến kinh ngiệm giải các dạng bài toán liệt kê bằng phương pháp vét cạn sử dụng thuật toán quay lùi trong ôn luyện học sinh giỏi môn tin học

23 489 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 23
Dung lượng 259,5 KB

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

Nội dung

SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HÓATRƯỜNG THPT TRIỆU SƠN 2 SÁNG KIẾN KINH NGHIỆM GIẢI CÁC DẠNG BÀI TOÁN LIỆT KÊ BẰNG PHƯƠNG PHÁP VÉT CẠN SỬ DỤNG THUẬT TOÁN QUAY LUI TRONG ÔN LUYỆN HỌC SINH

Trang 1

SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HÓA

TRƯỜNG THPT TRIỆU SƠN 2

SÁNG KIẾN KINH NGHIỆM

GIẢI CÁC DẠNG BÀI TOÁN LIỆT KÊ BẰNG PHƯƠNG PHÁP VÉT CẠN SỬ DỤNG THUẬT TOÁN QUAY LUI TRONG ÔN LUYỆN HỌC SINH GIỎI MÔN TIN HỌC

Người thực hiện: Phạm Thị Biên Chức vụ: Giáo viên

SKKN thuộc bộ môn: Tin học

THANH HÓA NĂM 2014

Trang 2

MỤC LỤC

A ĐẶT VẤN ĐỀ 3

I Lý do chọn đề tài 3

II Thực trạng của vấn đề 3

III Mục đích nghiên cứu 4

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

B GIẢI QUYẾT VẤN ĐỀ 5

I Cơ sở lý luận 5

II Biện pháp giải quyết vấn đề 5

1 Một số khái niệm 5

2 Một số dạng bài toán liệt kê 7

3 Một số bài toán tham khảo 19

III Kết quả thực nghiệm 19

C KẾT LUẬN VÀ ĐỀ XUẤT 20

I Kết luận 20

II Đề xuất, kiến nghị 20

Trang 3

A ĐẶT VẤN ĐỀ

I LÝ DO CHỌN ĐỀ TÀI

Trong thời đại ngày nay, thế giới đang diễn ra quá trình tin học hóa trongnhiều lĩnh vực hoạt động của xã hội Tin học phát triển nhanh như vũ bão và đã trởthành một ngành khoa học đóng vai trò quan trọng không thể thiếu đối với sự pháttriển của xã hội

Nhiều quốc gia ý thức được tầm quan trọng của tin học và có những đầu tư lớnvào lĩnh vực này đặc biệt là lĩnh vực giáo dục nhằm đào tạo một đội ngũ tri thức trẻ

có nền tảng tin học vững vàng nhằm đáp ứng nhu cầu ngày càng cao của xã hội

Từ năm 2006 ngành giáo dục Việt Nam đã chính thức đưa bộ môn tin học vàotrong trường THPT nhằm mục đích phổ cập các kiến thức cơ bản về Tin học, ngoài

ra còn giúp học sinh có khả năng phân tích, tổng hợp, trừu tượng hóa, khái quát hóavấn đề, đặc biệt là phát triển khả năng tư duy Muốn vậy ngoài việc dạy đại trà,hướng nghiệp và dạy nghề cần tạo điều kiện cho học sinh có năng khiếu tin họcđược phát triển khả năng lập trình để giải quyết tốt các bài toán

Để có thể phát huy những tài năng tin học thông qua ôn luyện đội tuyển họcsinh giỏi, đòi hỏi người dạy phải tiếp cận với nhiều dạng bài toán khó và nắm vữngcác phương pháp giải quyết bài toán đó

Bài toán trong tin học thường rất đa dạng và phức tạp, mỗi bài toán có thể cónhiều phương pháp giải khác nhau Để có thể lựa chọn phương pháp thích hợp chobài toán, chúng ta có thể phân chia các bài toán thành các dạng bài toán tổng quan

và chỉ ra phương pháp giải cho các dạng bài toán đó

Bài toán liệt kê là một trong những lớp bài toán khó, thường xuất hiện trongcác đề thi học sinh giỏi cấp thành phố, cấp tỉnh hay cấp quốc gia Có nhiều phươngpháp giải lớp bài toán này nhưng phương pháp vét cạn là phù hợp nhất Chính vì

vậy nên tôi chọn đề tài: “Giải các dạng các bài toán liệt kê bằng phương pháp

vét cạn sử dụng thuật toán quay lui trong ôn luyện học sinh giỏi môn Tin học”

II THỰC TRẠNG CỦA VẤN ĐỀ

1 Thuận lợi

Do sự quan tâm và đầu tư của Bộ giáo dục và đào tạo nói chung và của trườngTHPT Triệu Sơn 2 nói riêng, về cơ sở vật chất môn Tin học đã có 1 phòng thựchành hoạt động tốt, ngoài ra còn có một số phòng máy chiếu projector hỗ trợ chogiáo viên trong công tác giảng dạy

Mặc dù môn Tin không phải là môn trọng điểm nhưng rất được Ban giám hiêuquan tâm động viên và tạo mọi điều kiện trong công tác giảng dạy và ôn luyện độituyển học sinh giỏi cũng như trong các công tác khác

Trong quá trình thực hiện đề tài tôi đã được các giáo viên trong tổ bộ môn tưvấn và hỗ trợ rất nhiều giúp tôi hoàn thành đề tài

Trang 4

2 Khó khăn

Ngôn ngữ lập trình Pascal là một môn học mới, cách học cũng hoàn toàn mới,

vì vậy khi tiếp cận với môn học này đa số học sinh thấy rất bỡ ngỡ Học các thaotác sử dụng hay dùng phương pháp học thuộc lòng không còn phù hợp nữa Lúcnày các em cần phải học cách tư duy logic, tìm thuật toán, và viết những dòng lệnhtrên máy tính chính xác đến từng đấu chấm, dấu phẩy

Với tâm lí thông thường các em học sinh coi tin học là môn phụ không quantrọng nên nhiều em chủ quan không dành đủ thời gian để học nên không hiểu bài

và dần bị mất căn bản Đây cũng là lí do mà nhiều em bị điểm kém, thậm chí là thilại, học lại bộ môn tin học mặc dù có thể các em học rất giỏi các môn học khác.Chính vì xem môn Tin là môn phụ nên khi lựa chọn đội tuyển ôn thi học sinhgiỏi giáo viên chúng tôi thường rất khó lựa chọn được những học sinh có năngkhiếu thực sự

Các dạng bài toán liệt kê là những bài toán khó, nếu người học có tư duy chưatốt thì người dạy sẽ rất khó khăn trong quá trình truyền đạt để giúp các em có thểhiểu được

3 Kết quả của thực trạng

Trước khi đi vào nghiên cứu và thực hiện đề tại này, tôi thường hướng dẫnhọc sinh tiếp cận với các bài toán liệt kê bằng cách cho bài tập và cách giải vớitừng bài mà không phân chia thành từng dạng cụ thể và thuật toán tổng quan chotừng dạng, dẫn đến học sinh rất mơ hồ, khó hiểu Kết quả khảo sát trong quá trìnhgiảng dạy và thông qua các bài kiểm tra như sau:

Nội dung cần nắm bắt Số lượng Tỉ lệ (%)

Vận dụng kiến thức đã học để làm tốt các

bài tập

Trang 5

B GIẢI QUYẾT VẤN ĐỀ

I CƠ SỞ LÝ LUẬN

Bài toán liệt kê (hay còn gọi là bài toán cấu hình tổ hợp) là những bài toán khicho trước một tập các đối tượng, yêu cầu cho biết có bao nhiêu đối tượng thỏa mãnnhững điều kiện nhất định và chỉ rõ những cấu hình tìm được thỏa mãn những điềukiện trên

Bài toán liệt kê gồm có 3 dạng: tổ hợp, chỉnh hợp lặp và chỉnh hợp không lặp.Trong đó dạng bài toán chỉnh hợp không lặp thường hay xuất hiện nhiều nhất trongcác bài toán tin học

Sơ lược một số kiến thức đại số tổ hợp:

Cho S là một tập hữu hạn gồm n phần tử và số tự nhiên k Gọi X là tập hợpcác số nguyên dương từ 1 đến k: X= {1, 2, …, k}

Tổ hợp

Một tổ hợp chập k của n là một tập con k phần tử của tập n phần tử

Chẳng hạn tập {1,2,3,4} có các tổ hợp chập 2 là: {1,2}, {1,3, {1,4}, {2,3},{2,4}, {3,4} Vì trong tập hợp các phần tử không phân biệt thứ tự nên tập {1,2}cũng là tập {2,1} và do đó, ta coi chúng chỉ là một tổ hợp

Vậy số tổ hợp chập k của S gồm n phần tử là:

Chỉnh hợp lặp

Chỉnh hợp lặp chập k của n là một dãy k thành phần, mỗi thành phần là mộtphần tử của tập n phần tử, có xét đến thứ tự và không yêu cầu các thành phần khácnhau

Chỉnh hợp không lặp

Khác với chỉnh hợp lặp là các thành phần được phép lặp lại, tức là có thểgiống nhau, chỉnh hợp không lặp chập k của tập n phần tử cũng là một dãy k thànhphần lấy từ tập n phần tử có xét thứ tự nhưng các thành phần không được phépgiống nhau

Chẳng hạn có n người, một cách chọn ra k người để xếp thành một hàng làmột chỉnh hợp không lặp chập k của n

Số chỉnh hợp không lặp chập k của n phần tử là: n(n-1)(n-2)…(n-k+1)=

Để giải được bài toán liệt kê cần xác định được thuật toán tổng quan để trên cơ

sở đó xây dựng được tất cả các cầu hình liên quan

Khi đi vào giải quyết bài toán liệt kê, yêu cầu các cấu hình tìm được khôngđược lặp lại và không được bỏ sót cầu hình nào Để đáp ứng được yêu cầu trên thìphương pháp vét cạn sự lựa chọn thích hợp nhất

Trang 6

II BIỆN PHÁP GIẢI QUYẾT VẤN ĐỀ

*Ưu điểm:

- Luôn đảm bảo tìm ra nghiệm chính xác

- Đòi hỏi rất ít bộ nhớ và cài đặt đơn giản

* Nhược điểm: Thời gian thực thi rất lớn, độ phức tạp thường bậc mũ

1.2 Quay lui (Backtracking)

Trong 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 luật tính toán nhất định Muốn tìm nghiệm, phải thực hiện từngbước theo dõi, tìm kiếm từng phần tử của nghiệm Giá trị mỗi phần tử có thể cónhiều khả năng khác nhau Để tìm giá trị gán cho mỗi phần tử, phải thử các khảnăng có thể xem chúng có thỏa mãn các điều kiện của bài toán hay không gọi là thửđúng/sai

Nếu có một lựa chọn được chấp nhận thì ghi nhớ các thông tin cần thiết cácbước thử tiếp theo.Trái lại, nếu không có một lựa chọn nào thích hợp thì làm lạibước trước, xoá bớt các ghi nhớ và quay về chu trình thử với các lựa chọn còn lại.Hành động này được gọi là quay lui (Back tracking) và các giải thuật thể hiệnphương pháp này gọi là các giải thuật quay lui

Tìm mọi nghiệm (gọi là vét cạn) bằng cách tiến dần, tìm kiếm các khả năng cóthể chấp nhận được cho từng phần tử của một nghiệm và biết quay lui khi khôngthể tiến được nữa Khi mọi phần tử của một nghiệm đã được gán giá trị thì kết thúcquá trình tìm một nghiệm, chuyển sang tìm nghiệm tiếp theo

Do 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ìnhthành từ kết quả trước nên có thể sử dụng các hàm và các thủ tục đệ quy để thựchiện

Có thể so sánh các nghiệm tìm được để tìm nghiệm tối ưu

1.3 Thuật toán quay lui

Mô hình giải thuật quay lui có thể mô tả như sau:

Procedure Try (i);

Trang 7

Begin

+ Lưu trạng thái của bài toán

+ Xác nhận giá trị đề cử cho bước i

+ Xác nhận trạng thái mới của bài toán sau khi chấp nhận đề cử + Nếu là bước cuối cùng thì hiện nghiệm và tăng biến đếm nghiệm Ngược lại thì Try(i+1)

+Trả lại trạng thái như trước khi chấp nhận đề cử

End;

End;

End;

Hoặc có thể viết dưới dạng sau:

Procedure Try (i);

+ Lưu trạng thái của bài toán

+ Xác nhận giá trị đề cử cho bước i

+ Xác nhận trạng thái mới của bài toán sau khi chấp nhận đề cử + Try(i+1)

+ Trả lại trạng thái như trước khi chấp nhận đề cử

Trang 8

<ghi nhận trạng thái mới>;

If i=n then Update

Trên đây là các thuật toán vét cạn đối với bài toán tìm mọi cấu hình hay đếm

số cấu hình Trong trường hợp bài toán cần tìm một cấu hình, tìm cấu hình tối ưuthì thuật toán cũng tương tự, chỉ khác ở phần cập nhật (Update) khi sinh được mộtcấu hình mới

Chẳng hạn thủ tục Update đối với bài toán tìm nghiệm tối ưu:

2 Một số dạng bài toán liệt kê (cấu hình tổ hợp)

Bài toán tổ hợp yêu cầu tìm các đối tượng x có dạng là một vector thỏa mãncác điều kiện sau:

1 x gồm k phần tử: x=(x1,x2,…,xn)

2 Mỗi phần tử xi có thể nhận một trong tập các đối tượng a1,a2,…,an,

3 x thỏa mãn các ràng buộc có thể cho bởi hàm logic G(x)

Tùy từng trường hợp bài toán có thể yêu cầu tìm một nghiệm, tìm tất cả cácnghiệm hay đếm số nghiệm

2.1 Tổ hợp

Bài toán đặt ra cho chúng ta là hãy xác định tất cả các tổ hợp châp k của tập nphần tử Để đơn giản ta chỉ xét bài toán tìm các tổ hợp của tập các số nguyên từ 1đến n Đối với một tập hữu hạn bất kì, bằng cách đánh số thứ tự của các phần tử, tacũng đưa được về bài toán đối với tập các số nguyên từ 1 đến n

Nghiệm cần tìm của bài toán tìm các tổ hợp chập k của n phần tử phải thoảmãn các điều kiện sau:

1 Là một vector x =(x1,x2,…xk)

Trang 9

2 xi lấy giá trị trong tập {1,2,…n}

3 Ràng buộc: xi<xi+1 với mọi giá trị i từ 1 đến k-1

Có ràng buộc 3 là vì tập hợp không phân biệt thứ tự phần tử nên ta sắp xếp cácphần tử theo thứ tự tăng dần

Từ đó suy ra x[i-1] + 1 x[i]  n-k+i (1 i  k) Giả thiết có thêm số x[0] =

0 khi xét i=1 (x[0] là lính canh)

Về cấu trúc dữ liệu ta chỉ cần một mảng x để biểu diễn tổ hợp Ràng buộc đốivới giá trị x[i] là: x[i-1]< x[i]  n-ki

Trang 10

2 xi lấy giá trị trong tập {1,2,…n}

3 Không có ràng buộc nào giữa các thành phần

Chú ý là cũng như bài toán tìm tổ hợp, ta chỉ xét đối với tập n số nguyên từ 1đến n Nếu tập hợp cần tìm chỉnh hợp không phải là tập các số nguyên từ 1 đến nthì ta có thể đánh số các phần tử của tập đó để đưa về tập các số nguyên từ 1 đến nĐối với bài toán sinh chỉnh hợp lặp chập k của n hoàn toàn không có ràngbuộc nào đối với cấu hình sinh ra Do đó, cấu trúc dữ liệu của ta chỉ gồm một mảng

Trang 11

if i=k then Print(x)

Trang 12

*Phân tích

Với bài toán này chúng ta sẽ dùng một mảng d[j] (j=1 2)chứa dấu cộng và trừ,một mảng x[i] (i=2 n) chứa các phép toán tương ứng được chèn vào giữa các số 1,2,…, N Vậy nghiệm bài toán được mô tả như sau:

Trang 14

Nghiệm của bài toán tìm các chỉnh hợp không lặp chập k của tập n số nguyên

từ 1 đến n là các vector x thoả mãn các điều kiện:

1 x có k thành phần: x = (x1,x2,…xk)

2 Các giá trị xi lấy trong tập {1,2, n}

3 Ràng buộc: các giá trị xi đôi một khác nhau, tức là xi¹xj với mọi i¹j

Chỉnh hợp không lặp yêu cầu các phần tử phải khác nhau Để đảm bảo điều

đó, ngoài mảng x, ta sẽ dùng thêm một cấu trúc dữ liệu nữa là mảng d để đánh dấu.Khi một giá trị được chọn, ta đánh dấu giá trị đó, và khi chọn, ta chỉ chọn các giátrị chưa đánh dấu Mảng d sẽ là "trạng thái" của thuật toán Bạn đọc xem phần giả

mã dưới đây để thấy rõ hơn ý tưởng đó

Trang 15

2

2 3

1

2 1

3

Trang 16

Ví dụ 2: Bài toán xếp hậu

Cho bàn cờ vua nxn Hãy xếp n con hậu lên bàn cờ sao cho không con nàokhống chế con nào Hai con hậu khống chế nhau nếu chúng ở trên cùng một hàng,một cột hoặc một đường chéo

*Phân tích

Để chuyển bài toán này về dạng chuẩn của bài toán tìm cấu hình tổ hợp, ta có

có nhận xét: mỗi con hậu phải ở trên một hàng và một cột Do đó ta coi con hậu thứ

i ở hàng i và nếu biết x[i] là cột đặt con hậu thứ i thì ta suy ra được lời giải Vậynghiệm của bài toán có thể coi là một vector x gồm n thành phần với ý nghĩa:

1 Con hậu thứ i được đặt ở hàng i và cột x[i]

2 x[i] lấy giá trị trong tập {1,2…n}

3 Ràng buộc: các giá trị x[i] khác nhau từng đôi một và không có 2 con hậu ởtrên cùng một đường chéo

Khác với những bài toán sinh các cấu hình đơn giản ở phần trước, sinh các cấuhình của bài toán xếp hậu đòi hỏi những phân tích chi tiết hơn về các điều kiện ràngbuộc

Ràng buộc thứ nhất là các giá trị x[i] phải khác nhau Ta có thể dùng mộtmảng đánh dấu như ở thuật toán sinh hoán vị để đảm bảo điều này

Ràng buộc thứ 2 là các con hậu không được nằm trên cùng một đường chéochính và phụ Các bạn có thể dễ dàng nhận ra rằng 2 vị trí (x1,y1) và (x2,y2) nằmtrên cùng đường chéo chính nếu:

x1-y1=x2-y2=const

Trang 17

Tương tự, 2 vị trí (x1,y1) và (x2,y2) nằm trên cùng đường chéo phụ nếu:

x1y1=x2y2=const

Do đó, con hậu i đặt tại vị trí (i,x[i]) và con hậu j đặt tại vị trí (j,x[j]) phải thỏamãn ràng buộc: i-x[i] ¹ j-x[j] và i+x[i] ¹ j+x[j] với mọi i¹j

Ta có thể viết riêng một hàm Ok để kiểm tra các ràng buộc đó Nhưng giảipháp tốt hơn là dùng thêm các mảng đánh dấu để mô tả rằng một đường chéo chính

và phụ đã có một con hậu khống chế Tức là khi ta đặc con hậu i ở vị trí (i,j), ta sẽđánh dấu đường chéo chính i-j và đường chéo phụ i+j

Như vậy về cấu trúc dữ liệu, ta dùng 4 mảng:

- Mảng x với ý nghĩa: x[i] là cột ta sẽ đặt con hậu thứ i

- Mảng cot với ý nghĩa: cot[j]=true nếu cột j đã có một con hậu được đặt,ngược lại thì cot[j]=false

- Mảng dcc với ý nghĩa: dcc[k]=true nếu đường chéo chính thứ k đã có mộtcon hậu được đặt, tức là ta đã đặt một con hậu tại vị trí (i,j) mà i-j=k; ngược lại thìdcc[k]=false

- Tương tự ta dùng mảng dcp với ý nghĩa: dcp[k]=true nếu đường chéo phụthứ k đã có một con hậu được đặt

cot: array[1 max] of Boolean;

dcp: array[2 2 * max] of Boolean;

dcc: array[1 - max max - 1] of Boolean;

f1,f2: Text;

procedure Init;

begin

Assign(f1, InputFile); Reset(f1);

Assign(f2, OutputFile); Rewrite(f2);

ReadLn(f1, n);

FillChar(cot, SizeOf(cot), false);

FillChar(dcp, SizeOf(dcp), false);

FillChar(dcc, SizeOf(dcc), false);

end;

procedure Print;

Trang 18

if i=n then print else Try(i+1);

cot[j]:=false; dcc[i-j]:=false; dcp[i+j]:=false ;{phục hồi trạng thái cũ} end;

*Phân tích

đến thăm tại lần di chuyển thứ i Các điều kiện của x như sau:

1 x = (x1,x2,…xn)

2 xi lấy giá trị trong tập {1,2,…n}

3 Ràng buộc: xi ¹ xj với mọi i¹j và a[xi,xi+1]>0 với mọi i=1,2, n, coi xn+1=x1

n

i i i

- mảng x[i]: ghi lại hành trình

- Mảng a[i,j]: chi phí để đi từ thành phố i đến thành phố j

Trang 19

- Mảng d[i]: đánh dấu thành phố đã đi thăm, d[i]=true nếu đã đi thăm thànhphố i

Mỗi phương án của bài toán người du lịch là một hoán vị của n thành phố Vìphương án là một chu trình nên ta có thể coi thành phố xuất phát là thành phố 1

A: array[1 max, 1 max] of Integer;

X, Best : array[1 max + 1] of Integer;

Ngày đăng: 23/10/2016, 12:32

TỪ KHÓA LIÊN QUAN

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

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN

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

w