6

Tôi đang tìm một cấu trúc dữ liệu tốt để xây dựng các lớp tương đương trên các nút của cây. Trong một cấu trúc lý tưởng, các hoạt động sau phải nhanh (O (1)/O (n) khi thích hợp) và dễ dàng (không có đoạn mã bí ẩn):Cấu trúc dữ liệu tốt để xây dựng các lớp tương đương trên các nút của cây là gì?

  • (A) Đi bộ từ gốc; trên mỗi nút -> chuyển đổi con liệt kê tất cả các phiên bản tương đương của nút con
  • (B) Hợp nhất hai lớp tương đương
  • (C) Tạo nút mới từ danh sách các nút hiện có (trẻ em) và các dữ liệu khác
  • (D) Tìm bất kỳ nút nào có cấu trúc tương đương với nút (nghĩa là chúng có cùng số lượng con, con tương ứng thuộc cùng một lớp tương đương, và "dữ liệu khác" của chúng bằng nhau) để các nút mới (hoặc mới được sửa đổi) có thể được đưa vào lớp tương đương phù hợp (thông qua hợp nhất)

Cho đến nay tôi đã xem xét (một số có thể được sử dụng kết hợp):

  • Một parfait, nơi trẻ em tham chiếu đến bộ sưu tập các nút thay vì các nút. (A) là nhanh, (B) yêu cầu đi bộ cây và cập nhật các nút để trỏ đến bộ sưu tập đã hợp nhất, (C) yêu cầu tìm bộ sưu tập chứa mỗi con của nút mới, (D) yêu cầu đi bộ cây
  • Duy trì một băm của các nút theo đặc điểm của chúng. Điều này làm cho (D) nhanh hơn nhiều nhưng (B) chậm hơn (vì băm sẽ phải được cập nhật khi các lớp tương đương được sáp nhập)
  • Ghép các nút lại với nhau thành một danh sách liên kết vòng tròn. (A) là nhanh, (B) sẽ được nhanh chóng, nhưng thực tế là "sáp nhập" một phần của một danh sách tròn với chính nó thực sự chia danh sách (C) sẽ được nhanh chóng, (D) sẽ yêu cầu đi bộ cây
  • Giống như ở trên, nhưng với một con trỏ "lên" bổ sung trong mỗi nút, có thể được sử dụng để tìm một thành viên kinh điển của danh sách vòng tròn.

Tôi có thiếu lựa chọn ngọt ngào không?

+1

Thẻ phải là thuật toán chứ không phải thuật toán. – ashawley

Trả lời

4

Bạn dường như có hai hình thức tương đương để giải quyết. Tương đương đồng bằng (A), được theo dõi là các lớp tương đương được giữ cho đến nay và tương đương cấu trúc (D), mà bạn thỉnh thoảng đi xây dựng một lớp tương đương duy nhất và sau đó vứt nó đi.

Nghe có vẻ như vấn đề sẽ đơn giản hơn nếu bạn duy trì các lớp tương đương cho cả sự tương đương đơn giản lẫn cấu trúc. Nếu điều đó giới thiệu quá nhiều churn cho tương đương cấu trúc, bạn có thể duy trì các lớp tương đương cho một số khía cạnh tương đương về cấu trúc. Sau đó, bạn có thể tìm thấy một sự cân bằng, nơi bạn có thể đủ khả năng duy trì các lớp tương đương nhưng vẫn làm giảm đáng kể số lượng các nút để kiểm tra khi xây dựng một danh sách các nút tương đương về mặt cấu trúc.

+0

"Tương đương về cấu trúc" là một chỉ mục, để tạo điều kiện cho việc khám phá các kết quả mới (ví dụ: nếu tôi biết A: {x = sqrt (z + a + 7)} và B: {y = sqrt (z + b + 7)} sau đó tìm hiểu C: {a = b} nó tạo điều kiện phát hiện ra rằng tôi có thể hợp nhất A và B). Nhưng đề xuất của bạn có ý nghĩa (ví dụ: lập chỉ mục chúng theo toán tử cấp cao nhất). – MarkusQ

3

Tôi không nghĩ rằng bất kỳ cấu trúc nào sẽ giải quyết vấn đề của bạn, nhưng bạn có thể xem qua số Disjoint-set data structure. Một lớp tương đương, sau khi tất cả, là điều tương tự như một phân vùng của một tập hợp. Nó sẽ có thể xử lý một số hoạt động đó một cách nhanh chóng.

+0

Các giải pháp được nêu trong liên kết về cơ bản là một tập con của những cái mà tôi liệt kê ở trên (với ngoại lệ nhỏ làm phẳng cây, mà tôi coi là một phần ẩn của trường hợp con trỏ lên). Câu trả lời của bạn là "không, bạn không bỏ lỡ bất kỳ lựa chọn thay thế ngọt ngào nào"? – MarkusQ

1

Quay lại một lúc tôi khuyên bạn không nên sử dụng cây. Lần trước tôi phải đối mặt với một vấn đề tương tự, tôi bắt đầu với một cái cây, nhưng sau đó chuyển sang một mảng.Lý do là nhiều nhưng lý do số một là hiệu suất, các lớp của tôi có tới 100 hoặc hơn con thực sự sẽ hoạt động tốt hơn trong khi thao tác chúng như mảng hơn là thông qua các nút của cây, chủ yếu là do địa phương phần cứng và tìm nạp trước CPU logic, và CPU pipelining. Vì vậy, mặc dù theo thuật toán một cấu trúc mảng đòi hỏi một N hoạt động lớn hơn một cây, thực hiện hàng chục hoạt động này có khả năng nhanh hơn so với theo dõi con trỏ trên bộ nhớ.

+0

Vâng, "cây" có thể sẽ được lưu trữ dưới dạng một mảng TAC hoặc một số loại như vậy. Nhưng do bản chất của thuật toán tổng thể, tôi nghĩ rằng địa phương đang gặp rủi ro. – MarkusQ

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