Và một lý do quan trọng nữa là, đối với các em học sinh học chương trìnhTin học phổ thông, việc cài đặt thuật toán xong mà chạy không có lỗi cú pháp đã làmột thành công và thành công hơn
Trang 1ĐƠN VỊ CÔNG TÁC: Trường THPT Cẩm Phả
Quảng Ninh, tháng 12 năm 2017
Trang 3MỤC LỤC
MỤC LỤC 1
PHẦN I MỞ ĐẦU 2
1.1 Lý do viết sáng kiến kinh nghiệm 2
1.2 Mục tiêu của sáng kiến 2
1.2.1 Mục tiêu chung 2
1.2.2 Mục tiêu cụ thể 3
1.3 Giới hạn của sáng kiến 3
1.3.1 Đối tượng nghiên cứu: 3
1.3.2 Về không gian: 3
1.3.3 Về thời gian: 4
1.4 Phương pháp nghiên cứu 4
PHẦN II NỘI DUNG 5
CHƯƠNG 1: TỔNG QUAN 5
1 Cơ sở lý luận: 5
2 Cơ sở thực tiễn: 5
CHƯƠNG 2: NỘI DUNG NGHIÊN CỨU 7
1 Lý thuyết 7
1.1 Cách thứ nhất: Bằng thực nghiệm 7
1.2 Cách thứ hai: Bằng phương pháp lý thuyết 8
1.3 Các quy tắc xác định độ phức tạp của thuật toán 8
1.4 Phân loại câu lệnh trong ngôn ngữ lập trình bậc cao 8
2 Ví dụ 9
3 Bài tập 12
CHƯƠNG 3: KẾT QUẢ ĐẠT ĐƯỢC 23
1 Kết quả sau khi áp dụng sáng kiến kinh nghiệm 23
2 Điều kiện để áp dụng sáng kiến 24
PHẦN III: KẾT LUẬN, KIẾN NGHỊ 25
1 Kết luận: 25
2 Kiến nghị: 25
TÀI LIỆU THAM KHẢO 26
Trang 4PHẦN I MỞ ĐẦU 1.1 Lý do viết sáng kiến kinh nghiệm
Như chúng ta đã biết, có thể có nhiều thuật toán để giải một bài toán Mộtđiều đặt ra là khi giải một bài toán, ta cần lựa chọn thuật toán như thế nào mà đượccho là “tốt” hơn cả, và dựa trên cơ sở nào để đánh giá thuật toán này “tốt” hơn
thuật toán kia? Chính vì thế tôi đã đi tìm và nghiên cứu về “Độ phức tạp của thuật toán”
Và một lý do quan trọng nữa là, đối với các em học sinh học chương trìnhTin học phổ thông, việc cài đặt thuật toán xong mà chạy không có lỗi cú pháp đã làmột thành công và thành công hơn nữa khi chạy chương trình cho kết quả đúng thì
đó là một niềm vui rất lớn đối với các em Nhưng, đối với những bài toán khótrong các kì thi chọn học sinh giỏi môn Tin học hay kỳ thi Tin học trẻ khôngchuyên, có rất nhiều em cài đặt được thuật toán, chạy được các test đemo nhưngcác em lại không được điểm tối đa khi các giám khảo chấm và chạy các bộ test với
dữ liệu lớn, đó là vì các em chưa quan tâm đến thời gian thực hiện thuật toán, đếndung lượng không gian nhớ cần thiết để lưu các dữ liệu vào, ra và các kết quảtrung gian trong quá trình tính toán Đấy là một vấn đề mà giáo viên ôn đội tuyểnTin học rất cần quan tâm và hướng dẫn các em
Tôi lấy một ví dụ trong kì thi chọn học sinh giỏi cấp tỉnh năm học 2017
vừa qua, với câu 1 được đánh giá là dễ hơn cả so với 2 câu còn lại, xin trích một
phần đề bài như sau: “Cho một sâu S chỉ gồm các chữ cái tiếng Anh (a z, A Z) Bạn hãy thống kê các chữ cái xuất hiện trong xâu S theo thứ tự từ điển và số lần xuất hiện của nó Việc thống kê các chữ cái không phân biệt chữ hoa, chữ thường.
Ví dụ xâu S=’afbAAffbbDda’ có kết quả thống kê như sau:
- A xuất hiện 4 lần,
- B xuất hiện 3 lần,
- D xuất hiện 2 lần,
- F xuất hiện 4 lần …”
Với đề bài trên, thì có em lựa chọn thuật toán là:
+ B1: Sắp xếp các chữ cái trong xâu;
+ B2: Đếm số lần xuất hiện của các chữ cái trong xâu
Nhưng có những em thì lại lựa chọn thuật toán:
+ B1: Đếm số lần xuất hiện của các chữ cái trong xâu;
+ B2: Sắp xếp các chữ cái trong xâu
Với hai cách lựa chọn trên thì cách nào là lựa chọn tốt hơn? Đó cũng là một
lý do càng thôi thúc tôi muốn nghiên cứu đề tài này
1.2 Mục tiêu của sáng kiến
Trang 51.2.1 Mục tiêu chung
Mục tiêu của đề tài “Độ phức tạp của thuật toán” không chỉ là để phân
tích, để so sánh thuật toán, để đánh giá xem thuật toán nào tốt hơn thuật toán nào
mà còn dựa vào kết quả phân tích đánh giá đó để hiệu chỉnh, cải tiến thuật toán đã
Nếu chỉ là các chương trình đơn giản như những bài tập ví dụ trên lớp, haynhững bài tập về nhà đơn giản ở sách giáo khoa chương trình phổ thông, chỉ thựchiện một số ít lần trên dữ liệu vào và dữ liệu không quá lớn thì tôi hướng học sinhcủa tôi thực hiện theo tiêu chí thứ nhất l, có thể hướng dẫn học sinh dùng một thuậttoán có sẵn, ít hiệu quả hơn cũng được miễn sao có thể dễ dàng lập trình
Nhưng nếu các em tham gia các kì thi học sinh giỏi thì các em sẽ vấp phảinhững bộ test với dữ liệu lớn, khi đó tính hiệu quả của thuật toán là yêu cầu quantrọng và tôi hướng các em đặt tiêu chí thứ 2 là quan trọng hơn Trong trường hợpnày, cần chọn một thuật toán chạy nhanh và sử dụng ít các tài nguyên cho dù thuậttoán có thể phải cài đặt phức tạp để nhận được chương trình chạy nhanh hơn, hiệuquả hơn
Quay trờ lại ví dụ bài 1 của bài thi chọn học sinh giỏi Tỉnh vừa qua, nếu bộInput là xâu dài với vài nghìn kí tự thì việc sắp xếp trước có tối ưu hơn hay khônghay là sau khi ta tính được có bao nhiêu loại kí tự (tối đa là 24 chữ cái) và chỉ phảisắp xếp 24 chữ cái thay vì hàng nghìn chữ cái?
Như vậy, việc lựa chọn thuật toán tốt hơn còn phụ thuộc vào rất nhiều yếu tốnhư bài toán ấy sẽ phải viết chương trình dùng nhiều hay ít lần? Các yêu cầu về hệthống máy tính dùng để thực hiện chương trình là như thế nào? Điều mấu chốt
là các em phải dựa vào các đặc tính cụ thể của từng bài toán để các em xác địnhtiêu chí nào hiệu quả cho sự lựa chọn của thuật toán
1.3 Giới hạn của sáng kiến
1.3.1 Đối tượng nghiên cứu:
Đề tài “Độ phức tạp của thuật toán” được thực nghiệm trong các giờ dạy
môn Tin học trên lớp và các buổi ôn học sinh giỏi Tin học
1.3.2 Về không gian:
Trang 6Trường Trung học phổ thông Cẩm Phả - Thành phố Cẩm Phả - Tỉnh QuảngNinh
1.3.3 Về thời gian:
Đề tài được thực hiện trong năm học 2015 - 2016 và tiếp tục nghiên cứu đếnnay, có sự đúc kết kinh nghiệm từ những năm học trước năm 2015
1.4 Phương pháp nghiên cứu
- Dựa trên cơ sở lý thuyết của các môn Khoa học tự nhiên, nhất là môn Toánmôn học cơ sở cho sự phát triển tư duy lập trình trong Tin học
- Dựa trên cơ sở lý thuyết của Ngôn ngữ lập trình Pascal, sự hoạt động tuần tựtừng bước của máy tính khi thực hiện chương trình
- Thu thập dữ liệu thông qua việc hỏi học sinh về mức độ biết, hiểu và vậndụng ngôn ngữ lập trình Pascal vào giải các bài tập Toán
- Phân tích đánh giá mức độ học sinh hiểu vận dụng, từ đó xây dựng, giới thiệucác bài toán phù hợp với từng đối tượng học sinh
- Tổng kết rút kinh nghiệm sau mỗi giờ dạy, mỗi học kỳ đã qua để tìm raphương pháp cũng như nội dung phù hợp nhất đối với từng đối tượng học sinh
Trang 7PHẦN II NỘI DUNG CHƯƠNG 1: TỔNG QUAN
1 Cơ sở lý luận:
Thực hiện Nghị quyết trung ương số 29-NQ/TW “về đổi mới căn bản, toàn diện giáo dục và đào tạo, đáp ứng công nghiệp hóa, hiện đại hóa trong điều kiện kinh tế thị trường định hướng xã hội chủ nghĩa và hội nhập quốc tế ” đã được hội nghị Trung ương 8 (khóa XI) thông qua Trong đó có mục tiêu: “Đối với giáo dục phổ thông, tập trung phát triển trí tuệ, thể chất, hình thành phẩm chất, năng lực công dân, phát hiện và bồi dưỡng năng khiếu, định hướng nghề nghiệp cho học sinh Nâng cao chất lượng giáo dục toàn diện, chú trọng giáo dục lý tưởng, truyền thống, đạo đức, lối sống, ngoại ngữ, tin học, năng lực và kĩ năng thực hành, vận dụng kiến thức vào thực tiễn…”
Thực hiện Chỉ thị số 05 - CT/TW của Bộ chính trị về đẩy mạnh học tập vàlàm theo tư tưởng, đạo đức, phong cách Hồ Chí Minh Đó là: phong cách tư duyđộc lập, tự chủ, sáng tạo, luôn gắn chặt lý luận với thực tiễn, phong cách làm việcdân chủ, khoa học, kỹ lưỡng, cụ thể, tới nơi, tới chốn; phong cách ứng xử văn hóa,tinh tế, đầy tính nhân văn, viết và nói ngắn gọn, dễ hiểu, dễ nhớ, dễ làm,…
2 Cơ sở thực tiễn:
Môn Tin học đến nay không còn là môn học mới mẻ đối với học sinh phổthông, bởi học sinh đã được làm quen nó ngay ở các cấp học dưới Đây là mộtthuận lợi cho học sinh, học sinh không phải học từ đầu để làm quen với môn học
Sự liên quan của môn Tin học với các môn học khác là nhiều, vì vậy học sinh sẽphải vất vả để xem lại, tìm kiếm lại tri thức ở các môn học khác Đặc biệt nội dunglập trình trong môn học Tin học lại có liên quan rất nhiều đến kiến thức các mônkhoa học tự nhiên như Toán, Lí, liên quan nhiều đến tư duy Toán học Nếu họcsinh yếu tư duy về Toán học thì sẽ rất là khó khăn khi lập trình Muốn giải quyếtđược việc này thì giáo viên cần phải dẫn dắt học sinh tiếp cận với môn học mộtcách tự nhiên, hào hứng thông qua những kiến thức sẵn có của các em ở các mônhọc mà các em yêu thích
Nhiều giáo viên còn hạn chế về trình độ, khả năng cập nhật thông tin Khôngchỉ vậy, một số giáo viên tư duy về thuật toán còn chậm, hay nói cách khác là chưahiểu rõ thuật toán để diễn đạt trong việc dạy lập trình Chính điều này đã làm chogiáo viên có những hạn chế khi dạy cho các em các thuật toán tối ưu
Khi bước vào học phổ thông thì học sinh đã bắt đầu định hình học theo khối
để thi đại học Thời gian học chủ yếu dành cho các môn học chính như Toán, Lý,Hóa, Văn, Anh Tin học là một môn phụ nên thời gian để học chỉ là những tiết học
ở trên lớp Đối với Tin học 10, 12 thì tính ứng dụng của môn học trong thực tế các
em dễ dàng nhìn thấy và thực hiện được luôn Còn với Tin học 11 thuộc về lĩnhvực lập trình, khó có sản phẩm để các em nhìn thấy Hơn thế việc tư duy thuật toáncũng là một nội dung khó đối với các em Điều này dẫn đến rất nhiều học sinhkhông thích và không đầu tư cho đội tuyển
Trang 8Ngoài ra, chúng ta cần giải quyết các bài toán không chỉ đúng mà còn xử lýphải nhanh với những bộ test dữ liệu lớn
Từ thực tế trên tôi muốn nghiên cứu “Độ phức tạp thuật toán” để có thể hiểu
rõ hơn, có cái nhìn sâu, rộng hơn để có thể giúp các em lựa chọn và tư duy thuậttoán tốt hơn
Trang 9CHƯƠNG 2: NỘI DUNG NGHIÊN CỨU
1 Lý thuyết
Việc giải một bài toán trên máy tính thường được tiến hành qua các bướcsau:
Bước 1: Xác định bài toán
Bước 2: Thiết kế hoặc lựa chọn thiết kế thuật toán
Bước 3: Viết chương trình
Bước 4: Kiểm thử và hiệu chỉnh chương trình
Bước 5: Viết tài liệu
Mỗi bài toán được đặc tả bởi hai thành phần: Input và Output Việc xác địnhbài toán chính xác là xác định rõ hai thành phần này và mối quan hệ giữa chúng.Các thông tin đó cần được nghiên cứu cẩn thận để có thể lựa chọn thuật toán, cáchthể hiện các đại lượng đã cho, các đại lượng phát sinh trong quá trình giải bài toán
và ngôn ngữ lập trình thích hợp
Ví dụ, trong một bài toán tin học khi đề cập đến một số nguyên dương N, làtuổi của một người, có thể chỉ rõ phạm vi giá trị của N là từ 0 đến 150, để lựa chọncách thể hiện N bằng kiểu dữ liệu thích hợp
Để giải một bài toán bước 1 là bước đơn giản nhất nhưng cũng khá quan
trọng Nhưng quan nhất trong 5 bước trên thì là bước 2: Bước lựa chọn hoặc thiết
kế thuật toán.
Mỗi thuật toán chỉ giải một bài toán nào đó, nhưng có thể có nhiều thuậttoán khác nhau cùng giải một bài toán Vì thế, cần phải thiết kế hoặc lựa chọn mộtthuật toán phù hợp đã có để giải bài toán cho trước
Có hai cách tiếp cận để đánh giá thời gian thực hiện của một thuật toán:
+ Bước 1: Đếm số lần xuất hiện của các chữ cái trong xâu;
+ Bước 2: Sắp xếp các chữ cái trong xâu
Với cách này việc đếm số lần xuất hiện của các kí tự trong xâu là rất đơngiản, kể cả dãy kí tự có hàng ngàn kí tự, vì đó chỉ là phép tính cộng đơn giản; sau
đó là sắp xếp, nếu có nhiều tối đa cũng chỉ là 24 kí tự phải sắp xếp Khi đó chươngtrình sẽ chạy nhanh hơn rất nhiều so với cách thứ hai như sau:
+ Bước 1: Sắp xếp các chữ cái trong xâu;
+ Bước 2: Đếm số lần xuất hiện của các chữ cái trong xâu
Trang 10Với cách giải như này nếu ta có xâu đưa vào là hàng nghìn kí tự thì việcmáy tính phải sắp xếp hàng nghìn kí tự như vậy sẽ mất rất nhiều thời gian, có thểdẫn đến treo máy.
1.2 Cách thứ hai: Bằng phương pháp lý thuyết
Chúng ta coi thời gian thực hiện thuật toán như hàm số của cỡ dữ liệu vào(dữ liệu phần input) Ta sử dụng hàm số T(n) để biểu diễn thời gian thực hiện củamột thuật toán (trong đó n là cỡ của dữ liệu vào)
Chúng ta xem xét việc xác định độ phức tạp của thuật toán thông qua kí
Giả thiết, thuật toán gồm hai phần liên tiếp T 1 và T 2. Khi đó, nếu phần T 1 của
thuật toán có thời gian thực hiện là T 1 (n) = O(f(n)) và phần T 2 có thời gian thực
hiện là T 2 (n)=O(g(n)), khi đó thời gian thực hiện thuật toán sẽ là:
T 1 (n) + T 2 (n) = O(f(n) + g(n))
- Quy tắc lấy max:
Nếu thuật toán T có thời gian thực hiện T(n) = O(f(n) + g(n)) thì có thể coi thuật toán T có độ phức tạp tính toán là O(max(f(n),g(n)))
Chú ý: Với quy tắc này, nếu T(n) là một đa thức thì các toán hạng bậc thấp
có thể bỏ qua khi đánh giá độ phức tạp của thuật toán
- Quy tắc nhân:
Nếu thuật toán T có thời gian thực hiện T(n) = O(f(n)) Khi đó nếu thực hiện k(n) lần đoạn thuật toán T với k(n)=O(g(n)) thì độ phức tạp tính toán sẽ là:
O(f(n).g(n))
1.4 Phân loại câu lệnh trong ngôn ngữ lập trình bậc cao
a Câu lệnh đơn thực hiện một thao tác, ví dụ câu lệnh gán đơn giản (khôngchứa lời gọi hàm trong biểu thức), đọc/ ghi đơn giản, câu lệnh chuyển điều khiểnđơn giản (break, goto, return …)
b Nếu S1, S2, Sm là các câu lệnh thì
Begin S1; S2,…; Sm; End;
Là các câu lệnh hợp hay khối lệnh
c Nếu S1, S2 là các câu lệnh và E là biểu thức logic thì
Trang 11If E then S1 else S2;
Là câu lệnh rẽ nhánh hay câu lệnh If
d Nếu S là câu lệnh và E là biểu thức logic thì
While E do S;
Là câu lệnh lặp điều kiện trước
e Nếu S1, S2,…,Sm là các câu lệnh và E là biểu thức logic thì
Repeat
S1;S2;…Sm;
Until E;
Là câu lệnh lặp điều kiện sau hay Repeat
f Nếu S là lệnh, E1, E2 là các biểu thức cùng một kiểu thứ tự đếm được thìFor i:= e1 to e2 do S;
Là câu lệnh lặp với số lần xác định
Để đánh giá thời gian thực hiện chương trình, cần thiết phải biết đánh giáthời gian thực hiện các câu lệnh Để áp dụng điều đó ta có thể áp dụng các quy tắctính độ phức tạp của thuật toán, cụ thể:
- Thời gian thực hiện một lệnh đơn không phụ thuộc vào kích thước dữ liệu
là: O(1).
- Thời gian thực hiện một câu lệnh hợp thành sẽ được tính theo qui tắc cộng
và quy tắc max: O(max(f1(n),f2(n)…,fm(n)).
- Thời gian thực hiện câu lệnh điều kiện IF: Giả sử thười gian thực hiện hai
câu lệnh thành phần dạng đủ là f(n) và g(n) thì thời gian thực hiện của câu lệnh IF
sẽ được tính theo qui tắc max: O(max(f(n),g(n)).
- Thời gian thực hiện câu lệnh lặp sẽ áp dụng theo qui tắc nhân, nghĩa là
O(k(n)f(n)), trong đó k(n) là số lần lặp và f(n) là thời gian thực hiện câu lệnh bên
trong vòng lặp
Chú ý: Trong một thuật toán, ta chú ý đặc biệt đến một phép toán gọi là phép toán tích cực Đó là phép toán mà số lần thực hiện không ít hơn các phép toán khác
Trang 13=> Dùng quy tắc nhân ta có O(n^2)
tương tự như vậy ta sẽ có O(n^3), O(n^4)
Trang 15Bài 1 Phân tích thời gian thực hiện của chương trình sau:
Thời gian thực hiện chương trình phụ thuộc vào n Các lệnh {1},{2}, {4},
{5}, {7}, {8}, {9} có thời gian thực hiện là O(1);
Lệnh lặp for {3} có số lần lặp là n, nên thời gian thực hiện là O(n);
Tương tự, lệnh lặp for {6} có thời gian thực hiện là O(n).
Vậy thời gian thực hiện của chương trình là: max(O(1), O(1), O(n), O(1), O(1), O(n), O(1), O(1)) = O(n).
Bài 2: Phân tích thời gian thực hiện của đoạn chương trình sau:
Thời gian thực hiện chương trình phụ thuộc vào n
Các lệnh {1}, {3}, {6} có thời gian thực hiện là O(1).
Trang 16Lệnh lặp for {2} có số lần lặp là 2n, như vậy lệnh {2} có thời gian thực hiện
là O(n).
Lệnh lặp for {5} có số lần lặp là n, như vậy lệnh {5} có thời gian thực hiện
là O(n) Lệnh lặp for {4} có số lần lặp là n, như vậy lệnh {4} có thời gian thực hiện là O(n2)
Vậy thời gian thực hiện đoạn chương trình trên là:
Max(O(1), O(n), O(n2)) = O(n2)
Bài 3 Phân tích thời gian thực hiện của đoạn chương trình sau:
{1} for i :=1 to n do
{2} for j :=1 to i do
Phân tích:
Thời gian thực hiện chương trình phụ thuộc vào n
Các lệnh {3} có thời gian thực hiện là O(1)
Khi i = 1, j chạy từ 1 đến 1 lệnh lặp For {2} lặp 1 lần
Khi i = 2, j chạy từ 1 đến 2 lệnh lặp For {2} lặp 2 lần
…
Khi i = n, j chạy từ 1 đến n lệnh lặp For {2} lặp n lần
Như vậy lệnh {3} được lặp 1+ 2 + 3 + + n = n( n2 1) lần, do đó lệnh {1} có thời
gian thực hiện là O(n2)
Vậy thời gian thực hiện chương trình là: O(n2)
Bài 4 Phân tích đoạn chương trình sau: