Một thuật toán tra cứu tập hợp con


9

Giả sử tôi có một danh sách X các tập con của {1,...,n} . Tôi có thể làm tiền xử lý trong danh sách này nếu cần thiết. Sau quá trình tiền xử lý này, tôi được trình bày với một bộ Một{1,...,n} . Tôi muốn xác định bất kỳ bộ BX với BMột .

Thuật toán rõ ràng (không có bất kỳ tiền xử lý nào) cần có thời gian Ôi(n|X|) - bạn chỉ cần kiểm tra Một với từng BX riêng biệt. Có điều gì tốt hơn thế này không?

Nếu hữu ích, bạn có thể giả định rằng, đối với bất kỳ Một , tổng số các trận đấu BX được bao bọc bởi một cái gì đó như Ôi(1) .

Câu trả lời:


3

Đây không phải là một câu trả lời. Đó là một quan sát đơn giản nhưng dài. Tôi hy vọng nó sẽ hữu ích.

Phiên bản quyết định của vấn đề của bạn là: có chứa tập hợp con của A không?XMột

Vấn đề này liên quan đến vấn đề đánh giá các hàm boolean đơn điệu của biến. Một tập hợp con của { 1 , ... , n } là tương đương với một n -bitstring, vì vậy gia đình X tương đương với một hàm boolean f của n biến. Với một hàm f , người ta có thể xác định các chức năng đơn điệu nhất đó là không lớn hơn f , cụ thể là g ( y ) = ( x y ,n{1,Giáo dục,n}nXfnff . Vấn đề ban đầu sau đó được giảm xuống để đánh giá g ( A ) . Ngược lại, vấn đề đánh giá hàm boolean đơn điệu có thể được giảm xuống thành vấn đề ban đầu, hoặc là ngây thơ bằng cách lấy f = g hoặc bằng cách chọn một f làm cho X nhỏ hơn.g(y)= =(xy,f(x))g(Một)f= =gfX

Trong thực tế, BDD có xu hướng hoạt động tốt. Vì vậy, một cách tiếp cận khả thi là xây dựng BDD cho , xuất phát từ nó là BDD cho g , sau đó đánh giá g . Kích thước trung bình của BDD cho g phải là Ω ( ( nfggg, vìcó nhiều hàm boolean đơn điệu. Do đó, trên lý thuyết đây là một giải pháp tồi.Ω((nn/2))

Nhưng (1) một phân tích tốt hơn có thể là có thể và (2) có thể có những điều chỉnh đối với phương pháp này làm cho nó tốt hơn. Ví dụ, tôi đã không sử dụng theo bất kỳ cách nào mối tương quan giữa kích thước của và kích thước của BDD của g . (Phải có một mối tương quan, nhưng tôi không biết nó đơn giản hay có thể sử dụng được ở đây.)Xg

Để hoàn thiện, một thuật toán đơn giản để tính toán BDD cho từ BDD cho f là như sau. m ( x ? f 1 : f 0 ) = x ? ( m ( f 0 ) m ( f 1 ) ) : m ( f 0 ) Ở đây là tiêu chuẩn hoặc hoạt động trên các BDD.gf

m(x?f1:f0)= =x?(m(f0)m(f1)):m(f0)

2
{1,2,...,n}2nÔi(n)Một

Sử dụng không gian theo cấp số nhân để lưu trữ dữ liệu được xử lý trước nghe có vẻ như gian lận đối với tôi, mặc dù điều đó không bị cấm trong câu hỏi. Nhưng tôi có thể bị thiên vị đối với Giáo hội phức tạp nhất.
Tsuyoshi Ito

mjqxxxx và Tsuyoshi: Tôi đồng ý với cả hai bạn. Tôi viết lại văn bản để tôi hy vọng, rõ ràng hơn là tôi đồng ý. :)
Radu GRIGore

3

Có lẽ bạn có thể sử dụng kỹ thuật "truy xuất thông tin": trong giai đoạn tiền xử lý, xây dựng một chỉ mục đảo ngược (trong trường hợp của bạn là một n×|X|xTôi{1,...,n}XTôinv(xTôi)= ={XjX|xTôiXj}

occ|X|

Sau đó, với mỗi lấy i n v (yTôiMộtTôinv(yTôi)XjTôinv(yTôi)occ[j]= =occ[j]+1

|Xj|= =occ[j]

Bạn có thể tùy ý tăng tốc quá trình (với chi phí không gian theo cấp số nhân) bằng cách lập chỉ mục hai hoặc nhiều phần tử với nhau.

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.