Tìm hiểu thuật toán DIJKSTRA

Một phần của tài liệu Ứng dụng ngôn ngữ sql trong tính toán khoa học và giảng dạy (Trang 73)

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úcdb 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/

Một phần của tài liệu Ứng dụng ngôn ngữ sql trong tính toán khoa học và giảng dạy (Trang 73)

Tải bản đầy đủ (PDF)

(87 trang)