Cấu trúc dữ liệu để kiểm tra tất cả các tập hợp con của truy vấn cho thành viên


7

Có một cấu trúc dữ liệu hỗ trợ hiệu quả các hoạt động sau đây không?

  1. Thêm bộ
  2. Truy vấn xem bất kỳ tập hợp con của một bộ đã được thêm vào.

Điều này có thể được thực hiện với chi phí tuyến tính bằng cách kiểm tra mọi bộ được thêm trong mỗi truy vấn. Nó có thể được thực hiện hiệu quả hơn? Xác suất nhỏ của dương tính / âm tính giả được chấp nhận (ví dụ: kiểu bộ lọc Bloom).


Thậm chí có thể kiểm tra nhanh hơn o (n) nếu một số bộ được thêm vào, trong đó n là số lượng bộ được thêm vào? Làm sao?
Albert Hendriks

@alberthendriks Nếu tất cả các bộ đều là singleton, bạn có thể thực hiện trong thời gian đăng nhập, vì vậy tôi tự hỏi liệu nó có thể được thực hiện hiệu quả hơn trong cài đặt chung hơn này không
Elliot Gorokhovsky


1
Bạn có thể cho biết thêm chi tiết về bộ của bạn? Có phải chúng là bộ số nguyên? Nếu không, họ ít nhất có một trật tự yếu?
orlp

1
@ RenéG Những số nguyên này có giới hạn hay không? Nếu có, ràng buộc là gì? Bất kể, xin vui lòng chỉnh sửa thông tin này vào câu hỏi.
orlp

Câu trả lời:


2

Giả sử tất cả bộ của bạn là tập con hữu hạn của . Đặt biểu thị tập hợp các tập hợp của bạn.NSP(N)

Bạn muốn hai hoạt động:

  • O1(S,s) : Với mọi , hãy thêm vàosNsS

  • O2(S,s) : Với bất kỳ , có một số sao cho ?sNsSss


Dưới đây là một vài ý tưởng để tăng tốc mọi thứ:

  • Bạn sẽ kiểm tra xem một tập hợp nếu một tập hợp con khác rất nhiều vì vậy bạn có thể nên giữ kích thướccủa mỗi bộ có sẵn trong để khi bạn cần kiểm tra xem , bạn bắt đầu bằng cách kiểm tra xemvà nếu không, bạn có thể trả lại sai ngay lập tức. Và bạn thực sự có, sau đó bạn chỉ cần chạy thử nghiệm chậm bình thường.|s|sO(1)ss|S||S'||S||S'|

  • Lưu ý rằng nếu bạn có vàS1SS2S, vậy nên S1S2, sau đó nếu S2S', bạn cũng có S1S'. Vì vậy, bạn không cần phải giữS2 trong S cho Ôi2. Vì vậy, bạn có thể đại diệnS bởi một bộ các tập hợp sao cho SSSS'ngụ ý . Nói cách khác, bạn chỉ cần theo dõi các tập hợp trong là tối thiểu để đưa vào. Điều này có thể được thực hiện khá hiệu quả: Khi thêm một bộ , cho tất cả các bộ sao cho(được sắp xếp bằng cách tăng hồng y), nếu , thì đừng thêm vì nó sẽ không ở mức tối thiểu (hoặc đã có trong ). Mặt khác, thêm và sau đó trong số các bộ sao cho, xóa những cái đó để (vì chúng không còn tối thiểu nữa).S'SSS'SS|S||S'|SS'S'SS'SS|S'|<|S|S'S

  • Giữ một tập rằng nhân bằng để sự kết hợp của tất cả các bộ trong . Sau đó, thay vì chạy , bạn có thể chạy (vì nếu với một số , , thì kể từ , và, nếu , thì ).tSÔi2(S,S')Ôi2(S,S't)SSSS'StSS'tSS'tSS'tS'

Với những ý tưởng trong tâm trí, tôi muốn đại diện cho bởi một dictionnary (thực hiện như một danh sách gấp đôi liên kết của các cặp với các phím theo thứ tự tăng) sao cho là một danh sách gấp đôi liên kết có chứa chính xác bộ tối thiểu (để bao gồm) trong của hồng y .S(key,vmộttôibạne)dd(k)Sk

O1(S,s')
  if O2(S,s')
    return
  if d(k) doesn't exist
    d(k) := new_doubly_linked_list()
  add(d(k),s')
  S.t := union(S.t, s')
  for each key k of d so that |s'|+1 <= k
    for s in d(k)
      if subset(s', s)
        remove s

_O2(S,s')
  for each key k of d so that k <= |s'|
    for s in d(k)
      if subset(s,s')
        return true
  return false

O2(S,s')
  return _O2(S,inter(S.t,s'))

(Lưu ý rằng mặc dù tôi đã không làm điều đó một cách rõ ràng trong mã của O1, bạn có thể thực hiện một giao dịch duy nhất của danh sách liên kết gấp đôi đại diện d)

Tôi không nghĩ rằng điều này cải thiện quá nhiều trong trường hợp xấu nhất nhưng trung bình thì nên.


Chúng trông giống như những cải tiến thực tế hữu ích. Nhưng tôi nghĩ bạn có nghĩa là nên là một danh sách các cấu trúc dữ liệu bản đồ được liên kết (bản thân chúng có thể là danh sách được liên kết theo thứ tự theo khóa - mặc dù hashtables hoặc cây cân bằng sẽ nhanh hơn nhiều). d
j_random_hacker

3
Cũng liên quan đến đề xuất thứ hai của bạn, trong trường hợp xấu nhất vẫn có thể có , không có bộ nào bao gồm bộ kia, theo Định lý của Sperner . Điều này xảy ra khi vũ trụ có phần tử và bạn thêm tất cả các tập hợp kích thước . (nn2)nn2
j_random_hacker

Cuối cùng, tôi nghĩ rằng bạn có "hướng" của truy vấn sai cách - tôi lấy câu hỏi của OP để hỏi liệu có tập hợp con nào đã được thêm vào có chứa bộ truy vấn không. Tất nhiên, điều này có thể được khắc phục một cách dễ dàng (theo luật của DeMorgan, bạn thậm chí có thể chỉ "bao bọc" việc thực hiện của mình bằng các hàm "đảo ngược" tất cả các bộ đầu vào (nghĩa là lấy sự khác biệt đối xứng với vũ trụ) và cũng đảo ngược giá trị trả về của truy vấn ).
j_random_hacker

Trong viên đạn thứ hai của bạn, s nên là một tập hợp con nghiêm ngặt để ngụ ý không phải là thành viên. Dù sao, tôi nghĩ rằng câu trả lời này có lẽ là tốt nhất có thể, vì vậy tôi sẽ chấp nhận nó.
Elliot Gorokhovsky

@j_random_hacker Đúng, nhưng bạn chỉ cần một bộ (tức là ánh xạ tới đơn vị). Nếu tôi biểu thị bằng thứ tự từ điển trên các tập hợp được đưa ra bằng cách xem chúng là các hàm từ vũ trụ đến , thì bản đồ có thể được thực hiện bằng cách sử dụng thứ tự đó và các cây cân bằng. Hoặc cách khác, biểu diễn nó dưới dạng sơ đồ quyết định nhị phân và đặt giá trị được liên kết với khóa trong lá tương ứng. tôiex{0,1}
xavierm02
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.