3.3.1. Phân tích
Dùng ma trận kềđể biểu diễn đồ thị C= (cij), cij = trọng số của cung (i,j), cij = + ∞ nếu không có cung (i,j). Một mảng d[] dùng đểghi các độ dài đường đi ngắn nhất từ s tới đỉnh i đang có. Xuất phát d[s] =0 và d[i] =csi nếu i kề s, d[j] = + ∞ nếu j không kề s.
3.3.2. Giải thuật tìm đường đi ngắn nhất giữa một cặp đỉnh
Định nghĩa 1. Xét đồ thị có trọng số cạnh G = (V,E,w), với hàm trọng số w: E→R là ánh xạ từ tập các cạnh E đến tập số thực R.
Định nghĩa 2. Đường đi p từ đỉnh u đến đỉnh v là dãy các cạnh nối tiếp nhau bắt đầu từ đỉnh u kết thúc tại đỉnh v. Đường đi p từ u đến v được biểu diễn như sau:
p=(u=v0,v1…,vk=v).
Định nghĩa 3. Độ dài của đường đi p = ( v0,v1,...,vk), ký hiệu: ω(p), là tổng các trọng số của các cạnh trên đường đi.
ω(p) = ∑ = − k i i i v v w 1 1, ) (
Định nghĩa 4. Gọi ℘(u,v) là tập tất cả đường đi từ u đến v. Độ dài đường đi ngắn nhấttừ đỉnh u đến đỉnh v được xác định bởi:
d(u,v) = min{ω(p)| p∈℘(u,v)}
Định nghĩa 5. Đường đi ngắn nhất pmin(u,v) từđỉnh u đến đỉnh v là đường đi có độ dài d(u,v).
3.3.3. Thuật toán Dijkstra 3.3.3.1. Các bước thực hiện 3.3.3.1. Các bước thực hiện
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 luận vănnày em chỉ xin giới thiệu giải thuật Dijkstra.
65
Giải thuật Dijkstra là một giải thuật để 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 a đến đỉnh b.
Ở mỗi đỉnh v, giải thuật Dijkstra xác định 3 thông tin: kv, dv và pv.
Trong đó:
+) kv: mang giá 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à:
kv = false, ∀ v ∈ V.
+) dv: là chiều dài đường đi mà ta tìm thấy cho đến thời điểm đang xét từ a đến v.
Khởi tạo dv = ∞, ∀v ∈ V \{a}, da = 0.
+) pv: là đỉnh trước của đỉnh v trên đường đi ngắn nhất từ a đến b. Đường đi ngắn nhất từ a đến b có dạng {a,...,pv,v,...,b}. Khởi tạo, pv = null, ∀v∈ V.
Sau đây là các bước của giải thuật Dijkstra:
Bước 1. Khởi tạo: Đặt kv:= false ∀v ∈ V; dv:=∞, ∀v ∈ V \ {a}, da:=0.
Bước 2. Chọn v ∈ V sao cho kv = false và dv = min {dt / t∈ V, kt = false}
Nếu dv = ∞ thì kết thúc, không tồn tại đường đi từ a đến b.
Bước 3. Đánh dấu đỉnh v, kv:= true.
Bước 4. Nếu v = b thì kết thúc và db là độ dài đường đi ngắn nhất từ a đến b.
Ngược lại nếu v ≠ b sang B5.
Bước 5. Với mỗi đỉnh u kề với v mà ku = false, kiểm tra Nếu du> dv + w(v,u) thì du:= dv + w(v,u)
66
3.3.3.2. Độ phức tạp của giải thuật Dijkstraa) Trường hợp sử dụng ma trận kề a) Trường hợp sử dụng ma trận kề
Gọi f(n) là số lần giải thuật Dijkstra khảo sát một cạnh của đồ thị G trong
trường hợp xấu nhất. Khi đó ta có:
f(n) < O(|V|2)
Chứng minh: Cho n = |V|, Bước 5 là vòng lặp chứa các bước Bước 2 →
Bước 5, vòng lặp được thực hiện đến khi v = b. Vì ở mỗi vòng lặp ta rút ra một đỉnh của V và khởi đầu V có n phần tử nên vòng lặp được xử lý nhiều nhất là n lần.
Ở Bước 2 số đỉnh tối đa được khảo sát là n - 1 đỉnh Ở Bước 5 số đỉnh kề tối đa được khảo sát là n -1 đỉnh Do đó: f(n) ≤ 2(n-1)n < O(|V|2)
Vậy độ phức tạp của giải thuật Dijkstra là O(|V|2).
b) Trường hợp sử dụng danh sách kề
Độ phức tạp của giải thuật Dijkstra là O((|V| + |E|)lg|V|).
67
Hình 3.11. Lưu đồ thuật toán Dijkstra
Đ Begin n, C = (cij), a, z L(a) = 0 L(v) = ∞∀v ≠ a T(i) 1 ∀i ≤ z ∈T
Chọn v∈ T sao cho L[v] đạt min T = T \ {v} L(x) = min(L(x), L(v) + c(v,x)) End S Đ S L(z) x∈ T& kề v
68
3.3.3.4. Ví dụ thực hiện thuật toánTa có đồ thịnhư sau: Ta có đồ thịnhư sau: 2 Tìm đường đi ngắn nhất từđỉnh a đến đỉnh d. Giải: Ta có điểm xuất phát là V = a. Từđồ thị ta có ma trận như sau: 6 0 4 2 0 0 0 4 0 1 5 0 0 2 1 0 8 10 0 0 5 8 0 2 6 0 0 10 2 0 3 0 0 0 6 3 0
Lập bảng tính toán theo thuật toán Dijkstra ta có như sau:
TT V T a b e c f d 0 0 ∞ ∞ ∞ ∞ ∞ 1 a bcdef - 4 2* ∞ ∞ ∞ 2 e bcfd - 3* - 10 12 ∞ 3 b cfd - - - 8* 12 ∞ a b 5 c 4 6 d 1 8 2 10 3 f e
69
4 c fd - - - - 10* 14
5 f d - - - - - 13*
6 d - - - - - -
Vậy đường đi ngắn nhất từđỉnh ađỉnh f có độ dài là 13.
Cách vẽđường đi:
Nhìn vào bảng trên ta thấy: Trước đỉnh d phải ở đỉnh f; trước đỉnh f phải ở đỉnh c; trước đỉnh c phải ở đỉnh b; trước đỉnh b phải ở đỉnh e; trước đỉnh e phải ở đỉnh a.
2 1 5 2 3
3.4. Cài đặt thuật toán
3.4.1. Thiết kế dữ liệu mô tảđồ thị- Tạo bảng chứa các node của đồ thị: - Tạo bảng chứa các node của đồ thị:
Tên dữ liệu Kiểu dữ liệu Diễn giải
NodeID int Khóa chính của bảng
NodeName int Tên của node trong đồ thị
Cost int Số đỉnh
PathID int Khóa đường đi của đồ thị
Calculated tinyint
70
- Tạo bảng chứa đường đi của đồ thị:
Tên dữ liệu Kiểu dữ liệu Diễn giải
PathID Int Khóa chính của bảng
FromNodeID Int Khóa phụ của bảng (từ đỉnh)
ToNodeID Int Đến đỉnh kế tiếp
Cost Int Giá trị của đường đi
3.4.2. Thủ tục tạo bảng chứa các node của đồ thị
3.4.3. Thủ tục tạo bảng chứa đường đi ngắn nhất trên đồ thị
3.4.4. Chương trình tìm đường đi ngắn nhất trên đồ thị
CREATEPROCEDURE dbo.uspDijkstraResolve
71 @FromNodeName VARCHAR(20), @ToNodeName VARCHAR(20) ) AS SETNOCOUNTON
EXEC dbo.uspDijkstraClearMap
DECLARE @FromNodeID INT,
@ToNodeID INT,
@NodeID INT,
@Cost INT,
@PathID INT
SELECT @FromNodeID = NodeID,
@NodeID = NodeID
FROM Nodes
WHERE NodeName = @FromNodeName
IF @FromNodeID ISNULL
BEGIN
72
RAISERROR ('From node name ''%s'' can not be found.', 16, 1,@FromNodeName)
RETURN END
SELECT @ToNodeID = NodeID
FROM Nodes
WHERE NodeName = @ToNodeName
IF @ToNodeID ISNULL
BEGIN
SELECT @ToNodeName =ISNULL(@ToNodeName,'')
RAISERROR ('To node name ''%s'' can not be found.', 16, 1, @ToNodeName)
RETURN END
--====================== UPDATE Nodes
SET Cost = 0
WHERE NodeID = @FromNodeID
WHILE @NodeID ISNOTNULL
BEGIN
UPDATE ToNodes
73
WHEN ToNodes.Cost ISNULLTHEN FromNodes.Cost + Paths.Cost
WHEN FromNodes.Cost + Paths.Cost < ToNodes.Cost THEN FromNodes.Cost +
Paths.Cost
ELSE ToNodes.Cost
END,
ToNodes.PathID = Paths.PathID
FROM Nodes AS FromNodes
INNERJOIN Paths ON
Paths.FromNodeID = FromNodes.NodeID
INNERJOIN Nodes AS ToNodes ON
ToNodes.NodeID = Paths.ToNodeID
WHERE FromNodes.NodeID = @NodeID
AND(ToNodes.Cost ISNULLOR
FromNodes.Cost + Paths.Cost < ToNodes.Cost) AND ToNodes.Calculated = 0
UPDATE FromNodes
SET FromNodes.Calculated = 1
FROM Nodes AS FromNodes
WHERE FromNodes.NodeID = @NodeID
74
SELECTTOP 1 @NodeID = Nodes.NodeID
FROM Nodes
WHERE Nodes.Calculated = 0
AND Nodes.Cost ISNOTNULL
ORDERBY Nodes.Cost
END CREATETABLE #Map ( RowID INTIDENTITY(-1,-1), FromNodeName VARCHAR(20), ToNodeName VARCHAR(20), Cost INT )
IFEXISTS(SELECTNULLFROM Nodes WHERE NodeID = @ToNodeID AND
Cost ISNULL) BEGIN SELECT FromNodeName, ToNodeName, Cost FROM #Map DROPTABLE #Map RETURN
75
END
WHILE @FromNodeID <> @ToNodeID
BEGIN
SELECT @FromNodeName = FromNodes.NodeName,
@ToNodeName = ToNodes.NodeName,
@Cost = ToNodes.Cost,
@PathID = ToNodes.PathID
FROM Nodes AS ToNodes
INNERJOIN Paths ON Paths.PathID = ToNodes.PathID
INNERJOIN Nodes AS FromNodes ON
FromNodes.NodeID = Paths.FromNodeID
WHERE ToNodes.NodeID = @ToNodeID
INSERT #Map ( FromNodeName, ToNodeName, Cost ) VALUES ( @FromNodeName, @ToNodeName, @Cost
76
SELECT @ToNodeID = Paths.FromNodeID
FROM Paths
WHERE Paths.PathID = @PathID
END SELECT FromNodeName, ToNodeName, Cost FROM #Map ORDERBY RowID DROPTABLE #Map GO
77
KẾT LUẬN
Các kết quảđạt được của luận văn:
- Trình bày được tổng quan về Cơ sở dữ liệu quan hệ, về mục đích và vai trò của ngôn ngữ SQL, cách vấn tin bằng ngôn ngữ SQL.
- Tìm hiểu về ma trận, các phép toán trên ma trận; Trình bày các thuật toán thực hiện các phép toán trên ma trận: cộng hai ma trận, nhân hai ma trận, nhân ma trận với một số, ma trận chuyển vị.
- Tìm hiểu vềđồ thị và thuật toán tìm đường đi ngắn nhất trên đồ thị.
- Sử dụng Hệ quản trị Cơ sở dữ liệu SQL Server 2008 để viết các chương trình thực hiện các phép toán trên ma trận và tìm đường đi ngắn nhất trên đồ thị.
- Tích lũy được những kiến thức thực tế phụ giúp cho công việc trong chuyên ngành công tác, tạo nền tảng cho việc nghiên cứu chuyên sâu về ngôn ngữ SQL cũng như mở ra cho bản thân một hướng đi mới.
Hướng nghiên cứu tiếp theo:
- Tiếp tục tìm hiểu các thuật toán tối ưu hơn.
- Xây dựng chương trình để biểu diễn đồ thị trong máy tính, bài toán cây và bài toán cây khung có trọng số nhỏ nhất.
Do thời gian và khả năng có hạn, luận văn còn thiếu sót nhiều, em rất mong nhận được sự góp ý, chỉ dẫn thêm của các thầy cô, bạn bè để em có thể xây dựng được ứng dụng hoàn thiện hơn. Một lần nữa em xin chân thành cảm ơn cô giáo Tiến sĩ Nguyễn Thị Thanh Huyền cùng các thầy, cô trong Viện Toán ứng dụng và Tin học đã tạo mọi điều kiện thuận lợi nhất để em có thể hoàn thành tốt luận văn.
78
TÀI LIỆU THAM KHẢO
[1]. Hồ Thuần, Hồ Cẩm Hà, Các hệ cơ sở dữ liệu Lí thuyết & Thực hành, NXBGD, 2004.
[2]. Tô Văn Nam, Giáo trình cơ sở dữ liệu, NXBGD, 2009.
[3]. Hồ Thuần, Hồ Cẩm Hà, Trần Thiên Thanh, Cấu trúc dữ liệu, Phân tích thuật toán và phát triển phần mềm, NXBGD, 2004.
[4]. Phạm Hữu Khang, Phương Lan, Microsoft SQL Server 2008 Quản trị cơ sở dữ liệu, NXBLĐ-XH, 2009
[5]. Nguyễn Đức Nghĩa, Nguyễn Tô Thành, Toán rời rạc, NXB Giáo Dục. [6]. Bùi Minh Trí, Giáo trình Toán ứng dụng trong tin học, NXBGD, 2011. [7]. http://www.idoc.vn/tai-lieu/