Tải bản đầy đủ (.pdf) (14 trang)

TÌM ĐƯỜNG ĐI CHO NGƯỜI DU LỊCH SAO CHO QUÃNG ĐƯỜNG LÀ DÀI NHẤT

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (874.36 KB, 14 trang )

ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI

BÁO CÁO BÀI TẬP LỚN TRÍ TUỆ NHÂN TẠO

ĐỀ TÀI: TÌM ĐƯỜNG ĐI CHO NGƯỜI DU LỊCH SAO CHO QUÃNG
ĐƯỜNG LÀ DÀI NHẤT

Sinh viên thực hiện:

Nguyễn Văn Linh

Lớp: CNTT K52


MỤC LỤC
CHƯƠNG I: TỔNG QUAN VỀ NGÔN NGỮ C# .................................................... 3
1.1.

C# là gì? ...................................................................................................... 3

1.2.

Đặc trưng của C# ........................................................................................ 3

CHƯƠNG II. TỔNG QUAN VỀ THUẬT TOÁN NHÁNH CẬN ........................... 5
2.1.

Định nghĩa .................................................................................................. 5

2.2.


Ví dụ về giải thuật ...................................................................................... 5

2.3.

Ứng dụng .................................................................................................... 8

2.4.

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

2.5.

Code demo ................................................................................................ 10

2.6.

Giao diện chương trình ............................................................................. 13

KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN ............................................................... 14

2


CHƯƠNG I: TỔNG QUAN VỀ NGÔN NGỮ C#
1.1. C# là gì?
- C# (hay C sharp) là một ngơn ngữ lập trình đơn giản, được phát triển bởi đội ngũ
kỹ sư của Microsoft vào năm 2000, trong đó người dẫn đầu là Anders Hejlsberg và
Scott Wiltamuth.
- C# là ngôn ngữ lập trình hiện đại, hướng đối tượng và nó được xây dựng trên nền
tảng của hai ngôn ngữ mạnh nhất là C++ và Java.

- C# được thiết kế cho Common Language Infrastructure (CLI), mà gồm
Executable Code và Runtime Environment, cho phép chúng ta sử dụng các ngôn
ngữ high-level đa dạng trên các nền tảng và cấu trúc máy tính khác nhau.
- C# với sự hỗ trợ mạnh mẽ của .NET Framework giúp cho việc tạo một ứng dụng
Windows Forms hay WPF (Windows Presentation Foundation), . . trở nên rất dễ
dàng.
1.2. Đặc trưng của C#
Các đặc điểm để làm cho C# là ngơn ngữ lập trình chun nghiệp được sử dụng
rộng rãi:
- C# là ngôn ngữ đơn giản :
Như ta đã biết thì ngơn ngữ C# dựng trên nền tảng C++ và Java nên ngôn ngữ C#
khá đơn giản. Nếu chúng ta thân thiện với C và C++ hoặc thậm chí là Java, chúng
ta sẽ thấy C# khá giống về diện mạo, cú pháp, biểu thức, toán tử và những chức
năng khác được lấy trực tiếp từ ngôn ngữ C và C++, nhưng nó đã được cải tiến để
làm cho ngơn ngữ đơn giản hơn. Một vài trong các sự cải tiến là loại bỏ các dư
thừa, hay là thêm vào những cú pháp thay đổi.
- C# là ngôn ngữ hiện đại:
Một vài khái niệm khá mới mẻ khá mơ hồ với các bạn vừa mới học lập trình, như
xử lý ngoại lệ, những kiểu dữ liệu mở rộng, bảo mật mã nguồn…v…v... Đây là
những đặc tính được cho là của một ngơn ngữ hiện đại cần có. Và C# chứa tất cả
các đặt tính ta vừa nêu trên.
- C# là một ngơn ngữ lập trình thuần hướng đối tượng:
Lập trình hướng đối tượng (tiếng Anh: Object-oriented programming, viết tắt:
OOP) là một phương pháp lập trình có 4 tính chất. Đó là tính trừu tượng

3


(abstraction), tính đóng gói (encapsulation), tính đa hình (polymorphism) và tính kế
thừa (inheritance). C# hỗ trợ cho chúng ta tất cả những đặc tính trên.

- C# là một kiểu ngơn ngữ ít từ khố:
C được sử dụng để mơ tả là ngơn ngữ sử dụng giới hạn những từ khóa (gồm
khoảng 80 từ khóa và mười mấy kiểu dữ liệu xây dựng sẵn). Nếu bạn nghĩ rằng
ngơn ngữ có càng nhiều từ khóa thì sẽ càng mạnh mẽ hơn. Điều này khơng phải sự
thật, lấy ví dụ ngơn ngữ C# làm điển hình nhé. Nếu bạn học sâu về C# bạn sẽ thấy
rằng ngơn ngữ này có thể được sử dụng để làm bất cứ nhiệm vụ nào.
Ngoài những đặc điểm trên thì cịn một số ưu điểm nổi bật của C#:
• C# có cấu trúc khá gần gũi với các ngơn ngữ lập trình truyền thống, nên cũng khá
dể dàng tiếp cận và học nhanh với C#.
• C# có thể biên dịch trên nhiều nền tảng máy tính khác nhau.
• C# được xây dựng trên nền tảng của C++ và Java nên nó được thừa hưởng những
ưu điểm của ngơn ngữ đó.
• C# là một phần của .NET Framework nên được sự chống lưng khá lớn đến từ bộ
phận này.
• C# có IDE Visual Studio cùng nhiều plug-in vơ cùng mạnh mẽ.

4


CHƯƠNG II. TỔNG QUAN VỀ THUẬT TỐN NHÁNH CẬN
Thuật tốn nhánh cận là phương pháp chủ yếu để giải các bài toán tối ưu tổ hợp.
Ta sẽ thực hiện việc đánh giá theo từng bước, nếu khơng có khả năng tìm thấy kết
quả tốt hơn thì sẽ cắt thành nhánh đó, khơng thực hiện tìm tiếp mà chuyển ngay
sang nhánh khác. Khi đó, chỉ ghi nhận các kết quả tốt hơn lúc ban đầu. Nghiệm
của bài toán sẽ tốt dần lên do khi tìm ra kết quả tốt hơn ta sẽ cập nhập lại giá trị
hiện thời của bài toán.
2.1.

Định nghĩa


Thuật tốn nhánh_và_cận là thuật tốn sử dụng tìm kiếm leo đồi với hàm đánh giá
f(u).
Trong thuật toán này, tại mỗi bước khi phát triển trạng thái u, thì ta sẽ chọn trạng
thái tốt nhất v (f(v) nhỏ nhất) trong số các trạng thái kề u đề phát triển ở bước sau.
Đi xuống cho tới khi gặp trạng thái v là đích, hoặc gặp trạng thái v khơng có đỉnh
kề, hoặc gặp trạng thái v mà f(v) lớn hơn độ dài đường đi tối ưu tạm thời, tức là
đường đi đầy đủ ngắn nhất trong số các đường đi đầy đủ mà ta đã tìm ra. Trong các
trường hợp này, ta khơng phát triển đỉnh v nữa, hay nói cách khác, ta cất đi các
nhánh cây xuất phát từ v, và quay lên cha của v đề tiếp tục đi xuống trạng thái tốt
nhất trong các trạng thái còn lại chưa được phát triển.
2.2.

Ví dụ về giải thuật

Ví dụ 1: Chúng ta lại xét khơng gian trạng thái trong hình 4.1. Phát triển đỉnh A, ta
nhận được các đỉnh con C, D, E và F, f(C) = 24, f(D) = 13, f(E) = 21, f(F) = 27.
Trong số này D là tốt nhất, phát triển D, sinh ra các đỉnh con H và E, f(H) = 25,
f(E) = 19. Đi xuống phát triển E, sinh ra các đỉnh con là K và I, f(K) = 17, f(I) = 18.
Đi xuống phát triển K sinh ra đỉnh B với f(B) = g(B) = 21. Đi xuống B, vì B là đỉnh
đích, vậy ta tìm được đường đi tối ưu tạm thời với độ dài 21. Từ B quay lên K, rồi
từ K quay lên cha nó là E. Từ E đi xuống J, f(J) = 18 nhỏ hơn độ dài đường đi tạm
thời (là 21). Phát triển I sinh ra các con K và B, f(K) = 25, f(B) = g(B) = 19. Đi
xuống đỉnh B, vì đỉnh B là đích ta tìm được đường đi đầy đủ mới với độ dài là 19
nhỏ hơn độ dài đường đi tối ưu tạm thời cũ (21). Vởy độ dài đường đi tối ưu tạm
thời bây giờ là 19. Bây giờ từ B ta lại quay lên các đỉnh còn lại chưa được phát
triển. Song các đỉnh này đều có giá trị hàm đánh giá lớn hơn 19, do đó khơng có
đỉnh nào được phát triển nữa. Như vậy, ta tìm được đường đi tối ưu với độ dài 19.
Cây tìm kiếm được biểu diễn trong hình sau:
5



Hình 2.2.1. Cây tìm kiếm thuật tốn nhánh – và – cận

Thuật toán nhánh_và_cận sẽ được biểu diễn bởi thủ tục Branch_and_Bound. Trong
thủ tục này, biến cost được dùng để lưu độ dài đường đi ngắn nhất. Giá trị ban đầu
của cost là số đủ lớn, hoặc độ dài của một đường đi đầy đủ mà ta đã biết.
Procedure Branch_and_Bound;
Begin
1. Khởi tạo danh sách L chỉ chứa trạng thái ban đầu; Gán giá trị ban đầu cho cost;
2. loop do
2.1. if L rỗng then stop;
2.2. Loại trạng thái u ở đầu danh sách L;
2.3. if u là trạng thái kết thúc then
if g(u) 2.4. if f(u) > cost then Quay lại 2.1;
2.5. for mỗi trạng thái v kề u do
{g(v) g(u) + k(u,v);
f(v) g(v) + h(v);
Đặt v vào danh sách L1};
2.6. Sắp xếp L1 theo thứ tự tăng của hàm f;
2.7. Chuyển L1 vào đầu danh sách L sao cho trạng thái ở đầu L1 trở thành ở đầu L;
End.
6


U0=A
T={H, J}
Áp dụng thuật toán nhánh cận đồ thị trên.

Giải:


Quá trình tìm kiếm thành cơng. Đường đi ngắn nhất từ A ->B->H, cost=4.

7


2.3.

Ứng dụng

Bài toán người du lịch.
Cho n thành phố và m tuyến đường nối giữa chúng. Một người du lịch xuất phát từ
một thành phố bất kì muốn đi tất cả các thành phố còn lại mỗi thành phố đúng 1 lần
và cuối cùng quay trở về thành phố ban đầu. Hãy chỉ ra cho người đó một hành
trình với qng đường ngắn nhất (chi phí ít nhất).
Thuật tốn.
Gọi A[nxn] là ma trận trọng số mô tả cho mạng lưới giao thơng trên trong đó a[i,j]
chính là khoảng cách trực tiếp từ thành phố i tới thành phố j, ta quy ước nếu khơng
có đường đi trực tiếp chi phí sẽ là +∞ và a[i,i]=0. Nghiệm của bài toán là hành trình
có dạng x1, x2, x3, … xn, xn+1=x1 .
Khởi tạo x1 chính là thành phố ban đầu (1) và khoảng cách ban đầu BEST=+∞, khi
đó để tìm x2 ta chỉ có thể chọn một trong các thành phố có đường đi trực tiếp tới
x1, với mỗi cách chọn x2 như vậy ta lại có một cách chọn x3 tương ứng... quá trình
trên cứ tiếp tục cho tới cấu hình cuối cùng, mỗi khi tới thành phố nào đánh dấu đã
thăm tới thành phố đó. Như vậy xi có thể chọn trong các thành phố chưa thăm và
có đường đi trực tiếp tới xi-1 với (1Kĩ thuật nhánh cận thể hiện ở chỗ, với mỗi bước thử chọn xi ta xem khoảng cách
tại thời điểm đó có nhỏ hơn khoảng cách của cấu hình tốt nhất ban đầu khơng? Nếu
khơng nhỏ hơn thì thử giá trị khác, đồng thời khi tới xn phải kiểm tra có về được x1
khơng, khoảng cách hiện tại lúc này phải bằng khoảng cách từ x1 đến xn cộng với

khoảng cách trực tiếp từ xn về thành phố x1 là (a[xn,x1]), nếu nhỏ hơn BEST thì
cập nhật lại BEST chính bằng khoảng cách hiện thời.
Kết thúc q trình đệ quy nếu BEST=+∞ điều đó có nghĩa là bài tốn vơ nghiệm
trái lại nghi nhận nghiệm bài tốn là hành trình x1, x2, x3, … xn, xn+1=x1.

Mơ phỏng thuật tốn
Gọi T[i] là khoảng cách từ thành phố ban đầu (1) tới thành phố i, T[1]= 0, dùng
mảng Free[j] để đánh dấu các đỉnh thăm hoặc chưa thăm j khởi tạo là true.

Procedure Branch(i);

8


begin
for j:=2 to n do if (free[j]) then
begin
x[i]:=j; T[i]:=T[i-1]+a[x[i-1],j];

if (T[i] < BEST) then
if (i=n) then
if (T[n] +a[x[n],x[1]]< BEST) then
begin;
BEST:= T[n] +a[x[n],x[1]];
end
else
begin
free[j]:=false;
Branch(i+1);
free[j]:=true;

end;
end;
end;
Người ta bắt đầu thử và công bố các kết quả giải bài tốn này trên máy tính từ năm
1954 (49 đỉnh), cho đến năm 2004 bài toán giải được với số đỉnh lên tới 24.978, và
dự báo sẽ còn tiếp tục tăng cao nữa.

9


2.4.

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

Trong trường hợp tệ nhất thuật toán đi theo hướng trở thành thuật toán vét cạn
những trong nhiều trường hợp cụ thể kỹ thuật đó cho phép rút ngắn được một cách
đáng kể quá trình tìm kiếm. Trong mục này ta trình bày những tư tưởng chinh của
giải thuật cận nhánh thông qua việc áp dụng nó vào giải quyết bài tốn người đi du
lịch.
Thuật toán trên chỉ là một trong các giải pháp áp dụng kĩ thuật nhánh cận, bạn đọc
có thể tìm cách đánh giá nhánh cận chặt hơn bằng một số tiêu chí khác. Ngồi ra
người ta có thể giải quyết bài tốn trên bằng thuật tốn tìm chu trình Hamilton
thơng qua bài toán người đưa thư Trung hoa bằng cách xây dựng tập các đỉnh lẻ và
xét các phân hoạch của chúng để tìm phân hoạch min. (bạn đọc tìm hiểu thêm
phương pháp giải bài toán người đưa thư Trung hoa trong lí thuyết đồ thị).
2.5.
using
using
using
using

using

Code demo
System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;

namespace NguoiDuLich2
{
class Program
{
int n; //Số thành phố
int [,]c; //Ma trận chi phí
int[] x; //Mảng các thành phố đã đi qua
int[] chuaxet; //Mảng lưu trữ các thành phố chưa đi qua
int[] kq; //Mảng lưu trữ đường đi với quãng đường là ngắn nhất
int MIN; //Biến lưu trữ khoảng cách ngắn nhất của đoạn đường
tìm được
int a; //Nếu a=1: Chưa có đường đi nào được tìm; a=0: Đã có
đường đi được tìm
//Khởi tạo dữ liệu cho các mảng
Program()
{
c = new int[100, 100];
x = new int[100];
chuaxet = new int[100];
kq = new int[100];
MIN = 0;

a = 1;

10


}
//Hàm nhập dữ liệu đầu vào
void Init()
{
Console.Write("Nhập số lượng thành phố: ");
n = int.Parse(Console.ReadLine());
Console.WriteLine("Nhập khoảng cách cho các cung đường: ");
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (c[i, j] == c[j, i] && c[i, j] != 0)
{
continue;
}
if (i != j)
{
Console.Write("Từ thành phố {0} đến thành phố
{1}: " , i, j);
c[i, j] = c[j, i] =
int.Parse(Console.ReadLine());
}
else
{
c[i, j] = 0;

}
}
}
x[1] = 1; //Đỉnh xuất phát là đỉnh 1
for (int i = 2; i <= n; i++) // danh dau tat ca cac thanh
pho deu chua xet
{
chuaxet[i] = 1;
}
}
void Out()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
Console.Write("{0} ", c[i, j]);
}
Console.WriteLine();
}

11


}
//Hàm hiển thị kết quả của thuật toán
void Result()
{
//Đỉnh đầu tiên
Console.Write("T1=>");

//Các đỉnh tiếp theo
for (int i = 2; i <= n; i++)
{
Console.Write("T{0}=>", kq[i]);
}
//Quay về đỉnh đầu
Console.WriteLine("T1");
//Khoảng cách của hành trình
Console.WriteLine("Quãng đường ngắn nhất là: {0}", MIN);
}
//Hàm tính tốn khoảng cách
void Work()
{
int S = 0; //Biến lưu giá trị nhánh cận
for (int i = 1; i <= n; i++)
{
S += c[x[i], x[i+1]];
}
S += c[x[n], 1];
if (S < MIN || a == 1)
{
a = 0;
MIN = S; //Gán khoảng cách nhánh cận bằng khoảng cách
hành trình
for (int i = 1; i <= n; i++)
{
kq[i] = x[i]; //Ghi nhớ và gán đỉnh đã xét vào kết
quả
}
}

}
//Hàm thực hiện các cách chọn x[i]
void Try(int i)
{
for (int j = 2; j <=n; j++)
{
//Nếu gặp thành phố chưa đi qua
if (chuaxet[j] == 1)

12


{
x[i] = j;
chuaxet[j] = 0;
if (i == n)
{
Work();
}
else
{
Try(i + 1);
}
chuaxet[j] = 1;
}
}
}
static void Main(string[] args)
{
Console.OutputEncoding = Encoding.UTF8;

Program program = new Program();
program.Init();
program.Out();
program.Try(2);
program.Result();
Console.ReadKey();
}
}
}

2.6.

Giao diện chương trình

13


KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
Đạt được:
Trong vài tuần tìm hiểu, nghiên cứu và làm báo cáo cho đề tài của nhóm: “Tìm
đường đi cho người du lịch sao cho quãng đường đi là ngắn nhất”. Bài báo cáo của
nhóm em được hoàn thành với những nội dung:
+ Tư tưởng, các bước thực hiện của các thuật toán nhánh cận
+ Cài đặt được chương trình chạy thuật tốn tìm kiểm theo chiều sâu bằng ngơn
ngữ C#.

Hạn chế:
- Chương trình cịn đơn giản.
- Mơ hình giao diện chương trình chưa có khả năng ứng dụng vào thực tế.


Hướng phát triển:
- Xây dựng giao diện chương trình có tính chun nghiệp hơn.

Đóng góp thành viên trong nhóm
Bảng phân cơng và kết quả đạt được của từng thành viên trong nhóm:
Thành viên

Cơng việc

Đánh giá kết quả

Lỷ Văn Cường

-Tìm hiểu thuật tốn
nhánh cận

Hồn thành

Nơng Thanh Thiên

- Tìm hiểu C#

Hồn thành

-Xây dựng chương trình
Lầu A Phong

- Tổng hợp viết báo cáo
- Làm Powerpoint thuyết
trình


14

Hồn thành



×