1. Trang chủ
  2. » Luận Văn - Báo Cáo

Báo cáo thực tập tốt nghiệp ngành công nghệ thông tin Đề tài chương trinh tim Đường Đi ngắn nhất

25 1 0
Tài liệu được quét OCR, nội dung có thể không chính xác
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Chương Trình Tìm Đường Đi Ngắn Nhất
Tác giả Nguyễn Gia Huy
Người hướng dẫn GVHD: Tran Uyộn Trang
Trường học Trường Đại Học Sư Phạm
Chuyên ngành Công Nghệ Thông Tin
Thể loại Báo Cáo Thực Tập Tốt Nghiệp
Năm xuất bản 04/2019
Thành phố Đà Nẵng
Định dạng
Số trang 25
Dung lượng 1,13 MB

Nội dung

Bài toán này có thể chia lam 2 loại: Tìm đường đi ngắn nhất giữa một cặp đỉnh: Cho đồ thị G1# có trọng số cạnh và hai đỉnh ø, w thuộc VY tim duong di ngắn nhất từ đỉnh z đến đỉnh v trên

Trang 1

DAI HQC DA NANG TRUONG DAI HOC SU PHAM

KHOA TIN HOC

Da Nang 04/2019

BAO CAO THUC TAP TOT NGHIEP

NGANH CONG NGHE THONG TIN

DE TAI:

CHUONG TRINH TIM DUONG DI NGAN NHAT

GVHD: Tran Uyén Trang SVTH: Nguyễn Gia Huy Lop: 17CNTT3

Trang 2

MO DAU

Bài toán tìm đường đi ngắn nhất là bài toán quan trọng trong Lý thuyết đồ thị, nó được áp dụng để giải quyết rất nhiều bài toán trong thực tế như điều khiến tối ưu, giao théng van tai, mang viễn thông

Bài toán này có thể chia lam 2 loại:

Tìm đường đi ngắn nhất giữa một cặp đỉnh: Cho đồ thị G(1#) có trọng số cạnh

và hai đỉnh ø, w thuộc VY tim duong di ngắn nhất từ đỉnh z đến đỉnh v trên đồ thi G Các giải thuật được phát triển để giải bài toán dạng nảy tiêu biểu là các giải thuật: Dijkstra, Bellman-Ford,

Tìm đường đi ngắn nhất giữa tất cả các cặp đỉnh: Cho đồ thị G(1#) có trọng số cạnh tìm đường ởi từ đỉnh z đến đỉnh v, với mọi cặp đỉnh ø„ v thuộc Ƒ Các giải thuật đã được phát triển đề giải bài toán này là: Floyd-Warshall, Johnson,

Trong thực tế nhiều khi ta không chỉ cần tìm đường đi ngắn nhất giữa hai đỉnh mả

còn cần xác định đường đi ngắn nhất giữa một tập đỉnh này đến một tập đỉnh khác Bài toán đó được phát biểu như sau: Cho dé thi G(KE) cé trong số cạnh và hai tập định A,B C V tìm đường đi ngắn nhất từ tập đỉnh A đến tập định B

Bài viết này nghiên cứu bài toán tìm đường đi ngắn nhất giữa hai tập đỉnh trên đồ

thị và đề xuất một số giải thuật hiệu quả để giải bài toán

Trang 3

NOI DUNG

1 Tìm đường đi ngắn nhất giữa một cặp đỉnh

Ld Dinh nghia Xét đồ thị có trọng số cạnh Œ = (1,E,w), với hàm trọng số ww:—› # là ánh xạ từ tập các cạnh # đến tập số thực R

Định nghĩa 1.1 Đường đi p từ đỉnh đến đỉnh v là đãy các cạnh nối tiếp nhau bắt đầu từ đỉnh z kết thúc tại đỉnh v Duong di p tr wu dén v được biểu điễn như sau: P=(U=VoV) , Ve=V)

Dinh nghia 1.2 D6 dai ctia dong di p =(voV1 ,Ve), ky hiệu øœÁp), là tông các trọng số của các cạnh trên đường đi:

k Ap) ~ WO, )

Có rất nhiều giải thuật đã được phát triển đề giải bài toán tìm đường đi ngắn nhất giữa một cặp đỉnh, trong khuôn khổ bài viết này chúng tôi chỉ xin giới thiệu giải thuật Dijkstra Giải thuật Dijkstra là một giải thuật dé giải bài toán đường đi ngắn nhất nguồn đơn trên một đồ thị có trọng số cạnh mà tất cả các trọng số đều không

âm Nó xác định đường đi ngắn nhất giữa hai đỉnh cho trước, từ đỉnh øz đến đỉnh 5

Ở mỗi đỉnh v, giải thuật Dijkstra xác định 3 thông tin: &,„ đ, và p,

k,: mang ø1â trị boolean xác định trạng thái được chọn của đỉnh v

Ban đầu ta khởi tạo tất cả các đỉnh v chưa được chọn, nghĩa là:

k, = false, Vv EV

đ,: là chiều đài đường đi mà ta tìm thấy cho đến thời điểm đang xét từ a dén v

Trang 4

Khoi tao: d, = ©, Vv € V \fa}, d,= 0

pv: la dinh trước của đỉnh v trên đường đi ngắn nhất tir a dén 5 Đường đi ngắn nhất tir a dén b c6 dang {a ,p.,v, ,.5} Khoi tạo, p, = null, Wwe V

Sau đây là các bước của giải thuật DiJkstra:

Giai thuat Dykstra la dung

2 Giải thuật tìm đường đi ngắn nhất giữa hai tập đỉnh

2.1 Định nghĩa Xét đồ thị có trọng số cạnh G=(V,E,w) với các tập đỉnh 41, B la các tập con khác rong cua V

Định nghia 2.1 Goi (4,8) la tap hop duong di giiia tat ca các cặp đỉnh của hai

tap dinh A va B Đường đi ngắn nhất giữa hai tap đỉnh 4 và B, ký hiệu p„„(44,), là

đường đi có độ dài:

œ(„„(4,B)) = mìn{œ({) | p S@CA B)}

0XP„(4,B)) gọi là khoảng cách giữa hai tập đỉnh 41 và B và ký hiệu là đ(41,Đ)

Luu y rang, neu AN B # @, thi đ(4,ð) = 0

2.2 Giải thuật

Cho dé thi G(VE,w) Cho :

- Ala tap cac dinh nguén

- B la tap cac dinh dich

Kí hiệu:

Alà đường đi ngắn nhất từ 44 đến B tai thoi diém dang xét

Trang 5

MA) : là độ dài đường đi ngắn nhất từ 44 đến B tai thời điểm đang xét

Đầu ra: acA, bcB, sao cho d(A,B) = d(a,b) nhỏ nhất, và p„n(A,B) =

Pmin(a,b)

BI Ta sắp xếp các phân tử của tích Đê-các A xB theo thứ tự nào

do AXB = {(U1,V1), (U2, V2), ., (Uk, Vi}

Đặt 2= AxB, A = @, AA) = too B2 Chọn (u,v) có chỉ số ¡ nhỏ nhất Đặt (u,v)=(u, v,) B3 Tìm đường đi ngắn nhất Pmin(u, Vv)

Néu d(u,v)<d(A), thì đặt d(A)= d(u,v), A = Pmin(u, Vv)

W= W— f(u,v)}

B4 Néuw- @, thi quay vé B2 Néu © = 0, thi kết thúc, p„a(A,B) = A, d(A,B) = d(A)

Ở giải thuật nay, dé tim được đường đi ngắn nhất giữa hai tập đỉnh ta phải tìm

đường đi ngắn nhất giữa œ Ø cặp đỉnh, ở đây a = |A| va B = |B| Trong thực tế khi

Trang 6

mà đồ thị Œ có số lượng đỉnh lớn và nếu các tập đỉnh nguồn và tập đỉnh đích có

nhiều đỉnh thì độ phức tạp của giải thuật này là œ/O(|1⁄2) (Ở đây giải thuật đề tìm

đường đi ngắn nhất giữa hai cặp đỉnh ở B3 là giải thuật Dijkstra với độ phức tạp Ó(/

3 Vy€„, đường đi từ a đến v trong 744 là đường đi ngắn nhất từ a đến v trong Ở

Ty = (Va„E) gọi là cây đường đi ngắn nhất cực đại nêu nó là cây đường đi ngắn nhất thoả:

Va =V

Với khái niệm cây đường di ngắn nhất ta có thể đưa ra một giải thuật khác hiệu qua hơn giải thuật l:

Trang 7

Giải thuật 2

Đầu vào: G(V,E) và 2 tập đỉnh A, B c V

Đầu ra: acA, bcB, sao cho d(A,B) = d(a,b) nhỏ nhất, và p„n(A,B) =

B3 Tim cây đường đi ngắn nhất T,u(V,„,E') cho đến khi Vụ ì B # @

hoặc T,y cực dai (Vay 0B = 2)

Néu VOB # @ thi

Chọn v = V¿¿ rì B

Xác định đường đi ngắn nhất p„u(u, v)

Nếu d(u,v) < d(A), thì đặt d(A) = d(u,v), A= Pmin(u,v)

Sang B4

Nếu Tụ là cực đại, thì sang B4

B4 A’=A’— {u}

Néu A’ # @, thi quay vé B2

Nếu A'= o, thì kết thúc, p„(A,B) = A, d(A,B) = d(A)

Độ phức tạp của giải thuật này là œO(|VJ? Cuối cùng chúng tôi xin đề xuất một

giải thuật khác hiệu quả hơn

Giải thuật 3

Dau vào: G(V,E) và 2 tập đỉnh A, B c V

Đầu ra: acA, beB, sao cho d(A,B) = d(a,b) nhỏ nhất, và p„m(A,B) =

Pmin(a,)

Trang 8

Test các giải thuật:

Chương trình đã xét đến các đồ thị có dạng sau với mỗi đỉnh được xác định bởi tọa

Trang 9

Với 100 đỉnh và 270 cạnh với hướng và trọng số được lựa chọn ngẫu nhiên từ 1 đến

9 và 20 đỉnh nguồn, 20 đỉnh đích cùng được lựa chọn ngẫu nhiên

Kết quả trung bình sau 100 lần chạy:

Giải thuật Thời gian

(ms)

Giải thuật Í 4854.581 Giải thuật 2 41.981 Giải thuật 3 37.657

Ma tran ké A=[i,j] > gia tri cua phan tử a[i][j] là độ dài từ i->j ,

> [Vậy nếu a[ï][I]E0 > gitta i va j không có cạnh nối nhau.]

Mark[i] = 1 : da chon (dinh 1 da được chọn vào cây T), Mark[IjF0: ngược lại

> [Mark la mang co n phan tu dung để đánh dấu một đỉnh ¡ đã được chọn vào cây

T hay chưa

pr[Il: đỉnh trước đỉnh ¡

(ví dụ: pr[6]=3 > đỉnh 3 là đỉnh trước khi tới đỉnh 6)

Trang 10

> [pr : (previous) là mảng có n phân tử dùng đề truy tìm ngược lại đỉnh trước(đỉnh cha) của một đỉnh nào đó]

d[ï]: giá trị của phan tur d[i] là độ dài đường đi nối từ s>¡ (s là đỉnh gốc)

> [d la mang c6 n phan tử, giá trị của phần tử thứ ¡ chính là độ đài của s->i]

- Mark[s]=1; =3 [chọn s là một đỉnh trong cây T, (s là đỉnh gốc)]

- đ=a[s|[il; > [lưu lại độ đài từ s đến tất cả đỉnh ¡ (lấy ra được từ ma trận kể) vào mảng d|

- pr[iJ=s; > [dinh s là đỉnh trước(đỉnh cha) của tat cả các đỉnh còn lại]

Với mọi đỉnh J mà Mark|J]=0

Nếu đ[k]~a[k][j] < d[j] thi d{j] = d{k}+a[k] fj];

prj] =k;

giải thích phần cập nhật:

Mark[k] = 1 >> [chọn đỉnh k vào cây T]

Mark[j]=0 > [chỉ chọn đỉnh j chưa được đánh dau (con nam ngoài cây T)]

Trang 11

d[k]+a[k][j] < d[j > [nếu khoảng cách từ s->j (tức là đ[j]) mà lớn hon khoảng cách từ s->k->j (tức là d[k]+a[k][j] ) thì chọn lại đường đi ngắn nhất từ s->j sẽ đi qua k (s->J->k)|

d[j] = d[k]+a[k][j] > [độ dài từ s->j (tức là d[j]) bằng với độ dài từ s->k (tức 1a d[k]) và từ k->j (tức là a[k][j])-]

pr[ï]=k > [đỉnh k là đỉnh trước khi tới j]

Thêm một thủ tục mô phỏng dễ hiểu hơn cho thuật toán này như sau:

Dijkstra(G, s) {

Khởi tạo tập S chỉ chứa đỉnh ban đầu s;

for (mỗi đỉnh v thuộc G) {

Div] = C(s, v); 1 C(s, v)=vô cùng nếu s và v không nối với nhau }

}

Thoi gian chay Thuật toán Dijkstra bình thường sẽ có độ phức tạp là O( n^2+m ) Tuy nhiên ta có thê sử dụng kết hợp với cầu trúc heap, khi đó độ phức tạp sẽ là O( (n+m)*log2(n) )

Trang 12

4 Kết luận

Qua bải báo này chúng tôi đã mở rộng bài toán tìm đường đi ngắn nhất giữa hai tập đỉnh từ đó đưa ra một số giải thuật dé giải quyết bài toán này, các giải thuật đã được cài đặt trên máy tính và được so sánh đánh øiá hiệu qua

Hướng phát triển tiếp theo cua dé tai nay là tiếp tục mở rộng vả phát triển bài toán

tìm đường đi ngắn nhất giữa hai tập đỉnh đồng thời dựa trên các giải thuật đã thiết

kế chúng tôi sẽ đưa ra một số giải thuật dé giải nhiều bài toán khác nhau cụ thể là các bài toán như:

- Bài toán tìm đường đi ngắn nhất với đa đỉnh nguồn, đa đỉnh đích

- Bài toán tìm đường kính giữa hai tập hợp đỉnh của đồ thị

LỜI GIẢI THEO YEU CAU CUA THAY

1.Ý tưởng:

Trang 13

> Ta sẽ xây dựng một cây phủ tối tiêu T từ một đỉnh s la dinh géc ctia cây

> Ở mỗi bước lặp: chọn một đỉnh ¡ ở ngoài cây T, sao cho đỉnh này nối được với cây, mà có đường đi tới gốc s là ngắn nhất Dừng lặp khi T đã đủ n đỉnh

> Vậy kết quả là cây T cuối cùng là cây phủ, có đỉnh gốc là s đi tới các đỉnh con lai bat ky la ngan nhất

da[u,v] € V, ma trận trong sô; Giả thiết: afu,b] 2 8, u,v € V;

Đầu ra: khoảng cách tù đỉnh s đên tất cả các đỉnh còn Lại d[v],v

€V */

Trang 14

Begin

Tim dinh u € T thoa maGn d[u] = min {d[z]:z € T};

T :=T\{u}; //cỗ định nhãn cua đỉnh u

1ƒ d[v]>d[u] +a[u,v] then

sử rằng sử rằng ở mỗi bước lặp nảo đó các nhãn cố định, ta sẽ chứng minh rằng ở lần lặp tiếp theo nếu đỉnh u* thu được nhãn cố định thì d(u*) chính

là độ dài đường đi ngắn nhất từ s đến u*

s* Ky hiéu S1 la tap các đỉnh có nhãn có định, S2 là tập các đỉnh có nhãn tạm thời ở bước lặp đang xét Kết thúc mỗi bước lặp nhãn tạm thời d(v) cho ta

độ dài của đường đi ngắn nhất từ s đến v chỉ qua những đỉnh nằm hoàn toàn trong tap S1

~ Gia su rang: duong di ngan nhat tir ul đến u* không nằm tong tập SI, tức

là nó đi qua ít nhất một dinh cua tap S2 Goi z € 82 la dinh dau tién như vậy

trên đường đi này Do trọng số trên các cung là không âm, nên đoạn đường

từ s đến u* có độ dai

L> 0 va d(z) < d(u*) - L< d(U*)

Trang 15

%_ Bất đẳng thức này mâu thuẫn với cách xác định đỉnh u* là đỉnh có nhãn

tmaj thời nhỏ nhất Vậy đường đi ngăn nhất từ s đến u* phải nằm trọn trong

tập S1, và vi thế d[u*] là độ dài của nó Do ở lần lặp đầu tiên S1={s} và sau

mỗi lần tặp ta chỉ thêm vào S1 một đỉnh u* nên gả thiết là đ(v) cho độ dài đường di ngắn nhất từ s đến v với mọi v € S1 là đúng với bước lặp đầu tiên Theo quy nạp suy ra thuât toán cho ta đường đi ngắn nhất từ s đến mọi đỉnh của đồ thị

*_ Kết luận: Thuật toán Dijkstra cho phép ta tìm được đường đi ngắn nhất từ đỉnh này đến đỉnh khác trong đồ thị

4 Mô phỏng thuật toán:

int Dijsktra::TT_Dijkstra(int a[][MAX],int n,int s)

{

int Mark[MAX],d[MAX], pr[MAX], k,min,dem;

//Khoi tao theo ly thuyet slide hoc cua cac ban for(int i=0;i<n;it++){

d [d la mang luu lai khoang cach tinh tu s]

}

d[s]=9; //khoang cach s->s la @ [d la mang luu lai khoang cach tỉnh tu s]

con lai vao cay T, [n-1: tru ra dinh s da dc chon roi]

Trang 16

for(int i=0;i<n;i++) //di tim dinh k,

if ((Mark[i]==0) && (d[i]<min)) { //ma k o ngoai cay T, sao cho d[k] la nho nhat

for (int j=0;j<n; j++) //Cap nhat lai gia tri

if ((Mark[j]==0) && (d[k]+a[k][j]<d[j]) && (a[k]

else { cout<<"\n\nduong di tu "<<s<<" -> "<<i<<" co do dai la: "<<d[i];

cout<<”"\nCac dinh di qua la : "3;

int mang[MAX];

dem=0;

int tam=pr[i];

while (tam!=s) { mang[dem]=tam;

tam=pr[tam];

dem++;

}

cout<<s<<" -> "5 ofile<<s<<” -> ";

for (int j=dem;j>0;j ) f{

cout<<mang[j-1]<<" -> "3 ofile<<mang[j-1]<<" -> "3

Trang 17

5 Độ phức tạp (theo lý thuyết):

> Nếu đồ thị có nhiều đỉnh, ít cạnh, ta có thể sử dụng danh sách kể kèm trọng

số đề biểu diễn đồ thị, tuy nhiên tốc độ của thuật toán DELJKSTRA vẫn khá chậm vì trong trường hợp xấu nhất, nó cần n lần cô định nhãn và mỗi lần tìm đỉnh dé cô định nhãn cần một đoạn chương trình với độ phức tạp O(n)

> Vay độ phức tạp của thuật toán DIJKSTRA là O(n')

> Để tăng tốc người ta thường sử dụng cấu trúc đữ liệu HEAP để lưu các đỉnh chưa cố định nhãn HEAP ở đây là một cây nhị phân hoàn chỉnh thỏa mãn: nếu u là đỉnh lưu ở nút cha thì v là đỉnh lưu của nút con thì đ[u] < d[v]

Trang 18

6 Code thực hiện nhập dữ liệu tir file: input.txt, két qua xuat ra file output.txt

void Dijsktra::Xuat_Matran(int a[][MAX],int n)

for(int i=@ ; i<n ; i++){

cout<<end1;

for(int j=0 ; j<n ; j++) cout<<"\t "<<a[i][J]<<” ”;

ofile<<"Cap cua ma tran vua duoc nap vao ”<«<n;

ofile<<"\nMa Tran vua duoc nap vao co hinh dang nhu sau ”<<endl;

for(int i=@ ; i<n ; i++)

ofile<<end1;

for(int j=0 ; j<n ; j++) ofile<<"\t "<<a[i][j]<<" "3

Ngày đăng: 11/12/2024, 09:52

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w