NỘI DUNG VÀ KẾT QUẢ NGHIÊN CỨU
CƠ SỞ LÝ THUYẾT
Bài toán người du lịch (Travelling Salesman Problem - TSP) [1], [2] là một bài toán NP-Khó ( NP-hard - là bài toán chưa tìm ra lời giải tối ưu cho dạng tổng quát), thuộc thể loại tối ưu rời rạc hay tổ hợp được nghiên cứu trong vận trù học hoặc lý thuyết khoa học máy tính.
Bài toán được phát biểu như sau: Cho một danh sách các thành phố và khoảng cách giữa chúng, tìm chu trình ngắn nhất đi qua mỗi địa điểm đúng một lần.
Bài toán người du lịch thường được dùng làm thước đo cho nhiều phương pháp tối ưu hóa Đã được các nhà toán học và khoa học máy tính chú ý bởi nó rất dễmô tả và rất khó giải quyết.
Mặc dù bài toán rất khó giải trong trường hợp tổng quát, có nhiều phương pháp giải chính xác và gần đúng đã được biết đến, do đó đã tìm ra để giải quyết một sốvấn trường hợp có tới hành chục nghìn thành phố.
Trong lý thuyết của độ phức tạp tính toán [3], phiên bản quyết định của bài toán TSP thuộc lớp NP-đầy đủ(- lớp NP-đầy đủlà một lớp các bài toán quyết định).
Vì vậy không có giải thuật hiệu quả nào cho việc giải bài toán TSP Hay nói cách khác, giống như thời gian chạy xấu nhất cho bất kỳ giải thuật nào cho bài toán TSP tăng theo hàm mũ và số lượng thành phố, vì vậy thậm chí nhiều trường hợp vài trăm thành phố cũng đã mất vài trăm CPU để giải một cách chính xác (bài toán chỉ tương đối đúng).
Một cuốn sổ tay dành cho người du lịch xuất bản 1832 có đề cập đến bài toán này và có ví dụ cho chu trình trong nước Đức và Thụy Sĩ, nhưng không chứa bất kỳnội dung toán học nào.
Bài toán người du lịch được định nghĩa trong thế kỷ 19 bởi nhà toán học
Ireland William Rowan Hamilton và nhà toán học Anh Thomas Kirkman Trò chơi
Icosa [4] của Hamilton là một trò chơi giải trí dựa trên việc tìm kiếm chu trình
Hamilton Trường hợp tổng quát của TSP có thể được nghiên cứu lần đầu tiên bởi
Trường Đại học Kinh tế Huế các nhà toán học ở Vienna và Harvard trong nhũng năm 1930, đặc biệt Karl
Menger, người đã định nghĩa bài toán, xem xét thuật toán hiển nhiên nhất cho bài toán và phát hiện ra thuật toán láng giềng gần nhất là không tối ưu.
Hassler Whitneyở đại học Princeton đưa ra tên bài toán người du lịch ngay sau đó.
Trong những năm 1950 và 1960, bài toán trởnên phổ biến trong giới nghiên cứu khoa họcở Châu Âu và Mỹ George Dantzig, Delbert Ray Fulkerson và Selmer
M.Johnsonở công ty RAND tại Santa Moncia [5]đã có đóng góp quan trọng cho bài toán này, biểu diễn bài toán này dưới dạng quy hoạch nguyênvà đưa ra phương pháp mặt phẳng cắt để tìm ra lời giải Bằng phương pháp này họ đã giải được tối ưu một trường hợp 49 thành phố bằng cách xây dựng một chu trình và chứng minh không có chu trình nào ngắn hơn.
Trong những thập niên tiếp theo, bài toán được nghiên cứu bởi nhiều nhà nghiên cứu trong các lĩnh vực toán học, khoa học máy tính, hóa học, vật lý và các ngành khác.
Năm 1972, Richard M.Karp [6] chứng minh rằng bài toán chu trình
Hamilton là NP-đầy đủ, kéo theo bài toán TSP cũng là NP-đầy đủ Đây cũng là một lý giải toán học cho sự khó khăn trong việc tìm kiếm chu trình ngắn nhất.
Cuối thập niên 1970 và 1980 khi Grotschel [7], Padberg, Rinaldi và cộng sự [8] đã giải được những trường hợp lên đến 2393 thành phố, sử dụng phương pháp mặt phẳng cắt và nhánh cận.
Trong thập niên 1990 Applegate, Bixby, Chavátal và Cook [9] phát triển một chương trình mang tên Concorde giải được nhiều trường hợp có độkỷlục lớn hiện nay.
Năm 1991 Gerhard Reinnelt xuất bản một bộdữliệu các trường hợp có độkhó khác nhau mang tên TSPLIB [10] và nó đãđược sử dụng bởi nhiều nhóm nghiên cứu đểso sánh kết quả
Năm 2005 Cook và cộng sự đã giải được một trường hợp có 33810 thành phố, xuất phát từmột bài toán thiết kếvi mạch.
Trường Đại học Kinh tế Huế
Bài toánngười du lịchđược phát biểu như sau:
Có một người du lịch muốn viếng thăm tại n thành phố Xuất phát từ một thành phố nào đó, đi qua các thành phố khác để du lịch và trở về thành phố ban đầu, biết chi phí đi lại và khoảng cách giữa các thảnh phố Mỗi thành phố chỉ đến một lần và khoảng cách từ một thành phố đến các thành phố khác đã được biết trước.
Hãy tìm một chu trình (một đường đi khép kín thõa mãn cácđiều kiện trên) sao cho tổngđộdài các cạnh là nhỏ nhất.
Bài toán người du lịch [1], [2] có thể được mô hình hóa như một đồ thị vô hướng có trọng số, trong đó mỗi thành phố là một đỉnh của đồ thị Khoảng cách giữa hai thành phố là độ dài cạnh Đây là vấn đềcực tiểu hóa với điểm đầu và điểm cuối là cùng một đỉnh sau khi thăm hết các đỉnh còn lại đúng một lần Mô hình này thường là một đồ thị đầy đủ (giữa mỗi cặp đỉnh đều có cạnh) Nếu không có đường giữa hai thành phố thì có thể thêm một cạnh với độ dài đủ lớn vào đồ thị mà không ảnh hưởng đến kết quảtối ưu sau cùng. Được biểu diễn bằng toán học có đồ thị vô hướng G=(V,E) với
V={v 1 ,v 2 , ,v n } là tập các đỉnh hoặc nút và E{(v i ,v j ) : v i ,v j ∈V } là tập hợp các cạnh.
Mỗi đỉnh v i đại diện cho một thành phố v i ∈V và mỗi cạnh (v i ,v j ) ∈V là khoảng cách giữa hai thành phối,j.
Trường Đại học Kinh tế Huế
PHÂN TÍCH VÀ THIẾT KẾ THUẬT TOÁN
2.1 Giải thuật đềxuất Đề xuất giải thuật di truyền đơn giản cho bài toán người du lịch Giải thuật được cài đặt bằng ngôn ngữC#.
Dữ liệu được lấy từ file text txt, được lựa chọn 50 địa điểm trên Google
Map địa bàn tỉnh Thừa Thiên Huếvà thiết lập ma trận khoảng cách.
2.2 Mãhóa đường đi Đối với bài toán người du lịch giải theo thuật toán di truyền sẽcó các lớp sau:
Bước 1:Đưa( tải) file dữ liệu txt ma trận khoảng cách giữa các địa điểm đã chuẩn bị sẵn vào chương trình (chứa n = 50 địa điểm).
Bước 2: Khởi tạo một mảng một chiều được gọi là duong để chứa danh sách các thành phố (được đánh sốtừ 0 đến n-1 ).
Bước 3: Gán giá trị cho mảng đường đi duong có giá trị từ 1 đến n, sau đó xáo trộn giá trị các vị trí trong mảng duong một cách ngẫu nhiên Tìm thành phố bắt đầu gán vào vị trí đầu mảng, tức là thành phố đầu tiên phải đi trong mảng duong.
Bước 4: Trong class DuongDi có các method tính khoảng cách giữa các thành phố và tính độ thích nghi Khoảng cách giữa các thành phố được tính theo ma trận khoảng cách, khoảng cách từ thành phố i đến j bằng a[i,j] Độ thích nghi sẽ được tính theo công thức bằng một chia cho khoảng cách của chu trình.
Trường Đại học Kinh tế Huế
Bước 1: Khai báo một mảng quần thể kiểu DuongDi Khởi tạo quần thể có kích thước l cho trước, chứa l đường đi.
- Tạo method lấy đường đi tại một vịtrí cụthểtrong mảng quanthe.
- Tạo method lưu đường đi tại một vị trí cụthể
- Tạo method tìmđường đi ngắn nhất trong lớp quần thể, được đánh giá lựa chọn dựa trên độthích nghi.
Bước 1: Tạo method ChonLoc, nhóm 5 đường đi ngẫu nhiên trong quần thể và đưa ra đường đi ngắn nhất trong 5 đường nhóm đó.
Bước 2: Tạo method GhepLai, lấy chu tình Cha Mẹ được chọn ra bằng ghép chọn lọc để tạo chu trình con Chu trình con được tạo ra bằng cách lấy một điểm ngẫu nhiên vitri, gán các giá trị trong đường đi cha trong khoảng vitri 0 đến vitri, và gán các giá trị của đường đi cha mẹ chưa có trong duongdi con trong khoảng còn lại.
Bước 3: Tạo method DotBien, trong khoảng từ i = 1 đến n-1 của đường đi, lấy một số ngẫu nhiên kiểu double trong khoảng từ 0 đến 1 nếu số đó lớn hơn tỉ lệ đột biến, thì lấy một điểm ngẫu nhiên j trong khoảng từ 1 đến n-1, tiến hành đổi giá trị tại 2 vị trí i,j cho nhau.
Bước 4: Tạo method TienHoaQuanThe để tiến hóa đưa ra quần thể mới, trong quanthemoi với kích thước cho trước, có phần tử đầu tiên là đường đi ngắn nhất của quần thể hiện tại, và các phần tử tiếp theo được tạo ra bằng cách chọn lọc và lai các đường đi để đưa ra đường đi mới Tiếp theo là đột biến từng đường đi trong quần thể và đưa raquanthemoi.
Trường Đại học Kinh tế Huế
Hình 2 1 : Sơ đồ các l ớ p cho thu ậ t toán di truy ề n
Ngôn ngữ xây dựng chương trình bằng C# cụ thể là Winform C# dùng dể đưa ra kết quả chu trình ngắn nhất mà người giao hàng (shipper) sẽ thực hiện, bao gồm các bước xây dựng như sau:
- Xây dựng lớp biểu diễn đường đi.
- Xây dựng lớp biểu diễn quần thể.
- Cài đặt Thuật toán di truyền.
- Cài đặt Winform C# gồm Form1 là tìm kiếm đường đi và Form 2 là hiển thị danh sách địa điểm đượcđánh số.
Trường Đại học Kinh tế Huế
2.4.1 Lớp DuongDi public class DuongDi
{ public static int[,] matranKC; public int[] duong; double khoangcach; double dothichnghi; public static Random rd = new Random();
// Tạo một ma trận khoảng cách giữa các thành phố public static void taoMatranKC(string urlFile) {
StreamReader file = new StreamReader(urlFile); string dls = file.ReadToEnd(); file.Close(); string[] tach = dls.Split('\n'); int[,] duLieu = new int[tach.Length, tach.Length]; for (int i = 0; i < tach.Length; i++) { string[] tach2 = tach[i].Split(' '); if (tach2.Length != tach.Length) { return;
} else { for (int j = 0; j < tach2.Length; j++) { try { duLieu[i, j] = Convert.ToInt32(tach2[j]);
Trường Đại học Kinh tế Huế
} // Khởi tạo đường đi public DuongDi(int stp) { duong = new int[stp]; khoangcach = 0; dothichnghi = 0;
} // Tính độ dài đường đi public int DoDaiDuongDi() { return duong.Count();
} //Gán giá trị tại một ví trí nhất định trong đường đi public void SetDiaDiem(int vitri, int giatri)
{ duong.SetValue(giatri, vitri); dothichnghi = 0; khoangcach = 0;
} //Đưa ra thành phố tại vị trí public int GetDiaDiem(int vitri) { return duong[vitri]; // dùng để đưa ra giá trị sd trong lai ghép
} //Kiểm tra một thành phố đã tồn tại trong đường đi hay chưa public bool ChuaDiaDiem(int giatri)
Trường Đại học Kinh tế Huế
Boolean kq = duong.Contains(giatri); return kq;
// Đưa ra vị trí của thành phố bắt đầu trong mảng đường đi
//bằng giá trị của người dùng nhập trừ cho 1 public static int DiemBatDau(int dd)
} //Mảng đường đi sẽ chứa các thành phố từ 1 đến n public void TaoDuongDi(int diemdau)
{ for (int i = 1; i tiledotbien) { int i2 = (int)(r.NextDouble() * duongdi.DoDaiDuongDi() - 1); if (i2 != 0) { var tp1 = duongdi.GetDiaDiem(i1); var tp2 = duongdi.GetDiaDiem(i2); duongdi.SetDiaDiem(i1, tp2); duongdi.SetDiaDiem(i2, tp1);
} } } } public static QuanThe TienHoaQuanThe(QuanThe quanthe) {
QuanThe quanthemoi = new QuanThe(5, false, diemcuoi, diemdau); quanthemoi.LuuDuongDi(0, quanthe.LayDuongDiNganNhat()); tp = 0; while (tp < quanthemoi.KichThuocQuanthe()) {
Trường Đại học Kinh tế Huế
DuongDi con = GhepLai(cha, me); quanthemoi.LuuDuongDi(tp, con); tp++;
} // Set thành phố bắt đầu mà người dùng nhập vào public static void SetDiemBatDau(int tp)
//Set số thành phố cần đi mà người dùng nhập vào public static void SetDiemCuoi(int sotp)
2.4.4 Winform Form1 public partial class Form1 : Form
Trường Đại học Kinh tế Huế
{ if (DuongDi.matranKC != null) { lvDanhSachDiem.Clear(); for (int i = 0; i