CHƯƠNG 2.THUẬT TOÁN GIẢI QUYẾT BÀI TOÁN - THUẬT TOÁN DIJKSTRA Thuật toán Dijkstra, mang tên của nhà khoa học máy tính người Hà Lan Edsger Dijkstra, là một thuật toán giải quyết bài toán
Trang 1CHƯƠNG 1: THIẾT KẾ GIAO DIỆN 3
1.1 Màn hình 3
1.2 Màn hình chính 4
CHƯƠNG 2.THUẬT TOÁN GIẢI QUYẾT BÀI TOÁN - THUẬT TOÁN DIJKSTRA 5
1 Bài toán 5
2 Cài đặt 5
3 Ví dụ 7
CHƯƠNG 3.MÔ TẢ CHUNG VÀ CODE 10
KẾT LUẬN 15
TÀI LIỆU THAM KHẢO 15
Trang 2LỜI NÓI ĐẦU
Trong đời sống, chúng ta thường gặp những tình huống như sau: để đi từ địa điểm A đến địa điểm B , có nhiều đường đi, nhiều cách đi; có lúc ta chọn đường đi ngắn nhất (theo nghĩa cự ly), có lúc lại cần chọn đường đi nhanh nhất (theo nghĩa thời gian) và có lúc phải cân nhắc để chọn đường đi rẻ tiền nhất (theo nghĩa chi phí), v.v
Trang 3CHƯƠNG I: THIẾT KẾ GIAO DIỆN
1 Màn hình :
Màn hình này dùng để nhập vào các thông tin cơ bản là :
- Load Map
- Open
-Start
-Reset
-About, Exit
Trang 41.2 Màn hình chính
Gồm phần hiển thị thành phố,Thông tin,Kết quả,các chức năng
Trang 5CHƯƠNG 2.THUẬT TOÁN GIẢI QUYẾT BÀI TOÁN - THUẬT TOÁN
DIJKSTRA
Thuật toán Dijkstra, mang tên của nhà khoa học máy tính người Hà Lan Edsger Dijkstra, là một thuật toán giải quyết bài toán đường đi ngắn nhất nguồn đơn trong một đồ thị có hướng không có cạnh mang trọng số âm
1/Bài toán:
Ta có thể giải bài toán bằng cách xác định một tập hợp S chứa các đỉnh mà khoảng cách ngắn nhất từ nó đến đỉnh nguồn v đã biết Khởi đầu S = { V } Sau đó tại mỗi bước ta sẽ thêm vào S các đỉnh mà khoảng cách từ nó đến v là ngắn nhất Với giả thiết rằng mỗi cung có một giá trị không âm thì ta luôn luôn tìm được một đường đi ngắn nhất như vậy mà chỉ đi qua các đỉnh đã tồn tại trong S Ðể dễ dàng chi tiết hóa giải thuật, giả sử G có n đỉnh và nhãn trên mỗi cung được lưu trong mảng C, tức là C[i, j] bằng giá trị(có thể xem là độ dài) của cung (i, j) Nếu i và j không có cung nối thì ta cho C[i, j] =Ġ Ta sẽ dùng một mảng D có n phần tử để lưu độ dài của đường đi ngắn nhất từ v đến mỗi đỉnh của đồ thị Khởi đầu thì giá trị này chính là độ dài cạnh (v, i), tức D[i] = C[v, i] Tại mỗi bước của giải thuật thì D[i] sẽ lưu độ dài đường đi ngắn nhất từ đỉnh v đến đỉnh i, đường đi này chỉ đi qua các đỉnh đã có trong S
2/Cài đặt:
Ðể cài đặt giải thuật dễ dàng, ta giả sử các đỉnh của đồ thị được đánh số từ 1 đến n
và đỉnh nguồn là đỉnh
Trang 6procedure Dijkstra;
begin
S := [1] ; { S chỉ chứa đỉnh nguồn }
for i:=2 to n do
D[i] := C[1, i] ; { Khởi đầu các giá trị cho D }
for i:=1 to n - 1 do
begin
Lấy đỉnh w trong V - S sao cho D[w] là nhỏ nhất ;
Thêm w vào S ;
for mỗi đỉnh u thuộc V - S do
D[u] := Min (D[u], D[w] + C[w, u]) ;
end;
end;
<! [if !supportLineBreakNewLine] >
<! [endif] >
Nếu muốn lưu trữ lại các đỉnh trên đường đi ngắn nhất để có thể xây dựng lại đường đi này từ đỉnh nguồn đến các đỉnh khác, ta dùng một mảng P Mảng này sẽ lưu P[u] = w với đỉnh u là đỉnh trước của đỉnh w trên đường đi ngắn nhất Lúc khởi đầu ta cho P[u] = 1, với mọi u khác 1
Giải thuật Dijkstra ở trên sẽ được viết lại như sau :
<! [if !supportLineBreakNewLine] >
<! [endif] >
Trang 7procedure Dijkstra ;
begin
S := [1] ; { S chỉ chứa đỉnh nguồn }
for i:=2 to n do
begin
D[i] := C[1, i] ; { Khởi đầu các giá trị cho D }
P[i] := 1 ; { Khởi đầu các giá trị cho P }
end ;
for i:=1 to n - 1 do
begin
Lấy đỉnh w trong V - S sao cho D[w] là nhỏ nhất ;
Thêm w vào S ;
for mỗi đỉnh u thuộc V - S do
if (D[w] + C[w, u] < D [u]) then
begin
D[u] := D[w] + C[w, u] ; P[u] := w ;
end ;
end;
end;
3/Ví dụ :
Trang 8Áp dụng giải thuật Dijkstra cho đồ thị hình sau:
<! [if !supportLineBreakNewLine] >
Trang 9procedure DijksTra;
begin
t:=false;
t[u0]:=true;
d[i]:=c[u0,i];{Neu khong co duong di thi d[i]=i’}
k:=1;{Da ket nap duoc 1 dinh}
while kdo
begin
{Tim min}
min:=i’;
for i:=1 to n do
if (d[i]<MIN)and(not t[i])then
begin
u:=i;
min:=d[u]
end;
t[u]:=true;{thêm u vao tập đỉnh}
inc(k);
{Tính lại đường đi}
for i:=1 to n do
if d[i]>d[u]+c[u,i] then
if not((d[i]=i’)and(d[u]=i’)and(c[u,i]=i’)) then
begin
d[i]:=d[u]+c[u,i];
truoc[i]:=u
Trang 10end;
if d[v0]=i’ then
KhongCoDuongDi
else
QuayLaiMangTruocDeTimDuong
end;
Chương 3: Mô tả chung và code:
1.1 Mô tả chung và kí hiệu:
Ký hiệu dùng trong giải thuật Dijkstra
Tập đỉnh đã được sắp thứ tự 0… n-1 , (có n đỉnh), với s là đỉnh gốc
giá trị của phần tử a[i][j] là độ dài từ i-◊Ma trận kề A=[i,j] >j , [Vậy nếu
a[i][j]=0, giữa i và j không có cạnh nối nhau]
Mark[i] = 1 : đã chọn (đỉnh i đã được chọn vào cây T), Mark[i]=0:
ngược lại, [Mark là mảng có n phần tử dùng để đánh dấu một đỉnh i đã
được chọn vào cây T hay chưa]
pr[i]: đỉnh trước đỉnh i (ví dụ: pr[6]=3, đỉnh 3 là đỉnh trước khi tới đỉnh
6), [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[i]: giá trị của phần tử d[i] là độ dài đường đi nối từ s->i (s là đỉnh
Trang 11Ta sẽ xây dựng một cây phủ tối tiểu T từ một đỉnh s là đỉnh gốc của
cây
Ở mỗi bước lặp: chọn một đỉnh i ở 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 còn lại bất kỳ là ngắn nhất
Thủ tục
Khởi tạo:
Gốc s; d=vocuc; d[s]=0
Mark=0;
Mark[s]=1; [chọn s là một đỉnh trong cây T, (s là đỉnh gốc)]
d=a[s][i]; [lưu lại độ dài từ s đến tất cả đỉnh i (lấy ra được từ ma trận
kề) vào mảng d]
pr[i]=s; [đỉnh s là đỉnh trước(đỉnh cha) của tất cả các đỉnh còn lại]
Ở mỗi bước lặp trong thuật toán Dijkstra
1) Tìm k: d[k] = min {d[j]: Mark[j] =0 }, [k là đỉnh được chọn từ tất cả các đỉnh j nằm ngoài cây T (tức là Mark[j]=0), sao cho khoảng cách từ s->k (tức là d[k]) là nhỏ nhất so với các khoảng cách từ s->j (tức là d[j]) ]
2) Cập nhật:
Mark[k] = 1;
Với mọi đỉnh j mà Mark[j]=0
Trang 12Nếu d[k]+a[k][j] < d[j] thì
d[j] = d[k]+a[k][j];
pr[j] = 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 dấu (còn nằm ngoài cây T)
]
d[k]+a[k][j] < d[j], [nếu khoảng cách từ s->j (tức là d[j]) mà lớn hơn
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
là d[k]) và từ k->j (tức là a[k][j]).]
pr[j]=k, [đỉnh k là đỉnh trước khi tới j]
K T LU N ẾT LUẬN ẬN
Bài báo cáo của em đã cố gắng tổng hợp đầy đủ những nội dung cơ bản liên quan đến đề tài ” Tìm đường đi ngắn nhất bằng phương pháp Dijikstra”
Xin chân thành cảm ơn!