1. Trang chủ
  2. » Luận Văn - Báo Cáo

TÌM KIẾM THEO CHIỀU SÂU TRÊN ĐỒ THỊ CÓ HƯỚNG ĐƯỢC BIỂU DIỄN BỞI DANH SÁCH KỀ VÀ ỨNG DỤNG VÀO SẮP XẾP TÔPÔ

17 1,4K 1

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 17
Dung lượng 588,19 KB

Nội dung

TÌM KIẾM THEO CHIỀU SÂU TRÊN ĐỒ THỊ CÓ HƯỚNG ĐƯỢC BIỂU DIỄN BỞI DANH SÁCH KỀ VÀ ỨNG DỤNG VÀO SẮP XẾP TÔPÔ

Trang 1

Viện Công nghệ Thông tin và Truyền thông

BÀI TẬP LỚN CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT

ĐỀ TÀI: TÌM KIẾM THEO CHIỀU SÂU TRÊN ĐỒ THỊ CÓ HƯỚNG ĐƯỢC BIỂU DIỄN BỞI DANH SÁCH KỀ VÀ ỨNG DỤNG VÀO SẮP XẾP TÔPÔ.

NHÓM 5

Giáo viên hướng dẫn: PGS Nguyễn Đức Nghĩa

Trang 2

NỘI DUNG

A-Định nghĩa ADT

I- Đồ thị

II-Danh sách kề

B- Bài toán tìm kiếm theo chiều sâu trên đồ thị có hướng biểu diễn bởi danh sách kề

I-Phát biểu bài toán

II-Ứng dụng bài toán tìm kiếm theo chiều sâu

C- Ứng dụng bài toán tìm kiếm theo chiều sâu trên đồ thị có hướng được biểu diễn bởi danh sách kề vào bài toán sắp xếp tôpô

Trang 3

A-Định nghĩa ADT

I-Đồ thị

1.Khái niệm đồ thị

Đồ thị G là cấu trúc rời rạc bao gồm hai tập

- Tập đỉnh V(G) là tập hữu hạn khác rỗng

- Tập cạnh E(G) là tập hữu hạn có thể là tập rỗng các cặp (u,v) trong đó u,v V

Kí hiệu G=(V,E)

2 Các loại đồ thị

Phụ thuộc vào kiểu của cạnh nối và số lượng cạnh nối giữa hai đỉnh mà ta phân biệt các loại đồ thị khác nhau

2.1 Đồ thị vô hướng

Đơn (đa) đồ thị vô hướng G = (V,E) là cặp gồm:

- Tập đỉnh V là tập hữu hạn phần tử, các phần tử gọi là các đỉnh

- Tập cạnh E là tập (họ) các bộ không có thứ tự dạng

(u, v), u, v  V, u≠v

2.2 Đồ thị có hướng

Đơn (đa) đồ thị có hướng G = (V,E) là cặp gồm:

Tập đỉnh V là tập hữu hạn phần tử, các phần tử gọi là các đỉnh

Tập cung E là tập (họ) các bộ có thứ tự dạng

(u, v), u, v  V, u≠v

3.Biểu diễn đồ thị

3.1.Biểu diễn đồ thị bằng ma trận kề

3.2.Biểu diễn đồ thị bằng danh sách kề

3.3.Biểu diễn đồ thị bằng danh sách cạnh

4.Các thao tác cơ bản thường gặp khi xử lý đồ thị

- incidentEdge(v)- duyệt các đỉnh kề của đỉnh v

- areAdjacent(v,w)- trả lại giá trị true khi và chỉ khi v và w là kề nhau

- insertVertex(z)-bổ sung đỉnh z

- insertEdge(v)-bổ sung cạnh e=(v,w)

- removeVertex(v)-loại bỏ đỉnh v

- removeEdge(e)-loại bỏ cạnh e

5 Các thuật toán duyệt đồ thị

5.1.Thuật toán tìm kiếm theo chiều rộng (BFS)

5.2.Thuật toán tìm kiếm theo chiều sâu (DFS)

Trang 4

II-Danh sách kề

Với mỗi đỉnh v cất giữ danh sách các đỉnh kề với nó

-Là mảng Ke gồm có | V| danh sách

-Mỗi đỉnh có một danh sách

-Với mỗi u V, Ke[u] bao gồm tất cả các đỉnh kề của u

Ví dụ

a) Biểu diễn đồ thị vô hướng G=(V,E) sử dung danh sách kề

v u u z v x

w w v

y

u v w x y z t

Bộ nhớ đòi hỏi = a|V|+2b|E|

b) Biểu diễn đồ thị có hướng G=(V,E) sử dụng danh sách kề

b e b

b f

c a

b c d e

Bộ nhớ đòi hỏi = a|V|+b|E|

Có thể sử dụng mô tả trên C sau đây để biểu diễn danh sách kề

#define MAX_ VERTICES 500

Typedef struct node*node_ptr;

Typedef struct node

{

int vertex;

node_ptr link;

} node;

node_ptr graph[MAX_VERTICES];

Trang 5

B-Bài toán tìm kiếm theo chiều sâu trên đồ thị có hướng biểu diễn bởi danh sách kề

I-Phát biểu bài toán

1.Ý tưởng chung cho các thuật toán tìm kiếm

-Trong quá trình thực hịện thuật toán , ở mỗi đỉnh có một trong ba

trạng thái sau:

+ Chưa thăm thì thể hiện bằng màu trắng

+ Đã thăm (nhưng chưa duyệt xong) thì thể hiện bằng màu xám

+ Đã duyệt xong thể hiện bằng màu đen

2 Thuật toán tìm kiếm theo chiều sâu (depth first search)

Input: G=(V,E) – đồ thị vô hướng hoặc có hướng

Output: Với mỗi v V

d[v]= thời điểm bắt đầu thăm(v chuyển từ màu trắng sang xám)

f[v]= thời điểm kết thúc thăm(v chuyển từ màu xám sang đen)

π[v]: từ đỉnh đó ta đến thăm đỉnh v

Rừng tìm kiếm theo chiều sâu(gọi tắt là rừng DFS – Forest of depth-first trees):

Gπ=(V,Eπ),

Eπ={(π[v] , v): vV và π[v] ≠ null}

2.1.thuật toán tìm kiếm theo chiều sâu bắt đầu từ đỉnh u

DFS-Visit(u)

1.color[u] ← GRAY

2.time ← time+1

3.d[u] ← time

4.for v  Adj[u]

5 do if color[v]=WHITE

6 then π [v] ←u

7 DFS-Visit(v)

8.color[u]← BLACK

9.f[u] ← time ← time+1

2.2.thuật toán theo chiều sâu trên đồ thị G

DFS(G)

1 for u V[G]

2 do color[u] ← white

3 π[u] ← NULL

4 Time ← 0

5 for u V[G]

Trang 6

6 do if color[u] = white

7 then DFS-Visit(u)

Quá trình thực hiện thuật toán được trình diễn trong các hình minh hoạ sau

u v w

1/ / /

/ / /

x y z DFS(u): Thăm đỉnh u DFS( n) u v w 1/ 2/ /

/ / /

x y z

DFS(v): thăm đỉnh v DFS(u) DFS(v) u v w 1/ 2/ /

/ 3/ /

x y z

DFS(y): thăm đỉnh y DFS( u)

DFS(v)

DFS(y)

u v w

DFS(y): thăm đỉnh y DFS( u)

Trang 7

1/ 2/ /

4/ 3/ /

x y z

DFS(v)

DFS(y)

DFS(x)

u v w

1/ 2/ /

4/5 3/ /

x y z

Kết thúc thăm đỉnh x DFS( u)

DFS(v)

DFS(y)

DFS(x)

Trang 8

u v w

1/ 2/ /

4/5 3/6 /

x y z

Kết thúc thăm đỉnh y DFS( u)

DFS(v)

DFS(y)

DFS(x)

u v w

1/ 2/7 /

4/5 3/6 /

x y z

Kết thúc thăm đỉnh v DFS( u)

DFS(v)

DFS(y)

DFS(x)

u v w

1/8 2/7 /

4/5 3/6 /

Kết thúc thăm đỉnh u DFS( u)

DFS(v)

Trang 9

x y z DFS(y)

DFS(x)

u v w

1/8 2/7 9/

4/5 3/6 /

x y z

DFS(w): Thăm đỉnh w

u v w

1/8 2/7 9/

4/5 3/6 10/

x y z

DFS(z): Thăm đỉnh z

u v w

1/8 2/7 9/

4/5 3/6 10/11

x y z

Kết thúc thăm đỉnh z

u v w

Trang 10

1/8 2/7 9/12

4/5 3/6 10/11

x y z

Kết thúc thăm đỉnh w

Kết thúc DFS(G)

Rừng tìm kiếm gồm 2 cây: cây DFS(u) và cây DFS(w)

u v w

1/8 2/7 9/12

4/5 3/6 10/11

x y z

cây DFS(u) cây DFS(w)

3.Các tính chất của DFS

- Rừng DFS là phụ thuộc vào thứ tự các đỉnh được duỵêt trong vòng lặp for duyệt

đỉnh trong DFS(G) và DFS_Visit(u)

- Để gỡ đệ quy có thể sử dụng ngăn xếp Và có thể nói, điểm khác biệt cơ bản của DFS với BFS là các đỉnh đang được thăm trong DFS được cất giữ vào ngăn xếp thay vì hàng đợi trong BFS

- Các khoảng thời gian thăm [d[v],f[v]] của các đỉnh có cấu trúc lồng nhau

(parenthesis structure)

4.Cấu trúc lồng nhau (parenthesis structure)

Định lý: Với mọi u,v chỉ có thể xảy ra một trong các tình huống sau:

Trang 11

1.d[u] < f[u] < d[v] < f[v] hoặc d[v] < f[v] < d[u] < f[u] ( nghĩa là hai khoảng thời gian thăm của u và v là dời nhau) và khi đó u và v là không có quan hệ tổ

tiên-hậu duệ

2.d[u] < d[v] < f[v] < f[u] ( nghĩa là khoảng thời gian thăm của v là lồng trong khoảng thời gian thăm của u) và khi đó v là hậu duệ của u.

3.d[v] < d[u] < f[u] < f[v] (nghĩa là khoảng thời gian thăm của u là lồng trong khoảng thời gian thăm của v) và khi đó u là hậu duệ của v.

Ví dụ: Xét việc thực hiện thuật toán tìm kiếm theo chiều sâu trên đồ thị cho trong hình vẽ dưới đây

2/15 3/14 4/5

a b c DFS(s) Tree

1/16

s

8/9 Time stamps:

t d[]/t[]

d e f

11/12 6/13 7/10

Hình vẽ sau đây minh hoạ cho định lý về cấu trúc lồng nhau:

s

c

a

b e f t

d

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Trang 12

(s (a (b (c c) (e (f (t t) f ) (d d) e) b) a) s)

5.Độ phức tạp của DFS

-Thuật toán thăm mỗi đỉnh v V đúng một lần  (|V|)

- Với mỗi đỉnh v duyệt qua tất cả các đỉnh kề, với mỗi đỉnh kề thực hiện thao tác

với thời gian hằng số Do đó việc duyệt qua tất cả các đỉnh mất thời gian

vV |neighbors[v]| = (|E|)

- Tổng cộng (|V|)+ (|E|) =  (|V|+|E|), hay  (|V|2)

Như vậy, DFS có cùng độ phức tạp như BFS

6.Phân loại cạnh

DFS tạo ra một cách phân loại các cạnh của đồ thị đã cho:

- Cạnh của cây(Tree edge): là cạnh mà theo đó từ một đỉnh ta đến thăm một đỉnh mới

- Cạnh ngược (Back edge): đi từ con cháu (descendent) đến tổ tiên(ancestor)

- Cạnh tới (Forward edge): đi từ tổ tiên đến hậu duệ

- Cạnh vòng (Cross edge): cạnh nối hai đỉnh ko có quan hệ họ hàng

Để nhận biết cạnh (u,v) thuộc loại cạnh nào, ta dựa vào màu của đỉnh v khi lần đầu trên cạnh (u,v) được khảo sát Cụ thể, nếu màu của đỉnh v làp

- Trắng thì (u,v) là cạnh của cây

- Xám thì (u,v) là cạnh ngược

- Đen thì (u,v) là cạnh tới hoặc vòng Trong trường hợp này để phân biệt cạnh tới và cạnh vòng ta cần xét xem hai đỉnh u và v có quan hệ họ hàng hay

không nhờ sử dụng kết quả của định lý về cấu trúc lồng nhau

Nhiều ứng dụng của DFS chỉ đòi hỏi nhận biết cạnh của cây và cạnh ngược, Hơn nữa, đối với đồ thị vô hướng, DFS chỉ sản sinh ra hai loại cạnh này như chỉ ra trong khẳng định của định lý sau đây

Định lý: nếu G là đồ thị vô hướng, thì DFS chỉ sản sinh ra cạnh của cây và cạnh

ngược

II-Ứng dụng của thuật toán tìm kiếm theo chiều sâu (DFS)

Trang 13

 Tính liên thông của đồ thị

 Tìm đường đi từ s đến t

 Phát hiện chu trình

 Kiểm tra tính liên thông mạnh

 Định hướng đồ thị

C- Ứng dụng thuật toán tìm kiếm theo chiều sâu trên đồ thị

có hướng sử dụng danh sách kề vào bài toán sắp xếp tôpô I- Phát biểu bài toán

Bài toán đặt ra là : Cho đồ thị có hướng không có chu trình G=(V,E) hãy tìm cách sắp xếp các đỉnh sao cho nếu có cạnh (u,v) thì u phải đi trước v trong thứ tự đó (nói

cách khác, cần tìm cách đánh số các đỉnh của đồ thị sao cho mỗi cung của đồ thị luôn hướng từ đỉnh có chỉ số nhỏ hơn đến đỉnh có chỉ số lớn hơn)

II-Thuật toán sắp xếp tôpô

Thuật toán có thể viết vắn tắt như sau: Thực hiện DFS(G), khi mỗi đỉnh được duyệt

xong ta đưa nó vào đầu danh sách lien kết (điều đó có nghĩa là những đỉnh kết thúc thăm càng muộn sẽ càng ở đầu danh sách hơn) Danh sách lien kết thu được khi kết

thúc DFS(G) sẽ cho ta thứ tự cần tìm.

TopoSort(G)

1 for u V color[u]=white; //khởi tạo

2 L = new(linked_list); //khởi tạo danh sách liên kết rỗng

3 for u V

4 if (color[u] == white) TopVisit(u);

5 return L // L cho thứ tự cần tìm

TopVisit(u){

1 color[u] = gray; //bắt đầu tìm kiếm từ u

2 for v  Adj(u) //đánh dấu u đã thăm

3 if (color[v]==white)TopVisit(v);

4 Nạp u vào đầu danh sách L // u đã duyệt xong

Cài đặt trên C

Trang 14

void DFS(int vertex)

{

//printf(" %d ", vertex);

pListIt p;

color[vertex] = GRAY; // visited

for (p = adjacencyList[vertex]; p != NULL; p = p -> p_next)

if (!color[p -> value]) {

ancient[p->value] = vertex;

distance[p->value] = distance[vertex] +1;

p->type = TREE_EDGE;

DFS(p -> value);

} else {

if( color[p->value] == GRAY) {

p->type = BACK_EDGE;

isCircle = true;

// print the circle printf(" \n Circle: ");

int l = vertex;

while(l != p->value) {

printf( " %d ", l);

l = ancient[l];

} printf( " %d ", l);

} else

if (distance[p->value] > distance[vertex]) {

p->type = AHEAD_EDGE ; }

else

p->type = CROSS_EDGE ;

} // add to the topological order ++atPos;

Trang 15

topological_order[n-atPos] = vertex;

color[vertex] = BLACK;

}

A B D

1/

C E

Linked list:

A B D

1/

2/

C E Linked list:

A B D

1/

2 /3

C E

Linked list:

2/3

E

A B D

1/4

2/3

C E

Linked list:

1/4 2/3

D E

Trang 16

A B D

5/ 1/4

2 /3

C E

Linked list:

1/4 2/3

D E

A B D

5/ 1/4

6/ 2/3

C E

Linked list:

1/4 2/3

D E

A B D

5/ 1/4

6/7 2 /3

C E

Linked list:

6/7 1/4 2/3

C D E

A B D

5/8 1/4

6/7 2/3

C E Linked list:

5/8 6/7 1/4 2/3

B C D E

Trang 17

A B D

9/ 5/8 1/4

6/7 2 /3

C E

Linked list:

5/8 6/7 1/4 2/3

B C D E

A B D 9/10 5/8 1/4

6/7 2/3

C E Linked list:

9/10 5/8 6/7 1/4 2/3

A B C D E

III-Đánh giá độ phức tạp của thuật toán

Thời gian tính của TopoSort(G) là O(|V|+|E|)

Ngày đăng: 10/04/2016, 14:10

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w