(Giáo Trình) BTH5 - Các Bài Toán Về Đường Đi (TT)

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

Trường ĐH CNTP TP.

HCM
Khoa: CNTT BÀI 5
Bộ môn: Khoa học máy tính CÁC BÀI TOÁN VỀ ĐƯỜNG ĐI
TH CẤU TRÚC RỜI RẠC

A. MỤC TIÊU:
− Cài đặt thuật toán nhập đồ thị từ file
− Cài đặt thuật toán tìm đường đi ngắn nhất
− Các ứng dụng
B. TÓM TẮT LÝ THUYẾT
- Định nghĩa cây khung ngắn nhất:
Cho một đồ thị vô hướng G, trên mỗi cạnh của G được gán một trọng số c(i, j). Cây khung T
của G được gọi là cây khung ngắn nhất nếu tổng trọng số các cạnh của T là nhỏ nhất

- Thuật toán Prim tìm cây khung ngắn nhất


B1: Gọi T là tập chứa các cạnh của cây khung, T = .
S là tập chứa các đỉnh của cây khung, S = {x} (với x là đỉnh bất kỳ thuộc đồ thị)
B2: W(S) là tập các cạnh, sao cho mỗi cạnh chỉ có 1 đỉnh duy nhất x thuộc S.
Tìm cạnh (x,y) W(S) sao cho cạnh này có trọng số nhỏ nhất trong tập cạnh W(S).
T = T  (x,y); S = S  {y}
B3: Lặp lại bước 2 đến khi T có n-1 cạnh thì dừng
- Thuật toán Kruskal tìm cây khung ngắn nhất
Bước 1: Sắp các cạnh theo thứ tự tăng dần của trọng số, T =.
Bước 2: Lần lượt duyệt trong danh sách cạnh đã sắp xếp theo thứ tự trọng số từ nhỏ đến lớn,
chọn cạnh bổ sung vào tập T với điều kiện việc bổ sung này không tạo thành chu trình.
Bước 3: Tiếp tục thực hiện bước 2 cho đến khi T có n-1 cạnh thì dừng.
Minh họa thuật toán
 Sắp xếp cạnh theo thứ tự không giảm của trọng số

 Chọn cạnh bổ sung vào cây T sao cho khi thêm cạnh không tạo thành chu trình trong
cây T

Thuật toán Dijkstra


Ý tưởng:
Xác định tuần tự các đỉnh có khoảng cách đến u0 từ nhỏ đến lớn
 Trước tiên đỉnh có khoảng cách nhỏ nhất đến u0 là u0.
 Trong V\{u0} tìm đỉnh có khoảng cách đến u0 nhỏ nhất (đỉnh này phải là một trong các
đỉnh kề với u0) giả sử đó là u1
 Trong V\{ u0, u1} tìm đỉnh có khoảng cách đến u0 nhỏ nhất (đỉnh này phải là một trong các
đỉnh kề với u0 hoặc u1) giả sử đó là u2
 Tiếp tục như trên cho đến bao giờ tìm được khoảng cách từ u0 đến mọi đỉnh. Nếu G có n
đỉnh thì: 0 = d(u0, u0) < d(u0, u1) ≤ d(u0, u2) ≤ … ≤ d(u0, un-1)
Minh họa thuật toán
C. NỘI DUNG THỰC HÀNH
1. Bài tập mẫu
Bài tập 1: Cho đồ thị G có trọng số, liên thông gồm n đỉnh được đánh số từ 0 đến n-1. Viết thuật toán
tìm đường đi ngắn nhất giữa 2 đỉnh u, v của đồ thị (Áp dụng thuật toán Dijkstra)
Hiệu chỉnh thuật toán Prim để tính lại chi phí cho mảng nhãn của đỉnh

Viết hàm in đường đi giữa 2 đỉnh khi tinh được mảng nhãn chi phí các đỉnh

Bài tập 2: Cho đồ thị G có trọng số, liên thông gồm n đỉnh được đánh số từ 1 đến n. Hãy áp
dụng thuật toán Kruskal tìm cây khung nhỏ nhất tương ứng cho đồ thị G.
Yêu cầu thực hiện:
 Viết hàm đọc file nhập đồ thị, xuất đồ thị.
 Khai báo cấu trúc tập cạnh (tập cạnh là mảng 1 chiều, mỗi phần tử là 1 cạnh, 1 cạnh là một
cấu trúc gồm 3 thành phần, đỉnh đầu và đỉnh cuối, trọng số cạnh)
 Viết hàm tạo danh sách tập cạnh ban đầu (dựa vào ma trận A trong đồ thị g).
 Viết hàm in ds tập cạnh
 Viết hàm sắp xếp tập cạnh theo thứ tự không giảm của trọng số.
 Viết hàm kiểm tra 1 cạnh không tạo thành chu trình khi thêm vào cạnh đó vào tập cạnh
(cây T)
Viết hàm tìm cây khung ngắn nhất theo thuật toán Kruskal
Hướng dẫn:
Bước 1. Xây dựng hàm đọc file lưu trữ đồ thị

Bước 2. Xây dựng cấu trúc cạnh

 Viết hàm tạo danh sách tập cạnh ban đầu (dựa vào ma trận A trong đồ thị g).
 Viết hàm in ds tập cạnh
 Viết hàm sắp xếp tập cạnh theo thứ tự không giảm của trọng số.

Bước 3. Kiểm tra 1 cạnh không tạo thành chu trình khi thêm vào
Bước 4. Thuật toán Kruskal
void Kruskal(Graph g)
{
Tạo tập cạnh C có nC cạnh từ đồ thị g

Sắp xếp tập cạnh theo thứ tự trong số giảm dần

Khởi tạo mảng đánh dấu D

int dem=0;
for(int i=0; i<n_C; i++)
{
if(kt_chutrinh(C[i], D, g.n, socay)==1)
{
dem++;
Thêm cạnh c vào cây khung T
}
if(dem==g.n-1)
break;
}
}
Bài tập 3: Cho đồ thị G có trọng số, liên thông gồm n đỉnh được đánh số từ 0 đến n-1. Viết thuật toán
tìm đường đi giữa 2 đỉnh u, v bất kỳ.

Hướng dẫn:
Bước 1. Xây dựng hàm đọc file lưu trữ đồ thị
Bước 2. Xây dựng cấu trúc ngăn xếp Stack
- Cấu trúc Stack:

- Viết các hàm:


+ Tạo node (CreateNode)
+ InitStack
+ IsEmpty
+ Push
+ Pop
+ PrintfStack
Bước 3. Các hàm xây dựng đường đi
- Viết các hàm:
+ Khởi tạo mảng thăm: gán giá trị 0 (chưa thăm) cho tất cả các đỉnh
+ Khởi tạo mảng đường đi: gán – 1 (chưa xác định) cho tất cả các đỉnh
+ Tìm danh sách các đỉnh kề của đỉnh v (DSKe)
+ Tìm đường đi trong đồ thi g, bắt đầu từ đỉnh u đến v, lưu đường đi vào mảng D
int TimDuongDi (Graph g, int u, int v, int D[])
{

Khởi tạo stack


Khởi tạo mảng thăm
Khởi tạo mảng đường đi
test = 0;
Thêm đỉnh u (bắt đầu) vào Stack

while(Stack rỗng && test!=1) //chưa đến đỉnh cuối


{
Lấy đỉnh đầu Stack, gọi là u0
Đánh dấu thăm đỉnh u0
Tìm ds tập kê của đỉnh u0
for (Xét k lần lượt là đỉnh kề của u0 trong ds tập kề)
{

if(k chưa thăm)


{
Thêm k vào Stack
Đánh dấu đã thăm kk
Hiệu chỉnh u0 vao mang duong di tại đỉnh k
if(k là đỉnh cuối)
test=1;
}
}
}
//kiem tra dương di
if(v đã được thăm)
return 1; //có đường đi
}

You might also like