1) Mô tả bài toán. 2) Giải thuật GTS1 và GTS2. 3) ma trận hóa dữ liệu đồ thị. 4) cấu trúc dữ liệu đề nghị. 5) cài đặt thuật toán trên C#
Trang 1M C L C ỤC LỤC ỤC LỤC
BÀI TOÁN GTS1 1
I Mô tả bài toán 1
II Ma trận hóa dữ liệu đồ thị 2
III Giải thuật GTS1 3
IV Cấu trúc dữ liệu đề nghị 3
V Cài đặt 4
BÀI TOÁN GTS2 5
I Giải thuật GTS2 5
II Cấu trúc dữ liệu đề nghị 5
III Cài đặt 6
CÀI ĐẶT THUẬT TOÁN GTS TRÊN C# 8
BÀI TOÁN GTS1
I Mô tả bài toán
Một người du lịch dự định tham quan quốc gia ABC Anh ta dự kiến sẽ đến
N thành phố Chi phí để di chuyển từ thành phố i tới thành phố j là M[i][j] Bạn hãy tum một lộ trunh để người du lịch này có thể xuất phát từ thành phố (từ skn bay chẳng hạn) đi đến các thành phố cần tham quan và quay về địa điểm ban đầu, mỗi điểm tham quan chỉ qua 1 lần, sao cho chi phí là ít nhất
Ví dụ:
C
1 2 7 5
1 4 4 3
= 2 4 1 2
7 4 1 3
5 3 2 3
Trang 2Giả sử ta có đồ thị gồm N đỉnh Ma trận biểu diễn cho đồ thị là ma trận có kích thước N × N, với N là số đỉnh của đồ thị Mỗi phần tử M[i][j] biểu diễn thông tin của cạnh nối đỉnh i và đỉnh j (1≤ i, j ≤ N)
Trong bài toán GTS1, ta cần biểu diễn chi phí di chuyển giữa các thành phố Do
đó, ma trận sẽ có những đặc điểm sau:
Kích thước N × N, với N là số thành phố
M[i][j] = chi phí di chuyển giữa thành phố i và j
o Nếu tồn tại đường đi giữa i và j thì M[i][j] = x (x là giá trị xác
định)
o Ngược lại, M[i][j] = ∞ (khi cài đặt phải tum giá trị thích hợp cho
∞)
Mọi thành phố không có đường đi đến chính nó
Trang 3III Giải thuật GTS1
Bước 1: Khởi tạo TOUR:= , COST:= 0; v:= u (u là đỉnh bắt đầu)
Bước 2: Thăm tất cả các thành phố( cho k chạy từ 1 đến n-1)
Chọn (v, w) là cạnh có chi phí nhỏ nhất tính từ v đến các đỉnh chưa sử dụng w
Gán TOUR: = TOUR + (v, w);
COST: = COST + C(v, w);
Khi đó, đỉnh w được sử dụng Gán v:= w Trong khi chưa đủ N thành phố, lặp lại Bước 2
Bước 3: Chuyến đi hoàn thành
Gán TOUR: = TOUR + (v, u);
COST: = COST + C(v, u);
Chấm dứt thuật giải
IV Cấu trúc dữ liệu đề nghị
int[MAX,MAX] Matrix;
char[MAX] Visited;
char[MAX] TOUR;
int COST;
int nCities;
Diễn giải
Matrix: ma trận chi phí di chuyển giữa các thành phố, M[i][j]: chi phí di chuyển từ thành phố i đến thành phố j
Visited: mảng cho biết tunh trạng thăm viếng của các thành phố
o Visited[i] = 0: thành phố thứ i chưa được tham quan
o Visited[i] = 1: thành phố thứ i đã được tham quan
TOUR: mảng chứa chu trunh tham quan
COST: chi phí tham quan
nCities: số thành phố
Trang 4V Cài đặt
Void KhoiTaoMaTran(char *filename)
{
Đọc ma trận chi phí từ file
}
Void GTS1(int u)
{
Khởi tạo mảng thăm viếng
Lịch trình ban đầu chỉ có đỉnh u
TOUR[0] = u;
Visited[u] = 1;
số thjnh phố đã qua = 1;
Đặt đỉnh đang xét là v, v = u; Chi phí ban đầu
COST = 0;
while (số thành phố đã qua < số thành phố)
{
Đặt min = -1;
Duyệt tất cả các thành phố j Nếu có đường đi giữa v và j && chưa tham quan j Nếu min = -1 hoặc đường đi (v, j) < min min = Matrix[v][j];
w = j;
Nếu không tìm được min nào như thế Bài toán không có lời giải, dừng thuật giải COST = COST + min;
TOUR[nCount++] = w;
Visited[w] = 1;
v = w;
}
Nếu số thành phố đã qua bằng nCities và có đường đi giữa v và u
COST = COST + Matrix[v][u];
TOUR[nCities] = u;
Thuật giải kết thúc Ngược lại, bài toán không có lời giải, dừng thuật giải
}
Trang 5BÀI TOÁN GTS2
I Giải thuật GTS2
Giải thuật này sẽ tạo ra các lịch trình từ P thành phố xuất phát riêng biệt cho bài toán tìm chu trinh đi qua N thành phố (GTS1) như đã nói ở trên, với 1 ≤ P ≤ N Khi
đó P chu trình được tạo ra một cách tuần tự và chỉ có chu trình tốt nhất đã tìm thấy được giữ lại mà thôi
Bước 1: Khởi tạo K:=0; BEST:= , COST:= ∞;
Bước 2: Lần lượt tạo ra P chu trình với đỉnh thứ K
Call(GTS1(vK))
Bước 3: Cập nhật chu trunh tốt nhất
Nếu C (K) < COST thì gán BEST:= T(K); (chu trunh xuất phát từ K)
COST:= C(K);
Bước 4: Nếu K ≤ P, lặp lại bước 2
Ngược lại, chấm dứt thuật giải
II Cấu trúc dữ liệu đề nghị
int[MAX,MAX] Matrix;
int nCities;
char[MAX] BEST;
int COST;
Diễn giải
Matrix: ma trận chi phí di chuyển giữa các thành phố, M[i][j]: chi phí di chuyển từ thành phố i đến thành phố j
nCities: số thành phố
BEST: mảng chứa chu trunh tham quan tốt nhất
COST: chi phí nhỏ nhất
Trang 6III.Cài đặt
void GTS2(int P)
{
Đặt chi phí nhỏ nhất ban đầu COST = ∞; (∞ = giá trị lớn
nhất có thể có)
for (int k = 0; k < P; k++)
{
Tính GTS1(k) Nếu COST ≠ ∞ hoặc C(k) < COST
Gán COST = C(k);
Ghi nhớ T(K) làm chu trình tốt nhất hiện tại, BEST ← T(K)
} }
}
IV Ví dụ minh họa: GTS1
a Tìm hành trình tôt nhất và chi phí tương ứng theo thuật giải GTS1 với đỉnh xuất phát =1
Bước 1 TOUR ={}
COST =0 V=1// đỉnh xuất phát Bước 2:
Chọn w = 5// đỉnh được chọn vì có chi phí thấp nhất TOUR={1,5}
COST = 0 +2 V=5
Trang 7VI Code cài đặt
Trang 8CÀI ĐẶT THUẬT TOÁN GTS TRÊN C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace DemoGTS
{
public class GTS
{
int MAX= 10;
int[,] a;//khai báo ma trận a
int n,kt=0;//kb số pt n và biến lấy phần tử cuối cùng của dường đi
public int cost = 0;//luu trọng số của duong92 đi
string st="";//khai báo chuỗi để lưu chuỗi đọc dk
int[] ChuaXet;//mảng chưa xét
int Best = 10000000;//giá trị đường đi tốt nhất
string[] Luu;//lưu đường đi tốt nhất
public string[] LuuVet;//mảng để lưu dường đi
int dem = 0;//sử dụng làm số phần tử của mảng LuuVet
public void DocFile()//hàm đọc file ma trận
{
a=new int[MAX,MAX];
Console.WriteLine("Nhap ten file text chua Ma Tran(chu y:bo du lieu sau moi so phai co dau
Trang 9string filename = Console.ReadLine();//lấy tên nhập từ console
try
{
FileStream input = new FileStream(filename, FileMode.Open, FileAccess.Read);//đọc file
StreamReader reader = new StreamReader(input);
string stri;
while ((stri = reader.ReadLine()) != null)
{
st += stri;//cộng dồn chuỗi đọc vào st
}
Console.WriteLine(st);
string[] s = st.Split(' ');//cắt chuỗi
int t = Convert.ToInt32(s[0].ToString());//lấy số đỉnh của đồ thị trong file
n = t;//gán n=t(có thề đưa n thay chỗ của t)
int count = 1;// số phần tử trong s
for (int i = 0; i < n; i++)
for (int j = 0; j <n; j++)
{
int k = Convert.ToInt32(s[count]);
a[i, j] = k;
count++;
}
input.Close();//đóng file
reader.Close();//kết thúc đọc file
}
catch (IOException e)
Trang 10Console.WriteLine(e.Message);
}
}
public int layn()//hàm lấy số đỉnh
{
return n;
}
public int laya(int i,int j)//hàm lấy ma trận
{
return a[i, j];
}
public void HienThi()//hiển thị Ma trận
{
Console.WriteLine("so dinh ma tran la: {0}", n);
Console.WriteLine("Ma tran la:");
for (int i = 0; i < n; i++)
{
Console.WriteLine("\t");
for (int j = 0; j < n; j++)
{
Console.Write("{0}\t", a[i, j]);
}
Console.WriteLine("\n");
}
}
int timmin(int[,] u,int v)//hàm này dùng để tìm giá trị nhỏ nhất trong mảng
Trang 11int min=10000000;//vì giá trị nhỏ nhất ở đây có thể trùng với vị trí mà đỉnh đã dk xét nên chọn 1 giá trị lớn nhất có thể
for (int j = 0; j < n; j++)
{
if (j != v && ChuaXet[j] == 0)
{
if (min > u[v, j])
min = u[v, j];
}
}
return min;
}
public void GTS1(int v, int[,] a, int n)
{
ChuaXet[v] = 1;//chọn đỉnh v để xét nên chưa xét đỉnh V=1(đã được xét)
int i=0;
int k= timmin(a,v);//gọi lại hàm tìm min
for (i = 0; i < n; i++)
{
if (a[v,i]==k && a[v,i]!=0 && ChuaXet[i]==0)//kiếm tra
{
LuuVet[dem] = "("+v+","+i+")";///lưu dường đi
cost += a[v,i];//cộng các trong số của cạnh thỏa mãn
dem++;//đém số số đỉnh đã duyệt
kt = i;//lấy vị đỉnh cuối cùng được duyệt
GTS1(i, a, n);//gọi lại GTS với đỉnh tiếp theo là i
}
}
Trang 12}
public void GTS2(int[,] a, int n)
{
int i;
ChuaXet = new int[MAX];//khởi tạo mang chưa xét
LuuVet = new string[MAX];//khởi tạo mảng chứa dường đi
Luu = new string[MAX];//khởi tạo mảng chứa dường đi tốt nhất
for (i = 0; i < n; i++)
{
for (int di = 0; di < MAX; di++)//gán các giá trị mặc định cho mảng LuuVet,và ChuaXet {
LuuVet[di] = "-1,-1";
ChuaXet[di] = 0;
}
dem = 0;//gán biến đếm =0
cost = 0;//gán đường đi=0//dem và cost là 2 biến sử dụng trên hàm GTS()nên mỗi lần gọi lại GTS ta gan nó =0
GTS1(i, a, n);//gọi hàm GTS()
cost += a[kt, i];//tính giá trị dường đi
Console.WriteLine("{0}", cost);///in ra giá trị dường đi chỉ demo thử
if (Best > cost && cost != 0 && dem == n - 1)//so sánh nếu giá trị dường đi tốt nhất Best mà lớn hon7gia1 trị đường đi Cost vửa tính
{
Best = cost; //thỏa dk gán Best=Cost
for (int c = 0; c <= n; c++)
Trang 13
{
Luu[c] = LuuVet[c];//lưu lại dường đi vào mảng Luu
}
}
}
if (dem == n-1 )
{
Console.WriteLine("Duong di tot nhat la:");
int j = 0;
while (j <= n)
{
if (Luu[j].CompareTo("-1,-1") == 0)
j++;
else
{
Console.Write("{0}", Luu[j]);//in mảng chứa dường đi lên màng hình
j++;
}
}
Console.WriteLine("trong so nho nhat la : {0}", Best);//in giá trị dường đi nhỏ nhất lên màng hình
}
else
Console.WriteLine("Khong co duong di tot nhat đi qua tat ca ca dinh!!!!!!");
}
}
}