Tải bản đầy đủ

Đề tài nghiên cứu khoa học tìm hiểu về thuật toán sắp xếp

hocthuat.vn –Tài liệu online miễn phí

NGHIÊN CỨU KHOA HỌC
Đề tài : Tìm hiểu về Thuật Toán Sắp Xếp

Sinh viên thực hiện:Nguyễn Hải Nam

1


hocthuat.vn –Tài liệu online miễn phí
Mục lục
NGHIÊN CỨU KHOA HỌC ......................................................................... 1
Đề tài : Tìm hiểu về Thuật Toán Sắp Xếp ...................................................... 1
Mục lục ........................................................................................................... 2
PHẦN MỞ ĐẦU ............................................................................................ 4
1. Lý do chọn đề tài .................................................................................... 4
2. Mục tiêu và nhiệm vụ ............................................................................. 5
Chƣơng 1. MỘT SỐ KIẾN THỨC CƠ SỞ ................................................... 6
1.1. Thuật toán.......................................................................................... 6
1.1.1. Khái niệm thuật toán .................................................................. 6

1.1.2. Các đặc trƣng của thuật toán ...................................................... 7
Chƣơng 2. MÔ PHỎNG THUẬT TOÁN .................................................. 10
2.1. Tổng quan về mô phỏng thuật toán................................................. 10
2.1.1. Khái niệm mô phỏng thuật toán ............................................... 10
2.1.2. Lịch sử mô phỏng thuật toán.................................................... 11
2.1.3. Tác dụng của mô phỏng thuật toán .......................................... 14
2.1.4. Kiến trúc của hệ thống mô phỏng thuật toán ........................... 18
2.1.5. Lựa chọn công cụ mô phỏng thuật toán ................................... 20
2.2. Một số yêu cầu đối với mô phỏng thuật toán.................................. 21
2.2.1. Mô tả đúng theo thuật toán....................................................... 21
2.2.2. Hệ thống mô phỏng phải đƣợc thực hiện theo từng bƣớc ....... 21
2.2.3. Mô phỏng thuật toán phải có tính động ................................... 21
2.2.4. Phải tạo ra sự phân cấp cho ngƣời học .................................... 22
2.2.5. Cấu trúc của mô phỏng thuật toán ........................................... 22
2.3. Quy trình thiết kế nhiệm vụ mô phỏng thuật toán .......................... 23
2.3.1. Nghiên cứu và phân tích giải thuật .......................................... 23
2.3.2. Phân tích giải thuật thành nhiều bƣớc, sau đó lần lƣợt mô phỏng
từng bƣớc đó ......................................................................................... 26
2.3.3. Phân tích khả năng tổng hợp các bƣớc đã phân tích thành giải
thuật 27
2.3.4. Phân tích những khó khăn và thuận lợi với những ngƣời lần đầu
tiên biết đến giải thuật........................................................................... 27
2.4. Kết luận ........................................................................................... 28
Chƣơng3 : CHƢƠNG TRÌNH ỨNG DỤNG THUẬT TOÁN SẮP XẾP ... 29
3.1
CÁC THUẬT TOÁN SẮP XẾP ĐƠN GIẢN .............................. 30
3.1.1
Sắp xếp lựa chọn .................................................................... 30
3.1.2 Sắp xếp xen vào ...................................................................... 32
3.1.3 Sắp xếp nổi bọt ....................................................................... 33
3.2 Sắp xếp hòa nhập ........................................................................... 35
Sinh viên thực hiện:Nguyễn Hải Nam

2


hocthuat.vn –Tài liệu online miễn phí
3.3
3.4


Sắp xếp nhanh ............................................................................... 38
Sắp xếp sử dụng cây thứ tự bộ phận ............................................ 45

Sinh viên thực hiện:Nguyễn Hải Nam

3


hocthuat.vn –Tài liệu online miễn phí
PHẦN MỞ ĐẦU
1. Lý do chọn đề tài
Trong hai thập kỷ qua, mô phỏng thuật toán đã đƣợc các nhà sƣ phạm
của ngành công nghệ thông tin sử dụng nhƣ một công cụ có tính chất giúp
đỡ trong việc dạy các thuật toán đồ thị, các thuật toán sắp xếp, … khác nhau
bằng máy tính. Nguyên nhân của việc mô phỏng thuật toán đƣợc sử dụng
nhƣ một công cụ trợ giúp cho việc giảng dạy là do nó có thể cung cấp các
mô phỏng động bằng đồ họa của một thuật toán và các thay đổi trong cấu
trúc dữ liệu của nó trong suốt quá trình thực thi.
Nhƣ một phần của quá trình học thuật toán, những sinh viên ngành
công nghệ thông tin sẽ học về cấu trúc của một trình biên dịch (compiler)
trong một ngôn ngữ lập trình cho quá trình đó. Điều này sẽ chỉ ra cho chúng
ta từng nhiệm vụ của các giai đoạn khác nhau trong trình biên dịch.
Hiện nay, một số hệ thống mô phỏng thuật toán đƣợc phát triển sau
hai thập kỷ. Hầu hết các thuật toán đƣợc đề cập đến trong giai đoạn này đều
là các hệ thống phổ biến hơn và tinh vi hơn các hệ thống mà thực tế đang sử
dụng.
Mô phỏng thuật toán ngày càng trở nên hữu ích và trở thành một giáo
cụ trực quan rất quan trọng trong hầu hết các lĩnh vực, nhất là trong
môi trƣờng giáo dục. Với các nhà sƣ phạm của ngành công nghệ
thông tin thì mô phỏng thuật toán có tác dụng nhƣ một tài liệu hƣớng
dẫn trong việc dạy các thuật toán bằng máy tính. Đặc biệt, nó giúp học
sinh và sinh viên hiểu cấu trúc dữ liệu và thuật toán nhanh hơn. Nhƣ
vậy, mô phỏng thuật toán góp phần to lớn vào việc ứng dụng CNTT
trong giảng dạy và góp phần vào sự phát triển nhanh chóng của hệ
thống elearning.

Sinh viên thực hiện:Nguyễn Hải Nam

4


hocthuat.vn –Tài liệu online miễn phí
Thuật toán về sắp xếp rất đa dạng và phong phú. Vì vậy vấn đề “ Mô phỏng
thuật toán sắp xếp ” đƣợc chọn để nghiên cứu trong khóa luận này.
2. Mục tiêu và nhiệm vụ
 Nghiên cứu tổng quan về mô phỏng thuật toán.
 Hƣớng đến các kỹ thuật lập trình với mã nguồn mở và ngôn ngữ lập
trình C#
 Áp dụng kết quả nghiên cứu làm một demo mô phỏng thuật toán sắp
xếp
3. Cấu trúc khóa luận
Chƣơng 1: Một số kiến thức cơ sở
 Trình bày khái niệm thuật toán, các đặc trƣng của thuật toán
 Độ phức tạp của thuật toán
Chƣơng 2: Mô phỏng thuật toán
 Tổng quan về mô phỏng thuật toán
 Một số yêu cầu đối với mô phỏng thuật toán
 Quy trình thiết kế nhiệm vụ mô phỏng thuật toán
Chƣơng 3: Chƣơng trình ứng dụng thuật toán sắp xếp
Phân tích và thiết kế hệ thống mô phỏng thuật toán sắp xếp
 Phân tích một số thuật toán hiện tại

Sinh viên thực hiện:Nguyễn Hải Nam

5


hocthuat.vn –Tài liệu online miễn phí

Chƣơng 1. MỘT SỐ KIẾN THỨC CƠ SỞ

1.1. Thuật toán
1.1.1. Khái niệm thuật toán

Thuật ngữ “algorithm” (thuật toán hoặc còn gọi là giải thuật) đƣợc gọi
theo tên nhà toán học Ả rập thế kỷ IX al-Khowarizmi, ngƣời đã viết cuốn
sách về các chữ số Hindu – cơ sở của kí hiệu số thập phân hiện đại (xem [4],
trang 118). Xuất xứ ban đầu là từ algorism, đƣợc dùng để chỉ các quy tắc
thực hiện các phép tính số học trên các số thập phân. Sau đó, vào thế kỷ
XVIII algorism biến thành algorithm. Với sự quan tâm ngày càng tăng đối
với máy tính, khái niệm thuật toán đã đƣợc cho một ý nghĩa chung hơn, bao
hàm cả các thủ tục xác định để giải các bài toán, chứ không phải chỉ là thủ
tục để thực hiện các phép tính số học.
Thuật toán là một dãy hữu hạn các thao tác đƣợc sắp xếp theo một
trình tự xác định sao cho sau khi thực hiện dãy các thao tác ấy, từ Input của
bài toán ta nhận đƣợc Output cần tìm.
Cũng có thế xem thuật toán nhƣ một công cụ để giải quyết một bài
toán cụ thể. Phát biểu bài toán sẽ chỉ định tổng quát mối quan hệ
Input/Output cần thiết. Thuật toán mô tả một thủ tục tính toán cụ thể để đạt
đƣợc mối quan hệ Input/Output đó.
Vào khoảng những năm 1930 - 1936, lần lƣợt các nhà toán học
K.Gödel,
S. Kleene, A. Church, A. Turing đã đề ra một số định nghĩa khác nhau cho

Sinh viên thực hiện:Nguyễn Hải Nam

6


hocthuat.vn –Tài liệu online miễn phí
khái niệm thuật toán. Trong số các định nghĩa toán học khác nhau (nhƣng
tƣơng đƣơng) về thuật toán, các khái niệm Máy Turing (1937) và Hàm đệ
quy (1931-1936) đƣợc sử dụng rộng rãi hơn vì có nhiều thuận tiện cho các
nghiên cứu cả về lí thuyết lẫn thực hành.

1.1.2. Các đặc trƣng của thuật toán

Các thuật toán có một số tính chất chung, đó là:
 Đầu vào (Input): Một thuật toán có các giá trị đầu vào từ một
tập xác định.
 Đầu ra (Output): Từ mỗi tập giá trị đầu vào, thuật toán sẽ tạo ra
các giá trị đầu ra. Các giá trị đầu ra chính là nghiệm của bài
toán.
 Tính xác định: Các bƣớc của thuật toán phải đƣợc xác định một
cách chính xác.
 Tính đúng đắn: Một thuật toán phải cho các giá trị đầu ra đúng
đối với mỗi tập giá trị đầu vào.
 Tính hữu hạn: Một thuật toán phải tạo ra các giá trị đầu ra sau
một số hữu hạn (có thể rất lớn) các bƣớc thực hiện đối với mỗi
tập đầu vào.
 Tính hiệu quả: Mỗi bƣớc của thuật toán phải thực hiện đƣợc
một cách chính xác và trong một khoảng thời gian chấp nhận
đƣợc.

Sinh viên thực hiện:Nguyễn Hải Nam

7


hocthuat.vn –Tài liệu online miễn phí
 Tính tổng quát: Thuật toán cần phải áp dụng đƣợc cho mọi tập
dữ liệu đầu vào của bài toán, chứ không phải chỉ cho một tập
đặc biệt các giá trị đầu vào.
1.2.Độ phức tạp của thuật toán
Cần chú ý rằng mỗi thuật toán chỉ giải một lớp bài toán nào đó,
nhƣng có thể có nhiều thuật toán khác nhau giải cùng một bài toán. Một vấn
đề đặt ra là ta cần chọn một thuật toán tốt để giải bài toán đã cho.
Nhƣng thế nào là thuật toán tốt? Thƣớc đo hiệu quả là thời gian máy
tính sử dụng để giải bài toán theo thuật toán đang xét khi các giá trị đầu vào
có kích thƣớc xác định, và dung lƣợng bộ nhớ đòi hỏi để thực hiện thuật
toán đó. Nhƣ vậy khi xem xét đến độ phức tạp tính toán của thuật toán ta
phải xem xét đến độ phức tạp thời gian và độ phức tạp không gian.
Độ phức tạp không gian gắn liền với cấu trúc dữ liệu cụ thể đƣợc
dùng để thực hiện thuật toán.
Độ phức tạp thời gian:
Độ phức tạp thời gian của một thuật toán có thể biểu diễn qua số phép
toán thực hiện thuật toán đó khi các giá trị đầu vào có kích thƣớc xác định.
Độ phức tạp trong trƣờng hợp xấu nhất là trƣờng hợp phải dùng tối đa
các phép toán để giải bài toán theo thuật toán đang xét.
Độ phức tạp trong trƣờng hợp trung bình, trong trƣờng hợp này ta
phải đi tìm số trung bình các phép toán để giải bài toán trên toàn bộ các giá
trị đầu vào có kích thƣớc đã cho.
Các thuật ngữ thường dùng cho độ phức tạp của thuật toán:
O(1): Độ phức tạp hằng số

Sinh viên thực hiện:Nguyễn Hải Nam

8


hocthuat.vn –Tài liệu online miễn phí
O(logn): Độ phức tạp lôgarit
O(n): Độ phức tạp tuyến tính
O(nlogn): Độ phức tạp nlogn
O(nb): Độ phức tạp đa thức
O(bn), b > 1: Độ phức tạp hàm mũ
O(n!): Độ phức tạp giai thừa

Sinh viên thực hiện:Nguyễn Hải Nam

9


hocthuat.vn –Tài liệu online miễn phí
Chƣơng 2. MÔ PHỎNG THUẬT TOÁN

2.1. Tổng quan về mô phỏng thuật toán
2.1.1. Khái niệm mô phỏng thuật toán

Mô phỏng thuật toán là quá trình tách dữ liệu, thao tác, ngữ nghĩa và
tạo mô phỏng đồ họa cho quá trình trên [Stasko 1990] (xem [23]). Mô phỏng
thuật toán đƣợc thiết kế để giúp ngƣời dùng có thể hiểu thuật toán, đánh giá
chƣơng trình và sửa lỗi chƣơng trình.
Một chƣơng trình máy tính chứa các cấu trúc dữ liệu của thuật toán
mà nó thực thi. Trong quá trình thực thi chƣơng trình, các giá trị trong cơ sở
dữ liệu đƣợc thay đổi. Mô phỏng thuật toán sử dụng biểu diễn đồ họa để
biểu diễn cấu trúc dữ liệu và chỉ ra sự thay đổi giá trị trong cơ sở dữ liệu
trong mỗi trạng thái. Thông qua đó, ngƣời sử dụng có thể xem đƣợc từng
bƣớc thực thi chƣơng trình và nhờ vậy có thể hiểu chi tiết đƣợc thuật toán.
Mô phỏng thuật toán cũng đƣợc dùng để đánh giá một chƣơng trình
đã có bằng cách cung cấp các mô phỏng cho các thành phần của hệ thống,
nhờ đó có thể kiểm tra đƣợc hiệu năng của hệ thống.
Bên cạnh việc giúp ngƣời sử dụng hiểu hơn về hệ thống, mô phỏng
thuật toán còn đƣợc dùng để giúp thực hiện quá trình dò lỗi dễ dàng hơn. Để
sử dụng mô phỏng thuật toán trong quá trình dò lỗi của một chƣơng trình,
ngƣời sử dụng chú thích vào các trạng thái của chƣơng trình để tạo ra các
lệnh mô phỏng, sau đó chúng sẽ đƣợc đƣa vào hệ thống mô phỏng thuật toán
để tạo mô phỏng. Ngƣời sử dụng có thể xem chƣơng trình của họ đã thực
hiện nhƣ thế nào, các giá trị dữ liệu ở mỗi bƣớc và một bƣớc sẽ ảnh hƣởng

Sinh viên thực hiện:Nguyễn Hải Nam
10


hocthuat.vn –Tài liệu online miễn phí
tới các bƣớc sau nhƣ thế nào. Nó sẽ giúp ngƣời sử dụng tìm ra tất cả các lỗi
có thể xảy ra trong chƣơng trình.
2.1.2. Lịch sử mô phỏng thuật toán

Mô phỏng thuật toán đã đƣợc xây dựng từ hai thập kỷ gần đây. Nhƣng
chƣơng trình mô phỏng thuật toán đầu tiên là của Ken Knowlton ở Bell
Telephone Laboratories khi mô phỏng ngôn ngữ liên kết danh sách vào năm
1966. Mô phỏng thuật toán phát triển mạnh vào đầu những năm 80 của thế
kỷ 20.
Vào năm 1981, video (sorting out sorting) đƣợc xây dựng bởi Ronald
Baecker ở đại học Toronto đƣợc coi là khởi điểm của lĩnh vực mô phỏng
thuật toán. Từ đó các nhà giáo dục đã sử dụng mô phỏng thuật toán để trợ
giúp quá trình dạy học. Giữa những năm 80 và đầu những năm 90, hai hệ
thống có ảnh hƣởng mạnh đến về sau đƣợc phát triển và có ý nghĩa lớn trên
tất cả những hệ thống sau này. Hai hệ thống này là BALSA-I (Brown
ALgorithm Simulator and Animator) [Brown 1984] và TANGO (Transitionbased Animation GeneratiOn) [Stasko 1990].
BALSA-I là hệ thống mô phỏng thuật toán nổi tiếng rộng khắp đầu
tiên. Nó đƣợc phát triển bởi Marc Brown và Robert Sedgewick tại trƣờng
đại học Brown. BALSA-I là hệ thống mô phỏng thuật toán tƣơng tác mà hỗ
trợ đồng thời nhiều cái nhìn của một cấu trúc dữ liệu thuật toán và có thể
hiển thị nhiều thuật toán thực thi đồng thời. Sự phát triển của nó là động cơ
thúc đẩy các nhà nghiên cứu khác tham gia vào việc phát triển các hệ thống
mô phỏng thuật toán khác nữa.
Một hệ thống khác là TANGO, đƣợc phát triển bởi John Stasko của
trƣờng đại học Brown. Sự nổi bật của TANGO là chỉ ra mô hình pathSinh viên thực hiện:Nguyễn Hải Nam
11


hocthuat.vn –Tài liệu online miễn phí
transition để thiết kế mô phỏng và một framework cho hệ thống mô phỏng
thuật toán. Nó đƣa ra một khái niệm framework mới mà đƣợc chấp nhận bởi
một số hệ thống sau này nhƣ kiến trúc cơ sở của chúng. Kiến trúc này sẽ
đƣợc mô tả trong mục tiếp theo.
Từ khi hai hệ thống của BALSA và TANGO đƣợc phát triển, các hệ
thống đi sau của hai hệ thống đáng chú ý này cũng đƣợc phát triển. BALSAI có một hệ thống đi sau đó là BALSA-II [Brown 1988]. BALSA-II là một
hệ thống mô phỏng thuật toán vùng-độc lập thao tác các ảnh với nhiều cái
nhìn và cung cấp quá trình tạo ra bộ điều khiển dễ dàng. TANGO thì khác,
có nhiều hệ thống đi sau. XTANGO [Stasko 1992] là hệ thống trực tiếp đi
sau TANGO. POLKA đƣợc thiết kế để xây dựng mô phỏng đồng thời cho
các chƣơng trình song song. Nó là một hệ thống mô phỏng thuật toán hƣớng
đối tƣợng 2-D và đƣợc mở rộng thành hệ thống 3-D, POLKA 3-D. POLKA
3-D cung cấp cái nhìn 3-D và 3-D nguyên thủy, ví dụ nhƣ: hình nón, hình
cầu, hình lập phƣơng và một số hình khác nữa. Ngƣời dùng không bị yêu
cầu phải có hiểu biết trƣớc về đồ họa máy tính 3-D để sử dụng POLKA 3-D.
Samba cho phép thể hiện mô phỏng tƣơng tác mà đọc các câu lệnh ASCII và
thực hiện các hành động mô phỏng tƣơng ứng. Có một phiên bản Java của
Samba

đƣợc

gọi



JSamba

(xem

http://www.cc.gatech.due/gvu/softviz/parviz/ samba.html).
Các hệ thống mô phỏng thuật toán khác bao gồm: Zeus, Leonardo,
CATAI, Mocha. Zeus [Brown 1991] đƣợc phát triển tại trƣờng đại học
Brown cùng với BALSA và BALSA-II, nó đƣợc coi nhƣ một trong số các hệ
thống phần mềm có ảnh hƣởng lớn đến nhau đầu tiên. Zeus đƣợc thực thi
trong môi trƣờng multi-threaded và multi-processor, vì thế nó có thể làm cho
các

chƣơng

trình

song

Sinh viên thực hiện:Nguyễn Hải Nam
12

song.

CATAI

(xem


hocthuat.vn –Tài liệu online miễn phí
http://wonderland.dia.unisa.it/catai/) là một hệ thống mô phỏng các chƣơng
trình C++. Nó tin tƣởng vào những công nghệ đối tƣợng phân tán và cho
phép một vài ngƣời dùng chia sẻ mô phỏng đó thông qua sự trừu tƣợng hóa
lớp học thực tế. Truyền thông và sự đồng bộ hóa giữa các khách hàng mô
phỏng và thuật toán đƣợc mô phỏng đƣợc đảm bảo bởi ngƣời phục vụ mô
phỏng

Java



sử

dụng

công

nghệ

CORBA.

Mocha

(xem

http://www.cs.brown.edu/people/jib/Mocha.html) là một mô hình phân tán
với kiến trúc client-server nhằm tối ƣu phân chia những thành phần của phần
mềm trong một hệ thống mô phỏng thuật toán tiêu biểu. Trong mô hình
Mocha, chỉ mã giao diện đƣợc xuất tới máy ngƣời dùng, trong khi thuật toán
đƣợc thực hiện trên một server chạy trên máy của nhà cung cấp.
Với việc phát triển của công nghệ mới, tính phổ dụng của mạng toàn
cầu và sự tiến hóa của ngôn ngữ lập trình Java, những ngƣời phát triển đã
xây dựng những hệ thống mô phỏng thuật toán trực tuyến, có lợi thế của
những hệ thống mở dễ tiếp cận hơn.
Một số nhà phát triển cũng hợp nhất việc sử dụng đa phƣơng tiện
trong các hệ thống của họ. Việc sử dụng các hệ thống mô phỏng thuật toán
không còn bị bó hẹp trong các lớp học truyền thống hoặc phòng thí nghiệm
giảng dạy nữa mà đã đƣợc mở rộng để dạy từ xa.
Trong khoảng hai thập niên gần đây, một số rất lớn các hệ thống mô
phỏng thuật toán đã ra đời và phát triển mạnh mẽ. Phần lớn các hệ thống mô
phỏng thuật toán đã đề cập trong mục này đều phổ biến hơn và phức tạp hơn
các hệ thống đang đƣợc sử dụng trong thực tế. Chúng đã đƣợc phát triển và
sử dụng bởi những nhà chuyên môn, với mục đích giáo dục hoặc nghiên cứu
thực nghiệm của họ. Một trong số các hệ thống này có một kiến trúc phức
tạp và cần những công nghệ đặc biệt để chạy nó. Chúng ta không có bất kỳ
Sinh viên thực hiện:Nguyễn Hải Nam
13


hocthuat.vn –Tài liệu online miễn phí
tiện ích nào của các hệ thống này để xây dựng hệ thống mô phỏng các thuật
toán đồ thị; thay vào đó, chúng ta đã ƣớc lƣợng đƣợc các hệ thống mô phỏng
hiện hữu khác mà kích thƣớc nhỏ hơn và có những kiến trúc đơn giản hơn.
2.1.3. Tác dụng của mô phỏng thuật toán

Các hệ thống mô phỏng thuật toán đƣợc sử dụng rộng rãi nhƣ công cụ
hỗ trợ giảng dạy trong ngành giáo dục khoa học máy tính. Một số nghiên
cứu thực nghiệm đã ƣớc lƣợng hiệu quả của chúng trong giáo dục và kết quả
nhận đƣợc có thay đổi. Cụ thể là:
Brown (1984) đã sử dụng BALSA-I để dạy một khóa giới thiệu lập
trình và một khóa “ cấu trúc dữ liệu và giải thuật”. Hệ thống đƣợc sử dụng
nhƣ một chƣơng trình trực quan trong khóa giới thiệu, và nhƣ một ngƣời mô
phỏng thuật toán mức cao trong lớp cấu trúc dữ liệu. Ông ta báo cáo rằng
việc sử dụng các hoạt cảnh mô phỏng để phụ thêm vào thuyết trình dẫn tới
„những lợi ích có thể chứng minh được trong việc tăng tốc độ hiểu biết‟ qua
thuyết trình truyền thống. Stasko (1997) đã sử dụng Samba, chƣơng trình mô
phỏng của hệ thống XTango dạy một khóa thuật toán khoa học máy tính.
Những sinh viên đƣợc yêu cầu sử dụng hệ thống có thêm vào mô phỏng cho
các chƣơng trình ấn định của họ. Các kết quả thu đƣợc cho biết rằng những
sinh viên thích các mô phỏng và những mô phỏng đó có thể làm tăng tính
sáng tạo của các sinh viên. Hơn nữa, sự hiểu biết của sinh viên về thuật toán
đƣợc tăng lên nhờ việc mô phỏng.
Tuy nhiên, sử dụng thuật toán trong việc dạy học không phải lúc nào
cũng thành công. Các nhà giáo dục đã làm các thực nghiệm và thu đƣợc các
kết quả pha trộn. Stasko et al. (1993) đã chỉ ra một thí nghiệm bằng việc dạy
hai nhóm sinh viên với hai cách thuyết trình khác nhau. Cả hai nhóm sinh
viên này cùng nghiên cứu thuật toán “ Pairing heap” (ghép đôi đống). Một
Sinh viên thực hiện:Nguyễn Hải Nam
14


hocthuat.vn –Tài liệu online miễn phí
nhóm học thuật toán dựa vào sự mô tả văn bản và nhóm kia cũng nhận các
tài liệu đó nhƣng có thêm sự trợ giúp bằng các chƣơng trình mô phỏng thuật
toán. Mặc dầu những kết quả chỉ ra rằng nhóm thứ hai đạt đƣợc nhiều điểm
hơn nhóm kia, nhƣng không có điểm nổi trội nào có thể đƣợc kết luận là nhờ
sự trợ giúp của mô phỏng.
Tƣơng tự, Byrne et al. (1996) đã chủ đạo hai thí nghiệm mà trong đó
các kết quả chỉ ra rằng lợi ích của mô phỏng không phải là hiển nhiên.
Những kết quả pha trộn này đã gây ra chán nản, nhƣng đa số các nhà giáo
dục đều tin tƣởng rằng mô phỏng hỗ trợ việc học.
Tuy nhiên, những kết quả thí nghiệm bất lợi này gợi ý những yếu tố
quan trọng khác trong việc sử dụng mô phỏng thuật toán. Các kết quả đã
thông báo rằng để đạt đƣợc hiệu quả mô phỏng thuật toán đầy đủ thì điều
quan trọng là mô phỏng đƣợc sử dụng phối hợp với những yếu tố khác.
Lawrence et al. (1994) đã sử dụng các hệ thống XTANGO và POLKA để
dạy thuật toán cây khung nhỏ nhất Kruskal. Trong số nhóm sinh viên tham
dự các thí nghiệm, kết quả của những sinh viên mà tham dự một phiên thí
nghiệm tƣơng tác tốt hơn đáng kể so với những sinh viên mà tham dự những
phiên thí nghiệm bị động. Các kết quả này đã cho phép các sinh viên điều
khiển và tƣơng tác với mô phỏng tốt hơn, chẳng hạn, chƣơng trình mô
phỏng cho phép sinh viên đƣa vào tập dữ liệu của chính họ và thực hiện mô
phỏng trên tập dữ liệu này chứ không chỉ dừng lại ở việc quan sát những tập
dữ liệu mẫu.
Hơn nữa, nhiều nghiên cứu gần đây bởi Kehoe et al. (1999) cho thấy
có thể sử dụng mô phỏng nhƣ một công cụ giáo dục. Thí nghiệm đƣợc thực
hiện trong một thái độ khác từ các thí nghiệm khác. Những sinh viên đƣợc
chia thành hai nhóm và cả hai nhóm đều học thuật toán „binomial heap”
Sinh viên thực hiện:Nguyễn Hải Nam
15


hocthuat.vn –Tài liệu online miễn phí
(đống nhị thức). Một nhóm học thuật toán bởi sự tƣơng tác với mô phỏng
trong khi nhóm còn lại là đọc những hình dạng phẳng về các điểm khóa thao
tác của thuật toán. Sự khác nhau trong thí nghiệm này là kịch bản bài tập về
nhà. Những sinh viên đƣợc đƣa cho những câu hỏi trƣớc khi bắt đầu khóa
học. Trong suốt thời gian kiểm tra thử, những sinh viên có thể truy cập tới
bài dạy và thời gian để hoàn thành bài kiểm tra thử này đƣợc cho tƣơng đối
nhiều. Các kết quả của thí nghiệm này cho thấy nhóm đƣợc trang bị chƣơng
trình mô phỏng thuật toán thực hiện bài kiểm tra thử tốt hơn nhóm kia. Các
sinh viên của nhóm có sử dụng mô phỏng thuật toán phản hồi rằng mô
phỏng đã giúp đỡ họ hiểu thuật toán tốt hơn.
Báo cáo của Kehoe et al (1999) đã trình diễn một cách sử dụng mô
phỏng thuật toán trong việc dạy để đạt đƣợc giá trị sƣ phạm cao hơn. Nó đã
đƣợc thuyết trình rằng mô phỏng thuật toán đƣợc sử dụng tốt hơn trong các
tình trạng học tƣơng tác và mô phỏng (nhƣ một bài tập về nhà). Cũng nhƣ
vậy, mô phỏng thuật toán có thể có tính sƣ phạm hơn khi nó đƣợc sử dụng
trong việc phối hợp với các cách học khác hoặc giúp đỡ những chỉ dẫn khác
để giải thích làm thế nào thực hiện một thao tác của thuật toán. Báo cáo cũng
nói rằng với mô phỏng thuật toán ngƣời ta có thể dễ dàng học các thao tác
theo thủ tục của các thuật toán. Ngoài ra nó có thể làm cho việc học một
thuật toán bớt đáng sợ hơn vì nó làm cho thuật toán dễ tiếp cận hơn.
Stasko et al. (1993) đã kết luận từ thí nghiệm của họ một số điều kiện
mà mô phỏng thuật toán có thể có lợi nhất. Một trong số những điều kiện
này là hỗ trợ mô phỏng thuật toán với những chỉ dẫn thúc đẩy toàn diện. Khi
mô phỏng thuật toán đóng vai trò chỉ dẫn này, màn hình mô phỏng phải
đƣợc bổ sung bởi các mô tả văn bản của các thao tác đang diễn ra. Một điều
kiện khác đó là hệ thống mô phỏng thuật toán cần phải bao gồm các chức
Sinh viên thực hiện:Nguyễn Hải Nam
16


hocthuat.vn –Tài liệu online miễn phí
năng: quay lại hoặc lặp lại những bƣớc thực hiện thuật toán để cho phép
những ngƣời dùng sao lƣu và xem lại những thao tác quan trọng. Một số bài
giảng đòi hỏi các trạng thái thực hiện thuật toán cũng cần phải đƣợc ghi lại
và cung cấp lại đƣợc. Sự phản hồi của sinh viên cũng là quý giá trong việc
cải thiện chất lƣợng chỉ dẫn của mô phỏng.
Mặc dù những kết quả đƣợc đƣa ra từ những nghiên cứu thực nghiệm
này không phải luôn có lợi, thì cũng không có nghĩa rằng mô phỏng thuật
toán không hiệu quả trong dạy học. Hiện nay đang có nhiều nghiên cứu đang
đƣợc tiến hành về thiết kế và đánh giá mô phỏng thuật toán. Hansen et al.
(1999) tin rằng các kết quả trong các nghiên cứu thực nghiệm trên chƣa tốt
không phải vì mô phỏng thuật toán là phƣơng pháp dạy học không tốt, mà vì
cách thức thực hiện các mô phỏng chƣa tốt. Họ đã phát triển một hệ thống
trực quan hóa giải thuật siêu phƣơng tiện gọi là HalVis (Hypermedia
Algorithm Visualizations). Dựa vào framework của chúng, họ đã thiết kế các
trực quan hóa giải thuật, và họ đã hƣớng dẫn vài thí nghiệm thực nghiệm bởi
việc sử dụng hệ thống này. Tất cả các kết quả thí nghiệm cho thấy trực quan
hóa giải thuật bằng đồ họa có hiệu quả hơn so với các phƣơng pháp dạy
truyền thống. Những kết quả này cho thấy rằng để mô phỏng thuật toán có
hiệu quả và có lợi cho ngƣời dùng, thì việc thiết kế cho thích hợp và cách
thức mô phỏng là những yếu tố quan trọng. Để mô phỏng thuật toán có hiệu
quả thì hệ thống mô phỏng cần phải đáp ứng những điều sau :
 Truy cập mở (Open access): Ngƣời dùng có thể truy cập hệ thống mô
phỏng mở. Hơn nữa, nếu có cài đặt hệ thống mô phỏng trong trƣờng
học, thì họ có thể truy cập tới hệ thống này từ nhà hoặc từ bất cứ nơi
nào khác.

Sinh viên thực hiện:Nguyễn Hải Nam
17


hocthuat.vn –Tài liệu online miễn phí
 Mô phỏng một cách có điều khiển (Control animation): Ngƣời dùng
có thể tự tạo tập dữ liệu của chính mình khi sử dụng hệ thống mô
phỏng. Trong khi các tập dữ liệu đƣợc cài đặt sẵn cũng có thể giúp đỡ
sinh viên có những sự hiểu biết ban đầu, hệ thống nên có cả 2 tùy
chọn này.
 Tương tác (Ineractivity): Hệ thống mô phỏng phải cung cấp đƣợc sự
tƣơng tác giữa ngƣời dùng và hệ thống. Sự tƣơng tác bao gồm: ngƣời
dùng xem theo từng bƣớc, hủy, chạy nhanh tới một bƣớc mong muốn,
hay xem lại từ đầu, ...
 Lịch sử (History): Hệ thống mô phỏng cho phép ngƣời dùng xem lại
các bƣớc trƣớc trong quá trình thực hiện.
 Phản hồi (Feedback): Phải tiếp thu phản hồi của sinh viên về việc sử
dụng hệ thống mô phỏng để ƣớc lƣợng hiệu quả của hệ thống cũng
nhƣ để cải thiện hệ thống.
2.1.4. Kiến trúc của hệ thống mô phỏng thuật toán

Đa số các hệ thống mô phỏng thuật toán có những thƣ viện hỗ trợ thủ
tục mô phỏng và giao diện mô phỏng. Vài hệ thống mô phỏng đòi hỏi phải
đƣa vào trực tiếp bằng tay những thông điệp gửi tới các thủ tục mô phỏng
trong chƣơng trình thực hiện thuật toán. Những hệ thống mô phỏng thuật
toán ra đời sớm nhƣ: BALSA and TAGO là sự kiện – điều khiển (eventdriven), nghĩa là chúng có một chƣơng trình phát sinh những sự kiện trong
dạng những thông điệp tới một máy chủ thông điệp. Máy chủ thông điệp
chuyển thông điệp tới những cảnh quan tƣơng ứng. Một cảnh quan là một
cửa sổ trong một thiết bị màn hình nơi ngƣời dùng nhìn những đối tƣợng mô
phỏng. Thông điệp bao gồm thông tin của một đối tƣợng mô phỏng. Sau khi
Sinh viên thực hiện:Nguyễn Hải Nam
18


hocthuat.vn –Tài liệu online miễn phí
cảnh quan nhận thông điệp, nó tính toán lại đối tƣợng và kéo lại nó trên cảnh
quan.
Vài hệ thống gần đây đƣợc viết bằng Java và tất cả đều có những kiến
trúc tƣơng tự nhau. Ví dụ nhƣ: JSamba, hệ thống POLKA tiền tiêu (xem
http://www.cc. gatech.due/gvu/softviz/parviz/samba.html) và JAWAA (Java




phỏng

thuật

toán

trên

mạng,

xem

http://www.cs.duke.edu/~rodger/tools), phát triển bởi Pierson và Rodger tại
trƣờng đại học Duke vào năm 1996. Những hệ thống này chấp nhận
framework của TANGO nhƣ kiến trúc của nó. Tất cả các hệ thống sẽ gồm có
3 thành phần, các hàm mô phỏng (animator), kênh mô phỏng (animation
interpreter) và trình diễn mô phỏng (animation viewer) nhƣ đã chỉ ra trong
sơ đồ sau:
File
kịch bản
ASCII

Kênh
phỏng



Các hàm
mô phỏng

Màn
hình
trình diễn mô
phỏng

Hình 1. Kiến trúc của hệ thống mô phỏng thuật toán
- Các hàm mô phỏng: Chứa các thƣ viện để vẽ các đối tƣợng mô
phỏng trên thiết bị màn hình.
- Màn hình trình diễn mô phỏng: Cung cấp một môi trƣờng đồ họa
để trình diễn mô phỏng trên thiết bị màn hình tới ngƣời dùng cuối.
- Kênh mô phỏng: Đóng vai trò nhƣ một kênh truyền thông giữa hệ
thống mô phỏng và ngƣời dùng cuối. Nó đọc một file kịch bản
ASCII đƣợc cung cấp bởi ngƣời dùng cuối mà trong đó có chứa
mô phỏng văn bản cung cấp việc phát sinh những lệnh.

Sinh viên thực hiện:Nguyễn Hải Nam
19


hocthuat.vn –Tài liệu online miễn phí
- Kênh mô phỏng dịch các lệnh kịch bản thành các lệnh mô phỏng
tƣơng ứng và chuyển qua những tham số điều khiển của đối tƣợng
mô phỏng tới các hàm mô phỏng.
- Các hàm mô phỏng vẽ đối tƣợng đƣợc mô phỏng theo các tham số
điều khiển của đối tƣợng đó tới Animation viewer.
- Các tham số điều khiển bao gồm tọa độ x và y chỉ rõ nơi đối tƣợng
đƣợc mô phỏng xuất hiện trong Animation viewer hoặc màu sắc
của đối tƣợng đƣợc mô phỏng.
2.1.5. Lựa chọn công cụ mô phỏng thuật toán

Trong mục này, chúng ta sẽ phân tích cách tiếp cận khác để xây dựng
hệ thống mô phỏng và tính khả thi của chúng. Chúng ta cũng sẽ ƣớc lƣợng
một vài công cụ mô phỏng thuật toán thích hợp để xây dựng hệ thống mô
phỏng thuật toán. Công cụ thích hợp nhất sẽ đƣợc lựa chọn và các căn chỉnh
trên sự lựa chọn này sẽ đƣợc cung cấp.
Có ba cách tiếp cận có thể để xây dựng hệ thống mô phỏng phân tách.
Cách tiếp cận đầu tiên sẽ xây dựng hệ thống từ đầu nhờ việc sử dụng ngôn
ngữ C#. Cách tiếp cận thứ hai sẽ lựa chọn hệ thống mô phỏng thuật toán có
mục đích chung thích hợp để xây dựng các thành phần tƣơng tác của hệ
thống phân tách từ đầu. Cách tiếp cận cuối cùng là lựa chọn một hệ thống
mô phỏng thuật toán phân tách đã tồn tại và sửa đổi hệ thống đó thành hệ
thống cuối cùng.

Sinh viên thực hiện:Nguyễn Hải Nam
20


hocthuat.vn –Tài liệu online miễn phí
2.2. Một số yêu cầu đối với mô phỏng thuật toán
2.2.1. Mô tả đúng theo thuật toán

Thuật toán đƣợc đƣa ra mô phỏng phải chính xác, các bƣớc thực hiện
thuật toán phải trực quan và phản ánh đúng theo nội dung thuật toán đã đƣa
ra để đảm bảo tính đúng đắn của thuật toán.
Để kiểm tra tính đúng đắn của thuật toán, ta có thể cài đặt giải thuật
đó trên máy tính rồi đƣa vào các bộ dữ liệu xác định, lấy kết quả thu đƣợc
xác định với kết quả đã biết. Bộ dữ liệu đƣa vào phải đảm bảo kết quả thu
đƣợc phải vét kín các trƣờng hợp nghiệm của bài toán (trƣờng hợp thông
thƣờng và các trƣờng hợp đặc biệt). Làm theo cách này thì không chắc chắn,
ta chỉ phát hiện đƣợc thuật toán sai chứ không khẳng định đƣợc luôn đúng.
Tính đúng đắn chỉ có thể khẳng định bằng phƣơng pháp chứng minh toán
học.
2.2.2. Hệ thống mô phỏng phải đƣợc thực hiện theo từng bƣớc

Thuật toán thƣờng là trìu tƣợng, nếu để chƣơng trình chạy tự động thì
ngƣời dùng sẽ khó hiểu. Vì vậy, cần phải có chế độ thực hiện mô phỏng
thuật toán theo từng bƣớc, để ngƣời học có thể quan sát, theo dõi sự thay đổi
giá trị của từng biến. Nhờ đó, sẽ giúp cho ngƣời học hiểu thuật toán rõ hơn
và nhanh hơn.
2.2.3. Mô phỏng thuật toán phải có tính động

Để mô tả trực quan hóa quá trình thực hiện của thuật toán ta nên đƣa
vào hình ảnh động (có thể có âm thanh) để thể hiện sự thay đổi của dữ liệu
trong quá trình thực thi. Thuật toán phải đƣợc thử nghiệm trong mọi trƣờng
hợp để đảm bảo thời gian thực thi tốt nhất

Sinh viên thực hiện:Nguyễn Hải Nam
21


hocthuat.vn –Tài liệu online miễn phí
Một thuật toán đƣợc mô phỏng phải đảm bảo là thuật toán tốt, dễ hiểu
và đúng đắn. Muốn vậy ta phải thử nghiệm trong các trƣờng hợp dữ liệu
ngẫu nhiên, tốt nhất, xấu nhất. Nếu thuật toán vẫn chạy tốt và trong một thời
gian cho phép thì thuật toán mới hiệu quả. Ta không thể chấp nhận một thuật
toán đúng mà thời gian chạy quá lớn.
2.2.4. Phải tạo ra sự phân cấp cho ngƣời học

Đối tƣợng học thuật toán thƣờng là các sinh viên. Họ có trình độ tiếp
thu khác nhau, nên ta phải đƣa ra nhiều chế độ thao tác khác nhau để ngƣời
học đƣợc phép lựa chọn.
2.2.5. Cấu trúc của mô phỏng thuật toán

INPUT

ALGORITHM

- Dữ liệu mẫu
- Dữ liệu trực tiếp

OUTPUT
Cấu trúc dữ liệu trừu tƣợng

- Tự động
- Từng bƣớc

Biểu diễn bằng
demo

Độ phức tạp của
thuật toán

Hình 2. Cấu trúc của mô phỏng thuật toán

Sinh viên thực hiện:Nguyễn Hải Nam
22


hocthuat.vn –Tài liệu online miễn phí
2.3. Quy trình thiết kế nhiệm vụ mô phỏng thuật toán
Nghiên cứu và
phân tích giải thuật

Xây dựng mô hình
mô phỏng Input,
Output

Cơ chế sinh dữ liệu
vào

Những khó khăn
thuận lợi khi tiếp
thu giải thuật

Tổng hợp các bƣớc
thành giải thuật

Phân tích giải thuật
thành nhiều bƣớc

Hình 3. Sơ đồ quy trình thiết kế nhiệm vụ mô phỏng thuật toán
2.3.1. Nghiên cứu và phân tích giải thuật

Trƣớc khi lập trình cho máy tính giải một bài toán, điều đầu tiên là
chúng ta phải đi xác định bài toán, để từ đó xây dựng giải thuật cho bài toán.
Một bài toán đƣa ra có thể có nhiều hơn một giải thuật, vấn đề là ta phải đi
đánh giá các giải thuật đó để lựa chọn ra một giải thuật tốt nhất. Vậy nhƣ thế
nào là một giải thuật tốt? Để làm đƣợc điều này ta có thể căn cứ vào các tiêu
chuẩn sau:
 Giải thuật đƣa ra phải đúng đắn
 Giải thuật phải đơn giản (dễ hiểu)
 Giải thuật phải thực hiện nhanh (độ phức tạp của thuật toán phải thấp)
Khi đƣa ra một giải thuật, điều đầu tiên chúng ta quan tâm đến đó là tính
đúng đắn của giải thuật đó. Để biết giải thuật mình đƣa ra có đúng đắn hay
chƣa ta có thể cài đặt giải thuật bằng một ngôn ngữ lập trình cụ thể và cho
thực hiện trên máy với bộ dữ liệu mẫu, lấy kết quả thu đƣợc so sánh với kết
quả đã biết. Cách làm này nói chung là chƣa chắc chắn, vì kết quả có thể
đúng với bộ dữ liệu mẫu, nhƣng với bộ dữ liệu khác thì chƣa khẳng định là
đúng đƣợc. Mặt khác, cách làm này thực tế chỉ phát hiện ra giải thuật sai chứ
Sinh viên thực hiện:Nguyễn Hải Nam
23


hocthuat.vn –Tài liệu online miễn phí
không kết luận đƣợc là giải thuật đúng. Tính đúng đắn của giải thuật cần
phải đƣợc chứng minh bằng toán học. Nhƣng điều này không hề đơn giản.
Vì vậy, chúng ta có thể kiểm tra tính đúng đắn của giải thuật bằng cách kiểm
tra với các bộ dữ liễu mẫu, sao cho các bộ dữ liệu này phải phủ kín các
trƣờng hợp nghiệm có thể của bài toán.
Sau khi xây dựng giải thuật của bài toán xong. Khâu tiếp theo là chúng ta
tiến hành cài đặt giải thuật của bài toán bằng một ngôn ngữ lập trình nào đó.
Nếu bài toán với dữ liệu nhỏ, không quan tâm đến thời gian chạy chƣơng
trình (tức là thuật toán chỉ đƣợc sử dụng một vài lần) thì giải thuật sẽ tốt hơn
nếu việc cài đặt nó là dễ dàng và ngƣời dùng dễ hiểu.
Tuy nhiên, giải thuật cho một bài toán sau khi đƣợc cài đặt thƣờng xử lý
với dữ liệu lớn và đƣợc sử dụng nhiều lần trong chƣơng trình. Vì thế khi xây
dựng một giải thuật, ngƣời lập trình thƣờng quan tâm đến độ phức tạp của
thuật toán (thƣờng là độ phức tạp về thời gian mà đã đƣợc đề cập rất kỹ ở
mục 1.3). Điều này dẫn đến việc giải thuật đƣợc xây dựng phải có tính hiệu
quả về thời gian thực hiện chƣơng trình.
 Các phương pháp diễn tả giải thuật
- Phƣơng pháp liệt kê từng bƣớc (sử dụng ngôn ngữ tự nhiên)
- Giả mã và ngôn ngữ lập trình thân thiện với ngƣời dùng (ví dụ
nhƣ: PASCAL)
- Dùng sơ đồ khối
Hiện nay, trong ba phƣơng pháp trên thì việc dùng giả mã và một
ngôn ngữ lập trình thân thiện với ngƣời dùng để diễn tả một giải thuật đƣợc
đề cập đến nhiều hơn cả; đƣợc sử dụng trong dạy học cấu trúc dữ liệu và giải
thuật mà rất nhiều tài liệu đã đƣa ra.
Sinh viên thực hiện:Nguyễn Hải Nam
24


hocthuat.vn –Tài liệu online miễn phí
 Phân tích các trường hợp đặc biệt của dữ liệu đầu vào, các giá trị
của biến điều khiển lúc thoát khỏi vòng lặp.
Các giá trị của biến lúc thoát khỏi vòng lặp thƣờng là một dấu hiệu
đặc biệt để thoát khỏi vòng lặp. Dữ liệu đầu vào thƣờng gồm nhiều bộ dữ
liệu khác nhau về giá trị, tuy nhiên trong số đó phải có một số bộ dữ liệu đặc
biệt. Những bộ dữ liệu đó đặc biệt về giá trị dữ liệu đầu vào hoặc đặc biệt về
kết quả trả ra. Bộ dữ liệu đầu vào đặc biệt giúp ta không cần chạy thử
chƣơng trình cũng có thể biết kết quả thu đƣợc. Vì vậy, những bộ dữ liệu
đặc biệt thƣờng đƣợc dùng làm giá trị kiểm thử để đánh giá thuật toán đúng
hay sai, hoặc đánh giá chƣơng trình đƣợc viết để chạy trên máy tính có đúng
với thuật toán đƣa ra hay không?
 Phân tích đánh giá các lỗi có thể mắc phải khi viết chương trình
thực thi giải thuật
Bài toán sau khi đƣợc xác định và dựa trên ý tƣởng ta sẽ xây dựng
đƣợc giải thuật của bài toán đó. Sau đó tiến hành cài đặt thuật toán này bằng
một ngôn ngữ lập trình cụ thể ở một môi trƣờng lập trình trên máy tính để
máy thực hiện tự động giải thuật cho ta kết quả của bài toán.
Một bài toán có thể đƣợc viết bằng nhiều ngôn ngữ lập trình. Vì vậy
giải thuật phải đƣợc viết sao cho mọi lập trình viên của các ngôn ngữ lập
trình đều có thể hiểu đƣợc và dễ dàng chuyển từ giải thuật sang cài đặt bằng
ngôn ngữ lập trình mà họ thông thạo. Vì thế, khi viết giải thuật cho một bài
toán, nên viết bằng ngôn ngữ tự nhiên, gần gũi, dễ hiểu và ít gò bó.
Tuy nhiên, việc sử dụng một ngôn ngữ lập trình bậc cao để cài đặt giải
thuật thƣờng gặp phải một số vấn đề:
- Phải tuân thủ chặt chẽ các quy tắc về cú pháp
Sinh viên thực hiện:Nguyễn Hải Nam
25


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay

×