Đồ thị (graph)
• G = (V, E)
– V: Tập đỉnh
– E = { (u,v) | u, v ∈ V}: Tập cạnh
Ví dụ: Biểu diễn bản đồ đường đi trong thành phố bằng đồ thị G = (V, E)
– V: Tập hợp các điểm trong thành phố
– E: Tập hợp các đường đi trong thành phố, mỗi đường đi nối hai điểm
14 trang |
Chia sẻ: anhquan78 | Lượt xem: 740 | Lượt tải: 0
Bạn đang xem nội dung tài liệu Toán học - Đồ thị (Graph 2), để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Đồ thị
(Graph 2)
Lê Sỹ Vinh
Bộ môn Khoa Học Máy Tính – Khoa CNTT
Đại Học Công Nghệ - ĐHQGHN
Email: vinhbio@gmail.com
Đồ thị (graph)
• G = (V, E)
– V: Tập đỉnh
– E = { (u,v) | u, v ∈ V}: Tập cạnh
Ví dụ: Biểu diễn bản đồ đường đi trong thành phố bằng đồ thị G = (V, E)
– V: Tập hợp các điểm trong thành phố
– E: Tập hợp các đường đi trong thành phố, mỗi đường đi nối hai điểm
Đi qua đồ thị theo chiều rộng
(Breadth first search)
• Đi qua tất cả các đỉnh của đồ thị, mỗi đỉnh đúng một lần
• Bắt đầu xuất phát từ một đỉnh s, lần lượt thăm các đỉnh liền kề với s. Tiếp
tục quá trình thăm các đỉnh theo nguyên tắc: Đỉnh nào được thăm trước
thì các đỉnh liền kề với đỉnh đó sẽ được thăm trước
• Xem ví dụ
Đi qua đồ thị theo chiều sâu
(Depth first search)
//Đi qua đồ thị theo chiều sâu xuất phát từ v
DepthFirstSearch (v) {
for (mỗi đỉnh u kề với v)
if (u chưa được thăm) {
thăm u và đánh dấu u đã được thăm
DepthFirstSearch (u)
}
}
Xem ví dụ
Sắp xếp topo
Cho đồ thị có hướng nhưng không có chu trình G = (V, E)
(Directed acylic graph / DAG)
Sắp xếp các đỉnh của đồ thị G thành một danh sách sao cho nếu có cung
(u,v) ∈ E, thì đỉnh u phải đứng trước đỉnh v.
G A B C F E D
Sắp xếp topo
TopoSort (u) {
for (mỗi đỉnh v kề u)
if ( v chưa thăm)
TopoSort(v);
Xen u vào đầu danh sách T;
Đánh dấu u đã thăm;
}
//Sắp xếp các đỉnh của đồ thị định hướng
//không có chu trình G =(V,E) thành danh sách topo.
TopoSortGraph(G) {
for (mỗi đỉnh u ∈ V)
Đánh dấu u chưa được thăm;
Khởi tạo danh sách topo T rỗng;
for (mỗi đỉnh u ∈ V)
if (u chưa thăm)
TopoSort (u);
}
Đường đi giữa hai điểm
Cho đồ thị G = (V, E)
Giữa hai đỉnh (x0, xk) có đường đi, nếu tồn tại (x1,,xk-1 ) thỏa mãn
(xi, xi+1) ∈ E, ∀i = 0(k-1)
Đồ thị liên thông
(Connected graph)
Cho đồ thị G = (V, E), G được gọi là liên thông nếu tồn tại đường đi giữa hai
đỉnh bất kì của đồ thị
Tìm tất cả các thành phần liên thông
Cho đồ thị G = (V, E), tìm tất cả các thành phần liên thông của đồ thị. Đỉnh i
của đồ thị được gán nhãn ci cho biết thuộc miền liên thông ci.
Tìm các thành phần liên thông
//Đi qua đồ thị theo bề rộng xuất phát từ v
FindConnectedComponent (v, ci) {
(1) Khởi tạo hàng đợi Q rỗng;
(2) Xen v vào hàng đợi Q;
(3) Đánh dấu đỉnh v đã được thăm, và gán nhãn v bằng ci
(4) while (hàng đợi Q không rỗng) {
(5) Lấy đỉnh w ở đầu hàng đợi Q;
(6) for (mỗi đỉnh u kề w)
(7) if ( u chưa được thăm) {
(8) Xen u vào đuôi hàng đợi Q;
(9) Đánh dấu u đã được thăm, và gán nhãn u bằng ci
}
(10) Loại w ra khỏi hàng đợi Q
} // hết vòng lặp while.
}
Tìm các thành phần liên thông
// Tìm các thành phần liên thông của đồ thị G=(V, E)
FindAllConnectedComponent (G) {
(10) for (mỗi v ∈V)
(11) Đánh dấu v chưa được thăm;
(12) ci = 0;
(13) for (mỗi v ∈V)
(14) if (v chưa được thăm) {
(15) FindConnectedComponent(v, ci);
(16) ci = ci + 1
}
}
Đường đi ngắn nhất
Cho đồ thị G=(V, E), cạnh (u, v) ∈ E có độ dài weight (u,v) > 0. Tìm đường
đi ngắn nhất từ đỉnh s đến đỉnh e
Tư tưởng thuật toán Dijkstra (thuật toán gán nhãn)
dist[v] = Khoảng cách đường đi ngắn nhất từ s đến v
pre[v] = u: Đỉnh liền phía trước trên đường đi ngắn nhất từ s đến v
Gán nhãn (sửa nhãn):
Nếu
dist[u] + weight (u, v) < dist [v]
thì
dist [v] = dist[u] + weight (u, v)
pre[v] = u
s →→ u → v
Thuật toán Dijkstra
Known = {tập hợp các đỉnh đã xác định được đường đi ngắn nhất từ s đến}
Unknown = {tập hợp các đỉnh chưa xác định được đường đi ngắn nhất từ s đến}
Tiến hành quá trình lặp, tại bước i tìm đỉnh u ∈ unknown có khoảng cách nhỏ nhất.
if u = e then
kết thúc
else {
known = known ∪ {u}
unknown = unknown – {u}
Dùng u để sửa nhãn cho các đỉnh thuộc tập unknown
tiến hành bước thứ (i + 1)
}
Dijkstra Algorithm {
Known = {s};
Unknown = {E} – {s}
for v ∈ unknown {
dist[v] = weight [s, v];
pre[v] = s;
}
u = s; // at the first step
while (u != e ){
chọn u sao cho dist[u] = min {dist[x] | x ∈ unknown}
Known = Known ∪ {u}
Unknown = Unknown – {u}
for v ∈ Unknown
if dist[u] + weight [u, v] < dist[v] {
//sửa nhãn cho v từ u
dist[v] = dist[u] + weight[u,v];
pre[v] = u;
}
}
path = {e}
while (e != s) {
e = pre[e]
path = {e} ∪ path
}
}