Tìm một nguồn của đồ thị chu kỳ có hướng trong thời gian tuyến tính


10

Với một đạo diễn acyclic graph D=(V,A) , một đỉnh vV là một nguồn nếu nó indegree là zero, có nghĩa là nó có vòng cung chỉ đi.

Có tồn tại một thuật toán thời gian tuyến tính để tìm một nguồn trong một biểu đồ chu kỳ có hướng?

Câu hỏi tiếp theo: Một người trong thời gian tuyến tính có thể tìm thấy tất cả các nguồn không?


2
Theo root, bạn có nghĩa là một nút có tất cả các cạnh đi và không có cạnh đến? Nếu vậy, có thể có nhiều hơn một rễ.
Paresh

Vâng, bạn đúng. Đó là lý do tại sao tôi nói "một gốc" chứ không phải "gốc".
breezeintopl

2
Trong trường hợp đó, định nghĩa không đủ cho thuật toán thời gian tuyến tính?
Paresh

3
Cấu trúc dữ liệu là gì? Bạn có được cung cấp một ma trận kề, danh sách lân cận, danh sách kề hay không? Bạn có thể kiểm tra vùng lân cận (đến) của một đỉnh theo thời gian tỷ lệ với kích thước của nó không?
Pål GD

5
Nếu bạn có nghĩa là tuyến tính trong số lượng đỉnh, bạn nên chỉ ra rằng. Ngoài ra, danh sách kề là không rõ ràng đối với các biểu đồ được định hướng - bạn có liệt kê các cạnh đến, các cạnh đi, cả trong các danh sách riêng biệt hoặc cả hai cùng nhau không?
Yuval Filmus

Câu trả lời:


20

Như Yuval đề cập, cơ sở hạ tầng rất quan trọng ở đây. Tôi sẽ cố gắng đưa ra giải pháp cho một số loại danh sách kề:

  1. Danh sách cạnh đến : Đối với mỗi nút, có một danh sách các đỉnh mà từ đó có một cạnh đến nút này. Bạn có thể chỉ cần quét tất cả các đỉnh và kiểm tra xem kích thước của danh sách kề của chúng có bằng hay không. Danh sách kích thước 0 có nghĩa là không có cạnh đến, vì vậy nút là nguồn hoặc bị ngắt kết nối. Giả sử một đồ thị được kết nối, quá trình quét từng đỉnh này sẽ cung cấp cho bạn một danh sách tất cả các nguồn (hoặc bạn có thể dừng sau khi tìm thấy một) trong thời gian O ( | V | ) - tuyến tính theo số lượng đỉnh .00O(|V|)
  2. Danh sách cạnh đi : Đối với mỗi nút, có một danh sách các đỉnh có cạnh được định hướng từ nút này. Giữ một chuỗi bit với mỗi bit đại diện cho một đỉnh, được khởi tạo thành 0. Bắt đầu từ nút đầu tiên, bắt đầu quét danh sách của nó cho các đỉnh có cạnh đi ra từ đây. Mỗi nút như vậy (lân cận) không thể là một nguồn, vì vậy hãy tiếp tục đặt bit tương ứng của chúng trong chuỗi bit. Cuối cùng, tất cả các đỉnh có bit tương ứng vẫn chưa được đặt, là các đỉnh nguồn. Bạn có thể làm điều này theo thời gian tuyến tính theo kích thước của biểu đồ - .O(|V|+|E|)
  3. Cả hai danh sách cùng nhau : Đối với mỗi đỉnh, có một danh sách hỗn hợp các đỉnh có cạnh đến hoặc từ đỉnh này, với một số thuộc tính khác cho biết trường hợp nào trong hai đỉnh thực sự là trường hợp. Cách tiếp cận tương tự như 2 ở trên, với sự bổ sung rằng bất kỳ cạnh đến nào cũng ngay lập tức loại bỏ đỉnh hiện tại (và bạn có thể đánh dấu tập bit của nó). Không giống như ở điểm 2 nơi bạn cần đi qua tất cả các đỉnh, ở đây, bạn có thể tìm thấy một số nguồn sớm hơn. Nếu bạn không dừng lại, bạn sẽ có tất cả các nguồn. Đối với cả hai trường hợp, thời gian lại là tuyến tính theo kích thước của biểu đồ - .O(|V|+|E|)
  4. Cả hai danh sách riêng biệt : Chỉ cần chọn danh sách cạnh đến và làm theo 1.

Một lưu ý phụ, nếu chọn cơ sở hạ tầng nằm trong tay bạn, bạn có thể muốn phân tích tất cả các hoạt động bạn định thực hiện và tần suất và chọn cơ sở hạ tầng phù hợp.

Chỉnh sửa: Đối với trường hợp 1, nếu bạn có một dag trong đó số lượng nguồn rất nhỏ so với (ví dụ: trong một cây có một nguồn) trong đó khoảng cách trung bình từ bất kỳ đỉnh nào đến một nguồn nhỏ so với | V | bạn chỉ muốn bất kỳ một nguồn nào, bạn có thể sử dụng thuật toán trung bình nhanh hơn (mặc dù trường hợp phức tạp tiệm cận tồi tệ nhất sẽ giống nhau). Chọn bất kỳ đỉnh nào một cách ngẫu nhiên và đi đến bất kỳ cha mẹ nào của nó (từ danh sách cạnh đến) và tiếp tục với cha mẹ của nó, cho đến khi bạn đến một nút không có cha mẹ - một nguồn. Mức tăng hiệu quả nhỏ này dành cho các loại biểu đồ rất hạn chế với thuật toán phức tạp hơn một chút.|V||V|


1
Đối với các danh sách cạnh đến, trong trường hợp bạn chỉ cần tìm một nguồn duy nhất, sẽ không nhanh hơn nếu chỉ đi theo một cạnh tùy ý để có được tiền thân, cho đến khi bạn đạt được một nguồn? Đặc biệt là nếu đồ thị phẳng, tức là khoảng cách trung bình đến mọi nguồn của mọi đỉnh nhỏ hơn nhiều so với . |V|
Simon S

|V|

Cảm ơn bạn vì câu trả lời! Tôi nghĩ những gì tôi có nghĩa là trường hợp thứ hai, danh sách đi. BTW, tại sao lại là O (| V | + | E |)? Tôi biết | E |, vì bạn phải quét tất cả các cạnh, nhưng nơi | V | từ? Cảm ơn bạn!
breezeintopl

Θ(|V|+|E|)|E|O(|V|)O(|V|2)|V|

0

O(|V|1)


3
Nếu cấu trúc dữ liệu của bạn không bao gồm danh sách các cạnh trong cho một nút, thì việc tìm cha mẹ đã mất thời gian O (m) (trong cây do đó O (n). Vì đường dẫn đến gốc của cây có thể được tuyến tính dài, đây chỉ là một giải pháp bậc hai. Nhưng nếu bạn có các cạnh trong, thì việc tìm một số nút có 0 trong các cạnh là chuyện nhỏ.
adrianN

-1

Giả sử bạn có một biểu đồ G = (V, E) được đưa ra ở định dạng danh sách kề. (để rõ ràng ở đây danh sách chứa tất cả các cạnh đi từ nguồn). Bạn có thể xây dựng nghịch đảo của đồ thị G trong thời gian tuyến tính. Sau đó, bạn có thể lặp lại trên biểu đồ nghịch đảo và thu thập tất cả các đỉnh có danh sách kề kề trống. Các đỉnh này không có cạnh đi trong biểu đồ nghịch đảo, có nghĩa là chúng không có cạnh đến trong biểu đồ gốc, do đó, đây là các đỉnh nguồn của bạn.

Thời gian chạy là tuyến tính. Việc xây dựng nghịch đảo của đồ thị mất tối đa thời gian O (| V | + | E |). Lặp lại nghịch đảo của đồ thị mất thời gian O (| V |).


1
Thành thật mà nói, tính toán nghịch đảo đồ thị có vẻ như là một vấn đề khó hơn so với việc tìm kiếm các nguồn. Tôi nghi ngờ rằng ai đó không thể tìm ra cách lấy các nguồn có thể tìm ra cách đảo ngược tất cả các cạnh.
David Richerby

@DavidR Richby bạn nói tính toán nghịch đảo đồ thị là khó hơn. Làm thế nào để bạn xác định khó hơn? Nếu đó là độ phức tạp thời gian, nó có thể được thực hiện trong thời gian tuyến tính. bạn có thể xem giải pháp tại đây [link] ( stackoverflow.com/questions / 40378152 / trên ). Câu hỏi là về một giải pháp thời gian tuyến tính tìm ra nguồn của đồ thị và giải pháp đề xuất của tôi thực hiện điều đó. Nếu bạn nghĩ rằng nó không thể cụ thể và cho tôi biết làm thế nào thuật toán của tôi không đáp ứng yêu cầu thời gian tuyến tính?
MGB

Ý tôi là khó hơn về mặt khái niệm. Bạn đang nói rằng, để giải bài tập này, người hỏi chỉ cần giải một số bài tập khác, nhưng bài tập khác đó có vẻ khó hơn bài đầu tiên.
David Richerby
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.