2010-12-28 38 views
5

Giả sử chúng tôi có hàng nghìn tỷ tập được lưu ở đâu đó. Tên miền cho từng bộ này giống nhau. Nó cũng hữu hạn và rời rạc. Vì vậy, mỗi bộ có thể được lưu trữ dưới dạng một trường bit (ví dụ: 0000100111 ...) có độ dài tương đối ngắn (ví dụ: 1024). Nghĩa là, bit X trong bitfield cho biết liệu mục X (trong số 1024 mục có thể) có được bao gồm trong tập hợp đã cho hay không.Cách nhanh nhất để thực hiện thao tác kiểm tra tập hợp con trên một tập hợp lớn các tập hợp có cùng tên miền

Bây giờ, tôi muốn đưa ra một cấu trúc lưu trữ và một thuật toán để trả lời một cách hiệu quả truy vấn: những gì đặt trong kho dữ liệu đã đặt Y làm tập hợp con. Đặt Y chính nó không có trong kho dữ liệu và được chỉ định tại thời gian chạy. Bây giờ cách đơn giản nhất để giải quyết vấn đề này là AND và bitfield cho Y đặt bằng các trường bit của mỗi tập hợp trong kho dữ liệu từng cái một, chọn những kết quả AND có kết quả khớp với bit của Y.

Làm cách nào để tăng tốc độ này? Có một cấu trúc cây (chỉ mục) hoặc một số thuật toán thông minh mà sẽ cho phép tôi thực hiện truy vấn này mà không cần phải AND và mỗi bitfield của bộ lưu trữ?

Có cơ sở dữ liệu nào đã hỗ trợ các hoạt động đó trên các bộ sưu tập lớn không?

+0

Bạn đang sử dụng loại cơ sở dữ liệu nào? Một định dạng độc quyền? SQL Server? –

+0

Sự lựa chọn của DB sẽ phụ thuộc vào việc nó có hiệu quả hỗ trợ các hoạt động thiết lập đã cho trên các tập humongous hay không. Không có DBS SQL nào sẽ mở rộng đến kích thước được yêu cầu (DBMS DBs sẽ là một lựa chọn không tốt cho vấn đề này). Vì vậy, sự lựa chọn là một DB chuyên ngành hoặc một DB mà tôi sẽ thực hiện bản thân mình. – niktech

+0

Bạn đã tìm thấy một số giải pháp? Thật kỳ lạ là không có cơ sở dữ liệu nổi tiếng cho nhiệm vụ này. – actual

Trả lời

0

Tôi có xu hướng nói rằng câu trả lời là không, bởi vì trường bit bitin rất thấp.

0

Điều này có thể kéo dài trên RDBMS thông thường dựa trên khối lượng của bạn, bạn đã xem Neo4j dựa trên mô hình lưu trữ biểu đồ chưa?

+1

Liệu nó có hiệu quả hỗ trợ làm việc với các bộ lớn?Từ sự hiểu biết của tôi nó hữu ích hơn cho việc lưu trữ các đồ thị, không phải các bộ. – niktech

4

Nếu bạn có thể tiền xử lý các tập hợp, quan hệ tập hợp con có thể biểu diễn dưới dạng DAG (vì bạn mô tả một điểm đặt). Nếu tính toán giảm tính chuyển tiếp, thì tôi nghĩ bạn có thể tránh kiểm tra tất cả các bộ bằng cách chỉ thực hiện DFS bắt đầu từ các tập hợp lớn nhất và dừng bất cứ khi nào Y không còn là tập con của tập hiện tại đang được truy cập.

+0

Bạn có thể xây dựng? Về cơ bản bạn đang nói về việc xây dựng một DAG như sau http://en.wikipedia.org/wiki/File:Hypercubeorder_binary.svg nhưng chỉ với các nút từ bộ sưu tập các tập hợp hiện có? Làm cách nào để chọn nút khởi đầu khi tôi thực hiện DFS? – niktech

+2

vâng, về cơ bản. có một cạnh từ một tập A đến một bộ B nếu A là bội số của B. Sử dụng tính năng giảm chuyển tiếp là tốt hơn vì số cạnh giảm (do đó hệ số phân nhánh cũng sẽ giảm để các nút vô dụng ít được kiểm tra). Kể từ khi đồ thị là tuần hoàn, sẽ có một tập hợp các nút mà không có cạnh mà nhập chúng, và bạn có thể bắt đầu từ đó (những đại diện cho các bộ mà không có supersets trong bộ sưu tập của bạn). Bạn sẽ phải bắt đầu DFS trên tất cả các (hoặc chỉ bắt đầu từ một nút ảo kết nối với tất cả các bộ-với-không-supersets). – lijie

+0

Thú vị. Tôi sẽ giữ cho thuật toán này trong tâm trí, mặc dù bộ sưu tập các bộ trong kho dữ liệu là không có nhiều mối quan hệ con/superset trong nó, vì vậy tôi sẽ kết thúc làm DFS trên rất nhiều nút bắt đầu. – niktech

1

Tùy thuộc vào cardinality của tập hợp mà từ đó tất cả các bộ được vẽ, một tùy chọn có thể là xây dựng ánh xạ chỉ mục ngược từ các phần tử đến các bộ chứa chúng. Với một tập Y, bạn có thể tìm thấy tất cả các tập hợp có Y như một tập hợp con bằng cách tìm tất cả các tập hợp chứa từng phần tử riêng lẻ và tính toán giao điểm của chúng. Nếu bạn lưu trữ các danh sách theo thứ tự sắp xếp (ví dụ, bằng cách đánh số tất cả các bộ trong cơ sở dữ liệu của bạn với các giá trị 0, 1, v.v.) thì bạn sẽ có thể tính toán giao lộ này một cách hiệu quả, giả sử rằng không có phần tử nào được chứa trong quá nhiều bộ.

+0

Điểm tốt. Cardinality của các bộ trong kho dữ liệu là ~ <= 1024. Bây giờ phần khôn lanh sẽ làm giao lộ một cách hiệu quả. Kết quả của giao lộ có thể lớn bằng toàn bộ tập hợp các bộ hoặc nhỏ như vài chục bộ. Bạn sẽ đề xuất các thuật toán giao lộ nào? – niktech

+0

Tôi biết rằng trong trường hợp bạn có hai chuỗi sắp xếp và muốn tính toán giao lộ, bạn có thể làm như vậy bằng cách lặp lại những điều sau: trong khi hai danh sách không trống, hãy xem giá trị đầu tiên của mỗi chuỗi. Nếu chúng không giống nhau, hãy loại bỏ phần nhỏ hơn của cả hai. Nếu chúng giống nhau, thì bạn đã phát hiện một giá trị trong giao lộ. Điều này chạy theo thời gian O (n + m), trong đó n và m là độ dài của hai chuỗi. Nếu bạn chạy thủ tục này trên các cặp chuỗi, sau đó trên các kết quả, vv điều này chạy trong O (n lg k), trong đó k là số chuỗi và n chiều dài tối đa của một chuỗi. – templatetypedef

0

Nhìn lướt qua làm cho tôi nghĩ về BDD - điều này phần nào theo ý tưởng của giải pháp DAG. Ngoài ra một ZDD.

0

Nếu một RDBMS là lựa chọn duy nhất của bạn, tôi sẽ khuyên bạn nên nhìn vào bài viết thú vị này trên mô hình một DAG trong SQL:

http://www.codeproject.com/KB/database/Modeling_DAGs_on_SQL_DBs.aspx?msg=3051183

Nếu bạn không thể đủ khả năng Oracle hoặc MSSQL, có một cái nhìn tại PostgresQL 9, hỗ trợ truy vấn đệ quy. Nó cũng hỗ trợ tham gia chéo trong một thời gian khá dài.

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