Tải bản đầy đủ (.pdf) (57 trang)

Bài giảng Toán rời rạc: Tìm kiếm trên đồ thị (Version 0.4) - Trần Vĩnh Đức

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.09 MB, 57 trang )

CuuDuongThanCong.com

Tìm kiếm trên đồ thị (Version 0.4)
Trần Vĩnh Đức
HUST

Ngày 29 tháng 7 năm 2018

/>
1 / 57


Tài liệu tham khảo

▶ S. Dasgupta, C. H. Papadimitriou, and U. V. Vazirani,
Algorithms, July 18, 2016.
▶ Chú ý: Nhiều hình vẽ trong tài liệu được lấy tùy tiện mà chưa
xin phép.

CuuDuongThanCong.com

/>
2 / 57


Nội dung

Biểu diễn đồ thị

Tìm kiếm theo chiều sâu trên đồ thị vơ hướng


Tìm kiếm theo chiều sâu trên đồ thị có hướng

Thành phần liên thơng mạnh

CuuDuongThanCong.com

/>

Biểu diễn đồ thị dùng Ma trận kề
Nếu đồ thị có n = |V| đỉnh v1 , v2 , . . . , vn , thì ma trận kề là một
mảng n × n với phần tử (i, j) của nó là
{
1 nếu có cạnh từ vi tới vj
aij =
0 ngược lại.

Ví dụ

CuuDuongThanCong.com

v2


1 1 1
A = 0 0 1
0 1 0

v1

v3

/>
4 / 57


Dùng ma trận kề có hiệu quả?

▶ Có thể kiểm tra có cạnh nối giữa cặp đỉnh bất kỳ chỉ cần một
lần truy cập bộ nhớ.
▶ Tuy nhiên, không gian lưu trữ là O(n2 )

CuuDuongThanCong.com

/>
5 / 57


Biểu diễn đồ thị dùng danh sách kề
▶ Dùng một mảng Adj gồm |V| danh sách.
▶ Với mỗi đỉnh u ∈ V, phần tử Adj[u] lưu trữ danh sách các
hàng xóm của u. Có nghĩa rằng:
Adj[u] = {v ∈ V | (u, v) ∈ E}.

Ví dụ

CuuDuongThanCong.com

1

Adj[0] = {0, 1, 2}
Adj[1] = {2}

Adj[2] = {1}

0

2
/>
6 / 57


Dùng danh sách kề có hiệu quả?

▶ Có thể liệt kê các đỉnh kề với một đỉnh cho trước một cách
hiệu quả.
▶ Nó cần khơng gian lưu trữ là O(|V| + |E|). Ít hơn O(|V|2 ) rất
nhiều khi đồ thị ít cạnh.

CuuDuongThanCong.com

/>
7 / 57


Nội dung

Biểu diễn đồ thị

Tìm kiếm theo chiều sâu trên đồ thị vơ hướng

Tìm kiếm theo chiều sâu trên đồ thị có hướng


Thành phần liên thơng mạnh

CuuDuongThanCong.com

/>

EALIZETHATTHEORDERINWHICHEDGES
WHICHVERTICESAPPEARINTHEARRAYOF
H
M
T
E
R
E CâutinyG.txt
hỏi
đỉnh của đồ thị ta có
đi tớiGraph
những tinyG.txt
đỉnh nào?
% thể
java
T VTừ một
13
E
13 vertices, 13 edges
13
Y
0: 6 2 1 5
0 5
1: 0

T
4 3
2: 0
0 1
first adjacent
N
3: 5 4

CuuDuongThanCong.com

/>
9 / 57


Tìm đường trong mê cung
Algorithms

83

Figure 3.2 Exploring a graph is rather like navigating a maze.
L
K

D

G

H

A


B

C

F

F

E

I

J
J

K

H

B

E

C

G

L
I


A

D

Hình: Tìm kiếm trên đồ thị cũng giống tìm đường trong mê cung

3.2 Depth-first search in undirected graphs
3.2.1 Exploring mazes
Depth-first search is a surprisingly versatile linear-time procedure that reveals a
wealth of information about a graph. The most basic question it addresses is,

What
CuuDuongThanCong.com

parts of the graph
are reachable from a given vertex?
/>
10 / 57


procedure explore(G, v)
Input: đồ thị G = (V, E); v ∈ V
Output: visited(u)=true với mọi đỉnh u có thể đến
được từ v
visited(v) = true
previsit(v)
for each edge (v, u) ∈ E:
if not visited(u): explore(G, u)
postvisit(v)


CuuDuongThanCong.com

/>
11 / 57


Ví dụ: Kết quả chạy explore(G, A)

A

Chapter 3

Figure 3.2 Exploring
is rather
like navigating
a maze.
Figure 3.4a graph
The result
of explore(A)
on the graph
of Figure
L
K

D

A

B


A
F

E

B

B
G

H

C

F

I

J

F

E
J

K

L


I
J

C
I

E

D
G

C

H
A

For instance, while B was being visited, the edge B − E was n

3.2 Depth-first
in undirected
graphs
was as search
yet unknown,
was traversed via
a call to explore(E )

form a tree (a connected graph with no cycles) and are therefo

3.2.1 Exploring
mazesedges were ignored because they led back to familia

The dotted

CuuDuongThanCong.com

/>
12 / 57


Tìm kiếm theo chiều sâu

procedure dfs(G)
for all v ∈ V:
visited(v) = false
for all v ∈ V :
if not visited(v): explore(G, v)

CuuDuongThanCong.com

/>
13 / 57


during explore(x) and once during explore(y). The overall time for step 2 is
therefore O(|E |) and so the depth-first search has a running time of O(|V| + |E |),
linear in the size of its input. This is as efficient as we could possibly hope for, since
it takes this long even just to read the adjacency list.

Ví dụ: Đồ thị và Rừng DFS

Figure 3.6 (a) A 12-node graph. (b) DFS search forest.

(a)

(b)
A

B

C

1,10

11,22

23,24

A

C

F

D
B

E

4,9

12,21


D

I

5,8

13,20

H

2,3

E

F

G

H

I

J

K

L

J


14,17

G

6,7

L
18,19

K
15,16

Figure 3.6 shows the outcome of depth-first search on a 12-node graph, once again
breaking ties alphabetically (ignore the pairs of numbers for the time being). The
outer loop of DFS calls explore three times, on A, C , and finally F . As a result,
there are three trees, each rooted at one of these starting points. Together they
constitute a forest.
CuuDuongThanCong.com
/>
14 / 57


Bài tập
Xây dựng rừng DFS cho đồ thị sau với các đỉnh lấy theo thứ tự từ
điển. Vẽ cả những cạnh nét đứt.

CuuDuongThanCong.com

/>
15 / 57



Rừng
vàforest.
số thành
. (b)
DFSDFS
search
(b)

phần liên thông

1,10

11,22

23,24

A

C

F

B

E

4,9


12,21

D

I

5,8

13,20

H

2,3

J

14,17

G

6,7

L
18,19

K
15,16

v
A

B
C
D
E
F
G
H
I
J

ccnum[v]
1
1
2
2
1
3
2
2
1
1

Biến ccnum[v] để xác định thành phần liên thông của đỉnh v.

depth-first search on a 12-node graph, once again
re the pairs of numbers for the time being). The

CuuDuongThanCong.com

/>

16 / 57


Tính liên thơng trong đồ thị vơ hướng
procedure dfs(G)
cc = 0
for all v ∈ V: visited(v) = false
for all v ∈ V:
if not visited(v):
cc = cc + 1
explore(G, v)
procedure explore(G, v)
visited(v) = true
previsit(v)
for each edge (v, u) ∈ E:
if not visited(u): explore(G, u)
postvisit(v)
procedure previsit(v)
ccnum[v] = cc

CuuDuongThanCong.com

/>
17 / 57


Bài tập
Hãy cài đặt chương trình tìm số thành phần liên thông của một đồ
thị vô hướng.


CuuDuongThanCong.com

/>
18 / 57


previsit và postvisit
▶ Lưu thời gian lần đầu đến đỉnh trong mảng pre
▶ Lưu thời gian lần cuối rời khỏi đỉnh trong mảng post
▶ Để tính hai thơng tin này ta dùng một bộ đếm clock, khởi
tạo bằng 1, và được cập nhật như sau:

CuuDuongThanCong.com

procedure previsit(v)
pre[v] = clock
clock = clock + 1
procedure postvisit(v)
post[v] = clock
clock = clock + 1

/>
19 / 57


Bài tập
Vẽ rừng DFS với cả số pre và post cho mỗi đỉnh cho đồ thị sau.

CuuDuongThanCong.com


/>
20 / 57


Tính chất của previsit và postvisit

Mệnh đề
Với mọi đỉnh u và v, hai khoảng
[ pre(u), post(u) ] và [ pre(v), post(v) ]
▶ hoặc là rời nhau,
▶ hoặc là có một khoảng chứa một khoảng khác.
Tại sao? vì [ pre(u), post(u) ] là khoảng thời gian đỉnh u nằm
trong ngăn xếp. Cấu trúc vào-sau, ra-trước đảm bảo tính chất này.

CuuDuongThanCong.com

/>
21 / 57


Nội dung

Biểu diễn đồ thị

Tìm kiếm theo chiều sâu trên đồ thị vơ hướng

Tìm kiếm theo chiều sâu trên đồ thị có hướng

Thành phần liên thơng mạnh


CuuDuongThanCong.com

/>

Bài tập

88

Hãy vẽ rừng DFS với
số pre
post
trên mỗi
đỉnh cho đồ thị có
Figure
3.7 và
DFS
on a directed
graph.
hướng sau.

CuuDuongThanCong.com

A

B

A

C
B 2,11


E

F

D

G

H

E 3,10

4,7

F

5,6

G

H

In further analyzing the directed case, it helps to have terminolog
relationships between nodes of a tree. A is the root of the search
/>
23 / 57


88


3.3 Depth-first search in

Lời giải
Figure
3.7 DFS on a directed graph.
A 1,16

B

E

A

F

G

C

D

4,7

F

5,6

G


B 2,11

C 12,15

E 3,10

D 13,14

H

8,9

H

In further analyzing the directed case, it helps to have terminology for important
relationships between nodes of a tree. A is the root of the search tree; everything
else is its descendant. Similarly,
E has descendants F , G , and H , and conversely,
CuuDuongThanCong.com
/>
24 / 57


relationships between nodes of a tree. A is the root of the search tree; everything
else is its descendant. Similarly, E has descendants F , G , and H , and conversely,
is an ancestor of these three nodes. The family analogy is carried further: C is the
parent of D, which is its child.

Các kiểu cạnh


For undirected graphs we distinguished
between
treethuộc
edges and
nontree
Tree Edges
là cạnh
rừng
DFS.edges. In
the directed case, there is a slightly more elaborate taxonomy:

DFS tree

Forward
Edgespart
là ofcạnh
dẫnforest.
từ một
Tree edges
are actually
the DFS

A

war

Bac

k


For

Tr

ee

d

B
C

Cross

D

nút
tới một nút con cháu của nó nhưng
Forward edges lead from a node to a nonchild descendant in
không
the DFS
tree. thuộc rừng DFS.
Back edges lead to an ancestor in the DFS tree.
Cross edges lead to neither descendant nor ancestor; they
Back
là cạnh
dẫnalready
từ một
tới
therefore
leadEdges

to a node
that has
beennút
completely
explored
already
một(that
tổ is,
tiên
của postvisited).
nó.

Crosstwo
Edges
cạnhanddẫn
một
nútCan
tới you
Figure 3.7 has two forward edges,
back là
edges,
twotừ
cross
edges.
spot them?
một nút không phải tổ tiên cũng không
Ancestor and descendant relationships,
well as
edge
types, can be read off directly

phải conascháu
của
nó.
from pre and post numbers. Because of the depth-first exploration strategy, vertex
u is an ancestor of vertex v exactly in those cases where u is discovered first and

CuuDuongThanCong.com

/>
25 / 57


×