1. Trang chủ
  2. » Tài Chính - Ngân Hàng

Thuật toán đồ thị cơ bản

22 521 0

Đ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 22
Dung lượng 291,26 KB

Nội dung

Thuật toán đồ thị cơ bảnBởi: Đại Học Phương Đông Biểu diễn đồ thị Các phương pháp biểu diễn đồ thị Có hai chuẩn dùng để biểu diễn đồ thị G = V, E: Sử dụng tập hợp các danh sách kề: Danh

Trang 1

Thuật toán đồ thị cơ bản

Bởi:

Đại Học Phương Đông

Biểu diễn đồ thị

Các phương pháp biểu diễn đồ thị

Có hai chuẩn dùng để biểu diễn đồ thị G = (V, E):

Sử dụng tập hợp các danh sách kề:

Danh sách kề biểu diễn các đỉnh kề nhau, và thường hay được sử dụng bởi vì nó biểudiễn được một cách tối ưu đồ thị thưa (đồ thị thưa là đồ thị có số cạnh |E| ít hơn bìnhphương số các đỉnh |V|2 ) Hầu hết các thuật toán đồ thị được trình bày trong các phầnsau sẽ sử dụng danh sách kề để biểu diễn đồ thị

Sử dụng ma trận kề:

Nên sử dụng cách biểu diễn này đối với đồ thị dày, có nghĩa là khi |E| gần bằng |V|2,hoặc khi cần biết giữa hai đỉnh nào đó có cạnh nối hay không Một số thuật toán tìmđường đi ngắn nhất sử dụng cách biểu diễn đồ thị đầu vào G qua ma trận kề

Danh sách kề

Danh sách kề (là danh sách các đỉnh kề của đồ thị G = (V, E)) được mô tả bởi mảng Adjcủa |V| danh sách, mỗi một danh sách tương ứng với mỗi một đỉnh thuộc V Với mỗiđỉnh u∈ V, danh sách kề Adj[u] chứa (hay còn nói là trỏ tới) tất cả các đỉnh v mà từ v

có cạnh nối tới u (có nghĩa là (u,v) ∈ E) Điều này có nghĩa là Adj[u] chứa tất cả cácđỉnh kề với u trên đồ thị G Các đỉnh trong mỗi một danh sách kề thông thường đượclưu theo một trật tự tùy ý

Nếu G là đồ thị có hướng, tổng chiều dài của tất cả các danh sách kề là |E|, do có cạnhnối (u,v) chỉ khi đỉnh v xuất hiện trong Adj[u] Nếu G là một đồ thị vô hướng, tổng độdài của tất cả các danh sách kề là 2|E|, do tồn tại cạnh vô hướng (u,v) chỉ khi đỉnh u xuấthiện trong danh sách các đỉnh kề của v và đỉnh v xuất hiện trong danh sách các đỉnh kềcủa u Dù đồ thị có hướng hay vô hướng, việc biểu diễn qua danh sách kề chiếm mộtvùng bộ nhớ có kích thước là O(max(V,E)) = O(V + E)

Trang 2

Các danh sách các đỉnh kề có thể dễ dàng được sử dụng để biểu diễn các đồ thị có trọng

số Đó là đồ thị mà mỗi cạnh đều có một trọng số riêng, được tính bằng hàm trọng số w:

Ma trận kề

Với cách biểu diễn đồ thị G = (V, E) qua ma trận kề, quy ước rằng các đỉnh được đánhtùy ý từ 1, 2, cho đến |V| Biểu diễn qua ma trận kề này được mô tả qua ma trận A =(aij) có kích thước |V| x |V| như sau:

aij = 1 nếu (i,f )∈ E

= 0 trong trường hợp khác

Hình 23.1(c) và hình 23.2(c) là các ma trận kề của đồ thị vô hướng và có hướng cho

trong hình 23.1(a) và 23.2(a) tương ứng Ma trận kề của đồ thị yêu cầu Ρ(V2) bộ nhớ,không phụ thuộc vào số cạnh trong đồ thị

Nếu để ý quan sát tính đối xứng qua đường chéo chính của ma trận kề trong hình 23.1(c).Định nghĩa hoán vị của ma trận A = (aij) là ma trận AT = (aijT) với aijT = aij

Do với đồ thị vô hướng (u,v) và (v,u) đều biểu diễn cùng một cạnh, nên ma trận kề Acủa một đồ thị vô hướng chính là hoán vị của nó: A = AT Trong một vài ứng dụng, chỉcần lưu toàn bộ dữ liệu trên đường chéo của ma trận (tạo thành hình tam giác trên), do

đó bộ nhớ được giảm một nửa

Giống như cách biểu diễn qua danh sách các đỉnh kề, cách biểu diễn qua ma trận kề cóthể được sử dung cho đồ thị có trọng số Ví dụ, nếu G = (V, E) là một đồ thị trọng số vớihàm w, trọng số w(u,v) của cạnh (u,v) được lưu trữ tương ứng với hàng v và cột u của

ma trận kề Nếu cạnh không tồn tại, một giá trị rỗng (NIL) sẽ được lưu trưữ tưng ứng

Trang 3

Mặc dù cách biểu diễn đồ thị danh sách các đỉnh kề gần như có hiệu quả ít nhất là bằnggần cách biểu diễn ma trận kề, nhưng vì tính đơn giản của cách biểu diễn ma trậnkề nêncách biểu diễn này hay được sử dụng hơn đới với đồ thị khá nhỏ Hơn thế nữa, nếu đồthị không trọng số, lợi ích của việc sử dụng ma trận kề lại càng rõ ràng hơn:thay vì sửdụng một word nhớ cho mỗi một phần tử ma trận, ma trận kề chỉ cần sử dụng đến mộtbit tướng ứng với một phần tử của ma trận.

Tìm kiếm theo chiều rộng

Khái niệm

Duyệt theo chiều rộng (Breadth – first search, BFS) là một trong những thuật toánđơn giản nhất được sử dụng trong việc duyệt và tím kiếm trên đồ thị Trên cơ sở củathuậttoán này mà nhiều các thuật toán đồ thị quan trọng khác đã ra đời, như là:

• Thuật toán Dijkstra giải bài toán đường đi ngắn nhất

• Thuật toán Prim giải bài toán cây khung nhỏ nhất

Giả sử cho đồ thị G=(V,E) vô hướng hoặc có hướng và một đỉnh xuất phát s bất kỳ.Thuật toán duyệt theo chiều sâu tiến hành:

• Duyệt các cạnh của đồ thị G để tìm ra từ đỉnh xuất phát s có thể đến được cácđỉnh nào Các đỉnh này còng được gọi là các đỉnh được “thăm”

• Tính toán khoảng cách (là số ít nhất các cạnh) từ s tới tất cả các đỉnh có thể đếnđược từ s

• Xây dựng cây (breath-first tree) có gốc là s và chứa tất cả các đỉnh có thể đếnđược từ s.Với một đỉnh v được thăm bất kỳ, tồn tại một đường đi trên cây này

từ gốc s tới nút tương ứng với đỉnh v đó Đường đi này chính là đường đi nhắnnhất từ s tới v trong đồ thị G, có nghĩa là số các cạnh của đường này là ít nhất

Hoạt động của giải thuật

Nguyên tắc tô màu

Sở dĩ thuật toán BFS có tên gọi như vậy là do tại mỗi một bước của thuật toán, nó mởrộng biên giới giữa các đỉnh được thăm và chưa được thăm theo một quy tắc nhất định:thuật toán lần lượt thăm các đỉnh co khoảng cách từ đỉnh xuất phát là k (có nghĩa là sốcạnh tự s tới các đỉnh này là k) trước khi thăm bất cứ một đỉnh nào co khoảng cách từđỉnh s tới nó là k+1

Trong quá trình hoạt động, thuật toán tiến hành bôi màu các đỉnh với một trong 3 màu màu trắng, xám hoặc đen theo nguyên tắc sau:

Trang 4

-• Tại bước khởi động tất cả các đỉnh của đồ thị đều có màu trắng.

• Tất cả các đỉnh đã được thăm đều có màu xám hoặc đen

• Thuật toán BFS phân biệt giữa các đỉnh có màu xám và màu đen để đảm bảotính chất duyệt theo chiều rộng của mình

• Khi đỉnh v được thăm lần đầu tiên, nó được bôi màu xám Các đỉnh này biểuhiện biên giới giữa các đỉnh đã được thăm và chưa được thăm Sau đó thuậttoán tiến hành duyệt các đỉnh kề với đỉnh v

• Đỉnh v được bôi màu đen chỉ khi duyệt xong (thăm) tất cả các đỉnh kề với v.Như vậy là nếu có cạnh (u,v)∈E và đỉnh u có màu den, đỉnh v có thể là xám hoặc đen.Điều này có nghĩa là tất cả các đỉnh kề với đỉnh có màu đen đều chưa được thăm

Cây Breadth–First Tree

Thuật toán BFS cho phép xây dựng cây T (breadth – first tree) như sau:

• Ban đầu cây này chỉ có mỗi một gốc là đỉnh s

• Trong quá trình duyệt, giả sử thuật toán đã duyệt đến đỉnh chưa được thăm u

Khi đó u trở thành đỉnh đã được thăm và thuật toán sẽ tiến hành duyệt danh sách cácđỉnh kề với đỉnh u Nếu gặp phải đỉnh v kề với u, mà đỉnh v lại có màu trắng (chưa dượcthăm lần nào cả), đỉnh v và cạnh (u,v) được bổ sung vào trong cây Điều này có nghĩa lànút tương ứng với đỉnh u là nút cha của nút tương ứng với đỉnh v, còn đỉnh u được gọi

là đỉnh trước của đỉnh v trong thứ tự duyệ theo chiều rộng

Do các đỉnh được thăm nhiều nhất là một lần, nên nút trong cây T tương ứng với đỉnhnày chỉ có một cha

Mô tả thuật toán

Thuât toán BFS được mô tả như sau:

Đầu vào:

• Cho đồ thị vô hướng hoặc có hướng G=(V,E) được biểu diễn bằng danh sáchkề

• Màu của đỉnh u∈V được lưu trong mảng color[u]

• Đỉnh trước của đỉnh u được lưu trong mảng π[u] Nếu đỉnh u không có đỉnhtrước, khi đó π[u]=NIL

• Khoảng cách từ đỉnh xuất phát s tới dỉnh u được lưu trong mảng d[u]

• Thuật toán sử dụng hàng đợi Q (theo nguyên tắc FIFO – vào trước ra trước) đểquản lý tập các đỉnh có màu xám

Trang 5

Mô phỏng thuật toán BFS bằng ngôn ngữ giả Pascal:

Trang 6

Thực hiện vòng lặp for để khởi tạo các giá trị ban đầu cho tất cả các đỉnh khác với đỉnhxuất phát s của đồ thị (each vertex u <- V[G] - {s}):

• Gán màu trắng cho mọi đỉnh của đồ thị G trừ đỉnh s (color [u] <- white)

• Do tại bước đầu chưa tiến hành duyệt đồ thị, nên gán khoảng cách từ đỉnh s tớicác đỉnh còn lại bằng vô cùng (d[u] <- ∞)

• pi[u] <- NIL, có nghĩa là chưa xác định được đỉnh đứng trước đỉnh u trong thứ

tự duyệt theo chiều rộng

Bước 2 (dòng 5 cho đến dòng 7):

Khởi tạo cho đỉnh xuất phát s:

• Gán màu xám cho s color[s] <- gray

• Gán d[u] <- 0 (khoảng cách từ s tới chính nó là 0)

• Gán pi[s] <- nil

• Đẩy đỉnh s vào hàng đợi Q ( s trở thành phần tử đầu của Q)

Bước 3 (dòng 9 cho đến 18):

Đây là bước chính của thuật toán Nó được lặp đi lặp lại khi trên đồ thị vẫn còn các đỉnh

có màu xám, có nghĩa là khi còn có các đỉnh mà danh sách kề của chúng vẫn chưa đượcduyệt:

1) Kiểm tra hàng đợi Q co rỗng không Nếu rỗng, kết thúc thuật toán Ngược lại, chuyểnsang bước 2

2) Lấy phần tử u đầu từ Q

3) Duyệt lần lượt danh sách các đỉnh kề của đỉnh u

4) Với mỗi phần tử v của danh sách kề này kiểm tra xem v đã được thăm chưa (đỉnh vchưa được thăm khi color[v] <- WHITE) Nếu v chưa được thăm thì:

Tiến thành thăm đỉnh này bằng cách:

- gán color[v] <- GRAY

- gán giá trị mới cho khoảng cách tử đỉnh xuất phát s tới v: d[v] <- d[u]+1

- ghi nhớ lại đỉnh đứng trước đỉnh v: pi[v] <- u

Đẩy đỉnh vào cuối của hàng đợi Q (dòng 16)

Trang 7

5) Lặp lại bước 4 với phần tử tiếp theo trong danh sách các đỉnh kề với đỉnh u cho đếnkhi duyệt hết danh sách này.

6) Lấy phần tử u ra khởi hàng đợi Q

7) Gán màu đen cho u: color[u] <- BLACK

Chú ý:

Thuật toán BFS trên sẽ không duyệt hết tất cả các đỉnh của đồ thị G nếu đồ thị này gồmnhiều thành phần liên thông khác nhau

Trong trường hợp này thuật toán BFS phải được điều chỉnh lại như sau:

Để duyệt được hết các thành phần liên thông của đồ thị G, thuật toán được điều chỉchlại như sau:

Thêm một vòng lặp for ở ngoài cùng để duyệt mọi đỉnh của G Đỉnh nào chưa đượcthăm, tiến hành đẩy đỉnh đó vào hành đợi Q và tiến hành một số động tác duyệt danhsách kề và gán giá trị tương ứng như đã được đề cập trong thuật toán đầu

Như vậy, xuất phát từ đỉnh s nếu đã duyệt xong tất cả các đỉnh thuộc cùng một vùng liênthông mà thuật toán vẫn còn bỏ sót các đỉnh thuộc các thanh phần liên thông khác, thuậttoán kiểm tra xem có còn các đỉnh bị bỏ sót không (khác với thuật toán đầu), nếu còn,

nó sẽ tiến hành duyệt tiếp các đỉnh này

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

- Sau khi được khởi tạo, các đỉnh đều được gán màu trắng, nên mỗi một đỉnh sẽ đượcđưa vào trong hàng đợi Q nhiều nhất là một lần, và hiển nhiên là cũng được đưa ra khỏihàng đợi nhiều nhất là một lần Thao tác đẩy vào và lấy ra khỏi hàng đợi Q sẽ mất thờigian là O(1), vì vậy, thời gian tổng cộng dành cho các phép toán với hàng đợi là O(V)

- Do danh sách kề của mỗi một đỉnh được duyệt chri khi đỉnh này được đưa vào tronghành đợi, nên danh sách kề của mỗi một đỉnh cũng được duyệt nhiều nhất là một lần.Chiều dài của tất cả các danh dách kề là Ρ(E) Do vậy, thời gian dành cho việc duyệttoàn bộ các danh sách kề là O(E)

Vậy, độ phức tạp tính toán của thuật toán BFS là O(V+E) Từ đó cũng suy ra thời giantính toán của BFS tỷ lệ tuyến tính với kích thước của danh sách kề của đồ thị G

Trang 8

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

Trong thuật toán tìm kiếm theo chiều sâu, với u là một đỉnh đã được thăm, thì mỗi khimột đỉnh v thuộc danh sách kề của u được thăm, thuật toán sẽ đánh dấu bằng cách đặttrước v một truờng πv có giá trị là u Khác với thuật toán tìm kiếm theo chiều rộng toàn

bộ đồ thị con trước đó (predecessor subgraph – là đồ thị tạo ra khi thăm các đỉnh trước

đó trong quá trình tìm kiếm) xác định một cây tìm kiếm duy nhất , trong thuật toán tìmkiếm theo chiều sâu, đồ thị con trước đó có thể xác định nhiều cây tìm kiếm khác nhaubởi thuật toán có thể được lặp lại từ nhiều đỉnh khác nhau Vì vậy đồ thị con trước đótrong thuật toán tìm kiếm theo chiều sâu được định nghĩa hơi khác một chút so với trongthuật toán tìm kiếm theo chiều rộng Ta định nghĩa như sau:

Gπ = (V, Eπ) trong đó Eπ = { ( π[v], v) : v ∈ V và π[v] # Nil }

Đồ thị con trước đó trong thuật toán tìm kiếm theo chiều sâu sẽ xác định một rừng câytìm kiếm theo chiều sâu ( a depth-first forest ) là tập hợp của các cây tìm kiếm theo chiềusâu ( deepth- first trees ).Các cạnh thuộc Eπ gọi là các cạnh của cây (tree edges)

Trong thuật toán tìm kiếm theo chiều sâu các đỉnh của đồ thị được tô màu để mô tả trạngthái của nó tại mỗi thời điểm.Các đỉnh ban đầu chưa được thăm sẽ được khởi tạo là màutrắng., khi được thăm sẽ tô màu xám và tô màu đen khi đã duyệt xong Giải thuật tô màutrên sẽ đảm bảo chính xác mỗi đỉnh chỉ được duyệt một lần, vì vậy mà các cây tìm kiếmtheo chiều sâu phân biệt được với nhau

Bên cạnh việc tạo ra một rừng cây tìm kiếm theo chiều sâu, thuật toán tìm kiếm theochiều sâu còn gán cho mỗi đỉnh một tem thời gian (timestamps) Mỗi đỉnh v sẽ có 2 temthời gian: tem thứ nhất d[v] sẽ được gán khi đỉnh v được thăm lần đầu tiên ( được tômàu xám), tem thứ hai f[v] sẽ được gán khi các đỉnh trong danh sách kề của v đã đượcduyệt (v được tô màu đen) Các tem thời gian này được sử dụng nhiều trong các thuật

Trang 9

toán đồ thị và cũng giúp ích rất nhiều cho việc mô tả quá trình thực hiện các bước trongthuật toán tìm kiếm theo chiều sâu

Thủ tục DFS dưới đây sẽ ghi lại thời điểm thăm đỉnh u lần đầu tiên trong biến d[u] vàthời điểm đỉnh u đã duyệt xong trong biến f[u] Giá trị của 2 tem thời gian d[u], f[u] làcác số nguyên nằm trong khoảng từ 1 đến 2 ?V? Với mỗi đỉnh u: d[u] < f[u] , đỉnh uđược tô màu trắng trước thời điểm d[u], màu xám trong khoảng thời gian giữa d[u] vàf[u], và màu đen sau thời điểm f[u]

Thủ tục mô phỏng thuật toán tìm kiếm theo chiều sâu, trong đó đồ thị G ban đầu có thể

vô hướng hoặc có hướng Biến time là biến chung được chúng ta sử dụng cho việc gántem thời gian

1 color[u] <- GRAY Trong khi đỉnh v chưa được thăm

2 d[u] <- time <- time + 1

3 for v ∈ Adj[u] thăm cạnh (u,v)

Trang 10

8 f[u] <- time <- time + 1

Thủ tục DFS làm việc như sau:

Dòng 1-3 sẽ tô màu tất cả các đỉnh của đồ thị là màu trắng và khởi tạo trường π của mỗiđỉnh về giá trị NIL

Dòng 4 sẽ khởi tạo lại biến đếm thời gian chung

Dòng 5-7 sẽ kiểm tra từng đỉnh thuộc tập V, khi một đỉnh màu trắng được tìm thấy, thựchiện thăm đỉnh bằng thủ tục DFS-Visit Mỗi khi thủ tục DFS- Visit(u) được gọi tại dòng

7, đỉnh u sẽ trở thành gốc của một cây tìm kiếm mới trong rừng cây tìm kiếm theo chiềusâu

Khi thủ tục DFS kết thúc , mỗi đỉnh u sẽ được gán hai tem thời gian thời gian là d[u] vàf[u]

Tại mỗi lần gọi thủ tục DFS-Visit(u):

Đỉnh u ban đầu đang được tô màu trắng

Khi thực hiện, dòng 1 sẽ tô màu xám cho đỉnh u

Dòng 2 ghi lại thời điểm đỉnh u bắt đầu được thăm lần đầu tiên vào biến time sau ki tăngbiến lên 1

Dòng 3-6 kiểm tra các đỉnh v kề với đỉnh u và thực hiện thăm v một cách đệ quy nếu

nó vẫn là đỉnh trắng Với mỗi đỉnh v được xét tại dòng 3, ta nói rằng cạnh (u,v) đã đượcthăm trong thuật toán tìm kiếm theo chiều sâu

Khi tất cả các cạnh đi từ u đã được thăm, dòng 7-8 sẽ tô màu đen cho đỉnh u và ghi lạithời điểm đỉnh u đã duyệt xong trong biến f[u]

Trang 11

Nghiã là tổng số phép toán cần thực hiện tại các dòng 2-5 của thủ tục DFS-Visit là θ (E).

Vì vậy độ phức tạp tính toán của thủ tục DFS sẽ là θ (V+E)

Một số định lý của thuật toán tìm kiếm theo chiều sâu

Quá trình tìm kiếm theo chiều sâu trên đồ thị mô tả nhiều thông tin về cấu trúc của đồthị Một trong các thuộc tính cơ bản nhất của tìm kiếm sâu là đồ thị con trước đó Gπ

sẽ xác định một rừng cây tìm kiếm sâu dần, trong đó cấu trúc của các cây tìm kiếm sâuphản ánh cấu trúc của các lệnh gọi đệ quy thủ tục DFS-VISIT Nghĩa là u=π[v] khi vàchỉ khi thủ tục DFS-VISIT được gọi trong suốt quá trình tìm kiếm các đỉnh thuộc danhsách kề của u

Để dễ hiểu ta xét ví dụ với đồ thị chỉ có 2 đỉnh là u,v: khi thăm u danh sách kề của u là

v Theo thủ tục DFS-VISIT thì quá trình tìm kiếm có thể hiểu như sau: Bước khởi tạo

sẽ tô mầu trắng cho các đỉnh và gán các đỉnh trước của nó là rỗng Sau khi gọi, thủ tụcDFS-VISIT đầu tiên sẽ tô mầu cho u là xám (thủ tục bình thường thì thường có các hànhđộng như xem xét kết thúc nhưng thủ tục ở đây đưa ra mang tính tổng quan tiếp sauchúng ta không đề cập nữa), sau đó duyệt trên danh sách kề của u thấy v thăm tiếp và tô

v mầu xám Khi xét danh sách kề của v thấy không còn đỉnh nào, tô màu đen cho đỉnh

v và quay trở lại thăm gốc u Như vậy ta có thể thấy nó tạo thành một cây có 2 nút u, v,

và quá trình thăm mỗi nút chính là thực hiện gọi thủ tục đệ quy DFS-VISIT

Đối với đồ thị tổng quát nhiều đỉnh hơn thì cũng thực hiện tương tự

Một thuộc tính quan trọng khác của tìm kiếm sâu trên đồ thị là các lần thăm và kết thúcthăm đỉnh đều có cấu trúc ngoặc đơn (parenthesis structure) Nghĩa là nếu chúng ta biểudiễn quá trình bắt đầu thăm một đỉnh u (chẳng hạn có thể dùng stack, ) bằng một dấu

ngoặc trái trước u: ”(u”, quá trình kết thúc thăm u bằng một dấu ngoặc phải sau u: “u)”,

thì toàn bộ quá trình thăm và kết thúc thăm sẽ tạo ra một biểu thức có các dấu ngoặc đơnxếp lồng nhau và đối xứng hay còn gọi là có biểu thức cấu trúc ngoặc đơn

Định lý cấu trúc ngoặc đơn được đưa ra như sau:

Định lý 1 (Định lý dấu ngoặc đơn)

Khi tìm kiếm theo chiều sâu trên một đồ thị có hướng hay vô hướng G=(V,E), với 2đỉnh u và v bất kỳ, thì sẽ xảy ra một trong 3 trường hợp sau: Các khoảng [d[u],f[u]] và[d[v],f[v]] hoàn toàn rời nhau

Khoảng [d[u],f[u]] hoàn toàn nằm trong khoảng [d[v],f[v]] , và u là con của v trong câytìm kiếm sâu

Khoảng [d[v],f[v]] hoàn toàn nằm trong khoảng [d[u],f[u]] , và v là con của u trong câytìm kiếm sâu

Ngày đăng: 30/12/2015, 09:41

TỪ KHÓA LIÊN QUAN

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

TÀI LIỆU LIÊN QUAN

w