1. Giới thiệu bài tốn
Cho đơn đồ thị liên thơng, cĩ trọng số dƣơng G=(V,E). Bài tốn 1:
Tìm đƣờng đi ngắn nhất từ một đỉnh u đến mỗi đỉnh v của đồ thị G. Bài tốn 2:
2. Thuật tốn Dijkstra
Thuật tốn tìm đƣờng đi ngắn nhất từ đỉnh u đến mỗi đỉnh v của đồ thị G, đƣợc nhà tốn học ngƣời Hà Lan E. Dijkstra đề xuất vào năm 1959.
Thuật tốn thực hiện theo cách gán nhãn tại mỗi đỉnh. Thuật ngữ:
w(x,y) :trọng số dƣơng của cạnh (x,y);
w(x,y)là ∞ (vơ cùng lớn) nếu hai đỉnh khơng kề nhau. d(v) :độ dài đƣờng đi từ đỉnh xuất phát tới đỉnh v. p(v) :đỉnh đứng ngay trƣớc đỉnh v trên đƣờng đi từ đỉnh
xuất phát đến đỉnh v.
Nhãn của đỉnh v :gồm cặp (d(v), p(v))
T :Tập các nút mà đƣờng đi ngắn nhất đã đƣợc xác định. Gán T= ø; p(v) = NULL với mọi đỉnh v
d(a)=0; /* a là đỉnh xuất phát Với mỗi đỉnh v cịn lại thì d(v) = ∞;
Repeat
u =(uT | d(u) là bé nhất); T = T𝖴 {u};
for((v là đỉnh kề của u) và vT)
ifd(v) > d(u) + w(u,v)then d(v) = d(u) + w(u,v) p(v) = u
Until (T=V) Ví dụ :
Lập bảng để giải bài tốn tìm đƣờng đi ngắn nhất Nhận xét bảng kết quả đã thu đƣợc. 1/. Độ dài đƣờng đi ngắn nhất từ A đến các đỉnh là ->B: 1 ->C: 2 ->D: 6 ->E: 8 ->Z: 11 2/. Để vẽ đƣờng đi ngắn nhất từ A đến đỉnh Z, chúng ta sử dụng cách đi ngƣợc từ Z về A. Cụ thể làZ <- E <- D <- B <- A. 3/. Đƣờng đi ngắn nhất từ A đến Z khơng đi qua C. Vậy đƣờng đi ngắn nhất khơng đi qua tất cả các đỉnh của đồ thị.
3. Thuật tốn Floyd Giới thiệu
Để tìm đƣờng đi ngắn nhất giữa tất cả các cặp đỉnh của đồ thị G=(V,E), chúng ta sử dụng thuật tốn Floyd đƣợc cơng bố năm 1962.
Việc tìm đƣờng đi ngắn nhất dựa trên nguyên tắc sau:
" Nếu k là đỉnh nằm trên đƣờng đi ngắn nhất từ i đến j thì đoạn đƣờng từ i đến k và từ k đến j cũng ngắn nhất"
Ak[i,j]=min(Ak-1[i,j], Ak-1[i,k]+Ak-1[k,j]) BEGIN
for j := 1 to n do
begin D[i,j] := C[i,j] ; P[i,j] := 0 end ; for k := 1 to n do
for i := 1 to n do for j := 1 to n do
if D[i,k] + D[k,j] < D[i,j] then begin
D[i,j] := D[i,k] + D[k,j] ; P[i,j] := k
end END.
Xây dựng các hàm phục vụ cho việc tạo ma trận kề của đồ thị cần biễu diễn, gồm cĩ: • Nhập ma trận kề: Cho phép nhập thơng tin về đồ thị bằng tay gồm số đỉnh N,
các giá trị Ai,jcủa ma trận kề
• Đọc ma trận kề từ file: Cho phép nhập thơng tin về đồ thị từ file chứa các giá trị của ma trận kề gồm số đỉnh N, các giá trị Ai,j.
• Xuất ma trận kề: In thơng tin về đồ thị ở dạng ma trận kề gồm các giá trị Ai,j. Source code :
#define MaxV 20 //Define su dung cho so dinh cuc dai cua do thi int A[MaxV][MaxV]; //Ma tran ke
int V = 0; //So dinh cua do thi int ChuaXet[MaxV];
//Thu tuc nhap matran ke bang ban phim. void NhapMTKe(int A[][MaxV], int &V)
{
printf("Nhap V:"); scanf("%d", &V); for (int i=0; i<V; i++) { for (int j=0; j<V; j++) { printf("A[%d,%d] = ", i+1, j+1); scanf("%d", &(A[i][j])); } } }
// Xuat ket qua ma tran ke cua do thi ra man hinh. void XuatMTKe(int A[][MaxV], int V)
{
printf("\nMa tran ke:\n"); for (int i=0; i<V; i++) { for (int j=0; j<V; j++) printf("%3d ", A[i][j]); printf("\n"); } }
//Doc du lieu ma tran ke cua do thi da duoc tao thanh file text luu san tren dia. int DocMTKe(char *fileName, int A[][MaxV], int &V)
{
FILE *f = fopen(fileName, "rt"); if (f == NULL)
{
printf("Doc file loi !!!"); return 0;
}
fscanf(f, "%d", &V); for (int i=0; i<V; i++) { for (int j=0; j<V; j++) { fscanf(f, "%d", &(A[i][j])); } } return 1;}