Khi nào danh sách kề hoặc ma trận là sự lựa chọn tốt hơn?


14

Tôi được cho biết rằng chúng tôi sẽ sử dụng một danh sách nếu biểu đồ thưa thớt và ma trận nếu biểu đồ dày đặc . Đối với tôi, đó chỉ là một định nghĩa thô. Tôi không thấy nhiều hơn thế. Bạn có thể làm rõ khi nào nó sẽ là sự lựa chọn tự nhiên để thực hiện?

Cảm ơn trước!



Đó không phải là một định nghĩa, chủ yếu là vì không có định nghĩa duy nhất về "thưa thớt" và "dày đặc". Ngoài ra, có những cân nhắc khác, ví dụ như các khía cạnh của biểu đồ bạn truy cập thường xuyên.
Raphael

@Raphael Bạn có thể đi sâu vào chi tiết hơn về những cân nhắc khác không?
dùng21312

1
@ user21312, một sự khác biệt lớn là khả năng lặp lại so với quyền truy cập của các cạnh. Nếu bạn thường cần lặp đi lặp lại trên các cạnh thì danh sách điều chỉnh có thể hữu ích hơn. Nếu bạn thường cần xác định xem một cạnh tồn tại hoặc truy cập trọng lượng của nó (hoặc thông tin khác) thì ma trận có thể tốt hơn.
ryan

Với mục đích của bạn, có lẽ chúng ta có thể bất cẩn về định nghĩa 'thưa thớt' và 'dày đặc' là gì. Chỉ cần mô hình hóa độ phức tạp thời gian của hoạt động ma trận mà bạn muốn sử dụng cho từng loại cơ sở hạ tầng và xem 'điểm phá vỡ mật độ' nằm ở đâu. Tôi nghĩ rằng liên kết thứ hai của @ryan đang cố gắng làm điều gì đó tương tự
Apiwat Chantawibul

Câu trả lời:


16

Trước hết lưu ý rằng thưa thớt có nghĩa là bạn có rất ít cạnh và dày đặc có nghĩa là nhiều cạnh hoặc đồ thị gần như hoàn chỉnh. Trong một đồ thị hoàn chỉnh, bạn có cạnh, trong đó n là số nút.n(n1)/2n

Bây giờ, khi chúng ta sử dụng đại diện ma trận chúng tôi phân bổ ma trận để lưu trữ thông tin nút-kết nối, ví dụ, M [ i ] [ j ] = 1 nếu có cạnh giữa các nút ij , nếu không M [ i ] [ j ] = 0 . Nhưng nếu chúng ta sử dụng danh sách kề thì chúng ta có một mảng các nút và mỗi nút trỏ đến danh sách kề của nó chứa CHỈ các nút lân cận .n×nM[i][j]=1ijM[i][j]=0

Bây giờ nếu một biểu đồ thưa thớt và chúng tôi sử dụng biểu diễn ma trận thì hầu hết các ô ma trận vẫn không được sử dụng dẫn đến lãng phí bộ nhớ. Vì vậy, chúng ta thường không sử dụng biểu diễn ma trận cho các biểu đồ thưa thớt. Chúng tôi thích danh sách kề.

Nhưng nếu đồ thị dày đặc thì số cạnh gần với (hoàn thành) hoặc đến n 2 nếu đồ thị được định hướng bằng các vòng tự. Sau đó, không có lợi thế của việc sử dụng danh sách kề trong ma trận.n(n1)/2n2

Về độ phức tạp không gian
Ma trận điều chỉnh: Danh sách điều chỉnh: O ( n + m ) trong đó n là các nút số, m là số cạnh.O(n2)
O(n+m)
nm

Khi biểu đồ là cây vô hướng thì
ma trận Adjacency: Danh sách điều chỉnh: O ( n + n )O ( n ) (tốt hơn n 2 )O(n2)
O(n+n)O(n)n2

Khi đồ thị được định hướng, hoàn thành, với các vòng lặp tự lập thì
ma trận điều chỉnh: Danh sách điều chỉnh: O ( n + n 2 )O ( n 2 ) (không có sự khác biệt)O(n2)
O(n+n2)O(n2)

Và cuối cùng, khi bạn triển khai sử dụng ma trận, kiểm tra xem có một cạnh giữa hai nút mất lần hay không, trong khi với danh sách kề, nó có thể mất thời gian tuyến tính trong n .O(1)n


"trong khi với danh sách kề, có thể mất thời gian tuyến tính" - Cho rằng danh sách kề của bạn (có thể) thiếu bất kỳ thứ tự tự nhiên nào, tại sao nó là danh sách thay vì bộ băm?
Kevin

1
@Kevin Sau đó, nó sẽ được gọi là "băm kề" thay vì "danh sách". Cũng có thể, tại sao không? Nhưng nếu bạn chỉ đơn giản thực hiện DFS hoặc BFS, hoặc một số thủ tục khác quét một cách có hệ thống tất cả các nút thì lợi thế của việc sử dụng hàm băm qua danh sách là gì? Trong mọi trường hợp, bạn sẽ kiểm tra tất cả các nút liền kề.
fade2black

3
Tôi sẽ nói thêm rằng trong trường hợp không có trọng số không có trọng số, đối với một biểu đồ gần như hoàn chỉnh , có thể khả thi hơn để lưu trữ phần bù của nó, tức là một biểu đồ thưa thớt. Vì vậy, một ma trận rất hữu ích khi có khoảng một nửa các cạnh.
M. Mùa đông

3

Để trả lời bằng cách cung cấp một sự tương tự đơn giản .. Nếu bạn phải lưu trữ 6oz nước, bạn (nói chung) sẽ làm như vậy với một thùng chứa 5 gallon, hoặc một cốc 8oz?

Bây giờ, trở lại câu hỏi của bạn .. Nếu phần lớn ma trận của bạn trống, thì tại sao lại sử dụng nó? Chỉ cần liệt kê từng giá trị thay thế. Tuy nhiên, nếu danh sách của bạn thực sự dài, tại sao không sử dụng ma trận để ngưng tụ nó?

Lý do đằng sau danh sách vs ma trận thực sự là đơn giản trong trường hợp này.

PS một danh sách thực sự chỉ là một ma trận cột duy nhất !!! (cố gắng chỉ cho bạn thấy mức độ tùy tiện của quyết định / kịch bản này)


2

Xét một đồ thị có nút và cạnh E. Bỏ qua các điều khoản có thứ tự thấp, một ma trận bit cho đồ thị sử dụng N 2 bit cho dù có bao nhiêu cạnh.NEN2

Bạn thực sự cần bao nhiêu bit?

Giả sử rằng các cạnh là độc lập, số lượng đồ thị có nút và cạnh E( N 2NE . Số bit tối thiểu cần thiết để lưu trữ tập hợp con này làlog2 ( N2(N2E) .log2(N2E)

Chúng tôi sẽ giả định mà không mất tính tổng quát mà , đó là một nửa hoặc ít hơn các cạnh có mặt. Nếu đây không phải là trường hợp, chúng ta có thể lưu trữ tập hợp "không cạnh".EN22

Nếu ,đăng nhập2 ( N 2E=N22, do đó biểu diễn ma trận là tối ưu không có triệu chứng. NếuEN2, sử dụng phép tính gần đúng của Stirling và một số học nhỏ, chúng ta thấy:đăng nhập2(N2E)= =N2+o(N2)E«N2

=log2(N2)!

đăng nhập2(N2E)
=2Elog2N+O(điều khoản đặt hàng thấp)
= =đăng nhập2(N2)!E!(N2-E)!
= =2Eđăng nhập2N+Ôi(điều khoản đặt hàng thấp)

đăng nhập2N2E

p= =EN2-đăng nhập2p(1-p)p12

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.