Tuy nhiên do thời gian làm việc có hạn và người viết chưa am trường về Maple, nên bài toán được trình bày một cách đơn giản bỏ qua một số bước phức tạp, thuật toán chưa tổng quát, chưa c
Trang 1ĐẠI HỌC QUỐC GIA TP.HCM TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
P SAU ĐẠI HỌC - CHƯƠNG TRÌNH ĐẠO TẠO THẠC SĨ CNTT QUA MẠNG
-۞ -University of Information Technology
Mô phỏng bài toán người đưa thư dùng giải thuật Heuristis
Môn Học: Lập trình Symbolic
GVHD: PGS.TS Đỗ Văn Nhơn
HVTH: Dương Ngọc Nhân, MSHV: CH1101115
Trang 2TP.HCM, Tháng 01 năm 2013
1 Giới thiệu
Mục đích của đề tài và mô phỏng bài tập này là để hiểu thêm cách lập trình trong ngôn ngữ hình thức thông qua công cụ Maple và việc áp dụng công
cụ này để giải các bài toán ứng dụng phức tạp rất tiện lợi nhanh chóng cái
mà rất khó thực hiện hoặc chi phí cao nếu dùng các ngôn ngữ lập trình phổ biến như C#, Java
Tuy nhiên do thời gian làm việc có hạn và người viết chưa am trường về Maple, nên bài toán được trình bày một cách đơn giản bỏ qua một số bước phức tạp, thuật toán chưa tổng quát, chưa cho kết quả đúng một số trường hợp…
Bài toán gồm 4 phần:
• Mô tả bài toán
• Cách tổ chức dữ liệu
• Thuật giải
• Các thủ tục (coding)
• Dữ liệu thử nghiệm và kết quả
2 Mô tả bài toán
Cho một danh sác các địa điểm và khoảng cách giữa chúng trong một địa phương Để tiết kiệm thời gian, nhiệm vụ của người đưa thư là tìm đường
đi ngắn nhất để đi qua các địa điểm đúng một lần và trở về vị trí ban đầu
Bài toán có thể phát biểu lại như sau: Giả sử có một đồ thị vô hướng có trọng số dương, tìm đường đi ngắn nhất qua tất cả các đỉnh của đồ thị rồi trở về đỉnh ban đầu
Trang 33 Cách tổ chức dữ liệu
Bài toán cần dữ liệu đầu vào là tập các đỉnh V và tập các cạnh E (cung) của
đồ thị G (V,E) Trong phạm vi bài viết này, tập các đỉnh và cạnh được nhập trực tiếp vào các biến toàn cục trước khi thực hiện lệnh chạy chương trìn, theo định dạng sau:
• Tập các đỉnh V, bao gồm các tên đỉnh (hay địa điểm) là một ký tự hay một từ liền nhau không có khoảng trắng ngăn cách nhau bởi dấu phẩy (,) và được bao trong cặp ngoặc vuông [ ], ví dụ: đồ thị gồm 5 đỉnh được đánh dấu tên từ a đến e như sau V:=[a,b,c,d,e]
• Tập các cạnh E bao gồm các cạnh ngăn cách nhau bởi dấu phẩy (,) và được bao bởi cặp ngoặc móc { } Mỗi cạnh được bao trong dấu ngoặc vuông [ ] gồm 2 phần, phần đầu là cặp tên đỉnh {vi,vj}, phần sau là trọng số dương w (hay chiều dài giữa hai địa điểm) là một số nguyên dương hoặc số thực Cặp tên đỉnh ngăn cách nhau bởi dấu phẩy và bao trong dấu ngoặc móc
{[{v1,v2},w], [{v3,v4},w], ,,}
Ví dụ có 7 cạnh {[{a,b},2],[{a,c},1],[{a,d},1.5],[{b,d},3],[{d,e},2.5],[{b,e},4], [{c,e},3.8]}
Kết quả tính toán được xuất trực tiếp ra màn hình gồm một đồ thị và:
• Một chuỗi thông báo nếu không tìm thấy hoặc
• Một tập thứ tự các tên đỉnh định dạng giống như tập các đỉnh ở trên, độ dài đường đi ngắn nhất
Trang 44 Thuật giải
Thuật giải tối ưu cho bài toán này là thuật giải tìm đường đi ngắn nhất cho chu trình Hamilton như có độ phức tạp lớn O(n!) Trong phạm vi bài viết
này sẽ sử dụng thuật giải Heuristic dựa trên nguyên lý tham lam để giải bài
toán với một số sai số
Theo kinh nghiệm của con người trong thực tế khi ta đi trên những đoạn đường ngắn nhất thì cuối cùng ta sẽ có một hành trình ngắn nhất
Thuật giải
Biến toàn cục V, E, CYCLE
B1 Chọn một đỉnh bắt đầu bất kỳ
vIn:= vStart
CYCLE:= [vStart]
eRemaining:= E
B2 For v từ 2 đến n đỉnh của V
B21 Tìm đỉnh kề với đỉnh vIn trong E với điều kiện: có trọng số nhỏ
nhất và chưa được đi qua (tức là không nằm trong CYCLE)
B22 Nếu tìm thấy
- Lưu đỉnh kề vào CYCLE
- Lưu trọng số
- Loại bỏ bớt cạnh chứa vIn và đỉnh kề trong eRemaining
- vIn := đỉnh kề
B23 Nếu không tìm thấy đỉnh kề
- Kết thúc For: break;
B3 Nếu số đỉnh lưu trong đường đi CYCLE = số đỉnh của V đúng
B31 Kiểm tra nếu có một đường đi từ đỉnh cuối cùng với đỉnh đầu
- Lưu đỉnh đầu vào đường đi CYCLE lần nữa
- Lưu lại trọng số
Trang 5- rFound:=true;
B32 Nếu không có đường đì từ đỉnh cuối đến đỉnh đầu tiên
- rFound:= false;
B4 Ngược lại số đỉnh lưu trong đường đi CYCLE <> số đỉnh của V
B41 rFound:= fase;
B5 Xuất: vẽ đồ thị G (V,E) vô hướng có trọng số
B51 Nếu rFound đúng
- In ra thông báo đường đi và chiều dài
- Vẽ lại đồ thị trên tập đỉnh V nhưng theo các cạnh trong CYCLE
(đây là đồ thị có hướng)
B52 Nếu rFound sai
- In ra thông báo không tìm thấy đường đi ngắn nhất
5 Các thủ tục
Xem toàn bộ source code được viết trong Maple 16 trong phần mục lục, có
một số thủ tuc chính:
• NextCloseVertex:=proc(eSET, vCurr): thủ tục tìm đỉnh kề với đỉnh vCurr trong tập cạnh eSET.
• GetWeightOfLastFirst:=proc(eSET,vLast,vFirst): thủ tục kiểm tra nếu
có tồn tại cạnh nối giữa hai đỉnh cuối vLast và đầu vFirst, trả về trọng
số nếu có
• GetEdges:=proc(): thủ tục lấy tập cạnh mới từ đường đi đã tìm thấy
• Hcycle:=proc(vStart): thủ tục chính để thực thi
6 Dữ liệu thử nghiệm
Cho tập đỉnh V và E như sau:
V:=[a,b,c,d,e]:
Trang 6Ta được đồ thị ban đầu và kết quả như hình bên
Kết luận
Ưu điểm thuật giải Heuristic cho bài toán
người đưa thư ở trên có độ phức tạp O(n2)
tốt hơn rất nhiều so với thuật toán tối ưu Tuy nhiên thuật giải có những hạn chế chưa cho ra kết quả chính xác cho một số trường hợp dù thực tế vẫn tồn tại một đường đi ngắn chấp nhận được qua tất cả các đỉnh một lần Trong phần chương trình chưa xử lý các dữ liệu nhập vào (đỉnh và cạnh) không chính xác
Trang 7Mục lục
restart:
with(GraphTheory):
Trang 10Tài liệu tham khảo
[1] Đỗ Văn Nhơn, tài liệu và bài giảng: Lập trình symbolic, Đại học Công nghệ Thông tin – Đại học Quốc gia TP HCM.
[2] Phần Help của công cụ Maple v.16
[3] http://www.maplesoft.com