2013-08-06 27 views
9

Tôi phải phát triển thuật toán O (| V | + | E |) liên quan đến kiểu topo, trong biểu đồ tuần hoàn hướng (DAG), xác định số lượng đường đi từ mỗi đỉnh của đồ thị là t (t là một nút có độ lệch 0). Tôi đã phát triển một biến thể của DFS như sau:Loại topo để tìm số đường dẫn đến t

DFS(G,t): 
    for each vertex u ∈ V do 
     color(u) = WHITE 
     paths_to_t(u) = 0 
    for each vertex u ∈ V do 
     if color(u) == WHITE then 
      DFS-Visit(u,t) 

DFS-Visit(u,t): 
    color(u) = GREY 
    for each v ∈ neighbors(u) do 
     if v == t then 
      paths_to_t(u) = paths_to_t(u) + 1 
     else then 
      if color(v) == WHITE then 
       DFS-Visit(v) 
      paths_to_t(u) = paths_to_t(u) + paths_to_t(v) 
    color(u) = BLACK 

Nhưng tôi không chắc chắn nếu thuật toán này có liên quan đến loại topo hoặc nếu tôi nên cơ cấu lại công việc của mình với một góc độ khác.

+0

tôi giả sử đồ thị của bạn là một DAG (nếu không có điểm trên nói về loại topo, cũng không phải về số con đường, có thể có vô số những) – amit

+0

@amit Vâng, Tôi đặt trong câu hỏi "đồ thị tuần hoàn hướng". Tôi đã chỉnh sửa để thêm từ viết tắt "DAG" – Stratford

+2

Bản ngã của bạn là chính xác, bạn sẽ tìm thấy số cách để t. Và bạn làm điều đó theo phương thức topo: ngay khi u đỉnh có màu đen, giá trị path_to_t (u) là chính xác - nó tương ứng với việc đẩy đỉnh trong ngăn xếp trong bản ngã loại topo. –

Trả lời

8

Nó có thể được thực hiện bằng động Lập trình và sắp xếp topo như sau:

Topological sort the vertices, let the ordered vertices be v1,v2,...,vn 
create new array of size t, let it be arr 
init: arr[t] = 1 
for i from t-1 to 1 (descending, inclusive): 
    arr[i] = 0 
    for each edge (v_i,v_j) such that i < j <= t: 
     arr[i] += arr[j] 

Khi bạn làm xong, cho mỗi i trong [1,t], arr[i] cho biết số đường dẫn vi-vt

Bây giờ , chứng minh tuyên bố ở trên là dễ dàng (so sánh với thuật toán của bạn, mà tôi không biết nếu nó chính xác và cách chứng minh nó), nó được thực hiện bằng cách cảm ứng:

Cơ sở:arr[t] == 1 và thực sự có một đường đơn từ t đến t, dấu trống.
Giả thuyết: Lời khẳng định là đúng cho mỗi k trong phạm vi m < k <= t
Proof: Chúng tôi cần phải chứng minh tuyên bố là chính xác cho m.
Hãy xem từng cạnh ngoài từ vm: (v_m,v_i).
Do đó, số đường dẫn đến vt bắt đầu từ v_m sử dụng cạnh này (v_m,v_i). chính xác là arr[i] (giả thuyết cảm ứng). Tổng hợp tất cả các khả năng của các cạnh ngoài từ v_m, cung cấp cho chúng tôi tổng số đường dẫn từ v_m đến v_t - và đây chính xác là những gì thuật toán làm.
Như vậy, arr[m] = #paths from v_m to v_t

QED

Thời gian phức tạp:
Bước đầu tiên (topo loại) mất O(V+E).
Vòng lặp lặp lại tất cả các cạnh một lần và tất cả các đỉnh một lần, vì vậy nó cũng là O(V+E).
này cho chúng ta tổng phức tạp của O(V+E)

+0

Tôi không thực sự biết cách hoạt động của chương trình động. :(Tôi quên để chỉ ra rằng các thuật toán nên được trong O (| V | + | E |) – Stratford

+0

@Stratford tôi thêm một bằng chứng chính xác cho các thuật toán và tối ưu hóa nhỏ đảm bảo thời gian phức tạp là 'O (V + E) '.Lập trình động là một kỹ thuật mà chúng tôi xây dựng các giải pháp từ trường hợp nhỏ "dễ", đến giải pháp tổng thể cho vấn đề, và đây là vòng lặp sau khi loại topo thực hiện trong mã giả. – amit

+0

DP không cần thiết ở đây. Tại sao bận tâm và liệt kê các cạnh một lần nữa, nếu anh ta đã làm công việc trong DFS? –

Các vấn đề liên quan